diff options
Diffstat (limited to 'drivers/base/class.c')
-rw-r--r-- | drivers/base/class.c | 319 |
1 files changed, 231 insertions, 88 deletions
diff --git a/drivers/base/class.c b/drivers/base/class.c index a863bb091e11..59cf35894cfc 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
@@ -17,16 +17,17 @@ | |||
17 | #include <linux/kdev_t.h> | 17 | #include <linux/kdev_t.h> |
18 | #include <linux/err.h> | 18 | #include <linux/err.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/genhd.h> | ||
20 | #include "base.h" | 21 | #include "base.h" |
21 | 22 | ||
22 | #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) |
23 | #define to_class(obj) container_of(obj, struct class, subsys.kobj) | 24 | #define to_class(obj) container_of(obj, struct class, subsys.kobj) |
24 | 25 | ||
25 | static ssize_t | 26 | static ssize_t class_attr_show(struct kobject *kobj, struct attribute *attr, |
26 | class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) | 27 | char *buf) |
27 | { | 28 | { |
28 | struct class_attribute * class_attr = to_class_attr(attr); | 29 | struct class_attribute *class_attr = to_class_attr(attr); |
29 | struct class * dc = to_class(kobj); | 30 | struct class *dc = to_class(kobj); |
30 | ssize_t ret = -EIO; | 31 | ssize_t ret = -EIO; |
31 | 32 | ||
32 | if (class_attr->show) | 33 | if (class_attr->show) |
@@ -34,12 +35,11 @@ class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) | |||
34 | return ret; | 35 | return ret; |
35 | } | 36 | } |
36 | 37 | ||
37 | static ssize_t | 38 | static ssize_t class_attr_store(struct kobject *kobj, struct attribute *attr, |
38 | class_attr_store(struct kobject * kobj, struct attribute * attr, | 39 | const char *buf, size_t count) |
39 | const char * buf, size_t count) | ||
40 | { | 40 | { |
41 | struct class_attribute * class_attr = to_class_attr(attr); | 41 | struct class_attribute *class_attr = to_class_attr(attr); |
42 | struct class * dc = to_class(kobj); | 42 | struct class *dc = to_class(kobj); |
43 | ssize_t ret = -EIO; | 43 | ssize_t ret = -EIO; |
44 | 44 | ||
45 | if (class_attr->store) | 45 | if (class_attr->store) |
@@ -47,7 +47,7 @@ class_attr_store(struct kobject * kobj, struct attribute * attr, | |||
47 | return ret; | 47 | return ret; |
48 | } | 48 | } |
49 | 49 | ||
50 | static void class_release(struct kobject * kobj) | 50 | static void class_release(struct kobject *kobj) |
51 | { | 51 | { |
52 | struct class *class = to_class(kobj); | 52 | struct class *class = to_class(kobj); |
53 | 53 | ||
@@ -71,20 +71,20 @@ static struct kobj_type class_ktype = { | |||
71 | }; | 71 | }; |
72 | 72 | ||
73 | /* Hotplug events for classes go to the class_obj subsys */ | 73 | /* Hotplug events for classes go to the class_obj subsys */ |
74 | static decl_subsys(class, &class_ktype, NULL); | 74 | static struct kset *class_kset; |
75 | 75 | ||
76 | 76 | ||
77 | int class_create_file(struct class * cls, const struct class_attribute * attr) | 77 | 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->subsys.kobj, &attr->attr); |
82 | } else | 82 | else |
83 | error = -EINVAL; | 83 | error = -EINVAL; |
84 | return error; | 84 | return error; |
85 | } | 85 | } |
86 | 86 | ||
87 | void class_remove_file(struct class * cls, const struct class_attribute * attr) | 87 | void 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->subsys.kobj, &attr->attr); |
@@ -93,48 +93,48 @@ void class_remove_file(struct class * cls, const struct class_attribute * attr) | |||
93 | static struct class *class_get(struct class *cls) | 93 | static struct class *class_get(struct class *cls) |
94 | { | 94 | { |
95 | if (cls) | 95 | if (cls) |
96 | return container_of(kset_get(&cls->subsys), struct class, subsys); | 96 | return container_of(kset_get(&cls->subsys), |
97 | struct class, subsys); | ||
97 | return NULL; | 98 | return NULL; |
98 | } | 99 | } |
99 | 100 | ||
100 | static void class_put(struct class * cls) | 101 | static void class_put(struct class *cls) |
101 | { | 102 | { |
102 | if (cls) | 103 | if (cls) |
103 | kset_put(&cls->subsys); | 104 | kset_put(&cls->subsys); |
104 | } | 105 | } |
105 | 106 | ||
106 | 107 | static int add_class_attrs(struct class *cls) | |
107 | static int add_class_attrs(struct class * cls) | ||
108 | { | 108 | { |
109 | int i; | 109 | int i; |
110 | int error = 0; | 110 | int error = 0; |
111 | 111 | ||
112 | if (cls->class_attrs) { | 112 | if (cls->class_attrs) { |
113 | for (i = 0; attr_name(cls->class_attrs[i]); i++) { | 113 | for (i = 0; attr_name(cls->class_attrs[i]); i++) { |
114 | error = class_create_file(cls,&cls->class_attrs[i]); | 114 | error = class_create_file(cls, &cls->class_attrs[i]); |
115 | if (error) | 115 | if (error) |
116 | goto Err; | 116 | goto error; |
117 | } | 117 | } |
118 | } | 118 | } |
119 | Done: | 119 | done: |
120 | return error; | 120 | return error; |
121 | Err: | 121 | error: |
122 | while (--i >= 0) | 122 | while (--i >= 0) |
123 | class_remove_file(cls,&cls->class_attrs[i]); | 123 | class_remove_file(cls, &cls->class_attrs[i]); |
124 | goto Done; | 124 | goto done; |
125 | } | 125 | } |
126 | 126 | ||
127 | static void remove_class_attrs(struct class * cls) | 127 | static void remove_class_attrs(struct class *cls) |
128 | { | 128 | { |
129 | int i; | 129 | int i; |
130 | 130 | ||
131 | if (cls->class_attrs) { | 131 | if (cls->class_attrs) { |
132 | for (i = 0; attr_name(cls->class_attrs[i]); i++) | 132 | for (i = 0; attr_name(cls->class_attrs[i]); i++) |
133 | class_remove_file(cls,&cls->class_attrs[i]); | 133 | class_remove_file(cls, &cls->class_attrs[i]); |
134 | } | 134 | } |
135 | } | 135 | } |
136 | 136 | ||
137 | int class_register(struct class * cls) | 137 | int class_register(struct class *cls) |
138 | { | 138 | { |
139 | int error; | 139 | int error; |
140 | 140 | ||
@@ -149,9 +149,16 @@ int class_register(struct class * cls) | |||
149 | if (error) | 149 | if (error) |
150 | return error; | 150 | return error; |
151 | 151 | ||
152 | cls->subsys.kobj.kset = &class_subsys; | 152 | #ifdef CONFIG_SYSFS_DEPRECATED |
153 | /* let the block class directory show up in the root of sysfs */ | ||
154 | if (cls != &block_class) | ||
155 | cls->subsys.kobj.kset = class_kset; | ||
156 | #else | ||
157 | cls->subsys.kobj.kset = class_kset; | ||
158 | #endif | ||
159 | cls->subsys.kobj.ktype = &class_ktype; | ||
153 | 160 | ||
154 | error = subsystem_register(&cls->subsys); | 161 | error = kset_register(&cls->subsys); |
155 | if (!error) { | 162 | if (!error) { |
156 | error = add_class_attrs(class_get(cls)); | 163 | error = add_class_attrs(class_get(cls)); |
157 | class_put(cls); | 164 | class_put(cls); |
@@ -159,11 +166,11 @@ int class_register(struct class * cls) | |||
159 | return error; | 166 | return error; |
160 | } | 167 | } |
161 | 168 | ||
162 | void class_unregister(struct class * cls) | 169 | void class_unregister(struct class *cls) |
163 | { | 170 | { |
164 | pr_debug("device class '%s': unregistering\n", cls->name); | 171 | pr_debug("device class '%s': unregistering\n", cls->name); |
165 | remove_class_attrs(cls); | 172 | remove_class_attrs(cls); |
166 | subsystem_unregister(&cls->subsys); | 173 | kset_unregister(&cls->subsys); |
167 | } | 174 | } |
168 | 175 | ||
169 | static void class_create_release(struct class *cls) | 176 | static void class_create_release(struct class *cls) |
@@ -241,8 +248,8 @@ void class_destroy(struct class *cls) | |||
241 | 248 | ||
242 | /* Class Device Stuff */ | 249 | /* Class Device Stuff */ |
243 | 250 | ||
244 | int class_device_create_file(struct class_device * class_dev, | 251 | int class_device_create_file(struct class_device *class_dev, |
245 | const struct class_device_attribute * attr) | 252 | const struct class_device_attribute *attr) |
246 | { | 253 | { |
247 | int error = -EINVAL; | 254 | int error = -EINVAL; |
248 | if (class_dev) | 255 | if (class_dev) |
@@ -250,8 +257,8 @@ int class_device_create_file(struct class_device * class_dev, | |||
250 | return error; | 257 | return error; |
251 | } | 258 | } |
252 | 259 | ||
253 | void class_device_remove_file(struct class_device * class_dev, | 260 | void class_device_remove_file(struct class_device *class_dev, |
254 | const struct class_device_attribute * attr) | 261 | const struct class_device_attribute *attr) |
255 | { | 262 | { |
256 | if (class_dev) | 263 | if (class_dev) |
257 | sysfs_remove_file(&class_dev->kobj, &attr->attr); | 264 | sysfs_remove_file(&class_dev->kobj, &attr->attr); |
@@ -273,12 +280,11 @@ void class_device_remove_bin_file(struct class_device *class_dev, | |||
273 | sysfs_remove_bin_file(&class_dev->kobj, attr); | 280 | sysfs_remove_bin_file(&class_dev->kobj, attr); |
274 | } | 281 | } |
275 | 282 | ||
276 | static ssize_t | 283 | static ssize_t class_device_attr_show(struct kobject *kobj, |
277 | class_device_attr_show(struct kobject * kobj, struct attribute * attr, | 284 | struct attribute *attr, char *buf) |
278 | char * buf) | ||
279 | { | 285 | { |
280 | struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr); | 286 | struct class_device_attribute *class_dev_attr = to_class_dev_attr(attr); |
281 | struct class_device * cd = to_class_dev(kobj); | 287 | struct class_device *cd = to_class_dev(kobj); |
282 | ssize_t ret = 0; | 288 | ssize_t ret = 0; |
283 | 289 | ||
284 | if (class_dev_attr->show) | 290 | if (class_dev_attr->show) |
@@ -286,12 +292,12 @@ class_device_attr_show(struct kobject * kobj, struct attribute * attr, | |||
286 | return ret; | 292 | return ret; |
287 | } | 293 | } |
288 | 294 | ||
289 | static ssize_t | 295 | static ssize_t class_device_attr_store(struct kobject *kobj, |
290 | class_device_attr_store(struct kobject * kobj, struct attribute * attr, | 296 | struct attribute *attr, |
291 | const char * buf, size_t count) | 297 | const char *buf, size_t count) |
292 | { | 298 | { |
293 | struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr); | 299 | struct class_device_attribute *class_dev_attr = to_class_dev_attr(attr); |
294 | struct class_device * cd = to_class_dev(kobj); | 300 | struct class_device *cd = to_class_dev(kobj); |
295 | ssize_t ret = 0; | 301 | ssize_t ret = 0; |
296 | 302 | ||
297 | if (class_dev_attr->store) | 303 | if (class_dev_attr->store) |
@@ -304,10 +310,10 @@ static struct sysfs_ops class_dev_sysfs_ops = { | |||
304 | .store = class_device_attr_store, | 310 | .store = class_device_attr_store, |
305 | }; | 311 | }; |
306 | 312 | ||
307 | static void class_dev_release(struct kobject * kobj) | 313 | static void class_dev_release(struct kobject *kobj) |
308 | { | 314 | { |
309 | struct class_device *cd = to_class_dev(kobj); | 315 | struct class_device *cd = to_class_dev(kobj); |
310 | struct class * cls = cd->class; | 316 | struct class *cls = cd->class; |
311 | 317 | ||
312 | pr_debug("device class '%s': release.\n", cd->class_id); | 318 | pr_debug("device class '%s': release.\n", cd->class_id); |
313 | 319 | ||
@@ -316,8 +322,8 @@ static void class_dev_release(struct kobject * kobj) | |||
316 | else if (cls->release) | 322 | else if (cls->release) |
317 | cls->release(cd); | 323 | cls->release(cd); |
318 | else { | 324 | else { |
319 | printk(KERN_ERR "Class Device '%s' does not have a release() function, " | 325 | printk(KERN_ERR "Class Device '%s' does not have a release() " |
320 | "it is broken and must be fixed.\n", | 326 | "function, it is broken and must be fixed.\n", |
321 | cd->class_id); | 327 | cd->class_id); |
322 | WARN_ON(1); | 328 | WARN_ON(1); |
323 | } | 329 | } |
@@ -428,7 +434,8 @@ static int class_uevent(struct kset *kset, struct kobject *kobj, | |||
428 | add_uevent_var(env, "PHYSDEVBUS=%s", dev->bus->name); | 434 | add_uevent_var(env, "PHYSDEVBUS=%s", dev->bus->name); |
429 | 435 | ||
430 | if (dev->driver) | 436 | if (dev->driver) |
431 | add_uevent_var(env, "PHYSDEVDRIVER=%s", dev->driver->name); | 437 | add_uevent_var(env, "PHYSDEVDRIVER=%s", |
438 | dev->driver->name); | ||
432 | } | 439 | } |
433 | 440 | ||
434 | if (class_dev->uevent) { | 441 | if (class_dev->uevent) { |
@@ -452,43 +459,49 @@ static struct kset_uevent_ops class_uevent_ops = { | |||
452 | .uevent = class_uevent, | 459 | .uevent = class_uevent, |
453 | }; | 460 | }; |
454 | 461 | ||
455 | static decl_subsys(class_obj, &class_device_ktype, &class_uevent_ops); | 462 | /* |
456 | 463 | * DO NOT copy how this is created, kset_create_and_add() should be | |
464 | * called, but this is a hold-over from the old-way and will be deleted | ||
465 | * entirely soon. | ||
466 | */ | ||
467 | static struct kset class_obj_subsys = { | ||
468 | .uevent_ops = &class_uevent_ops, | ||
469 | }; | ||
457 | 470 | ||
458 | static int class_device_add_attrs(struct class_device * cd) | 471 | static int class_device_add_attrs(struct class_device *cd) |
459 | { | 472 | { |
460 | int i; | 473 | int i; |
461 | int error = 0; | 474 | int error = 0; |
462 | struct class * cls = cd->class; | 475 | struct class *cls = cd->class; |
463 | 476 | ||
464 | if (cls->class_dev_attrs) { | 477 | if (cls->class_dev_attrs) { |
465 | for (i = 0; attr_name(cls->class_dev_attrs[i]); i++) { | 478 | for (i = 0; attr_name(cls->class_dev_attrs[i]); i++) { |
466 | error = class_device_create_file(cd, | 479 | error = class_device_create_file(cd, |
467 | &cls->class_dev_attrs[i]); | 480 | &cls->class_dev_attrs[i]); |
468 | if (error) | 481 | if (error) |
469 | goto Err; | 482 | goto err; |
470 | } | 483 | } |
471 | } | 484 | } |
472 | Done: | 485 | done: |
473 | return error; | 486 | return error; |
474 | Err: | 487 | err: |
475 | while (--i >= 0) | 488 | while (--i >= 0) |
476 | class_device_remove_file(cd,&cls->class_dev_attrs[i]); | 489 | class_device_remove_file(cd, &cls->class_dev_attrs[i]); |
477 | goto Done; | 490 | goto done; |
478 | } | 491 | } |
479 | 492 | ||
480 | static void class_device_remove_attrs(struct class_device * cd) | 493 | static void class_device_remove_attrs(struct class_device *cd) |
481 | { | 494 | { |
482 | int i; | 495 | int i; |
483 | struct class * cls = cd->class; | 496 | struct class *cls = cd->class; |
484 | 497 | ||
485 | if (cls->class_dev_attrs) { | 498 | if (cls->class_dev_attrs) { |
486 | for (i = 0; attr_name(cls->class_dev_attrs[i]); i++) | 499 | for (i = 0; attr_name(cls->class_dev_attrs[i]); i++) |
487 | class_device_remove_file(cd,&cls->class_dev_attrs[i]); | 500 | class_device_remove_file(cd, &cls->class_dev_attrs[i]); |
488 | } | 501 | } |
489 | } | 502 | } |
490 | 503 | ||
491 | static int class_device_add_groups(struct class_device * cd) | 504 | static int class_device_add_groups(struct class_device *cd) |
492 | { | 505 | { |
493 | int i; | 506 | int i; |
494 | int error = 0; | 507 | int error = 0; |
@@ -498,7 +511,8 @@ static int class_device_add_groups(struct class_device * cd) | |||
498 | error = sysfs_create_group(&cd->kobj, cd->groups[i]); | 511 | error = sysfs_create_group(&cd->kobj, cd->groups[i]); |
499 | if (error) { | 512 | if (error) { |
500 | while (--i >= 0) | 513 | while (--i >= 0) |
501 | sysfs_remove_group(&cd->kobj, cd->groups[i]); | 514 | sysfs_remove_group(&cd->kobj, |
515 | cd->groups[i]); | ||
502 | goto out; | 516 | goto out; |
503 | } | 517 | } |
504 | } | 518 | } |
@@ -507,14 +521,12 @@ out: | |||
507 | return error; | 521 | return error; |
508 | } | 522 | } |
509 | 523 | ||
510 | static void class_device_remove_groups(struct class_device * cd) | 524 | static void class_device_remove_groups(struct class_device *cd) |
511 | { | 525 | { |
512 | int i; | 526 | int i; |
513 | if (cd->groups) { | 527 | if (cd->groups) |
514 | for (i = 0; cd->groups[i]; i++) { | 528 | for (i = 0; cd->groups[i]; i++) |
515 | sysfs_remove_group(&cd->kobj, cd->groups[i]); | 529 | sysfs_remove_group(&cd->kobj, cd->groups[i]); |
516 | } | ||
517 | } | ||
518 | } | 530 | } |
519 | 531 | ||
520 | static ssize_t show_dev(struct class_device *class_dev, char *buf) | 532 | static ssize_t show_dev(struct class_device *class_dev, char *buf) |
@@ -537,8 +549,8 @@ static struct class_device_attribute class_uevent_attr = | |||
537 | 549 | ||
538 | void class_device_initialize(struct class_device *class_dev) | 550 | void class_device_initialize(struct class_device *class_dev) |
539 | { | 551 | { |
540 | kobj_set_kset_s(class_dev, class_obj_subsys); | 552 | class_dev->kobj.kset = &class_obj_subsys; |
541 | kobject_init(&class_dev->kobj); | 553 | kobject_init(&class_dev->kobj, &class_device_ktype); |
542 | INIT_LIST_HEAD(&class_dev->node); | 554 | INIT_LIST_HEAD(&class_dev->node); |
543 | } | 555 | } |
544 | 556 | ||
@@ -566,16 +578,13 @@ int class_device_add(struct class_device *class_dev) | |||
566 | class_dev->class_id); | 578 | class_dev->class_id); |
567 | 579 | ||
568 | /* first, register with generic layer. */ | 580 | /* first, register with generic layer. */ |
569 | error = kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id); | ||
570 | if (error) | ||
571 | goto out2; | ||
572 | |||
573 | if (parent_class_dev) | 581 | if (parent_class_dev) |
574 | class_dev->kobj.parent = &parent_class_dev->kobj; | 582 | class_dev->kobj.parent = &parent_class_dev->kobj; |
575 | else | 583 | else |
576 | class_dev->kobj.parent = &parent_class->subsys.kobj; | 584 | class_dev->kobj.parent = &parent_class->subsys.kobj; |
577 | 585 | ||
578 | error = kobject_add(&class_dev->kobj); | 586 | error = kobject_add(&class_dev->kobj, class_dev->kobj.parent, |
587 | "%s", class_dev->class_id); | ||
579 | if (error) | 588 | if (error) |
580 | goto out2; | 589 | goto out2; |
581 | 590 | ||
@@ -642,7 +651,7 @@ int class_device_add(struct class_device *class_dev) | |||
642 | out3: | 651 | out3: |
643 | kobject_del(&class_dev->kobj); | 652 | kobject_del(&class_dev->kobj); |
644 | out2: | 653 | out2: |
645 | if(parent_class_dev) | 654 | if (parent_class_dev) |
646 | class_device_put(parent_class_dev); | 655 | class_device_put(parent_class_dev); |
647 | class_put(parent_class); | 656 | class_put(parent_class); |
648 | out1: | 657 | out1: |
@@ -659,9 +668,11 @@ int class_device_register(struct class_device *class_dev) | |||
659 | /** | 668 | /** |
660 | * class_device_create - creates a class device and registers it with sysfs | 669 | * class_device_create - creates a class device and registers it with sysfs |
661 | * @cls: pointer to the struct class that this device should be registered to. | 670 | * @cls: pointer to the struct class that this device should be registered to. |
662 | * @parent: pointer to the parent struct class_device of this new device, if any. | 671 | * @parent: pointer to the parent struct class_device of this new device, if |
672 | * any. | ||
663 | * @devt: the dev_t for the char device to be added. | 673 | * @devt: the dev_t for the char device to be added. |
664 | * @device: a pointer to a struct device that is assiociated with this class device. | 674 | * @device: a pointer to a struct device that is assiociated with this class |
675 | * device. | ||
665 | * @fmt: string for the class device's name | 676 | * @fmt: string for the class device's name |
666 | * | 677 | * |
667 | * This function can be used by char device classes. A struct | 678 | * This function can be used by char device classes. A struct |
@@ -785,7 +796,7 @@ void class_device_destroy(struct class *cls, dev_t devt) | |||
785 | class_device_unregister(class_dev); | 796 | class_device_unregister(class_dev); |
786 | } | 797 | } |
787 | 798 | ||
788 | struct class_device * class_device_get(struct class_device *class_dev) | 799 | struct class_device *class_device_get(struct class_device *class_dev) |
789 | { | 800 | { |
790 | if (class_dev) | 801 | if (class_dev) |
791 | return to_class_dev(kobject_get(&class_dev->kobj)); | 802 | return to_class_dev(kobject_get(&class_dev->kobj)); |
@@ -798,6 +809,139 @@ void class_device_put(struct class_device *class_dev) | |||
798 | kobject_put(&class_dev->kobj); | 809 | kobject_put(&class_dev->kobj); |
799 | } | 810 | } |
800 | 811 | ||
812 | /** | ||
813 | * class_for_each_device - device iterator | ||
814 | * @class: the class we're iterating | ||
815 | * @data: data for the callback | ||
816 | * @fn: function to be called for each device | ||
817 | * | ||
818 | * Iterate over @class's list of devices, and call @fn for each, | ||
819 | * passing it @data. | ||
820 | * | ||
821 | * We check the return of @fn each time. If it returns anything | ||
822 | * other than 0, we break out and return that value. | ||
823 | * | ||
824 | * Note, we hold class->sem in this function, so it can not be | ||
825 | * re-acquired in @fn, otherwise it will self-deadlocking. For | ||
826 | * example, calls to add or remove class members would be verboten. | ||
827 | */ | ||
828 | int class_for_each_device(struct class *class, void *data, | ||
829 | int (*fn)(struct device *, void *)) | ||
830 | { | ||
831 | struct device *dev; | ||
832 | int error = 0; | ||
833 | |||
834 | if (!class) | ||
835 | return -EINVAL; | ||
836 | down(&class->sem); | ||
837 | list_for_each_entry(dev, &class->devices, node) { | ||
838 | dev = get_device(dev); | ||
839 | if (dev) { | ||
840 | error = fn(dev, data); | ||
841 | put_device(dev); | ||
842 | } else | ||
843 | error = -ENODEV; | ||
844 | if (error) | ||
845 | break; | ||
846 | } | ||
847 | up(&class->sem); | ||
848 | |||
849 | return error; | ||
850 | } | ||
851 | EXPORT_SYMBOL_GPL(class_for_each_device); | ||
852 | |||
853 | /** | ||
854 | * class_find_device - device iterator for locating a particular device | ||
855 | * @class: the class we're iterating | ||
856 | * @data: data for the match function | ||
857 | * @match: function to check device | ||
858 | * | ||
859 | * This is similar to the class_for_each_dev() function above, but it | ||
860 | * returns a reference to a device that is 'found' for later use, as | ||
861 | * determined by the @match callback. | ||
862 | * | ||
863 | * The callback should return 0 if the device doesn't match and non-zero | ||
864 | * if it does. If the callback returns non-zero, this function will | ||
865 | * return to the caller and not iterate over any more devices. | ||
866 | |||
867 | * Note, you will need to drop the reference with put_device() after use. | ||
868 | * | ||
869 | * We hold class->sem in this function, so it can not be | ||
870 | * re-acquired in @match, otherwise it will self-deadlocking. For | ||
871 | * example, calls to add or remove class members would be verboten. | ||
872 | */ | ||
873 | struct device *class_find_device(struct class *class, void *data, | ||
874 | int (*match)(struct device *, void *)) | ||
875 | { | ||
876 | struct device *dev; | ||
877 | int found = 0; | ||
878 | |||
879 | if (!class) | ||
880 | return NULL; | ||
881 | |||
882 | down(&class->sem); | ||
883 | list_for_each_entry(dev, &class->devices, node) { | ||
884 | dev = get_device(dev); | ||
885 | if (dev) { | ||
886 | if (match(dev, data)) { | ||
887 | found = 1; | ||
888 | break; | ||
889 | } else | ||
890 | put_device(dev); | ||
891 | } else | ||
892 | break; | ||
893 | } | ||
894 | up(&class->sem); | ||
895 | |||
896 | return found ? dev : NULL; | ||
897 | } | ||
898 | EXPORT_SYMBOL_GPL(class_find_device); | ||
899 | |||
900 | /** | ||
901 | * class_find_child - device iterator for locating a particular class_device | ||
902 | * @class: the class we're iterating | ||
903 | * @data: data for the match function | ||
904 | * @match: function to check class_device | ||
905 | * | ||
906 | * This function returns a reference to a class_device that is 'found' for | ||
907 | * later use, as determined by the @match callback. | ||
908 | * | ||
909 | * The callback should return 0 if the class_device doesn't match and non-zero | ||
910 | * if it does. If the callback returns non-zero, this function will | ||
911 | * return to the caller and not iterate over any more class_devices. | ||
912 | * | ||
913 | * Note, you will need to drop the reference with class_device_put() after use. | ||
914 | * | ||
915 | * We hold class->sem in this function, so it can not be | ||
916 | * re-acquired in @match, otherwise it will self-deadlocking. For | ||
917 | * example, calls to add or remove class members would be verboten. | ||
918 | */ | ||
919 | struct class_device *class_find_child(struct class *class, void *data, | ||
920 | int (*match)(struct class_device *, void *)) | ||
921 | { | ||
922 | struct class_device *dev; | ||
923 | int found = 0; | ||
924 | |||
925 | if (!class) | ||
926 | return NULL; | ||
927 | |||
928 | down(&class->sem); | ||
929 | list_for_each_entry(dev, &class->children, node) { | ||
930 | dev = class_device_get(dev); | ||
931 | if (dev) { | ||
932 | if (match(dev, data)) { | ||
933 | found = 1; | ||
934 | break; | ||
935 | } else | ||
936 | class_device_put(dev); | ||
937 | } else | ||
938 | break; | ||
939 | } | ||
940 | up(&class->sem); | ||
941 | |||
942 | return found ? dev : NULL; | ||
943 | } | ||
944 | EXPORT_SYMBOL_GPL(class_find_child); | ||
801 | 945 | ||
802 | int class_interface_register(struct class_interface *class_intf) | 946 | int class_interface_register(struct class_interface *class_intf) |
803 | { | 947 | { |
@@ -829,7 +973,7 @@ int class_interface_register(struct class_interface *class_intf) | |||
829 | 973 | ||
830 | void class_interface_unregister(struct class_interface *class_intf) | 974 | void class_interface_unregister(struct class_interface *class_intf) |
831 | { | 975 | { |
832 | struct class * parent = class_intf->class; | 976 | struct class *parent = class_intf->class; |
833 | struct class_device *class_dev; | 977 | struct class_device *class_dev; |
834 | struct device *dev; | 978 | struct device *dev; |
835 | 979 | ||
@@ -853,15 +997,14 @@ void class_interface_unregister(struct class_interface *class_intf) | |||
853 | 997 | ||
854 | int __init classes_init(void) | 998 | int __init classes_init(void) |
855 | { | 999 | { |
856 | int retval; | 1000 | class_kset = kset_create_and_add("class", NULL, NULL); |
857 | 1001 | if (!class_kset) | |
858 | retval = subsystem_register(&class_subsys); | 1002 | return -ENOMEM; |
859 | if (retval) | ||
860 | return retval; | ||
861 | 1003 | ||
862 | /* ick, this is ugly, the things we go through to keep from showing up | 1004 | /* ick, this is ugly, the things we go through to keep from showing up |
863 | * in sysfs... */ | 1005 | * in sysfs... */ |
864 | kset_init(&class_obj_subsys); | 1006 | kset_init(&class_obj_subsys); |
1007 | kobject_set_name(&class_obj_subsys.kobj, "class_obj"); | ||
865 | if (!class_obj_subsys.kobj.parent) | 1008 | if (!class_obj_subsys.kobj.parent) |
866 | class_obj_subsys.kobj.parent = &class_obj_subsys.kobj; | 1009 | class_obj_subsys.kobj.parent = &class_obj_subsys.kobj; |
867 | return 0; | 1010 | return 0; |