xref: /OK3568_Linux_fs/kernel/drivers/rknpu/rknpu_debugger.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) Rockchip Electronics Co.Ltd
4  * Author: Felix Zeng <felix.zeng@rock-chips.com>
5  */
6 
7 #include <linux/slab.h>
8 #include <linux/delay.h>
9 #include <linux/syscalls.h>
10 #include <linux/debugfs.h>
11 #include <linux/proc_fs.h>
12 #include <linux/devfreq.h>
13 #include <linux/clk.h>
14 #include <asm/div64.h>
15 
16 #ifndef FPGA_PLATFORM
17 #ifdef CONFIG_PM_DEVFREQ
18 #include <../drivers/devfreq/governor.h>
19 #endif
20 #endif
21 
22 #include "rknpu_drv.h"
23 #include "rknpu_mm.h"
24 #include "rknpu_reset.h"
25 #include "rknpu_debugger.h"
26 
27 #define RKNPU_DEBUGGER_ROOT_NAME "rknpu"
28 
29 #if defined(CONFIG_ROCKCHIP_RKNPU_DEBUG_FS) ||                                 \
30 	defined(CONFIG_ROCKCHIP_RKNPU_PROC_FS)
rknpu_version_show(struct seq_file * m,void * data)31 static int rknpu_version_show(struct seq_file *m, void *data)
32 {
33 	seq_printf(m, "%s: v%d.%d.%d\n", DRIVER_DESC, DRIVER_MAJOR,
34 		   DRIVER_MINOR, DRIVER_PATCHLEVEL);
35 
36 	return 0;
37 }
38 
rknpu_load_show(struct seq_file * m,void * data)39 static int rknpu_load_show(struct seq_file *m, void *data)
40 {
41 	struct rknpu_debugger_node *node = m->private;
42 	struct rknpu_debugger *debugger = node->debugger;
43 	struct rknpu_device *rknpu_dev =
44 		container_of(debugger, struct rknpu_device, debugger);
45 	struct rknpu_subcore_data *subcore_data = NULL;
46 	unsigned long flags;
47 	int i;
48 	int load;
49 	uint64_t busy_time_total, div_value;
50 
51 	seq_puts(m, "NPU load: ");
52 	for (i = 0; i < rknpu_dev->config->num_irqs; i++) {
53 		subcore_data = &rknpu_dev->subcore_datas[i];
54 
55 		if (rknpu_dev->config->num_irqs > 1)
56 			seq_printf(m, " Core%d: ", i);
57 
58 		spin_lock_irqsave(&rknpu_dev->irq_lock, flags);
59 
60 		busy_time_total = subcore_data->timer.busy_time_record;
61 
62 		spin_unlock_irqrestore(&rknpu_dev->irq_lock, flags);
63 
64 		div_value = (RKNPU_LOAD_INTERVAL / 100000);
65 		do_div(busy_time_total, div_value);
66 		load = busy_time_total;
67 
68 		if (rknpu_dev->config->num_irqs > 1)
69 			seq_printf(m, "%2.d%%,", load);
70 		else
71 			seq_printf(m, "%2.d%%", load);
72 	}
73 	seq_puts(m, "\n");
74 
75 	return 0;
76 }
77 
rknpu_power_show(struct seq_file * m,void * data)78 static int rknpu_power_show(struct seq_file *m, void *data)
79 {
80 	struct rknpu_debugger_node *node = m->private;
81 	struct rknpu_debugger *debugger = node->debugger;
82 	struct rknpu_device *rknpu_dev =
83 		container_of(debugger, struct rknpu_device, debugger);
84 
85 	if (atomic_read(&rknpu_dev->power_refcount) > 0)
86 		seq_puts(m, "on\n");
87 	else
88 		seq_puts(m, "off\n");
89 
90 	return 0;
91 }
92 
rknpu_power_set(struct file * file,const char __user * ubuf,size_t len,loff_t * offp)93 static ssize_t rknpu_power_set(struct file *file, const char __user *ubuf,
94 			       size_t len, loff_t *offp)
95 {
96 	struct seq_file *priv = file->private_data;
97 	struct rknpu_debugger_node *node = priv->private;
98 	struct rknpu_debugger *debugger = node->debugger;
99 	struct rknpu_device *rknpu_dev =
100 		container_of(debugger, struct rknpu_device, debugger);
101 	char buf[8];
102 
103 	if (len > sizeof(buf) - 1)
104 		return -EINVAL;
105 	if (copy_from_user(buf, ubuf, len))
106 		return -EFAULT;
107 	buf[len - 1] = '\0';
108 
109 	if (strcmp(buf, "on") == 0) {
110 		atomic_inc(&rknpu_dev->cmdline_power_refcount);
111 		rknpu_power_get(rknpu_dev);
112 		LOG_INFO("rknpu power is on!");
113 	} else if (strcmp(buf, "off") == 0) {
114 		if (atomic_read(&rknpu_dev->power_refcount) > 0 &&
115 		    atomic_dec_if_positive(
116 			    &rknpu_dev->cmdline_power_refcount) >= 0) {
117 			atomic_sub(
118 				atomic_read(&rknpu_dev->cmdline_power_refcount),
119 				&rknpu_dev->power_refcount);
120 			atomic_set(&rknpu_dev->cmdline_power_refcount, 0);
121 			rknpu_power_put(rknpu_dev);
122 		}
123 		if (atomic_read(&rknpu_dev->power_refcount) <= 0)
124 			LOG_INFO("rknpu power is off!");
125 	} else {
126 		LOG_ERROR("rknpu power node params is invalid!");
127 	}
128 
129 	return len;
130 }
131 
rknpu_power_put_delay_show(struct seq_file * m,void * data)132 static int rknpu_power_put_delay_show(struct seq_file *m, void *data)
133 {
134 	struct rknpu_debugger_node *node = m->private;
135 	struct rknpu_debugger *debugger = node->debugger;
136 	struct rknpu_device *rknpu_dev =
137 		container_of(debugger, struct rknpu_device, debugger);
138 
139 	seq_printf(m, "%lu\n", rknpu_dev->power_put_delay);
140 
141 	return 0;
142 }
143 
rknpu_power_put_delay_set(struct file * file,const char __user * ubuf,size_t len,loff_t * offp)144 static ssize_t rknpu_power_put_delay_set(struct file *file,
145 					 const char __user *ubuf, size_t len,
146 					 loff_t *offp)
147 {
148 	struct seq_file *priv = file->private_data;
149 	struct rknpu_debugger_node *node = priv->private;
150 	struct rknpu_debugger *debugger = node->debugger;
151 	struct rknpu_device *rknpu_dev =
152 		container_of(debugger, struct rknpu_device, debugger);
153 	char buf[16];
154 	unsigned long power_put_delay = 0;
155 	int ret = 0;
156 
157 	if (len > sizeof(buf) - 1)
158 		return -EINVAL;
159 	if (copy_from_user(buf, ubuf, len))
160 		return -EFAULT;
161 	buf[len - 1] = '\0';
162 
163 	ret = kstrtoul(buf, 10, &power_put_delay);
164 	if (ret) {
165 		LOG_ERROR("failed to parse power put delay string: %s\n", buf);
166 		return -EFAULT;
167 	}
168 
169 	rknpu_dev->power_put_delay = power_put_delay;
170 
171 	LOG_INFO("set rknpu power put delay time %lums\n",
172 		 rknpu_dev->power_put_delay);
173 
174 	return len;
175 }
176 
rknpu_freq_show(struct seq_file * m,void * data)177 static int rknpu_freq_show(struct seq_file *m, void *data)
178 {
179 	struct rknpu_debugger_node *node = m->private;
180 	struct rknpu_debugger *debugger = node->debugger;
181 	struct rknpu_device *rknpu_dev =
182 		container_of(debugger, struct rknpu_device, debugger);
183 	unsigned long current_freq = 0;
184 
185 	rknpu_power_get(rknpu_dev);
186 
187 	current_freq = clk_get_rate(rknpu_dev->clks[0].clk);
188 
189 	rknpu_power_put(rknpu_dev);
190 
191 	seq_printf(m, "%lu\n", current_freq);
192 
193 	return 0;
194 }
195 
196 #ifdef CONFIG_PM_DEVFREQ
rknpu_freq_set(struct file * file,const char __user * ubuf,size_t len,loff_t * offp)197 static ssize_t rknpu_freq_set(struct file *file, const char __user *ubuf,
198 			      size_t len, loff_t *offp)
199 {
200 	struct seq_file *priv = file->private_data;
201 	struct rknpu_debugger_node *node = priv->private;
202 	struct rknpu_debugger *debugger = node->debugger;
203 	struct rknpu_device *rknpu_dev =
204 		container_of(debugger, struct rknpu_device, debugger);
205 	unsigned long current_freq = 0;
206 	char buf[16];
207 	unsigned long freq = 0;
208 	int ret = 0;
209 
210 	if (len > sizeof(buf) - 1)
211 		return -EINVAL;
212 	if (copy_from_user(buf, ubuf, len))
213 		return -EFAULT;
214 	buf[len - 1] = '\0';
215 
216 	ret = kstrtoul(buf, 10, &freq);
217 	if (ret) {
218 		LOG_ERROR("failed to parse freq string: %s\n", buf);
219 		return -EFAULT;
220 	}
221 
222 	if (!rknpu_dev->devfreq)
223 		return -EFAULT;
224 
225 	rknpu_power_get(rknpu_dev);
226 
227 	current_freq = clk_get_rate(rknpu_dev->clks[0].clk);
228 	if (freq != current_freq) {
229 		rknpu_dev->ondemand_freq = freq;
230 		mutex_lock(&rknpu_dev->devfreq->lock);
231 		update_devfreq(rknpu_dev->devfreq);
232 		mutex_unlock(&rknpu_dev->devfreq->lock);
233 	}
234 
235 	rknpu_power_put(rknpu_dev);
236 
237 	return len;
238 }
239 #else
rknpu_freq_set(struct file * file,const char __user * ubuf,size_t len,loff_t * offp)240 static ssize_t rknpu_freq_set(struct file *file, const char __user *ubuf,
241 			      size_t len, loff_t *offp)
242 {
243 	return -EFAULT;
244 }
245 #endif
246 
rknpu_volt_show(struct seq_file * m,void * data)247 static int rknpu_volt_show(struct seq_file *m, void *data)
248 {
249 	struct rknpu_debugger_node *node = m->private;
250 	struct rknpu_debugger *debugger = node->debugger;
251 	struct rknpu_device *rknpu_dev =
252 		container_of(debugger, struct rknpu_device, debugger);
253 	unsigned long current_volt = 0;
254 
255 	current_volt = regulator_get_voltage(rknpu_dev->vdd);
256 
257 	seq_printf(m, "%lu\n", current_volt);
258 
259 	return 0;
260 }
261 
rknpu_reset_show(struct seq_file * m,void * data)262 static int rknpu_reset_show(struct seq_file *m, void *data)
263 {
264 	struct rknpu_debugger_node *node = m->private;
265 	struct rknpu_debugger *debugger = node->debugger;
266 	struct rknpu_device *rknpu_dev =
267 		container_of(debugger, struct rknpu_device, debugger);
268 
269 	if (!rknpu_dev->bypass_soft_reset)
270 		seq_puts(m, "on\n");
271 	else
272 		seq_puts(m, "off\n");
273 
274 	return 0;
275 }
276 
rknpu_reset_set(struct file * file,const char __user * ubuf,size_t len,loff_t * offp)277 static ssize_t rknpu_reset_set(struct file *file, const char __user *ubuf,
278 			       size_t len, loff_t *offp)
279 {
280 	struct seq_file *priv = file->private_data;
281 	struct rknpu_debugger_node *node = priv->private;
282 	struct rknpu_debugger *debugger = node->debugger;
283 	struct rknpu_device *rknpu_dev =
284 		container_of(debugger, struct rknpu_device, debugger);
285 	char buf[8];
286 
287 	if (len > sizeof(buf) - 1)
288 		return -EINVAL;
289 	if (copy_from_user(buf, ubuf, len))
290 		return -EFAULT;
291 	buf[len - 1] = '\0';
292 
293 	if (strcmp(buf, "1") == 0 &&
294 	    atomic_read(&rknpu_dev->power_refcount) > 0)
295 		rknpu_soft_reset(rknpu_dev);
296 	else if (strcmp(buf, "on") == 0)
297 		rknpu_dev->bypass_soft_reset = 0;
298 	else if (strcmp(buf, "off") == 0)
299 		rknpu_dev->bypass_soft_reset = 1;
300 
301 	return len;
302 }
303 
304 static struct rknpu_debugger_list rknpu_debugger_root_list[] = {
305 	{ "version", rknpu_version_show, NULL, NULL },
306 	{ "load", rknpu_load_show, NULL, NULL },
307 	{ "power", rknpu_power_show, rknpu_power_set, NULL },
308 	{ "freq", rknpu_freq_show, rknpu_freq_set, NULL },
309 	{ "volt", rknpu_volt_show, NULL, NULL },
310 	{ "delayms", rknpu_power_put_delay_show, rknpu_power_put_delay_set,
311 	  NULL },
312 	{ "reset", rknpu_reset_show, rknpu_reset_set, NULL },
313 #ifdef CONFIG_ROCKCHIP_RKNPU_SRAM
314 	{ "mm", rknpu_mm_dump, NULL, NULL },
315 #endif
316 };
317 
rknpu_debugger_write(struct file * file,const char __user * ubuf,size_t len,loff_t * offp)318 static ssize_t rknpu_debugger_write(struct file *file, const char __user *ubuf,
319 				    size_t len, loff_t *offp)
320 {
321 	struct seq_file *priv = file->private_data;
322 	struct rknpu_debugger_node *node = priv->private;
323 
324 	if (node->info_ent->write)
325 		return node->info_ent->write(file, ubuf, len, offp);
326 	else
327 		return len;
328 }
329 
rknpu_debugfs_open(struct inode * inode,struct file * file)330 static int rknpu_debugfs_open(struct inode *inode, struct file *file)
331 {
332 	struct rknpu_debugger_node *node = inode->i_private;
333 
334 	return single_open(file, node->info_ent->show, node);
335 }
336 
337 static const struct file_operations rknpu_debugfs_fops = {
338 	.owner = THIS_MODULE,
339 	.open = rknpu_debugfs_open,
340 	.read = seq_read,
341 	.llseek = seq_lseek,
342 	.release = single_release,
343 	.write = rknpu_debugger_write,
344 };
345 #endif /* #if defined(CONFIG_ROCKCHIP_RKNPU_DEBUG_FS) || defined(CONFIG_ROCKCHIP_RKNPU_PROC_FS) */
346 
347 #ifdef CONFIG_ROCKCHIP_RKNPU_DEBUG_FS
rknpu_debugfs_remove_files(struct rknpu_debugger * debugger)348 static int rknpu_debugfs_remove_files(struct rknpu_debugger *debugger)
349 {
350 	struct rknpu_debugger_node *pos, *q;
351 	struct list_head *entry_list;
352 
353 	mutex_lock(&debugger->debugfs_lock);
354 
355 	/* Delete debugfs entry list */
356 	entry_list = &debugger->debugfs_entry_list;
357 	list_for_each_entry_safe(pos, q, entry_list, list) {
358 		if (pos->dent == NULL)
359 			continue;
360 		list_del(&pos->list);
361 		kfree(pos);
362 		pos = NULL;
363 	}
364 
365 	/* Delete all debugfs node in this directory */
366 	debugfs_remove_recursive(debugger->debugfs_dir);
367 	debugger->debugfs_dir = NULL;
368 
369 	mutex_unlock(&debugger->debugfs_lock);
370 
371 	return 0;
372 }
373 
rknpu_debugfs_create_files(const struct rknpu_debugger_list * files,int count,struct dentry * root,struct rknpu_debugger * debugger)374 static int rknpu_debugfs_create_files(const struct rknpu_debugger_list *files,
375 				      int count, struct dentry *root,
376 				      struct rknpu_debugger *debugger)
377 {
378 	int i;
379 	struct dentry *ent;
380 	struct rknpu_debugger_node *tmp;
381 
382 	for (i = 0; i < count; i++) {
383 		tmp = kmalloc(sizeof(struct rknpu_debugger_node), GFP_KERNEL);
384 		if (tmp == NULL) {
385 			LOG_ERROR(
386 				"Cannot alloc node path /sys/kernel/debug/%pd/%s\n",
387 				root, files[i].name);
388 			goto MALLOC_FAIL;
389 		}
390 
391 		tmp->info_ent = &files[i];
392 		tmp->debugger = debugger;
393 
394 		ent = debugfs_create_file(files[i].name, S_IFREG | S_IRUGO,
395 					  root, tmp, &rknpu_debugfs_fops);
396 		if (!ent) {
397 			LOG_ERROR("Cannot create /sys/kernel/debug/%pd/%s\n",
398 				  root, files[i].name);
399 			goto CREATE_FAIL;
400 		}
401 
402 		tmp->dent = ent;
403 
404 		mutex_lock(&debugger->debugfs_lock);
405 		list_add_tail(&tmp->list, &debugger->debugfs_entry_list);
406 		mutex_unlock(&debugger->debugfs_lock);
407 	}
408 
409 	return 0;
410 
411 CREATE_FAIL:
412 	kfree(tmp);
413 MALLOC_FAIL:
414 	rknpu_debugfs_remove_files(debugger);
415 
416 	return -1;
417 }
418 
rknpu_debugfs_remove(struct rknpu_debugger * debugger)419 static int rknpu_debugfs_remove(struct rknpu_debugger *debugger)
420 {
421 	rknpu_debugfs_remove_files(debugger);
422 
423 	return 0;
424 }
425 
rknpu_debugfs_init(struct rknpu_debugger * debugger)426 static int rknpu_debugfs_init(struct rknpu_debugger *debugger)
427 {
428 	int ret;
429 
430 	debugger->debugfs_dir =
431 		debugfs_create_dir(RKNPU_DEBUGGER_ROOT_NAME, NULL);
432 	if (IS_ERR_OR_NULL(debugger->debugfs_dir)) {
433 		LOG_ERROR("failed on mkdir /sys/kernel/debug/%s\n",
434 			  RKNPU_DEBUGGER_ROOT_NAME);
435 		debugger->debugfs_dir = NULL;
436 		return -EIO;
437 	}
438 
439 	ret = rknpu_debugfs_create_files(rknpu_debugger_root_list,
440 					 ARRAY_SIZE(rknpu_debugger_root_list),
441 					 debugger->debugfs_dir, debugger);
442 	if (ret) {
443 		LOG_ERROR(
444 			"Could not install rknpu_debugger_root_list debugfs\n");
445 		goto CREATE_FAIL;
446 	}
447 
448 	return 0;
449 
450 CREATE_FAIL:
451 	rknpu_debugfs_remove(debugger);
452 
453 	return ret;
454 }
455 #endif /* #ifdef CONFIG_ROCKCHIP_RKNPU_DEBUG_FS */
456 
457 #ifdef CONFIG_ROCKCHIP_RKNPU_PROC_FS
rknpu_procfs_open(struct inode * inode,struct file * file)458 static int rknpu_procfs_open(struct inode *inode, struct file *file)
459 {
460 #if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
461 	struct rknpu_debugger_node *node = PDE_DATA(inode);
462 #else
463 	struct rknpu_debugger_node *node = pde_data(inode);
464 #endif
465 
466 	return single_open(file, node->info_ent->show, node);
467 }
468 
469 static const struct proc_ops rknpu_procfs_fops = {
470 	.proc_open = rknpu_procfs_open,
471 	.proc_read = seq_read,
472 	.proc_lseek = seq_lseek,
473 	.proc_release = single_release,
474 	.proc_write = rknpu_debugger_write,
475 };
476 
rknpu_procfs_remove_files(struct rknpu_debugger * debugger)477 static int rknpu_procfs_remove_files(struct rknpu_debugger *debugger)
478 {
479 	struct rknpu_debugger_node *pos, *q;
480 	struct list_head *entry_list;
481 
482 	mutex_lock(&debugger->procfs_lock);
483 
484 	/* Delete procfs entry list */
485 	entry_list = &debugger->procfs_entry_list;
486 	list_for_each_entry_safe(pos, q, entry_list, list) {
487 		if (pos->pent == NULL)
488 			continue;
489 		list_del(&pos->list);
490 		kfree(pos);
491 		pos = NULL;
492 	}
493 
494 	/* Delete all procfs node in this directory */
495 	proc_remove(debugger->procfs_dir);
496 	debugger->procfs_dir = NULL;
497 
498 	mutex_unlock(&debugger->procfs_lock);
499 
500 	return 0;
501 }
502 
rknpu_procfs_create_files(const struct rknpu_debugger_list * files,int count,struct proc_dir_entry * root,struct rknpu_debugger * debugger)503 static int rknpu_procfs_create_files(const struct rknpu_debugger_list *files,
504 				     int count, struct proc_dir_entry *root,
505 				     struct rknpu_debugger *debugger)
506 {
507 	int i;
508 	struct proc_dir_entry *ent;
509 	struct rknpu_debugger_node *tmp;
510 
511 	for (i = 0; i < count; i++) {
512 		tmp = kmalloc(sizeof(struct rknpu_debugger_node), GFP_KERNEL);
513 		if (tmp == NULL) {
514 			LOG_ERROR("Cannot alloc node path for /proc/%s/%s\n",
515 				  RKNPU_DEBUGGER_ROOT_NAME, files[i].name);
516 			goto MALLOC_FAIL;
517 		}
518 
519 		tmp->info_ent = &files[i];
520 		tmp->debugger = debugger;
521 
522 		ent = proc_create_data(files[i].name, S_IFREG | S_IRUGO, root,
523 				       &rknpu_procfs_fops, tmp);
524 		if (!ent) {
525 			LOG_ERROR("Cannot create /proc/%s/%s\n",
526 				  RKNPU_DEBUGGER_ROOT_NAME, files[i].name);
527 			goto CREATE_FAIL;
528 		}
529 
530 		tmp->pent = ent;
531 
532 		mutex_lock(&debugger->procfs_lock);
533 		list_add_tail(&tmp->list, &debugger->procfs_entry_list);
534 		mutex_unlock(&debugger->procfs_lock);
535 	}
536 
537 	return 0;
538 
539 CREATE_FAIL:
540 	kfree(tmp);
541 MALLOC_FAIL:
542 	rknpu_procfs_remove_files(debugger);
543 	return -1;
544 }
545 
rknpu_procfs_remove(struct rknpu_debugger * debugger)546 static int rknpu_procfs_remove(struct rknpu_debugger *debugger)
547 {
548 	rknpu_procfs_remove_files(debugger);
549 
550 	return 0;
551 }
552 
rknpu_procfs_init(struct rknpu_debugger * debugger)553 static int rknpu_procfs_init(struct rknpu_debugger *debugger)
554 {
555 	int ret;
556 
557 	debugger->procfs_dir = proc_mkdir(RKNPU_DEBUGGER_ROOT_NAME, NULL);
558 	if (IS_ERR_OR_NULL(debugger->procfs_dir)) {
559 		pr_err("failed on mkdir /proc/%s\n", RKNPU_DEBUGGER_ROOT_NAME);
560 		debugger->procfs_dir = NULL;
561 		return -EIO;
562 	}
563 
564 	ret = rknpu_procfs_create_files(rknpu_debugger_root_list,
565 					ARRAY_SIZE(rknpu_debugger_root_list),
566 					debugger->procfs_dir, debugger);
567 	if (ret) {
568 		pr_err("Could not install rknpu_debugger_root_list procfs\n");
569 		goto CREATE_FAIL;
570 	}
571 
572 	return 0;
573 
574 CREATE_FAIL:
575 	rknpu_procfs_remove(debugger);
576 
577 	return ret;
578 }
579 #endif /* #ifdef CONFIG_ROCKCHIP_RKNPU_PROC_FS */
580 
rknpu_debugger_init(struct rknpu_device * rknpu_dev)581 int rknpu_debugger_init(struct rknpu_device *rknpu_dev)
582 {
583 #ifdef CONFIG_ROCKCHIP_RKNPU_DEBUG_FS
584 	mutex_init(&rknpu_dev->debugger.debugfs_lock);
585 	INIT_LIST_HEAD(&rknpu_dev->debugger.debugfs_entry_list);
586 	rknpu_debugfs_init(&rknpu_dev->debugger);
587 #endif
588 #ifdef CONFIG_ROCKCHIP_RKNPU_PROC_FS
589 	mutex_init(&rknpu_dev->debugger.procfs_lock);
590 	INIT_LIST_HEAD(&rknpu_dev->debugger.procfs_entry_list);
591 	rknpu_procfs_init(&rknpu_dev->debugger);
592 #endif
593 	return 0;
594 }
595 
rknpu_debugger_remove(struct rknpu_device * rknpu_dev)596 int rknpu_debugger_remove(struct rknpu_device *rknpu_dev)
597 {
598 #ifdef CONFIG_ROCKCHIP_RKNPU_DEBUG_FS
599 	rknpu_debugfs_remove(&rknpu_dev->debugger);
600 #endif
601 #ifdef CONFIG_ROCKCHIP_RKNPU_PROC_FS
602 	rknpu_procfs_remove(&rknpu_dev->debugger);
603 #endif
604 	return 0;
605 }
606