blob: b825adea677b9347afa6acd07a39ca9cc84adbcc [file] [log] [blame]
Kenneth Heitke98661912012-09-19 18:51:40 -06001/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13/**
14 * SPMI Debug-fs support.
15 *
16 * Hierarchy schema:
17 * /sys/kernel/debug/spmi
18 * /help -- static help text
19 * /spmi-0
20 * /spmi-0/address -- Starting register address for reads or writes
21 * /spmi-0/count -- number of registers to read (only on read)
22 * /spmi-0/data -- Triggers the SPMI formatted read.
23 * /spmi-0/data_raw -- Triggers the SPMI raw read or write
24 * /spmi-#
25 */
26
27#define DEBUG
28#define pr_fmt(fmt) "%s:%d: " fmt, __func__, __LINE__
29
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/slab.h>
33#include <linux/uaccess.h>
34#include <linux/spinlock.h>
35#include <linux/string.h>
36#include <linux/debugfs.h>
37#include <linux/spmi.h>
38#include <linux/ctype.h>
Kenneth Heitke5998fab2013-01-22 16:09:19 -070039#include "spmi-dbgfs.h"
Kenneth Heitke98661912012-09-19 18:51:40 -060040
41#define ADDR_LEN 6 /* 5 byte address + 1 space character */
42#define CHARS_PER_ITEM 3 /* Format is 'XX ' */
43#define ITEMS_PER_LINE 16 /* 16 data items per line */
44#define MAX_LINE_LENGTH (ADDR_LEN + (ITEMS_PER_LINE * CHARS_PER_ITEM) + 1)
45#define MAX_REG_PER_TRANSACTION (8)
46
47static const char *DFS_ROOT_NAME = "spmi";
48static const mode_t DFS_MODE = S_IRUSR | S_IWUSR;
49
50/* Log buffer */
51struct spmi_log_buffer {
52 u32 rpos; /* Current 'read' position in buffer */
53 u32 wpos; /* Current 'write' position in buffer */
54 u32 len; /* Length of the buffer */
55 char data[0]; /* Log buffer */
56};
57
58/* SPMI controller specific data */
59struct spmi_ctrl_data {
60 u32 cnt;
61 u32 addr;
Kenneth Heitke5998fab2013-01-22 16:09:19 -070062 struct dentry *dir;
Kenneth Heitke98661912012-09-19 18:51:40 -060063 struct list_head node;
64 struct spmi_controller *ctrl;
65};
66
67/* SPMI transaction parameters */
68struct spmi_trans {
69 u32 cnt; /* Number of bytes to read */
70 u32 addr; /* 20-bit address: SID + PID + Register offset */
71 u32 offset; /* Offset of last read data */
72 bool raw_data; /* Set to true for raw data dump */
73 struct spmi_controller *ctrl;
74 struct spmi_log_buffer *log; /* log buffer */
75};
76
77struct spmi_dbgfs {
78 struct dentry *root;
79 struct mutex lock;
80 struct list_head ctrl; /* List of spmi_ctrl_data nodes */
81 struct debugfs_blob_wrapper help_msg;
82};
83
84static struct spmi_dbgfs dbgfs_data = {
85 .lock = __MUTEX_INITIALIZER(dbgfs_data.lock),
86 .ctrl = LIST_HEAD_INIT(dbgfs_data.ctrl),
87 .help_msg = {
88 .data =
89"SPMI Debug-FS support\n"
90"\n"
91"Hierarchy schema:\n"
92"/sys/kernel/debug/spmi\n"
93" /help -- Static help text\n"
94" /spmi-0 -- Directory for SPMI bus 0\n"
95" /spmi-0/address -- Starting register address for reads or writes\n"
96" /spmi-0/count -- Number of registers to read (only used for reads)\n"
97" /spmi-0/data -- Initiates the SPMI read (formatted output)\n"
98" /spmi-0/data_raw -- Initiates the SPMI raw read or write\n"
99" /spmi-n -- Directory for SPMI bus n\n"
100"\n"
101"To perform SPMI read or write transactions, you need to first write the\n"
102"address of the slave device register to the 'address' file. For read\n"
103"transactions, the number of bytes to be read needs to be written to the\n"
104"'count' file.\n"
105"\n"
106"The 'address' file specifies the 20-bit address of a slave device register.\n"
107"The upper 4 bits 'address[19..16]' specify the slave identifier (SID) for\n"
108"the slave device. The lower 16 bits specify the slave register address.\n"
109"\n"
110"Reading from the 'data' file will initiate a SPMI read transaction starting\n"
111"from slave register 'address' for 'count' number of bytes.\n"
112"\n"
113"Writing to the 'data' file will initiate a SPMI write transaction starting\n"
114"from slave register 'address'. The number of registers written to will\n"
115"match the number of bytes written to the 'data' file.\n"
116"\n"
117"Example: Read 4 bytes starting at register address 0x1234 for SID 2\n"
118"\n"
119"echo 0x21234 > address\n"
120"echo 4 > count\n"
121"cat data\n"
122"\n"
123"Example: Write 3 bytes starting at register address 0x1008 for SID 1\n"
124"\n"
125"echo 0x11008 > address\n"
126"echo 0x01 0x02 0x03 > data\n"
127"\n"
128"Note that the count file is not used for writes. Since 3 bytes are\n"
129"written to the 'data' file, then 3 bytes will be written across the\n"
130"SPMI bus.\n\n",
131 },
132};
133
134static int spmi_dfs_open(struct spmi_ctrl_data *ctrl_data, struct file *file)
135{
136 struct spmi_log_buffer *log;
137 struct spmi_trans *trans;
138
139 size_t logbufsize = SZ_4K;
140
141 if (!ctrl_data) {
142 pr_err("No SPMI controller data\n");
143 return -EINVAL;
144 }
145
146 /* Per file "transaction" data */
147 trans = kzalloc(sizeof(*trans), GFP_KERNEL);
148
149 if (!trans) {
150 pr_err("Unable to allocate memory for transaction data\n");
151 return -ENOMEM;
152 }
153
154 /* Allocate log buffer */
155 log = kzalloc(logbufsize, GFP_KERNEL);
156
157 if (!log) {
158 kfree(trans);
159 pr_err("Unable to allocate memory for log buffer\n");
160 return -ENOMEM;
161 }
162
163 log->rpos = 0;
164 log->wpos = 0;
165 log->len = logbufsize - sizeof(*log);
166
167 trans->log = log;
168 trans->cnt = ctrl_data->cnt;
169 trans->addr = ctrl_data->addr;
170 trans->ctrl = ctrl_data->ctrl;
171 trans->offset = trans->addr;
172
173 file->private_data = trans;
174 return 0;
175}
176
177static int spmi_dfs_data_open(struct inode *inode, struct file *file)
178{
179 struct spmi_ctrl_data *ctrl_data = inode->i_private;
180 return spmi_dfs_open(ctrl_data, file);
181}
182
183static int spmi_dfs_raw_data_open(struct inode *inode, struct file *file)
184{
185 int rc;
186 struct spmi_trans *trans;
187 struct spmi_ctrl_data *ctrl_data = inode->i_private;
188
189 rc = spmi_dfs_open(ctrl_data, file);
190 trans = file->private_data;
191 trans->raw_data = true;
192 return rc;
193}
194
195static int spmi_dfs_close(struct inode *inode, struct file *file)
196{
197 struct spmi_trans *trans = file->private_data;
198
199 if (trans && trans->log) {
200 file->private_data = NULL;
201 kfree(trans->log);
202 kfree(trans);
203 }
204
205 return 0;
206}
207
208/**
209 * spmi_read_data: reads data across the SPMI bus
210 * @ctrl: The SPMI controller
211 * @buf: buffer to store the data read.
212 * @offset: SPMI address offset to start reading from.
213 * @cnt: The number of bytes to read.
214 *
215 * Returns 0 on success, otherwise returns error code from SPMI driver.
216 */
217static int
218spmi_read_data(struct spmi_controller *ctrl, uint8_t *buf, int offset, int cnt)
219{
220 int ret = 0;
221 int len;
222 uint8_t sid;
223 uint16_t addr;
224
225 while (cnt > 0) {
226 sid = (offset >> 16) & 0xF;
227 addr = offset & 0xFFFF;
228 len = min(cnt, MAX_REG_PER_TRANSACTION);
229
230 ret = spmi_ext_register_readl(ctrl, sid, addr, buf, len);
231 if (ret < 0) {
232 pr_err("SPMI read failed, err = %d\n", ret);
233 goto done;
234 }
235
236 cnt -= len;
237 buf += len;
238 offset += len;
239 }
240
241done:
242 return ret;
243}
244
245/**
246 * spmi_write_data: writes data across the SPMI bus
247 * @ctrl: The SPMI controller
248 * @buf: data to be written.
249 * @offset: SPMI address offset to start writing to.
250 * @cnt: The number of bytes to write.
251 *
252 * Returns 0 on success, otherwise returns error code from SPMI driver.
253 */
254static int
255spmi_write_data(struct spmi_controller *ctrl, uint8_t *buf, int offset, int cnt)
256{
257 int ret = 0;
258 int len;
259 uint8_t sid;
260 uint16_t addr;
261
262 while (cnt > 0) {
263 sid = (offset >> 16) & 0xF;
264 addr = offset & 0xFFFF;
265 len = min(cnt, MAX_REG_PER_TRANSACTION);
266
267 ret = spmi_ext_register_writel(ctrl, sid, addr, buf, len);
268 if (ret < 0) {
269 pr_err("SPMI write failed, err = %d\n", ret);
270 goto done;
271 }
272
273 cnt -= len;
274 buf += len;
275 offset += len;
276 }
277
278done:
279 return ret;
280}
281
282/**
283 * print_to_log: format a string and place into the log buffer
284 * @log: The log buffer to place the result into.
285 * @fmt: The format string to use.
286 * @...: The arguments for the format string.
287 *
288 * The return value is the number of characters written to @log buffer
289 * not including the trailing '\0'.
290 */
291static int print_to_log(struct spmi_log_buffer *log, const char *fmt, ...)
292{
293 va_list args;
294 int cnt;
295 char *buf = &log->data[log->wpos];
296 size_t size = log->len - log->wpos;
297
298 va_start(args, fmt);
299 cnt = vscnprintf(buf, size, fmt, args);
300 va_end(args);
301
302 log->wpos += cnt;
303 return cnt;
304}
305
306/**
307 * write_next_line_to_log: Writes a single "line" of data into the log buffer
308 * @trans: Pointer to SPMI transaction data.
309 * @offset: SPMI address offset to start reading from.
310 * @pcnt: Pointer to 'cnt' variable. Indicates the number of bytes to read.
311 *
312 * The 'offset' is a 20-bits SPMI address which includes a 4-bit slave id (SID),
313 * an 8-bit peripheral id (PID), and an 8-bit peripheral register address.
314 *
315 * On a successful read, the pcnt is decremented by the number of data
316 * bytes read across the SPMI bus. When the cnt reaches 0, all requested
317 * bytes have been read.
318 */
319static int
320write_next_line_to_log(struct spmi_trans *trans, int offset, size_t *pcnt)
321{
322 int i, j;
323 u8 data[ITEMS_PER_LINE];
324 struct spmi_log_buffer *log = trans->log;
325
326 int cnt = 0;
327 int padding = offset % ITEMS_PER_LINE;
328 int items_to_read = min(ARRAY_SIZE(data) - padding, *pcnt);
329 int items_to_log = min(ITEMS_PER_LINE, padding + items_to_read);
330
331 /* Buffer needs enough space for an entire line */
332 if ((log->len - log->wpos) < MAX_LINE_LENGTH)
333 goto done;
334
335 /* Read the desired number of "items" */
336 if (spmi_read_data(trans->ctrl, data, offset, items_to_read))
337 goto done;
338
339 *pcnt -= items_to_read;
340
341 /* Each line starts with the aligned offset (20-bit address) */
342 cnt = print_to_log(log, "%5.5X ", offset & 0xffff0);
343 if (cnt == 0)
344 goto done;
345
346 /* If the offset is unaligned, add padding to right justify items */
347 for (i = 0; i < padding; ++i) {
348 cnt = print_to_log(log, "-- ");
349 if (cnt == 0)
350 goto done;
351 }
352
353 /* Log the data items */
354 for (j = 0; i < items_to_log; ++i, ++j) {
355 cnt = print_to_log(log, "%2.2X ", data[j]);
356 if (cnt == 0)
357 goto done;
358 }
359
360 /* If the last character was a space, then replace it with a newline */
361 if (log->wpos > 0 && log->data[log->wpos - 1] == ' ')
362 log->data[log->wpos - 1] = '\n';
363
364done:
365 return cnt;
366}
367
368/**
369 * write_raw_data_to_log: Writes a single "line" of data into the log buffer
370 * @trans: Pointer to SPMI transaction data.
371 * @offset: SPMI address offset to start reading from.
372 * @pcnt: Pointer to 'cnt' variable. Indicates the number of bytes to read.
373 *
374 * The 'offset' is a 20-bits SPMI address which includes a 4-bit slave id (SID),
375 * an 8-bit peripheral id (PID), and an 8-bit peripheral register address.
376 *
377 * On a successful read, the pcnt is decremented by the number of data
378 * bytes read across the SPMI bus. When the cnt reaches 0, all requested
379 * bytes have been read.
380 */
381static int
382write_raw_data_to_log(struct spmi_trans *trans, int offset, size_t *pcnt)
383{
384 u8 data[16];
385 struct spmi_log_buffer *log = trans->log;
386
387 int i;
388 int cnt = 0;
389 int items_to_read = min(ARRAY_SIZE(data), *pcnt);
390
391 /* Buffer needs enough space for an entire line */
392 if ((log->len - log->wpos) < 80)
393 goto done;
394
395 /* Read the desired number of "items" */
396 if (spmi_read_data(trans->ctrl, data, offset, items_to_read))
397 goto done;
398
399 *pcnt -= items_to_read;
400
401 /* Log the data items */
402 for (i = 0; i < items_to_read; ++i) {
403 cnt = print_to_log(log, "0x%2.2X ", data[i]);
404 if (cnt == 0)
405 goto done;
406 }
407
408 /* If the last character was a space, then replace it with a newline */
409 if (log->wpos > 0 && log->data[log->wpos - 1] == ' ')
410 log->data[log->wpos - 1] = '\n';
411
412done:
413 return cnt;
414}
415
416/**
417 * get_log_data - reads data across the SPMI bus and saves to the log buffer
418 * @trans: Pointer to SPMI transaction data.
419 *
420 * Returns the number of "items" read or SPMI error code for read failures.
421 */
422static int get_log_data(struct spmi_trans *trans)
423{
424 int cnt;
425 int last_cnt;
426 int items_read;
427 int total_items_read = 0;
428 u32 offset = trans->offset;
429 size_t item_cnt = trans->cnt;
430 struct spmi_log_buffer *log = trans->log;
431 int (*write_to_log)(struct spmi_trans *, int, size_t *);
432
433 if (item_cnt == 0)
434 return 0;
435
436 if (trans->raw_data)
437 write_to_log = write_raw_data_to_log;
438 else
439 write_to_log = write_next_line_to_log;
440
441 /* Reset the log buffer 'pointers' */
442 log->wpos = log->rpos = 0;
443
444 /* Keep reading data until the log is full */
445 do {
446 last_cnt = item_cnt;
447 cnt = write_to_log(trans, offset, &item_cnt);
448 items_read = last_cnt - item_cnt;
449 offset += items_read;
450 total_items_read += items_read;
451 } while (cnt && item_cnt > 0);
452
453 /* Adjust the transaction offset and count */
454 trans->cnt = item_cnt;
455 trans->offset += total_items_read;
456
457 return total_items_read;
458}
459
460/**
461 * spmi_dfs_reg_write: write user's byte array (coded as string) over SPMI.
462 * @file: file pointer
463 * @buf: user data to be written.
464 * @count: maximum space available in @buf
465 * @ppos: starting position
466 * @return number of user byte written, or negative error value
467 */
468static ssize_t spmi_dfs_reg_write(struct file *file, const char __user *buf,
469 size_t count, loff_t *ppos)
470{
471 int bytes_read;
472 int data;
473 int pos = 0;
474 int cnt = 0;
475 u8 *values;
476 size_t ret = 0;
477
478 struct spmi_trans *trans = file->private_data;
479 u32 offset = trans->offset;
480
481 /* Make a copy of the user data */
482 char *kbuf = kmalloc(count + 1, GFP_KERNEL);
483 if (!kbuf)
484 return -ENOMEM;
485
486 ret = copy_from_user(kbuf, buf, count);
487 if (ret == count) {
488 pr_err("failed to copy data from user\n");
489 ret = -EFAULT;
490 goto free_buf;
491 }
492
493 count -= ret;
494 *ppos += count;
495 kbuf[count] = '\0';
496
497 /* Override the text buffer with the raw data */
498 values = kbuf;
499
500 /* Parse the data in the buffer. It should be a string of numbers */
501 while (sscanf(kbuf + pos, "%i%n", &data, &bytes_read) == 1) {
502 pos += bytes_read;
503 values[cnt++] = data & 0xff;
504 }
505
506 if (!cnt)
507 goto free_buf;
508
509 /* Perform the SPMI write(s) */
510 ret = spmi_write_data(trans->ctrl, values, offset, cnt);
511
512 if (ret) {
513 pr_err("SPMI write failed, err = %zu\n", ret);
514 } else {
515 ret = count;
516 trans->offset += cnt;
517 }
518
519free_buf:
520 kfree(kbuf);
521 return ret;
522}
523
524/**
525 * spmi_dfs_reg_read: reads value(s) over SPMI and fill user's buffer a
526 * byte array (coded as string)
527 * @file: file pointer
528 * @buf: where to put the result
529 * @count: maximum space available in @buf
530 * @ppos: starting position
531 * @return number of user bytes read, or negative error value
532 */
533static ssize_t spmi_dfs_reg_read(struct file *file, char __user *buf,
534 size_t count, loff_t *ppos)
535{
536 struct spmi_trans *trans = file->private_data;
537 struct spmi_log_buffer *log = trans->log;
538 size_t ret;
539 size_t len;
540
541 /* Is the the log buffer empty */
542 if (log->rpos >= log->wpos) {
543 if (get_log_data(trans) <= 0)
544 return 0;
545 }
546
547 len = min(count, log->wpos - log->rpos);
548
549 ret = copy_to_user(buf, &log->data[log->rpos], len);
550 if (ret == len) {
551 pr_err("error copy SPMI register values to user\n");
552 return -EFAULT;
553 }
554
555 /* 'ret' is the number of bytes not copied */
556 len -= ret;
557
558 *ppos += len;
559 log->rpos += len;
560 return len;
561}
562
563static const struct file_operations spmi_dfs_reg_fops = {
564 .open = spmi_dfs_data_open,
565 .release = spmi_dfs_close,
566 .read = spmi_dfs_reg_read,
567 .write = spmi_dfs_reg_write,
568};
569
570static const struct file_operations spmi_dfs_raw_data_fops = {
571 .open = spmi_dfs_raw_data_open,
572 .release = spmi_dfs_close,
573 .read = spmi_dfs_reg_read,
574 .write = spmi_dfs_reg_write,
575};
576
577/**
578 * spmi_dfs_create_fs: create debugfs file system.
579 * @return pointer to root directory or NULL if failed to create fs
580 */
581static struct dentry *spmi_dfs_create_fs(void)
582{
583 struct dentry *root, *file;
584
585 pr_debug("Creating SPMI debugfs file-system at\n");
586 root = debugfs_create_dir(DFS_ROOT_NAME, NULL);
587 if (IS_ERR(root)) {
588 pr_err("Error creating top level directory err:%ld",
589 (long)root);
590 if ((int)root == -ENODEV)
591 pr_err("debugfs is not enabled in the kernel");
592 return NULL;
593 }
594
595 dbgfs_data.help_msg.size = strlen(dbgfs_data.help_msg.data);
596
597 file = debugfs_create_blob("help", S_IRUGO, root, &dbgfs_data.help_msg);
598 if (!file) {
599 pr_err("error creating help entry\n");
600 goto err_remove_fs;
601 }
602 return root;
603
604err_remove_fs:
605 debugfs_remove_recursive(root);
606 return NULL;
607}
608
609/**
610 * spmi_dfs_get_root: return a pointer to SPMI debugfs root directory.
611 * @brief return a pointer to the existing directory, or if no root
612 * directory exists then create one. Directory is created with file that
613 * configures SPMI transaction, namely: sid, address, and count.
614 * @returns valid pointer on success or NULL
615 */
616struct dentry *spmi_dfs_get_root(void)
617{
618 if (dbgfs_data.root)
619 return dbgfs_data.root;
620
621 if (mutex_lock_interruptible(&dbgfs_data.lock) < 0)
622 return NULL;
623 /* critical section */
624 if (!dbgfs_data.root) { /* double checking idiom */
625 dbgfs_data.root = spmi_dfs_create_fs();
626 }
627 mutex_unlock(&dbgfs_data.lock);
628 return dbgfs_data.root;
629}
630
631/*
632 * spmi_dfs_add_controller: adds new spmi controller entry
633 * @return zero on success
634 */
635int spmi_dfs_add_controller(struct spmi_controller *ctrl)
636{
637 struct dentry *dir;
638 struct dentry *root;
639 struct dentry *file;
640 struct spmi_ctrl_data *ctrl_data;
641
642 pr_debug("Adding controller %s\n", ctrl->dev.kobj.name);
643 root = spmi_dfs_get_root();
644 if (!root)
645 return -ENOENT;
646
647 /* Allocate transaction data for the controller */
648 ctrl_data = kzalloc(sizeof(*ctrl_data), GFP_KERNEL);
649 if (!ctrl_data)
650 return -ENOMEM;
651
652 dir = debugfs_create_dir(ctrl->dev.kobj.name, root);
653 if (!dir) {
654 pr_err("Error creating entry for spmi controller %s\n",
655 ctrl->dev.kobj.name);
656 goto err_create_dir_failed;
657 }
658
659 ctrl_data->cnt = 1;
Kenneth Heitke5998fab2013-01-22 16:09:19 -0700660 ctrl_data->dir = dir;
Kenneth Heitke98661912012-09-19 18:51:40 -0600661 ctrl_data->ctrl = ctrl;
662
663 file = debugfs_create_u32("count", DFS_MODE, dir, &ctrl_data->cnt);
664 if (!file) {
665 pr_err("error creating 'count' entry\n");
666 goto err_remove_fs;
667 }
668
669 file = debugfs_create_x32("address", DFS_MODE, dir, &ctrl_data->addr);
670 if (!file) {
671 pr_err("error creating 'address' entry\n");
672 goto err_remove_fs;
673 }
674
675 file = debugfs_create_file("data", DFS_MODE, dir, ctrl_data,
676 &spmi_dfs_reg_fops);
677 if (!file) {
678 pr_err("error creating 'data' entry\n");
679 goto err_remove_fs;
680 }
681
682 file = debugfs_create_file("data_raw", DFS_MODE, dir, ctrl_data,
683 &spmi_dfs_raw_data_fops);
684 if (!file) {
685 pr_err("error creating 'data' entry\n");
686 goto err_remove_fs;
687 }
688
689 list_add(&ctrl_data->node, &dbgfs_data.ctrl);
690 return 0;
691
692err_remove_fs:
693 debugfs_remove_recursive(dir);
694err_create_dir_failed:
695 kfree(ctrl_data);
696 return -ENOMEM;
697}
698
Kenneth Heitke5998fab2013-01-22 16:09:19 -0700699/*
700 * spmi_dfs_create_file: creates a new file in the SPMI debugfs
701 * @returns valid dentry pointer on success or NULL
702 */
703struct dentry *spmi_dfs_create_file(struct spmi_controller *ctrl,
704 const char *name, void *data,
705 const struct file_operations *fops)
706{
707 struct spmi_ctrl_data *ctrl_data;
708
709 list_for_each_entry(ctrl_data, &dbgfs_data.ctrl, node) {
710 if (ctrl_data->ctrl == ctrl)
711 return debugfs_create_file(name,
712 DFS_MODE, ctrl_data->dir, data, fops);
713 }
714
715 return NULL;
716}
717
Kenneth Heitke98661912012-09-19 18:51:40 -0600718static void __exit spmi_dfs_delete_all_ctrl(struct list_head *head)
719{
720 struct list_head *pos, *tmp;
721
722 list_for_each_safe(pos, tmp, head) {
723 struct spmi_ctrl_data *ctrl_data;
724
725 ctrl_data = list_entry(pos, struct spmi_ctrl_data, node);
726 list_del(pos);
727 kfree(ctrl_data);
728 }
729}
730
731static void __exit spmi_dfs_destroy(void)
732{
733 pr_debug("de-initializing spmi debugfs ...");
734 if (mutex_lock_interruptible(&dbgfs_data.lock) < 0)
735 return;
736 if (dbgfs_data.root) {
737 debugfs_remove_recursive(dbgfs_data.root);
738 dbgfs_data.root = NULL;
739 spmi_dfs_delete_all_ctrl(&dbgfs_data.ctrl);
740 }
741 mutex_unlock(&dbgfs_data.lock);
742}
743
744module_exit(spmi_dfs_destroy);
745
746MODULE_LICENSE("GPL v2");
747MODULE_ALIAS("platform:spmi_debug_fs");