diff options
Diffstat (limited to 'drivers/base/component.c')
-rw-r--r-- | drivers/base/component.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/drivers/base/component.c b/drivers/base/component.c index 891f0e38647c..8946dfee4768 100644 --- a/drivers/base/component.c +++ b/drivers/base/component.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/mutex.h> | 15 | #include <linux/mutex.h> |
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/debugfs.h> | ||
17 | 18 | ||
18 | struct component; | 19 | struct component; |
19 | 20 | ||
@@ -38,6 +39,7 @@ struct master { | |||
38 | const struct component_master_ops *ops; | 39 | const struct component_master_ops *ops; |
39 | struct device *dev; | 40 | struct device *dev; |
40 | struct component_match *match; | 41 | struct component_match *match; |
42 | struct dentry *dentry; | ||
41 | }; | 43 | }; |
42 | 44 | ||
43 | struct component { | 45 | struct component { |
@@ -53,6 +55,80 @@ static DEFINE_MUTEX(component_mutex); | |||
53 | static LIST_HEAD(component_list); | 55 | static LIST_HEAD(component_list); |
54 | static LIST_HEAD(masters); | 56 | static LIST_HEAD(masters); |
55 | 57 | ||
58 | #ifdef CONFIG_DEBUG_FS | ||
59 | |||
60 | static struct dentry *component_debugfs_dir; | ||
61 | |||
62 | static int component_devices_show(struct seq_file *s, void *data) | ||
63 | { | ||
64 | struct master *m = s->private; | ||
65 | struct component_match *match = m->match; | ||
66 | size_t i; | ||
67 | |||
68 | mutex_lock(&component_mutex); | ||
69 | seq_printf(s, "%-40s %20s\n", "master name", "status"); | ||
70 | seq_puts(s, "-------------------------------------------------------------\n"); | ||
71 | seq_printf(s, "%-40s %20s\n\n", | ||
72 | dev_name(m->dev), m->bound ? "bound" : "not bound"); | ||
73 | |||
74 | seq_printf(s, "%-40s %20s\n", "device name", "status"); | ||
75 | seq_puts(s, "-------------------------------------------------------------\n"); | ||
76 | for (i = 0; i < match->num; i++) { | ||
77 | struct device *d = (struct device *)match->compare[i].data; | ||
78 | |||
79 | seq_printf(s, "%-40s %20s\n", dev_name(d), | ||
80 | match->compare[i].component ? | ||
81 | "registered" : "not registered"); | ||
82 | } | ||
83 | mutex_unlock(&component_mutex); | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | static int component_devices_open(struct inode *inode, struct file *file) | ||
89 | { | ||
90 | return single_open(file, component_devices_show, inode->i_private); | ||
91 | } | ||
92 | |||
93 | static const struct file_operations component_devices_fops = { | ||
94 | .open = component_devices_open, | ||
95 | .read = seq_read, | ||
96 | .llseek = seq_lseek, | ||
97 | .release = single_release, | ||
98 | }; | ||
99 | |||
100 | static int __init component_debug_init(void) | ||
101 | { | ||
102 | component_debugfs_dir = debugfs_create_dir("device_component", NULL); | ||
103 | |||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | core_initcall(component_debug_init); | ||
108 | |||
109 | static void component_master_debugfs_add(struct master *m) | ||
110 | { | ||
111 | m->dentry = debugfs_create_file(dev_name(m->dev), 0444, | ||
112 | component_debugfs_dir, | ||
113 | m, &component_devices_fops); | ||
114 | } | ||
115 | |||
116 | static void component_master_debugfs_del(struct master *m) | ||
117 | { | ||
118 | debugfs_remove(m->dentry); | ||
119 | m->dentry = NULL; | ||
120 | } | ||
121 | |||
122 | #else | ||
123 | |||
124 | static void component_master_debugfs_add(struct master *m) | ||
125 | { } | ||
126 | |||
127 | static void component_master_debugfs_del(struct master *m) | ||
128 | { } | ||
129 | |||
130 | #endif | ||
131 | |||
56 | static struct master *__master_find(struct device *dev, | 132 | static struct master *__master_find(struct device *dev, |
57 | const struct component_master_ops *ops) | 133 | const struct component_master_ops *ops) |
58 | { | 134 | { |
@@ -287,6 +363,7 @@ static void free_master(struct master *master) | |||
287 | struct component_match *match = master->match; | 363 | struct component_match *match = master->match; |
288 | int i; | 364 | int i; |
289 | 365 | ||
366 | component_master_debugfs_del(master); | ||
290 | list_del(&master->node); | 367 | list_del(&master->node); |
291 | 368 | ||
292 | if (match) { | 369 | if (match) { |
@@ -320,6 +397,7 @@ int component_master_add_with_match(struct device *dev, | |||
320 | master->ops = ops; | 397 | master->ops = ops; |
321 | master->match = match; | 398 | master->match = match; |
322 | 399 | ||
400 | component_master_debugfs_add(master); | ||
323 | /* Add to the list of available masters. */ | 401 | /* Add to the list of available masters. */ |
324 | mutex_lock(&component_mutex); | 402 | mutex_lock(&component_mutex); |
325 | list_add(&master->node, &masters); | 403 | list_add(&master->node, &masters); |