aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/class.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/class.c')
-rw-r--r--drivers/base/class.c87
1 files changed, 48 insertions, 39 deletions
diff --git a/drivers/base/class.c b/drivers/base/class.c
index 3918d0e432d4..06f09c929a91 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -21,17 +21,16 @@
21#include "base.h" 21#include "base.h"
22 22
23#define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr) 23#define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)
24#define to_class(obj) container_of(obj, struct class, subsys.kobj)
25 24
26static ssize_t class_attr_show(struct kobject *kobj, struct attribute *attr, 25static ssize_t class_attr_show(struct kobject *kobj, struct attribute *attr,
27 char *buf) 26 char *buf)
28{ 27{
29 struct class_attribute *class_attr = to_class_attr(attr); 28 struct class_attribute *class_attr = to_class_attr(attr);
30 struct class *dc = to_class(kobj); 29 struct class_private *cp = to_class(kobj);
31 ssize_t ret = -EIO; 30 ssize_t ret = -EIO;
32 31
33 if (class_attr->show) 32 if (class_attr->show)
34 ret = class_attr->show(dc, buf); 33 ret = class_attr->show(cp->class, buf);
35 return ret; 34 return ret;
36} 35}
37 36
@@ -39,17 +38,18 @@ static ssize_t class_attr_store(struct kobject *kobj, struct attribute *attr,
39 const char *buf, size_t count) 38 const char *buf, size_t count)
40{ 39{
41 struct class_attribute *class_attr = to_class_attr(attr); 40 struct class_attribute *class_attr = to_class_attr(attr);
42 struct class *dc = to_class(kobj); 41 struct class_private *cp = to_class(kobj);
43 ssize_t ret = -EIO; 42 ssize_t ret = -EIO;
44 43
45 if (class_attr->store) 44 if (class_attr->store)
46 ret = class_attr->store(dc, buf, count); 45 ret = class_attr->store(cp->class, buf, count);
47 return ret; 46 return ret;
48} 47}
49 48
50static void class_release(struct kobject *kobj) 49static void class_release(struct kobject *kobj)
51{ 50{
52 struct class *class = to_class(kobj); 51 struct class_private *cp = to_class(kobj);
52 struct class *class = cp->class;
53 53
54 pr_debug("class '%s': release.\n", class->name); 54 pr_debug("class '%s': release.\n", class->name);
55 55
@@ -78,7 +78,7 @@ int class_create_file(struct class *cls, const struct class_attribute *attr)
78{ 78{
79 int error; 79 int error;
80 if (cls) 80 if (cls)
81 error = sysfs_create_file(&cls->subsys.kobj, &attr->attr); 81 error = sysfs_create_file(&cls->p->subsys.kobj, &attr->attr);
82 else 82 else
83 error = -EINVAL; 83 error = -EINVAL;
84 return error; 84 return error;
@@ -87,21 +87,20 @@ int class_create_file(struct class *cls, const struct class_attribute *attr)
87void class_remove_file(struct class *cls, const struct class_attribute *attr) 87void class_remove_file(struct class *cls, const struct class_attribute *attr)
88{ 88{
89 if (cls) 89 if (cls)
90 sysfs_remove_file(&cls->subsys.kobj, &attr->attr); 90 sysfs_remove_file(&cls->p->subsys.kobj, &attr->attr);
91} 91}
92 92
93static struct class *class_get(struct class *cls) 93static struct class *class_get(struct class *cls)
94{ 94{
95 if (cls) 95 if (cls)
96 return container_of(kset_get(&cls->subsys), 96 kset_get(&cls->p->subsys);
97 struct class, subsys); 97 return cls;
98 return NULL;
99} 98}
100 99
101static void class_put(struct class *cls) 100static void class_put(struct class *cls)
102{ 101{
103 if (cls) 102 if (cls)
104 kset_put(&cls->subsys); 103 kset_put(&cls->p->subsys);
105} 104}
106 105
107static int add_class_attrs(struct class *cls) 106static int add_class_attrs(struct class *cls)
@@ -136,17 +135,23 @@ static void remove_class_attrs(struct class *cls)
136 135
137int class_register(struct class *cls) 136int class_register(struct class *cls)
138{ 137{
138 struct class_private *cp;
139 int error; 139 int error;
140 140
141 pr_debug("device class '%s': registering\n", cls->name); 141 pr_debug("device class '%s': registering\n", cls->name);
142 142
143 INIT_LIST_HEAD(&cls->devices); 143 cp = kzalloc(sizeof(*cp), GFP_KERNEL);
144 INIT_LIST_HEAD(&cls->interfaces); 144 if (!cp)
145 kset_init(&cls->class_dirs); 145 return -ENOMEM;
146 init_MUTEX(&cls->sem); 146 INIT_LIST_HEAD(&cp->devices);
147 error = kobject_set_name(&cls->subsys.kobj, "%s", cls->name); 147 INIT_LIST_HEAD(&cp->interfaces);
148 if (error) 148 kset_init(&cp->class_dirs);
149 init_MUTEX(&cp->sem);
150 error = kobject_set_name(&cp->subsys.kobj, "%s", cls->name);
151 if (error) {
152 kfree(cp);
149 return error; 153 return error;
154 }
150 155
151 /* set the default /sys/dev directory for devices of this class */ 156 /* set the default /sys/dev directory for devices of this class */
152 if (!cls->dev_kobj) 157 if (!cls->dev_kobj)
@@ -155,17 +160,21 @@ int class_register(struct class *cls)
155#if defined(CONFIG_SYSFS_DEPRECATED) && defined(CONFIG_BLOCK) 160#if defined(CONFIG_SYSFS_DEPRECATED) && defined(CONFIG_BLOCK)
156 /* let the block class directory show up in the root of sysfs */ 161 /* let the block class directory show up in the root of sysfs */
157 if (cls != &block_class) 162 if (cls != &block_class)
158 cls->subsys.kobj.kset = class_kset; 163 cp->subsys.kobj.kset = class_kset;
159#else 164#else
160 cls->subsys.kobj.kset = class_kset; 165 cp->subsys.kobj.kset = class_kset;
161#endif 166#endif
162 cls->subsys.kobj.ktype = &class_ktype; 167 cp->subsys.kobj.ktype = &class_ktype;
168 cp->class = cls;
169 cls->p = cp;
163 170
164 error = kset_register(&cls->subsys); 171 error = kset_register(&cp->subsys);
165 if (!error) { 172 if (error) {
166 error = add_class_attrs(class_get(cls)); 173 kfree(cp);
167 class_put(cls); 174 return error;
168 } 175 }
176 error = add_class_attrs(class_get(cls));
177 class_put(cls);
169 return error; 178 return error;
170} 179}
171 180
@@ -173,7 +182,7 @@ void class_unregister(struct class *cls)
173{ 182{
174 pr_debug("device class '%s': unregistering\n", cls->name); 183 pr_debug("device class '%s': unregistering\n", cls->name);
175 remove_class_attrs(cls); 184 remove_class_attrs(cls);
176 kset_unregister(&cls->subsys); 185 kset_unregister(&cls->p->subsys);
177} 186}
178 187
179static void class_create_release(struct class *cls) 188static void class_create_release(struct class *cls)
@@ -280,8 +289,8 @@ int class_for_each_device(struct class *class, struct device *start,
280 289
281 if (!class) 290 if (!class)
282 return -EINVAL; 291 return -EINVAL;
283 down(&class->sem); 292 down(&class->p->sem);
284 list_for_each_entry(dev, &class->devices, node) { 293 list_for_each_entry(dev, &class->p->devices, node) {
285 if (start) { 294 if (start) {
286 if (start == dev) 295 if (start == dev)
287 start = NULL; 296 start = NULL;
@@ -293,7 +302,7 @@ int class_for_each_device(struct class *class, struct device *start,
293 if (error) 302 if (error)
294 break; 303 break;
295 } 304 }
296 up(&class->sem); 305 up(&class->p->sem);
297 306
298 return error; 307 return error;
299} 308}
@@ -330,8 +339,8 @@ struct device *class_find_device(struct class *class, struct device *start,
330 if (!class) 339 if (!class)
331 return NULL; 340 return NULL;
332 341
333 down(&class->sem); 342 down(&class->p->sem);
334 list_for_each_entry(dev, &class->devices, node) { 343 list_for_each_entry(dev, &class->p->devices, node) {
335 if (start) { 344 if (start) {
336 if (start == dev) 345 if (start == dev)
337 start = NULL; 346 start = NULL;
@@ -344,7 +353,7 @@ struct device *class_find_device(struct class *class, struct device *start,
344 } else 353 } else
345 put_device(dev); 354 put_device(dev);
346 } 355 }
347 up(&class->sem); 356 up(&class->p->sem);
348 357
349 return found ? dev : NULL; 358 return found ? dev : NULL;
350} 359}
@@ -362,13 +371,13 @@ int class_interface_register(struct class_interface *class_intf)
362 if (!parent) 371 if (!parent)
363 return -EINVAL; 372 return -EINVAL;
364 373
365 down(&parent->sem); 374 down(&parent->p->sem);
366 list_add_tail(&class_intf->node, &parent->interfaces); 375 list_add_tail(&class_intf->node, &parent->p->interfaces);
367 if (class_intf->add_dev) { 376 if (class_intf->add_dev) {
368 list_for_each_entry(dev, &parent->devices, node) 377 list_for_each_entry(dev, &parent->p->devices, node)
369 class_intf->add_dev(dev, class_intf); 378 class_intf->add_dev(dev, class_intf);
370 } 379 }
371 up(&parent->sem); 380 up(&parent->p->sem);
372 381
373 return 0; 382 return 0;
374} 383}
@@ -381,13 +390,13 @@ void class_interface_unregister(struct class_interface *class_intf)
381 if (!parent) 390 if (!parent)
382 return; 391 return;
383 392
384 down(&parent->sem); 393 down(&parent->p->sem);
385 list_del_init(&class_intf->node); 394 list_del_init(&class_intf->node);
386 if (class_intf->remove_dev) { 395 if (class_intf->remove_dev) {
387 list_for_each_entry(dev, &parent->devices, node) 396 list_for_each_entry(dev, &parent->p->devices, node)
388 class_intf->remove_dev(dev, class_intf); 397 class_intf->remove_dev(dev, class_intf);
389 } 398 }
390 up(&parent->sem); 399 up(&parent->p->sem);
391 400
392 class_put(parent); 401 class_put(parent);
393} 402}