1 /*
2  * Copyright (C) 2011 ST-Ericsson
3  * License terms: GNU General Public License (GPL) version 2
4  * Debugfs support for the AB5500 MFD driver
5  */
6 
7 #include <linux/module.h>
8 #include <linux/debugfs.h>
9 #include <linux/seq_file.h>
10 #include <linux/mfd/abx500.h>
11 #include <linux/mfd/abx500/ab5500.h>
12 #include <linux/uaccess.h>
13 
14 #include "ab5500-core.h"
15 #include "ab5500-debugfs.h"
16 
17 static struct ab5500_i2c_ranges ab5500_reg_ranges[AB5500_NUM_BANKS] = {
18 	[AB5500_BANK_LED] = {
19 		.bankid = AB5500_BANK_LED,
20 		.nranges = 1,
21 		.range = (struct ab5500_reg_range[]) {
22 			{
23 				.first = 0x00,
24 				.last = 0x0C,
25 				.perm = AB5500_PERM_RW,
26 			},
27 		},
28 	},
29 	[AB5500_BANK_ADC] = {
30 		.bankid = AB5500_BANK_ADC,
31 		.nranges = 6,
32 		.range = (struct ab5500_reg_range[]) {
33 			{
34 				.first = 0x1F,
35 				.last = 0x22,
36 				.perm = AB5500_PERM_RO,
37 			},
38 			{
39 				.first = 0x23,
40 				.last = 0x24,
41 				.perm = AB5500_PERM_RW,
42 			},
43 			{
44 				.first = 0x26,
45 				.last = 0x2D,
46 				.perm = AB5500_PERM_RO,
47 			},
48 			{
49 				.first = 0x2F,
50 				.last = 0x34,
51 				.perm = AB5500_PERM_RW,
52 			},
53 			{
54 				.first = 0x37,
55 				.last = 0x57,
56 				.perm = AB5500_PERM_RW,
57 			},
58 			{
59 				.first = 0x58,
60 				.last = 0x58,
61 				.perm = AB5500_PERM_RO,
62 			},
63 		},
64 	},
65 	[AB5500_BANK_RTC] = {
66 		.bankid = AB5500_BANK_RTC,
67 		.nranges = 2,
68 		.range = (struct ab5500_reg_range[]) {
69 			{
70 				.first = 0x00,
71 				.last = 0x04,
72 				.perm = AB5500_PERM_RW,
73 			},
74 			{
75 				.first = 0x06,
76 				.last = 0x0C,
77 				.perm = AB5500_PERM_RW,
78 			},
79 		},
80 	},
81 	[AB5500_BANK_STARTUP] = {
82 		.bankid = AB5500_BANK_STARTUP,
83 		.nranges = 12,
84 		.range = (struct ab5500_reg_range[]) {
85 			{
86 				.first = 0x00,
87 				.last = 0x01,
88 				.perm = AB5500_PERM_RW,
89 			},
90 			{
91 				.first = 0x1F,
92 				.last = 0x1F,
93 				.perm = AB5500_PERM_RW,
94 			},
95 			{
96 				.first = 0x2E,
97 				.last = 0x2E,
98 				.perm = AB5500_PERM_RO,
99 			},
100 			{
101 				.first = 0x2F,
102 				.last = 0x30,
103 				.perm = AB5500_PERM_RW,
104 			},
105 			{
106 				.first = 0x50,
107 				.last = 0x51,
108 				.perm = AB5500_PERM_RW,
109 			},
110 			{
111 				.first = 0x60,
112 				.last = 0x61,
113 				.perm = AB5500_PERM_RW,
114 			},
115 			{
116 				.first = 0x66,
117 				.last = 0x8A,
118 				.perm = AB5500_PERM_RW,
119 			},
120 			{
121 				.first = 0x8C,
122 				.last = 0x96,
123 				.perm = AB5500_PERM_RW,
124 			},
125 			{
126 				.first = 0xAA,
127 				.last = 0xB4,
128 				.perm = AB5500_PERM_RW,
129 			},
130 			{
131 				.first = 0xB7,
132 				.last = 0xBF,
133 				.perm = AB5500_PERM_RW,
134 			},
135 			{
136 				.first = 0xC1,
137 				.last = 0xCA,
138 				.perm = AB5500_PERM_RW,
139 			},
140 			{
141 				.first = 0xD3,
142 				.last = 0xE0,
143 				.perm = AB5500_PERM_RW,
144 			},
145 		},
146 	},
147 	[AB5500_BANK_DBI_ECI] = {
148 		.bankid = AB5500_BANK_DBI_ECI,
149 		.nranges = 3,
150 		.range = (struct ab5500_reg_range[]) {
151 			{
152 				.first = 0x00,
153 				.last = 0x07,
154 				.perm = AB5500_PERM_RW,
155 			},
156 			{
157 				.first = 0x10,
158 				.last = 0x10,
159 				.perm = AB5500_PERM_RW,
160 			},
161 			{
162 				.first = 0x13,
163 				.last = 0x13,
164 				.perm = AB5500_PERM_RW,
165 			},
166 		},
167 	},
168 	[AB5500_BANK_CHG] = {
169 		.bankid = AB5500_BANK_CHG,
170 		.nranges = 2,
171 		.range = (struct ab5500_reg_range[]) {
172 			{
173 				.first = 0x11,
174 				.last = 0x11,
175 				.perm = AB5500_PERM_RO,
176 			},
177 			{
178 				.first = 0x12,
179 				.last = 0x1B,
180 				.perm = AB5500_PERM_RW,
181 			},
182 		},
183 	},
184 	[AB5500_BANK_FG_BATTCOM_ACC] = {
185 		.bankid = AB5500_BANK_FG_BATTCOM_ACC,
186 		.nranges = 2,
187 		.range = (struct ab5500_reg_range[]) {
188 			{
189 				.first = 0x00,
190 				.last = 0x0B,
191 				.perm = AB5500_PERM_RO,
192 			},
193 			{
194 				.first = 0x0C,
195 				.last = 0x10,
196 				.perm = AB5500_PERM_RW,
197 			},
198 		},
199 	},
200 	[AB5500_BANK_USB] = {
201 		.bankid = AB5500_BANK_USB,
202 		.nranges = 12,
203 		.range = (struct ab5500_reg_range[]) {
204 			{
205 				.first = 0x01,
206 				.last = 0x01,
207 				.perm = AB5500_PERM_RW,
208 			},
209 			{
210 				.first = 0x80,
211 				.last = 0x83,
212 				.perm = AB5500_PERM_RW,
213 			},
214 			{
215 				.first = 0x87,
216 				.last = 0x8A,
217 				.perm = AB5500_PERM_RW,
218 			},
219 			{
220 				.first = 0x8B,
221 				.last = 0x8B,
222 				.perm = AB5500_PERM_RO,
223 			},
224 			{
225 				.first = 0x91,
226 				.last = 0x92,
227 				.perm = AB5500_PERM_RO,
228 			},
229 			{
230 				.first = 0x93,
231 				.last = 0x93,
232 				.perm = AB5500_PERM_RW,
233 			},
234 			{
235 				.first = 0x94,
236 				.last = 0x94,
237 				.perm = AB5500_PERM_RO,
238 			},
239 			{
240 				.first = 0xA8,
241 				.last = 0xB0,
242 				.perm = AB5500_PERM_RO,
243 			},
244 			{
245 				.first = 0xB2,
246 				.last = 0xB2,
247 				.perm = AB5500_PERM_RO,
248 			},
249 			{
250 				.first = 0xB4,
251 				.last = 0xBC,
252 				.perm = AB5500_PERM_RO,
253 			},
254 			{
255 				.first = 0xBF,
256 				.last = 0xBF,
257 				.perm = AB5500_PERM_RO,
258 			},
259 			{
260 				.first = 0xC1,
261 				.last = 0xC5,
262 				.perm = AB5500_PERM_RO,
263 			},
264 		},
265 	},
266 	[AB5500_BANK_IT] = {
267 		.bankid = AB5500_BANK_IT,
268 		.nranges = 4,
269 		.range = (struct ab5500_reg_range[]) {
270 			{
271 				.first = 0x00,
272 				.last = 0x02,
273 				.perm = AB5500_PERM_RO,
274 			},
275 			{
276 				.first = 0x20,
277 				.last = 0x36,
278 				.perm = AB5500_PERM_RO,
279 			},
280 			{
281 				.first = 0x40,
282 				.last = 0x56,
283 				.perm = AB5500_PERM_RO,
284 			},
285 			{
286 				.first = 0x60,
287 				.last = 0x76,
288 				.perm = AB5500_PERM_RO,
289 			},
290 		},
291 	},
292 	[AB5500_BANK_VDDDIG_IO_I2C_CLK_TST] = {
293 		.bankid = AB5500_BANK_VDDDIG_IO_I2C_CLK_TST,
294 		.nranges = 7,
295 		.range = (struct ab5500_reg_range[]) {
296 			{
297 				.first = 0x02,
298 				.last = 0x02,
299 				.perm = AB5500_PERM_RW,
300 			},
301 			{
302 				.first = 0x12,
303 				.last = 0x12,
304 				.perm = AB5500_PERM_RW,
305 			},
306 			{
307 				.first = 0x30,
308 				.last = 0x34,
309 				.perm = AB5500_PERM_RW,
310 			},
311 			{
312 				.first = 0x40,
313 				.last = 0x44,
314 				.perm = AB5500_PERM_RW,
315 			},
316 			{
317 				.first = 0x50,
318 				.last = 0x54,
319 				.perm = AB5500_PERM_RW,
320 			},
321 			{
322 				.first = 0x60,
323 				.last = 0x64,
324 				.perm = AB5500_PERM_RW,
325 			},
326 			{
327 				.first = 0x70,
328 				.last = 0x74,
329 				.perm = AB5500_PERM_RW,
330 			},
331 		},
332 	},
333 	[AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP] = {
334 		.bankid = AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP,
335 		.nranges = 13,
336 		.range = (struct ab5500_reg_range[]) {
337 			{
338 				.first = 0x01,
339 				.last = 0x01,
340 				.perm = AB5500_PERM_RW,
341 			},
342 			{
343 				.first = 0x02,
344 				.last = 0x02,
345 				.perm = AB5500_PERM_RO,
346 			},
347 			{
348 				.first = 0x0D,
349 				.last = 0x0F,
350 				.perm = AB5500_PERM_RW,
351 			},
352 			{
353 				.first = 0x1C,
354 				.last = 0x1C,
355 				.perm = AB5500_PERM_RW,
356 			},
357 			{
358 				.first = 0x1E,
359 				.last = 0x1E,
360 				.perm = AB5500_PERM_RW,
361 			},
362 			{
363 				.first = 0x20,
364 				.last = 0x21,
365 				.perm = AB5500_PERM_RW,
366 			},
367 			{
368 				.first = 0x25,
369 				.last = 0x25,
370 				.perm = AB5500_PERM_RW,
371 			},
372 			{
373 				.first = 0x28,
374 				.last = 0x2A,
375 				.perm = AB5500_PERM_RW,
376 			},
377 			{
378 				.first = 0x30,
379 				.last = 0x33,
380 				.perm = AB5500_PERM_RW,
381 			},
382 			{
383 				.first = 0x40,
384 				.last = 0x43,
385 				.perm = AB5500_PERM_RW,
386 			},
387 			{
388 				.first = 0x50,
389 				.last = 0x53,
390 				.perm = AB5500_PERM_RW,
391 			},
392 			{
393 				.first = 0x60,
394 				.last = 0x63,
395 				.perm = AB5500_PERM_RW,
396 			},
397 			{
398 				.first = 0x70,
399 				.last = 0x73,
400 				.perm = AB5500_PERM_RW,
401 			},
402 		},
403 	},
404 	[AB5500_BANK_VIBRA] = {
405 		.bankid = AB5500_BANK_VIBRA,
406 		.nranges = 2,
407 		.range = (struct ab5500_reg_range[]) {
408 			{
409 				.first = 0x10,
410 				.last = 0x13,
411 				.perm = AB5500_PERM_RW,
412 			},
413 			{
414 				.first = 0xFE,
415 				.last = 0xFE,
416 				.perm = AB5500_PERM_RW,
417 			},
418 		},
419 	},
420 	[AB5500_BANK_AUDIO_HEADSETUSB] = {
421 		.bankid = AB5500_BANK_AUDIO_HEADSETUSB,
422 		.nranges = 2,
423 		.range = (struct ab5500_reg_range[]) {
424 			{
425 				.first = 0x00,
426 				.last = 0x48,
427 				.perm = AB5500_PERM_RW,
428 			},
429 			{
430 				.first = 0xEB,
431 				.last = 0xFB,
432 				.perm = AB5500_PERM_RW,
433 			},
434 		},
435 	},
436 	[AB5500_BANK_SIM_USBSIM] = {
437 		.bankid = AB5500_BANK_SIM_USBSIM,
438 		.nranges = 1,
439 		.range = (struct ab5500_reg_range[]) {
440 			{
441 				.first = 0x13,
442 				.last = 0x19,
443 				.perm = AB5500_PERM_RW,
444 			},
445 		},
446 	},
447 	[AB5500_BANK_VDENC] = {
448 		.bankid = AB5500_BANK_VDENC,
449 		.nranges = 12,
450 		.range = (struct ab5500_reg_range[]) {
451 			{
452 				.first = 0x00,
453 				.last = 0x08,
454 				.perm = AB5500_PERM_RW,
455 			},
456 			{
457 				.first = 0x09,
458 				.last = 0x09,
459 				.perm = AB5500_PERM_RO,
460 			},
461 			{
462 				.first = 0x0A,
463 				.last = 0x12,
464 				.perm = AB5500_PERM_RW,
465 			},
466 			{
467 				.first = 0x15,
468 				.last = 0x19,
469 				.perm = AB5500_PERM_RW,
470 			},
471 			{
472 				.first = 0x1B,
473 				.last = 0x21,
474 				.perm = AB5500_PERM_RW,
475 			},
476 			{
477 				.first = 0x27,
478 				.last = 0x2C,
479 				.perm = AB5500_PERM_RW,
480 			},
481 			{
482 				.first = 0x41,
483 				.last = 0x41,
484 				.perm = AB5500_PERM_RW,
485 			},
486 			{
487 				.first = 0x45,
488 				.last = 0x5B,
489 				.perm = AB5500_PERM_RW,
490 			},
491 			{
492 				.first = 0x5D,
493 				.last = 0x5D,
494 				.perm = AB5500_PERM_RW,
495 			},
496 			{
497 				.first = 0x69,
498 				.last = 0x69,
499 				.perm = AB5500_PERM_RW,
500 			},
501 			{
502 				.first = 0x6C,
503 				.last = 0x6D,
504 				.perm = AB5500_PERM_RW,
505 			},
506 			{
507 				.first = 0x80,
508 				.last = 0x81,
509 				.perm = AB5500_PERM_RW,
510 			},
511 		},
512 	},
513 };
514 
ab5500_registers_print(struct seq_file * s,void * p)515 static int ab5500_registers_print(struct seq_file *s, void *p)
516 {
517 	struct ab5500 *ab = s->private;
518 	unsigned int i;
519 	u8 bank = (u8)ab->debug_bank;
520 
521 	seq_printf(s, "ab5500 register values:\n");
522 	for (bank = 0; bank < AB5500_NUM_BANKS; bank++) {
523 		seq_printf(s, " bank %u, %s (0x%x):\n", bank,
524 				bankinfo[bank].name,
525 				bankinfo[bank].slave_addr);
526 		for (i = 0; i < ab5500_reg_ranges[bank].nranges; i++) {
527 			u8 reg;
528 			int err;
529 
530 			for (reg = ab5500_reg_ranges[bank].range[i].first;
531 				reg <= ab5500_reg_ranges[bank].range[i].last;
532 				reg++) {
533 				u8 value;
534 
535 				err = ab5500_get_register_interruptible_raw(ab,
536 								bank, reg,
537 								&value);
538 				if (err < 0) {
539 					dev_err(ab->dev, "get_reg failed %d"
540 						"bank 0x%x reg 0x%x\n",
541 						err, bank, reg);
542 					return err;
543 				}
544 
545 				err = seq_printf(s, "[%d/0x%02X]: 0x%02X\n",
546 						bank, reg, value);
547 				if (err < 0) {
548 					dev_err(ab->dev,
549 						"seq_printf overflow\n");
550 					/*
551 					 * Error is not returned here since
552 					 * the output is wanted in any case
553 					 */
554 					return 0;
555 				}
556 			}
557 		}
558 	}
559 	return 0;
560 }
561 
ab5500_registers_open(struct inode * inode,struct file * file)562 static int ab5500_registers_open(struct inode *inode, struct file *file)
563 {
564 	return single_open(file, ab5500_registers_print, inode->i_private);
565 }
566 
567 static const struct file_operations ab5500_registers_fops = {
568 	.open = ab5500_registers_open,
569 	.read = seq_read,
570 	.llseek = seq_lseek,
571 	.release = single_release,
572 	.owner = THIS_MODULE,
573 };
574 
ab5500_bank_print(struct seq_file * s,void * p)575 static int ab5500_bank_print(struct seq_file *s, void *p)
576 {
577 	struct ab5500 *ab = s->private;
578 
579 	seq_printf(s, "%d\n", ab->debug_bank);
580 	return 0;
581 }
582 
ab5500_bank_open(struct inode * inode,struct file * file)583 static int ab5500_bank_open(struct inode *inode, struct file *file)
584 {
585 	return single_open(file, ab5500_bank_print, inode->i_private);
586 }
587 
ab5500_bank_write(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)588 static ssize_t ab5500_bank_write(struct file *file,
589 	const char __user *user_buf,
590 	size_t count, loff_t *ppos)
591 {
592 	struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private;
593 	char buf[32];
594 	int buf_size;
595 	unsigned long user_bank;
596 	int err;
597 
598 	/* Get userspace string and assure termination */
599 	buf_size = min(count, (sizeof(buf) - 1));
600 	if (copy_from_user(buf, user_buf, buf_size))
601 		return -EFAULT;
602 	buf[buf_size] = 0;
603 
604 	err = strict_strtoul(buf, 0, &user_bank);
605 	if (err)
606 		return -EINVAL;
607 
608 	if (user_bank >= AB5500_NUM_BANKS) {
609 		dev_err(ab->dev,
610 			"debugfs error input > number of banks\n");
611 		return -EINVAL;
612 	}
613 
614 	ab->debug_bank = user_bank;
615 
616 	return buf_size;
617 }
618 
ab5500_address_print(struct seq_file * s,void * p)619 static int ab5500_address_print(struct seq_file *s, void *p)
620 {
621 	struct ab5500 *ab = s->private;
622 
623 	seq_printf(s, "0x%02X\n", ab->debug_address);
624 	return 0;
625 }
626 
ab5500_address_open(struct inode * inode,struct file * file)627 static int ab5500_address_open(struct inode *inode, struct file *file)
628 {
629 	return single_open(file, ab5500_address_print, inode->i_private);
630 }
631 
ab5500_address_write(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)632 static ssize_t ab5500_address_write(struct file *file,
633 	const char __user *user_buf,
634 	size_t count, loff_t *ppos)
635 {
636 	struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private;
637 	char buf[32];
638 	int buf_size;
639 	unsigned long user_address;
640 	int err;
641 
642 	/* Get userspace string and assure termination */
643 	buf_size = min(count, (sizeof(buf) - 1));
644 	if (copy_from_user(buf, user_buf, buf_size))
645 		return -EFAULT;
646 	buf[buf_size] = 0;
647 
648 	err = strict_strtoul(buf, 0, &user_address);
649 	if (err)
650 		return -EINVAL;
651 	if (user_address > 0xff) {
652 		dev_err(ab->dev,
653 			"debugfs error input > 0xff\n");
654 		return -EINVAL;
655 	}
656 	ab->debug_address = user_address;
657 	return buf_size;
658 }
659 
ab5500_val_print(struct seq_file * s,void * p)660 static int ab5500_val_print(struct seq_file *s, void *p)
661 {
662 	struct ab5500 *ab = s->private;
663 	int err;
664 	u8 regvalue;
665 
666 	err = ab5500_get_register_interruptible_raw(ab, (u8)ab->debug_bank,
667 		(u8)ab->debug_address, &regvalue);
668 	if (err) {
669 		dev_err(ab->dev, "get_reg failed %d, bank 0x%x"
670 			", reg 0x%x\n", err, ab->debug_bank,
671 			ab->debug_address);
672 		return -EINVAL;
673 	}
674 	seq_printf(s, "0x%02X\n", regvalue);
675 
676 	return 0;
677 }
678 
ab5500_val_open(struct inode * inode,struct file * file)679 static int ab5500_val_open(struct inode *inode, struct file *file)
680 {
681 	return single_open(file, ab5500_val_print, inode->i_private);
682 }
683 
ab5500_val_write(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)684 static ssize_t ab5500_val_write(struct file *file,
685 	const char __user *user_buf,
686 	size_t count, loff_t *ppos)
687 {
688 	struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private;
689 	char buf[32];
690 	int buf_size;
691 	unsigned long user_val;
692 	int err;
693 	u8 regvalue;
694 
695 	/* Get userspace string and assure termination */
696 	buf_size = min(count, (sizeof(buf)-1));
697 	if (copy_from_user(buf, user_buf, buf_size))
698 		return -EFAULT;
699 	buf[buf_size] = 0;
700 
701 	err = strict_strtoul(buf, 0, &user_val);
702 	if (err)
703 		return -EINVAL;
704 	if (user_val > 0xff) {
705 		dev_err(ab->dev,
706 			"debugfs error input > 0xff\n");
707 		return -EINVAL;
708 	}
709 	err = ab5500_mask_and_set_register_interruptible_raw(
710 		ab, (u8)ab->debug_bank,
711 		(u8)ab->debug_address, 0xFF, (u8)user_val);
712 	if (err)
713 		return -EINVAL;
714 
715 	ab5500_get_register_interruptible_raw(ab, (u8)ab->debug_bank,
716 		(u8)ab->debug_address, &regvalue);
717 	if (err)
718 		return -EINVAL;
719 
720 	return buf_size;
721 }
722 
723 static const struct file_operations ab5500_bank_fops = {
724 	.open = ab5500_bank_open,
725 	.write = ab5500_bank_write,
726 	.read = seq_read,
727 	.llseek = seq_lseek,
728 	.release = single_release,
729 	.owner = THIS_MODULE,
730 };
731 
732 static const struct file_operations ab5500_address_fops = {
733 	.open = ab5500_address_open,
734 	.write = ab5500_address_write,
735 	.read = seq_read,
736 	.llseek = seq_lseek,
737 	.release = single_release,
738 	.owner = THIS_MODULE,
739 };
740 
741 static const struct file_operations ab5500_val_fops = {
742 	.open = ab5500_val_open,
743 	.write = ab5500_val_write,
744 	.read = seq_read,
745 	.llseek = seq_lseek,
746 	.release = single_release,
747 	.owner = THIS_MODULE,
748 };
749 
750 static struct dentry *ab5500_dir;
751 static struct dentry *ab5500_reg_file;
752 static struct dentry *ab5500_bank_file;
753 static struct dentry *ab5500_address_file;
754 static struct dentry *ab5500_val_file;
755 
ab5500_setup_debugfs(struct ab5500 * ab)756 void __init ab5500_setup_debugfs(struct ab5500 *ab)
757 {
758 	ab->debug_bank = AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP;
759 	ab->debug_address = AB5500_CHIP_ID;
760 
761 	ab5500_dir = debugfs_create_dir("ab5500", NULL);
762 	if (!ab5500_dir)
763 		goto exit_no_debugfs;
764 
765 	ab5500_reg_file = debugfs_create_file("all-bank-registers",
766 		S_IRUGO, ab5500_dir, ab, &ab5500_registers_fops);
767 	if (!ab5500_reg_file)
768 		goto exit_destroy_dir;
769 
770 	ab5500_bank_file = debugfs_create_file("register-bank",
771 		(S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_bank_fops);
772 	if (!ab5500_bank_file)
773 		goto exit_destroy_reg;
774 
775 	ab5500_address_file = debugfs_create_file("register-address",
776 		(S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_address_fops);
777 	if (!ab5500_address_file)
778 		goto exit_destroy_bank;
779 
780 	ab5500_val_file = debugfs_create_file("register-value",
781 		(S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_val_fops);
782 	if (!ab5500_val_file)
783 		goto exit_destroy_address;
784 
785 	return;
786 
787 exit_destroy_address:
788 	debugfs_remove(ab5500_address_file);
789 exit_destroy_bank:
790 	debugfs_remove(ab5500_bank_file);
791 exit_destroy_reg:
792 	debugfs_remove(ab5500_reg_file);
793 exit_destroy_dir:
794 	debugfs_remove(ab5500_dir);
795 exit_no_debugfs:
796 	dev_err(ab->dev, "failed to create debugfs entries.\n");
797 	return;
798 }
799 
ab5500_remove_debugfs(void)800 void __exit ab5500_remove_debugfs(void)
801 {
802 	debugfs_remove(ab5500_val_file);
803 	debugfs_remove(ab5500_address_file);
804 	debugfs_remove(ab5500_bank_file);
805 	debugfs_remove(ab5500_reg_file);
806 	debugfs_remove(ab5500_dir);
807 }
808