diff options
-rw-r--r-- | drivers/base/base.h | 27 | ||||
-rw-r--r-- | drivers/base/class.c | 87 | ||||
-rw-r--r-- | drivers/base/core.c | 57 | ||||
-rw-r--r-- | include/linux/device.h | 7 |
4 files changed, 107 insertions, 71 deletions
diff --git a/drivers/base/base.h b/drivers/base/base.h index 2c9ae43e2219..0ec372a67762 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h | |||
@@ -36,6 +36,33 @@ struct driver_private { | |||
36 | }; | 36 | }; |
37 | #define to_driver(obj) container_of(obj, struct driver_private, kobj) | 37 | #define to_driver(obj) container_of(obj, struct driver_private, kobj) |
38 | 38 | ||
39 | |||
40 | /** | ||
41 | * struct class_private - structure to hold the private to the driver core portions of the class structure. | ||
42 | * | ||
43 | * @subsys - the struct kset that defines this class. This is the main kobject | ||
44 | * @children - list of class_devices associated with this class | ||
45 | * @devices - list of devices associated with this class | ||
46 | * @interfaces - list of class_interfaces associated with this class | ||
47 | * @class_dirs - | ||
48 | * @sem - semaphore to protect the children, devices, and interfaces lists. | ||
49 | * @class - pointer back to the struct class that this structure is associated | ||
50 | * with. | ||
51 | * | ||
52 | * This structure is the one that is the actual kobject allowing struct | ||
53 | * class to be statically allocated safely. Nothing outside of the driver | ||
54 | * core should ever touch these fields. | ||
55 | */ | ||
56 | struct class_private { | ||
57 | struct kset subsys; | ||
58 | struct list_head devices; | ||
59 | struct list_head interfaces; | ||
60 | struct kset class_dirs; | ||
61 | struct semaphore sem; | ||
62 | struct class *class; | ||
63 | }; | ||
64 | #define to_class(obj) container_of(obj, struct class_private, subsys.kobj) | ||
65 | |||
39 | /* initialisation functions */ | 66 | /* initialisation functions */ |
40 | extern int devices_init(void); | 67 | extern int devices_init(void); |
41 | extern int buses_init(void); | 68 | extern int buses_init(void); |
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 | ||
26 | static ssize_t class_attr_show(struct kobject *kobj, struct attribute *attr, | 25 | static 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 | ||
50 | static void class_release(struct kobject *kobj) | 49 | static 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) | |||
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->p->subsys.kobj, &attr->attr); |
91 | } | 91 | } |
92 | 92 | ||
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), | 96 | kset_get(&cls->p->subsys); |
97 | struct class, subsys); | 97 | return cls; |
98 | return NULL; | ||
99 | } | 98 | } |
100 | 99 | ||
101 | static void class_put(struct class *cls) | 100 | static 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 | ||
107 | static int add_class_attrs(struct class *cls) | 106 | static int add_class_attrs(struct class *cls) |
@@ -136,17 +135,23 @@ static void remove_class_attrs(struct class *cls) | |||
136 | 135 | ||
137 | int class_register(struct class *cls) | 136 | int 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 | ||
179 | static void class_create_release(struct class *cls) | 188 | static 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 | } |
diff --git a/drivers/base/core.c b/drivers/base/core.c index 9f05de6f80b5..64c150b5a883 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -551,7 +551,7 @@ static struct kobject *get_device_parent(struct device *dev, | |||
551 | { | 551 | { |
552 | /* class devices without a parent live in /sys/class/<classname>/ */ | 552 | /* class devices without a parent live in /sys/class/<classname>/ */ |
553 | if (dev->class && (!parent || parent->class != dev->class)) | 553 | if (dev->class && (!parent || parent->class != dev->class)) |
554 | return &dev->class->subsys.kobj; | 554 | return &dev->class->p->subsys.kobj; |
555 | /* all other devices keep their parent */ | 555 | /* all other devices keep their parent */ |
556 | else if (parent) | 556 | else if (parent) |
557 | return &parent->kobj; | 557 | return &parent->kobj; |
@@ -597,13 +597,13 @@ static struct kobject *get_device_parent(struct device *dev, | |||
597 | parent_kobj = &parent->kobj; | 597 | parent_kobj = &parent->kobj; |
598 | 598 | ||
599 | /* find our class-directory at the parent and reference it */ | 599 | /* find our class-directory at the parent and reference it */ |
600 | spin_lock(&dev->class->class_dirs.list_lock); | 600 | spin_lock(&dev->class->p->class_dirs.list_lock); |
601 | list_for_each_entry(k, &dev->class->class_dirs.list, entry) | 601 | list_for_each_entry(k, &dev->class->p->class_dirs.list, entry) |
602 | if (k->parent == parent_kobj) { | 602 | if (k->parent == parent_kobj) { |
603 | kobj = kobject_get(k); | 603 | kobj = kobject_get(k); |
604 | break; | 604 | break; |
605 | } | 605 | } |
606 | spin_unlock(&dev->class->class_dirs.list_lock); | 606 | spin_unlock(&dev->class->p->class_dirs.list_lock); |
607 | if (kobj) | 607 | if (kobj) |
608 | return kobj; | 608 | return kobj; |
609 | 609 | ||
@@ -611,7 +611,7 @@ static struct kobject *get_device_parent(struct device *dev, | |||
611 | k = kobject_create(); | 611 | k = kobject_create(); |
612 | if (!k) | 612 | if (!k) |
613 | return NULL; | 613 | return NULL; |
614 | k->kset = &dev->class->class_dirs; | 614 | k->kset = &dev->class->p->class_dirs; |
615 | retval = kobject_add(k, parent_kobj, "%s", dev->class->name); | 615 | retval = kobject_add(k, parent_kobj, "%s", dev->class->name); |
616 | if (retval < 0) { | 616 | if (retval < 0) { |
617 | kobject_put(k); | 617 | kobject_put(k); |
@@ -630,7 +630,7 @@ static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir) | |||
630 | { | 630 | { |
631 | /* see if we live in a "glue" directory */ | 631 | /* see if we live in a "glue" directory */ |
632 | if (!glue_dir || !dev->class || | 632 | if (!glue_dir || !dev->class || |
633 | glue_dir->kset != &dev->class->class_dirs) | 633 | glue_dir->kset != &dev->class->p->class_dirs) |
634 | return; | 634 | return; |
635 | 635 | ||
636 | kobject_put(glue_dir); | 636 | kobject_put(glue_dir); |
@@ -657,17 +657,17 @@ static int device_add_class_symlinks(struct device *dev) | |||
657 | if (!dev->class) | 657 | if (!dev->class) |
658 | return 0; | 658 | return 0; |
659 | 659 | ||
660 | error = sysfs_create_link(&dev->kobj, &dev->class->subsys.kobj, | 660 | error = sysfs_create_link(&dev->kobj, &dev->class->p->subsys.kobj, |
661 | "subsystem"); | 661 | "subsystem"); |
662 | if (error) | 662 | if (error) |
663 | goto out; | 663 | goto out; |
664 | 664 | ||
665 | #ifdef CONFIG_SYSFS_DEPRECATED | 665 | #ifdef CONFIG_SYSFS_DEPRECATED |
666 | /* stacked class devices need a symlink in the class directory */ | 666 | /* stacked class devices need a symlink in the class directory */ |
667 | if (dev->kobj.parent != &dev->class->subsys.kobj && | 667 | if (dev->kobj.parent != &dev->class->p->subsys.kobj && |
668 | device_is_not_partition(dev)) { | 668 | device_is_not_partition(dev)) { |
669 | error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj, | 669 | error = sysfs_create_link(&dev->class->p->subsys.kobj, |
670 | dev->bus_id); | 670 | &dev->kobj, dev->bus_id); |
671 | if (error) | 671 | if (error) |
672 | goto out_subsys; | 672 | goto out_subsys; |
673 | } | 673 | } |
@@ -704,12 +704,12 @@ out_device: | |||
704 | if (dev->parent && device_is_not_partition(dev)) | 704 | if (dev->parent && device_is_not_partition(dev)) |
705 | sysfs_remove_link(&dev->kobj, "device"); | 705 | sysfs_remove_link(&dev->kobj, "device"); |
706 | out_busid: | 706 | out_busid: |
707 | if (dev->kobj.parent != &dev->class->subsys.kobj && | 707 | if (dev->kobj.parent != &dev->class->p->subsys.kobj && |
708 | device_is_not_partition(dev)) | 708 | device_is_not_partition(dev)) |
709 | sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); | 709 | sysfs_remove_link(&dev->class->p->subsys.kobj, dev->bus_id); |
710 | #else | 710 | #else |
711 | /* link in the class directory pointing to the device */ | 711 | /* link in the class directory pointing to the device */ |
712 | error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj, | 712 | error = sysfs_create_link(&dev->class->p->subsys.kobj, &dev->kobj, |
713 | dev->bus_id); | 713 | dev->bus_id); |
714 | if (error) | 714 | if (error) |
715 | goto out_subsys; | 715 | goto out_subsys; |
@@ -723,7 +723,7 @@ out_busid: | |||
723 | return 0; | 723 | return 0; |
724 | 724 | ||
725 | out_busid: | 725 | out_busid: |
726 | sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); | 726 | sysfs_remove_link(&dev->class->p->subsys.kobj, dev->bus_id); |
727 | #endif | 727 | #endif |
728 | 728 | ||
729 | out_subsys: | 729 | out_subsys: |
@@ -749,14 +749,14 @@ static void device_remove_class_symlinks(struct device *dev) | |||
749 | sysfs_remove_link(&dev->kobj, "device"); | 749 | sysfs_remove_link(&dev->kobj, "device"); |
750 | } | 750 | } |
751 | 751 | ||
752 | if (dev->kobj.parent != &dev->class->subsys.kobj && | 752 | if (dev->kobj.parent != &dev->class->p->subsys.kobj && |
753 | device_is_not_partition(dev)) | 753 | device_is_not_partition(dev)) |
754 | sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); | 754 | sysfs_remove_link(&dev->class->p->subsys.kobj, dev->bus_id); |
755 | #else | 755 | #else |
756 | if (dev->parent && device_is_not_partition(dev)) | 756 | if (dev->parent && device_is_not_partition(dev)) |
757 | sysfs_remove_link(&dev->kobj, "device"); | 757 | sysfs_remove_link(&dev->kobj, "device"); |
758 | 758 | ||
759 | sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); | 759 | sysfs_remove_link(&dev->class->p->subsys.kobj, dev->bus_id); |
760 | #endif | 760 | #endif |
761 | 761 | ||
762 | sysfs_remove_link(&dev->kobj, "subsystem"); | 762 | sysfs_remove_link(&dev->kobj, "subsystem"); |
@@ -904,15 +904,16 @@ int device_add(struct device *dev) | |||
904 | klist_add_tail(&dev->knode_parent, &parent->klist_children); | 904 | klist_add_tail(&dev->knode_parent, &parent->klist_children); |
905 | 905 | ||
906 | if (dev->class) { | 906 | if (dev->class) { |
907 | down(&dev->class->sem); | 907 | down(&dev->class->p->sem); |
908 | /* tie the class to the device */ | 908 | /* tie the class to the device */ |
909 | list_add_tail(&dev->node, &dev->class->devices); | 909 | list_add_tail(&dev->node, &dev->class->p->devices); |
910 | 910 | ||
911 | /* notify any interfaces that the device is here */ | 911 | /* notify any interfaces that the device is here */ |
912 | list_for_each_entry(class_intf, &dev->class->interfaces, node) | 912 | list_for_each_entry(class_intf, &dev->class->p->interfaces, |
913 | node) | ||
913 | if (class_intf->add_dev) | 914 | if (class_intf->add_dev) |
914 | class_intf->add_dev(dev, class_intf); | 915 | class_intf->add_dev(dev, class_intf); |
915 | up(&dev->class->sem); | 916 | up(&dev->class->p->sem); |
916 | } | 917 | } |
917 | Done: | 918 | Done: |
918 | put_device(dev); | 919 | put_device(dev); |
@@ -1013,14 +1014,15 @@ void device_del(struct device *dev) | |||
1013 | if (dev->class) { | 1014 | if (dev->class) { |
1014 | device_remove_class_symlinks(dev); | 1015 | device_remove_class_symlinks(dev); |
1015 | 1016 | ||
1016 | down(&dev->class->sem); | 1017 | down(&dev->class->p->sem); |
1017 | /* notify any interfaces that the device is now gone */ | 1018 | /* notify any interfaces that the device is now gone */ |
1018 | list_for_each_entry(class_intf, &dev->class->interfaces, node) | 1019 | list_for_each_entry(class_intf, &dev->class->p->interfaces, |
1020 | node) | ||
1019 | if (class_intf->remove_dev) | 1021 | if (class_intf->remove_dev) |
1020 | class_intf->remove_dev(dev, class_intf); | 1022 | class_intf->remove_dev(dev, class_intf); |
1021 | /* remove the device from the class list */ | 1023 | /* remove the device from the class list */ |
1022 | list_del_init(&dev->node); | 1024 | list_del_init(&dev->node); |
1023 | up(&dev->class->sem); | 1025 | up(&dev->class->p->sem); |
1024 | } | 1026 | } |
1025 | device_remove_file(dev, &uevent_attr); | 1027 | device_remove_file(dev, &uevent_attr); |
1026 | device_remove_attrs(dev); | 1028 | device_remove_attrs(dev); |
@@ -1348,11 +1350,12 @@ int device_rename(struct device *dev, char *new_name) | |||
1348 | } | 1350 | } |
1349 | #else | 1351 | #else |
1350 | if (dev->class) { | 1352 | if (dev->class) { |
1351 | error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj, | 1353 | error = sysfs_create_link(&dev->class->p->subsys.kobj, |
1352 | dev->bus_id); | 1354 | &dev->kobj, dev->bus_id); |
1353 | if (error) | 1355 | if (error) |
1354 | goto out; | 1356 | goto out; |
1355 | sysfs_remove_link(&dev->class->subsys.kobj, old_device_name); | 1357 | sysfs_remove_link(&dev->class->p->subsys.kobj, |
1358 | old_device_name); | ||
1356 | } | 1359 | } |
1357 | #endif | 1360 | #endif |
1358 | 1361 | ||
diff --git a/include/linux/device.h b/include/linux/device.h index c1f72984875f..b0556082179b 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -35,6 +35,7 @@ struct device; | |||
35 | struct device_driver; | 35 | struct device_driver; |
36 | struct driver_private; | 36 | struct driver_private; |
37 | struct class; | 37 | struct class; |
38 | struct class_private; | ||
38 | struct bus_type; | 39 | struct bus_type; |
39 | struct bus_type_private; | 40 | struct bus_type_private; |
40 | 41 | ||
@@ -186,11 +187,6 @@ struct class { | |||
186 | const char *name; | 187 | const char *name; |
187 | struct module *owner; | 188 | struct module *owner; |
188 | 189 | ||
189 | struct kset subsys; | ||
190 | struct list_head devices; | ||
191 | struct list_head interfaces; | ||
192 | struct kset class_dirs; | ||
193 | struct semaphore sem; /* locks children, devices, interfaces */ | ||
194 | struct class_attribute *class_attrs; | 190 | struct class_attribute *class_attrs; |
195 | struct device_attribute *dev_attrs; | 191 | struct device_attribute *dev_attrs; |
196 | struct kobject *dev_kobj; | 192 | struct kobject *dev_kobj; |
@@ -204,6 +200,7 @@ struct class { | |||
204 | int (*resume)(struct device *dev); | 200 | int (*resume)(struct device *dev); |
205 | 201 | ||
206 | struct pm_ops *pm; | 202 | struct pm_ops *pm; |
203 | struct class_private *p; | ||
207 | }; | 204 | }; |
208 | 205 | ||
209 | extern struct kobject *sysfs_dev_block_kobj; | 206 | extern struct kobject *sysfs_dev_block_kobj; |