ab5500-debugfs.c 15 KB

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