diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-25 11:34:42 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-25 11:35:13 -0500 |
commit | df8dc74e8a383eaf2d9b44b80a71ec6f0e52b42e (patch) | |
tree | bc3799a43e8b94fa84b32e37b1c124d5e4868f50 /drivers/base | |
parent | 556a169dab38b5100df6f4a45b655dddd3db94c1 (diff) | |
parent | 4a3ad20ccd8f4d2a0535cf98fa83f7b561ba59a9 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-2.6
This can be broken down into these major areas:
- Documentation updates (language translations and fixes, as
well as kobject and kset documenatation updates.)
- major kset/kobject/ktype rework and fixes. This cleans up the
kset and kobject and ktype relationship and architecture,
making sense of things now, and good documenation and samples
are provided for others to use. Also the attributes for
kobjects are much easier to handle now. This cleaned up a LOT
of code all through the kernel, making kobjects easier to use
if you want to.
- struct bus_type has been reworked to now handle the lifetime
rules properly, as the kobject is properly dynamic.
- struct driver has also been reworked, and now the lifetime
issues are resolved.
- the block subsystem has been converted to use struct device
now, and not "raw" kobjects. This patch has been in the -mm
tree for over a year now, and finally all the issues are
worked out with it. Older distros now properly work with new
kernels, and no userspace updates are needed at all.
- nozomi driver is added. This has also been in -mm for a long
time, and many people have asked for it to go in. It is now
in good enough shape to do so.
- lots of class_device conversions to use struct device instead.
The tree is almost all cleaned up now, only SCSI and IB is the
remaining code to fix up...
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-2.6: (196 commits)
Driver core: coding style fixes
Kobject: fix coding style issues in kobject c files
Kobject: fix coding style issues in kobject.h
Driver core: fix coding style issues in device.h
spi: use class iteration api
scsi: use class iteration api
rtc: use class iteration api
power supply : use class iteration api
ieee1394: use class iteration api
Driver Core: add class iteration api
Driver core: Cleanup get_device_parent() in device_add() and device_move()
UIO: constify function pointer tables
Driver Core: constify the name passed to platform_device_register_simple
driver core: fix build with SYSFS=n
sysfs: make SYSFS_DEPRECATED depend on SYSFS
Driver core: use LIST_HEAD instead of call to INIT_LIST_HEAD in __init
kobject: add sample code for how to use ksets/ktypes/kobjects
kobject: add sample code for how to use kobjects in a simple manner.
kobject: update the kobject/kset documentation
kobject: remove old, outdated documentation.
...
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/Makefile | 3 | ||||
-rw-r--r-- | drivers/base/attribute_container.c | 9 | ||||
-rw-r--r-- | drivers/base/base.h | 64 | ||||
-rw-r--r-- | drivers/base/bus.c | 501 | ||||
-rw-r--r-- | drivers/base/class.c | 319 | ||||
-rw-r--r-- | drivers/base/core.c | 582 | ||||
-rw-r--r-- | drivers/base/cpu.c | 2 | ||||
-rw-r--r-- | drivers/base/dd.c | 164 | ||||
-rw-r--r-- | drivers/base/driver.c | 216 | ||||
-rw-r--r-- | drivers/base/firmware.c | 26 | ||||
-rw-r--r-- | drivers/base/hypervisor.c | 12 | ||||
-rw-r--r-- | drivers/base/init.c | 10 | ||||
-rw-r--r-- | drivers/base/memory.c | 2 | ||||
-rw-r--r-- | drivers/base/module.c | 94 | ||||
-rw-r--r-- | drivers/base/node.c | 2 | ||||
-rw-r--r-- | drivers/base/platform.c | 239 | ||||
-rw-r--r-- | drivers/base/power/Makefile | 1 | ||||
-rw-r--r-- | drivers/base/power/main.c | 502 | ||||
-rw-r--r-- | drivers/base/power/power.h | 19 | ||||
-rw-r--r-- | drivers/base/power/shutdown.c | 48 | ||||
-rw-r--r-- | drivers/base/sys.c | 49 |
21 files changed, 1681 insertions, 1183 deletions
diff --git a/drivers/base/Makefile b/drivers/base/Makefile index b39ea3f59c9b..63e09c015ca0 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile | |||
@@ -11,6 +11,9 @@ obj-$(CONFIG_FW_LOADER) += firmware_class.o | |||
11 | obj-$(CONFIG_NUMA) += node.o | 11 | obj-$(CONFIG_NUMA) += node.o |
12 | obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o | 12 | obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o |
13 | obj-$(CONFIG_SMP) += topology.o | 13 | obj-$(CONFIG_SMP) += topology.o |
14 | ifeq ($(CONFIG_SYSFS),y) | ||
15 | obj-$(CONFIG_MODULES) += module.o | ||
16 | endif | ||
14 | obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o | 17 | obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o |
15 | 18 | ||
16 | ifeq ($(CONFIG_DEBUG_DRIVER),y) | 19 | ifeq ($(CONFIG_DEBUG_DRIVER),y) |
diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c index 7370d7cf5988..d4dfb97de3b0 100644 --- a/drivers/base/attribute_container.c +++ b/drivers/base/attribute_container.c | |||
@@ -61,7 +61,7 @@ attribute_container_classdev_to_container(struct class_device *classdev) | |||
61 | } | 61 | } |
62 | EXPORT_SYMBOL_GPL(attribute_container_classdev_to_container); | 62 | EXPORT_SYMBOL_GPL(attribute_container_classdev_to_container); |
63 | 63 | ||
64 | static struct list_head attribute_container_list; | 64 | static LIST_HEAD(attribute_container_list); |
65 | 65 | ||
66 | static DEFINE_MUTEX(attribute_container_mutex); | 66 | static DEFINE_MUTEX(attribute_container_mutex); |
67 | 67 | ||
@@ -429,10 +429,3 @@ attribute_container_find_class_device(struct attribute_container *cont, | |||
429 | return cdev; | 429 | return cdev; |
430 | } | 430 | } |
431 | EXPORT_SYMBOL_GPL(attribute_container_find_class_device); | 431 | EXPORT_SYMBOL_GPL(attribute_container_find_class_device); |
432 | |||
433 | int __init | ||
434 | attribute_container_init(void) | ||
435 | { | ||
436 | INIT_LIST_HEAD(&attribute_container_list); | ||
437 | return 0; | ||
438 | } | ||
diff --git a/drivers/base/base.h b/drivers/base/base.h index 10b2fb6c9ce6..c0444146c09a 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h | |||
@@ -1,6 +1,42 @@ | |||
1 | 1 | ||
2 | /* initialisation functions */ | 2 | /** |
3 | * struct bus_type_private - structure to hold the private to the driver core portions of the bus_type structure. | ||
4 | * | ||
5 | * @subsys - the struct kset that defines this bus. This is the main kobject | ||
6 | * @drivers_kset - the list of drivers associated with this bus | ||
7 | * @devices_kset - the list of devices associated with this bus | ||
8 | * @klist_devices - the klist to iterate over the @devices_kset | ||
9 | * @klist_drivers - the klist to iterate over the @drivers_kset | ||
10 | * @bus_notifier - the bus notifier list for anything that cares about things | ||
11 | * on this bus. | ||
12 | * @bus - pointer back to the struct bus_type that this structure is associated | ||
13 | * with. | ||
14 | * | ||
15 | * This structure is the one that is the actual kobject allowing struct | ||
16 | * bus_type to be statically allocated safely. Nothing outside of the driver | ||
17 | * core should ever touch these fields. | ||
18 | */ | ||
19 | struct bus_type_private { | ||
20 | struct kset subsys; | ||
21 | struct kset *drivers_kset; | ||
22 | struct kset *devices_kset; | ||
23 | struct klist klist_devices; | ||
24 | struct klist klist_drivers; | ||
25 | struct blocking_notifier_head bus_notifier; | ||
26 | unsigned int drivers_autoprobe:1; | ||
27 | struct bus_type *bus; | ||
28 | }; | ||
29 | |||
30 | struct driver_private { | ||
31 | struct kobject kobj; | ||
32 | struct klist klist_devices; | ||
33 | struct klist_node knode_bus; | ||
34 | struct module_kobject *mkobj; | ||
35 | struct device_driver *driver; | ||
36 | }; | ||
37 | #define to_driver(obj) container_of(obj, struct driver_private, kobj) | ||
3 | 38 | ||
39 | /* initialisation functions */ | ||
4 | extern int devices_init(void); | 40 | extern int devices_init(void); |
5 | extern int buses_init(void); | 41 | extern int buses_init(void); |
6 | extern int classes_init(void); | 42 | extern int classes_init(void); |
@@ -13,17 +49,16 @@ static inline int hypervisor_init(void) { return 0; } | |||
13 | extern int platform_bus_init(void); | 49 | extern int platform_bus_init(void); |
14 | extern int system_bus_init(void); | 50 | extern int system_bus_init(void); |
15 | extern int cpu_dev_init(void); | 51 | extern int cpu_dev_init(void); |
16 | extern int attribute_container_init(void); | ||
17 | 52 | ||
18 | extern int bus_add_device(struct device * dev); | 53 | extern int bus_add_device(struct device *dev); |
19 | extern void bus_attach_device(struct device * dev); | 54 | extern void bus_attach_device(struct device *dev); |
20 | extern void bus_remove_device(struct device * dev); | 55 | extern void bus_remove_device(struct device *dev); |
21 | 56 | ||
22 | extern int bus_add_driver(struct device_driver *); | 57 | extern int bus_add_driver(struct device_driver *drv); |
23 | extern void bus_remove_driver(struct device_driver *); | 58 | extern void bus_remove_driver(struct device_driver *drv); |
24 | 59 | ||
25 | extern void driver_detach(struct device_driver * drv); | 60 | extern void driver_detach(struct device_driver *drv); |
26 | extern int driver_probe_device(struct device_driver *, struct device *); | 61 | extern int driver_probe_device(struct device_driver *drv, struct device *dev); |
27 | 62 | ||
28 | extern void sysdev_shutdown(void); | 63 | extern void sysdev_shutdown(void); |
29 | extern int sysdev_suspend(pm_message_t state); | 64 | extern int sysdev_suspend(pm_message_t state); |
@@ -44,4 +79,13 @@ extern char *make_class_name(const char *name, struct kobject *kobj); | |||
44 | 79 | ||
45 | extern int devres_release_all(struct device *dev); | 80 | extern int devres_release_all(struct device *dev); |
46 | 81 | ||
47 | extern struct kset devices_subsys; | 82 | extern struct kset *devices_kset; |
83 | |||
84 | #if defined(CONFIG_MODULES) && defined(CONFIG_SYSFS) | ||
85 | extern void module_add_driver(struct module *mod, struct device_driver *drv); | ||
86 | extern void module_remove_driver(struct device_driver *drv); | ||
87 | #else | ||
88 | static inline void module_add_driver(struct module *mod, | ||
89 | struct device_driver *drv) { } | ||
90 | static inline void module_remove_driver(struct device_driver *drv) { } | ||
91 | #endif | ||
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 9a19b071c573..f484495b2ad1 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -3,6 +3,8 @@ | |||
3 | * | 3 | * |
4 | * Copyright (c) 2002-3 Patrick Mochel | 4 | * Copyright (c) 2002-3 Patrick Mochel |
5 | * Copyright (c) 2002-3 Open Source Development Labs | 5 | * Copyright (c) 2002-3 Open Source Development Labs |
6 | * Copyright (c) 2007 Greg Kroah-Hartman <gregkh@suse.de> | ||
7 | * Copyright (c) 2007 Novell Inc. | ||
6 | * | 8 | * |
7 | * This file is released under the GPLv2 | 9 | * This file is released under the GPLv2 |
8 | * | 10 | * |
@@ -17,14 +19,13 @@ | |||
17 | #include "power/power.h" | 19 | #include "power/power.h" |
18 | 20 | ||
19 | #define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr) | 21 | #define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr) |
20 | #define to_bus(obj) container_of(obj, struct bus_type, subsys.kobj) | 22 | #define to_bus(obj) container_of(obj, struct bus_type_private, subsys.kobj) |
21 | 23 | ||
22 | /* | 24 | /* |
23 | * sysfs bindings for drivers | 25 | * sysfs bindings for drivers |
24 | */ | 26 | */ |
25 | 27 | ||
26 | #define to_drv_attr(_attr) container_of(_attr, struct driver_attribute, attr) | 28 | #define to_drv_attr(_attr) container_of(_attr, struct driver_attribute, attr) |
27 | #define to_driver(obj) container_of(obj, struct device_driver, kobj) | ||
28 | 29 | ||
29 | 30 | ||
30 | static int __must_check bus_rescan_devices_helper(struct device *dev, | 31 | static int __must_check bus_rescan_devices_helper(struct device *dev, |
@@ -32,37 +33,40 @@ static int __must_check bus_rescan_devices_helper(struct device *dev, | |||
32 | 33 | ||
33 | static struct bus_type *bus_get(struct bus_type *bus) | 34 | static struct bus_type *bus_get(struct bus_type *bus) |
34 | { | 35 | { |
35 | return bus ? container_of(kset_get(&bus->subsys), | 36 | if (bus) { |
36 | struct bus_type, subsys) : NULL; | 37 | kset_get(&bus->p->subsys); |
38 | return bus; | ||
39 | } | ||
40 | return NULL; | ||
37 | } | 41 | } |
38 | 42 | ||
39 | static void bus_put(struct bus_type *bus) | 43 | static void bus_put(struct bus_type *bus) |
40 | { | 44 | { |
41 | kset_put(&bus->subsys); | 45 | if (bus) |
46 | kset_put(&bus->p->subsys); | ||
42 | } | 47 | } |
43 | 48 | ||
44 | static ssize_t | 49 | static ssize_t drv_attr_show(struct kobject *kobj, struct attribute *attr, |
45 | drv_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) | 50 | char *buf) |
46 | { | 51 | { |
47 | struct driver_attribute * drv_attr = to_drv_attr(attr); | 52 | struct driver_attribute *drv_attr = to_drv_attr(attr); |
48 | struct device_driver * drv = to_driver(kobj); | 53 | struct driver_private *drv_priv = to_driver(kobj); |
49 | ssize_t ret = -EIO; | 54 | ssize_t ret = -EIO; |
50 | 55 | ||
51 | if (drv_attr->show) | 56 | if (drv_attr->show) |
52 | ret = drv_attr->show(drv, buf); | 57 | ret = drv_attr->show(drv_priv->driver, buf); |
53 | return ret; | 58 | return ret; |
54 | } | 59 | } |
55 | 60 | ||
56 | static ssize_t | 61 | static ssize_t drv_attr_store(struct kobject *kobj, struct attribute *attr, |
57 | drv_attr_store(struct kobject * kobj, struct attribute * attr, | 62 | const char *buf, size_t count) |
58 | const char * buf, size_t count) | ||
59 | { | 63 | { |
60 | struct driver_attribute * drv_attr = to_drv_attr(attr); | 64 | struct driver_attribute *drv_attr = to_drv_attr(attr); |
61 | struct device_driver * drv = to_driver(kobj); | 65 | struct driver_private *drv_priv = to_driver(kobj); |
62 | ssize_t ret = -EIO; | 66 | ssize_t ret = -EIO; |
63 | 67 | ||
64 | if (drv_attr->store) | 68 | if (drv_attr->store) |
65 | ret = drv_attr->store(drv, buf, count); | 69 | ret = drv_attr->store(drv_priv->driver, buf, count); |
66 | return ret; | 70 | return ret; |
67 | } | 71 | } |
68 | 72 | ||
@@ -71,22 +75,12 @@ static struct sysfs_ops driver_sysfs_ops = { | |||
71 | .store = drv_attr_store, | 75 | .store = drv_attr_store, |
72 | }; | 76 | }; |
73 | 77 | ||
74 | 78 | static void driver_release(struct kobject *kobj) | |
75 | static void driver_release(struct kobject * kobj) | ||
76 | { | 79 | { |
77 | /* | 80 | struct driver_private *drv_priv = to_driver(kobj); |
78 | * Yes this is an empty release function, it is this way because struct | 81 | |
79 | * device is always a static object, not a dynamic one. Yes, this is | 82 | pr_debug("driver: '%s': %s\n", kobject_name(kobj), __FUNCTION__); |
80 | * not nice and bad, but remember, drivers are code, reference counted | 83 | kfree(drv_priv); |
81 | * by the module count, not a device, which is really data. And yes, | ||
82 | * in the future I do want to have all drivers be created dynamically, | ||
83 | * and am working toward that goal, but it will take a bit longer... | ||
84 | * | ||
85 | * But do not let this example give _anyone_ the idea that they can | ||
86 | * create a release function without any code in it at all, to do that | ||
87 | * is almost always wrong. If you have any questions about this, | ||
88 | * please send an email to <greg@kroah.com> | ||
89 | */ | ||
90 | } | 84 | } |
91 | 85 | ||
92 | static struct kobj_type driver_ktype = { | 86 | static struct kobj_type driver_ktype = { |
@@ -94,34 +88,30 @@ static struct kobj_type driver_ktype = { | |||
94 | .release = driver_release, | 88 | .release = driver_release, |
95 | }; | 89 | }; |
96 | 90 | ||
97 | |||
98 | /* | 91 | /* |
99 | * sysfs bindings for buses | 92 | * sysfs bindings for buses |
100 | */ | 93 | */ |
101 | 94 | static ssize_t bus_attr_show(struct kobject *kobj, struct attribute *attr, | |
102 | 95 | char *buf) | |
103 | static ssize_t | ||
104 | bus_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) | ||
105 | { | 96 | { |
106 | struct bus_attribute * bus_attr = to_bus_attr(attr); | 97 | struct bus_attribute *bus_attr = to_bus_attr(attr); |
107 | struct bus_type * bus = to_bus(kobj); | 98 | struct bus_type_private *bus_priv = to_bus(kobj); |
108 | ssize_t ret = 0; | 99 | ssize_t ret = 0; |
109 | 100 | ||
110 | if (bus_attr->show) | 101 | if (bus_attr->show) |
111 | ret = bus_attr->show(bus, buf); | 102 | ret = bus_attr->show(bus_priv->bus, buf); |
112 | return ret; | 103 | return ret; |
113 | } | 104 | } |
114 | 105 | ||
115 | static ssize_t | 106 | static ssize_t bus_attr_store(struct kobject *kobj, struct attribute *attr, |
116 | bus_attr_store(struct kobject * kobj, struct attribute * attr, | 107 | const char *buf, size_t count) |
117 | const char * buf, size_t count) | ||
118 | { | 108 | { |
119 | struct bus_attribute * bus_attr = to_bus_attr(attr); | 109 | struct bus_attribute *bus_attr = to_bus_attr(attr); |
120 | struct bus_type * bus = to_bus(kobj); | 110 | struct bus_type_private *bus_priv = to_bus(kobj); |
121 | ssize_t ret = 0; | 111 | ssize_t ret = 0; |
122 | 112 | ||
123 | if (bus_attr->store) | 113 | if (bus_attr->store) |
124 | ret = bus_attr->store(bus, buf, count); | 114 | ret = bus_attr->store(bus_priv->bus, buf, count); |
125 | return ret; | 115 | return ret; |
126 | } | 116 | } |
127 | 117 | ||
@@ -130,24 +120,26 @@ static struct sysfs_ops bus_sysfs_ops = { | |||
130 | .store = bus_attr_store, | 120 | .store = bus_attr_store, |
131 | }; | 121 | }; |
132 | 122 | ||
133 | int bus_create_file(struct bus_type * bus, struct bus_attribute * attr) | 123 | int bus_create_file(struct bus_type *bus, struct bus_attribute *attr) |
134 | { | 124 | { |
135 | int error; | 125 | int error; |
136 | if (bus_get(bus)) { | 126 | if (bus_get(bus)) { |
137 | error = sysfs_create_file(&bus->subsys.kobj, &attr->attr); | 127 | error = sysfs_create_file(&bus->p->subsys.kobj, &attr->attr); |
138 | bus_put(bus); | 128 | bus_put(bus); |
139 | } else | 129 | } else |
140 | error = -EINVAL; | 130 | error = -EINVAL; |
141 | return error; | 131 | return error; |
142 | } | 132 | } |
133 | EXPORT_SYMBOL_GPL(bus_create_file); | ||
143 | 134 | ||
144 | void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr) | 135 | void bus_remove_file(struct bus_type *bus, struct bus_attribute *attr) |
145 | { | 136 | { |
146 | if (bus_get(bus)) { | 137 | if (bus_get(bus)) { |
147 | sysfs_remove_file(&bus->subsys.kobj, &attr->attr); | 138 | sysfs_remove_file(&bus->p->subsys.kobj, &attr->attr); |
148 | bus_put(bus); | 139 | bus_put(bus); |
149 | } | 140 | } |
150 | } | 141 | } |
142 | EXPORT_SYMBOL_GPL(bus_remove_file); | ||
151 | 143 | ||
152 | static struct kobj_type bus_ktype = { | 144 | static struct kobj_type bus_ktype = { |
153 | .sysfs_ops = &bus_sysfs_ops, | 145 | .sysfs_ops = &bus_sysfs_ops, |
@@ -166,7 +158,7 @@ static struct kset_uevent_ops bus_uevent_ops = { | |||
166 | .filter = bus_uevent_filter, | 158 | .filter = bus_uevent_filter, |
167 | }; | 159 | }; |
168 | 160 | ||
169 | static decl_subsys(bus, &bus_ktype, &bus_uevent_ops); | 161 | static struct kset *bus_kset; |
170 | 162 | ||
171 | 163 | ||
172 | #ifdef CONFIG_HOTPLUG | 164 | #ifdef CONFIG_HOTPLUG |
@@ -224,10 +216,13 @@ static ssize_t driver_bind(struct device_driver *drv, | |||
224 | if (dev->parent) | 216 | if (dev->parent) |
225 | up(&dev->parent->sem); | 217 | up(&dev->parent->sem); |
226 | 218 | ||
227 | if (err > 0) /* success */ | 219 | if (err > 0) { |
220 | /* success */ | ||
228 | err = count; | 221 | err = count; |
229 | else if (err == 0) /* driver didn't accept device */ | 222 | } else if (err == 0) { |
223 | /* driver didn't accept device */ | ||
230 | err = -ENODEV; | 224 | err = -ENODEV; |
225 | } | ||
231 | } | 226 | } |
232 | put_device(dev); | 227 | put_device(dev); |
233 | bus_put(bus); | 228 | bus_put(bus); |
@@ -237,16 +232,16 @@ static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind); | |||
237 | 232 | ||
238 | static ssize_t show_drivers_autoprobe(struct bus_type *bus, char *buf) | 233 | static ssize_t show_drivers_autoprobe(struct bus_type *bus, char *buf) |
239 | { | 234 | { |
240 | return sprintf(buf, "%d\n", bus->drivers_autoprobe); | 235 | return sprintf(buf, "%d\n", bus->p->drivers_autoprobe); |
241 | } | 236 | } |
242 | 237 | ||
243 | static ssize_t store_drivers_autoprobe(struct bus_type *bus, | 238 | static ssize_t store_drivers_autoprobe(struct bus_type *bus, |
244 | const char *buf, size_t count) | 239 | const char *buf, size_t count) |
245 | { | 240 | { |
246 | if (buf[0] == '0') | 241 | if (buf[0] == '0') |
247 | bus->drivers_autoprobe = 0; | 242 | bus->p->drivers_autoprobe = 0; |
248 | else | 243 | else |
249 | bus->drivers_autoprobe = 1; | 244 | bus->p->drivers_autoprobe = 1; |
250 | return count; | 245 | return count; |
251 | } | 246 | } |
252 | 247 | ||
@@ -264,49 +259,49 @@ static ssize_t store_drivers_probe(struct bus_type *bus, | |||
264 | } | 259 | } |
265 | #endif | 260 | #endif |
266 | 261 | ||
267 | static struct device * next_device(struct klist_iter * i) | 262 | static struct device *next_device(struct klist_iter *i) |
268 | { | 263 | { |
269 | struct klist_node * n = klist_next(i); | 264 | struct klist_node *n = klist_next(i); |
270 | return n ? container_of(n, struct device, knode_bus) : NULL; | 265 | return n ? container_of(n, struct device, knode_bus) : NULL; |
271 | } | 266 | } |
272 | 267 | ||
273 | /** | 268 | /** |
274 | * bus_for_each_dev - device iterator. | 269 | * bus_for_each_dev - device iterator. |
275 | * @bus: bus type. | 270 | * @bus: bus type. |
276 | * @start: device to start iterating from. | 271 | * @start: device to start iterating from. |
277 | * @data: data for the callback. | 272 | * @data: data for the callback. |
278 | * @fn: function to be called for each device. | 273 | * @fn: function to be called for each device. |
279 | * | 274 | * |
280 | * Iterate over @bus's list of devices, and call @fn for each, | 275 | * Iterate over @bus's list of devices, and call @fn for each, |
281 | * passing it @data. If @start is not NULL, we use that device to | 276 | * passing it @data. If @start is not NULL, we use that device to |
282 | * begin iterating from. | 277 | * begin iterating from. |
283 | * | 278 | * |
284 | * We check the return of @fn each time. If it returns anything | 279 | * We check the return of @fn each time. If it returns anything |
285 | * other than 0, we break out and return that value. | 280 | * other than 0, we break out and return that value. |
286 | * | 281 | * |
287 | * NOTE: The device that returns a non-zero value is not retained | 282 | * NOTE: The device that returns a non-zero value is not retained |
288 | * in any way, nor is its refcount incremented. If the caller needs | 283 | * in any way, nor is its refcount incremented. If the caller needs |
289 | * to retain this data, it should do, and increment the reference | 284 | * to retain this data, it should do, and increment the reference |
290 | * count in the supplied callback. | 285 | * count in the supplied callback. |
291 | */ | 286 | */ |
292 | 287 | int bus_for_each_dev(struct bus_type *bus, struct device *start, | |
293 | int bus_for_each_dev(struct bus_type * bus, struct device * start, | 288 | void *data, int (*fn)(struct device *, void *)) |
294 | void * data, int (*fn)(struct device *, void *)) | ||
295 | { | 289 | { |
296 | struct klist_iter i; | 290 | struct klist_iter i; |
297 | struct device * dev; | 291 | struct device *dev; |
298 | int error = 0; | 292 | int error = 0; |
299 | 293 | ||
300 | if (!bus) | 294 | if (!bus) |
301 | return -EINVAL; | 295 | return -EINVAL; |
302 | 296 | ||
303 | klist_iter_init_node(&bus->klist_devices, &i, | 297 | klist_iter_init_node(&bus->p->klist_devices, &i, |
304 | (start ? &start->knode_bus : NULL)); | 298 | (start ? &start->knode_bus : NULL)); |
305 | while ((dev = next_device(&i)) && !error) | 299 | while ((dev = next_device(&i)) && !error) |
306 | error = fn(dev, data); | 300 | error = fn(dev, data); |
307 | klist_iter_exit(&i); | 301 | klist_iter_exit(&i); |
308 | return error; | 302 | return error; |
309 | } | 303 | } |
304 | EXPORT_SYMBOL_GPL(bus_for_each_dev); | ||
310 | 305 | ||
311 | /** | 306 | /** |
312 | * bus_find_device - device iterator for locating a particular device. | 307 | * bus_find_device - device iterator for locating a particular device. |
@@ -323,9 +318,9 @@ int bus_for_each_dev(struct bus_type * bus, struct device * start, | |||
323 | * if it does. If the callback returns non-zero, this function will | 318 | * if it does. If the callback returns non-zero, this function will |
324 | * return to the caller and not iterate over any more devices. | 319 | * return to the caller and not iterate over any more devices. |
325 | */ | 320 | */ |
326 | struct device * bus_find_device(struct bus_type *bus, | 321 | struct device *bus_find_device(struct bus_type *bus, |
327 | struct device *start, void *data, | 322 | struct device *start, void *data, |
328 | int (*match)(struct device *, void *)) | 323 | int (*match)(struct device *dev, void *data)) |
329 | { | 324 | { |
330 | struct klist_iter i; | 325 | struct klist_iter i; |
331 | struct device *dev; | 326 | struct device *dev; |
@@ -333,7 +328,7 @@ struct device * bus_find_device(struct bus_type *bus, | |||
333 | if (!bus) | 328 | if (!bus) |
334 | return NULL; | 329 | return NULL; |
335 | 330 | ||
336 | klist_iter_init_node(&bus->klist_devices, &i, | 331 | klist_iter_init_node(&bus->p->klist_devices, &i, |
337 | (start ? &start->knode_bus : NULL)); | 332 | (start ? &start->knode_bus : NULL)); |
338 | while ((dev = next_device(&i))) | 333 | while ((dev = next_device(&i))) |
339 | if (match(dev, data) && get_device(dev)) | 334 | if (match(dev, data) && get_device(dev)) |
@@ -341,51 +336,57 @@ struct device * bus_find_device(struct bus_type *bus, | |||
341 | klist_iter_exit(&i); | 336 | klist_iter_exit(&i); |
342 | return dev; | 337 | return dev; |
343 | } | 338 | } |
339 | EXPORT_SYMBOL_GPL(bus_find_device); | ||
344 | 340 | ||
345 | 341 | static struct device_driver *next_driver(struct klist_iter *i) | |
346 | static struct device_driver * next_driver(struct klist_iter * i) | ||
347 | { | 342 | { |
348 | struct klist_node * n = klist_next(i); | 343 | struct klist_node *n = klist_next(i); |
349 | return n ? container_of(n, struct device_driver, knode_bus) : NULL; | 344 | struct driver_private *drv_priv; |
345 | |||
346 | if (n) { | ||
347 | drv_priv = container_of(n, struct driver_private, knode_bus); | ||
348 | return drv_priv->driver; | ||
349 | } | ||
350 | return NULL; | ||
350 | } | 351 | } |
351 | 352 | ||
352 | /** | 353 | /** |
353 | * bus_for_each_drv - driver iterator | 354 | * bus_for_each_drv - driver iterator |
354 | * @bus: bus we're dealing with. | 355 | * @bus: bus we're dealing with. |
355 | * @start: driver to start iterating on. | 356 | * @start: driver to start iterating on. |
356 | * @data: data to pass to the callback. | 357 | * @data: data to pass to the callback. |
357 | * @fn: function to call for each driver. | 358 | * @fn: function to call for each driver. |
358 | * | 359 | * |
359 | * This is nearly identical to the device iterator above. | 360 | * This is nearly identical to the device iterator above. |
360 | * We iterate over each driver that belongs to @bus, and call | 361 | * We iterate over each driver that belongs to @bus, and call |
361 | * @fn for each. If @fn returns anything but 0, we break out | 362 | * @fn for each. If @fn returns anything but 0, we break out |
362 | * and return it. If @start is not NULL, we use it as the head | 363 | * and return it. If @start is not NULL, we use it as the head |
363 | * of the list. | 364 | * of the list. |
364 | * | 365 | * |
365 | * NOTE: we don't return the driver that returns a non-zero | 366 | * NOTE: we don't return the driver that returns a non-zero |
366 | * value, nor do we leave the reference count incremented for that | 367 | * value, nor do we leave the reference count incremented for that |
367 | * driver. If the caller needs to know that info, it must set it | 368 | * driver. If the caller needs to know that info, it must set it |
368 | * in the callback. It must also be sure to increment the refcount | 369 | * in the callback. It must also be sure to increment the refcount |
369 | * so it doesn't disappear before returning to the caller. | 370 | * so it doesn't disappear before returning to the caller. |
370 | */ | 371 | */ |
371 | 372 | int bus_for_each_drv(struct bus_type *bus, struct device_driver *start, | |
372 | int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, | 373 | void *data, int (*fn)(struct device_driver *, void *)) |
373 | void * data, int (*fn)(struct device_driver *, void *)) | ||
374 | { | 374 | { |
375 | struct klist_iter i; | 375 | struct klist_iter i; |
376 | struct device_driver * drv; | 376 | struct device_driver *drv; |
377 | int error = 0; | 377 | int error = 0; |
378 | 378 | ||
379 | if (!bus) | 379 | if (!bus) |
380 | return -EINVAL; | 380 | return -EINVAL; |
381 | 381 | ||
382 | klist_iter_init_node(&bus->klist_drivers, &i, | 382 | klist_iter_init_node(&bus->p->klist_drivers, &i, |
383 | start ? &start->knode_bus : NULL); | 383 | start ? &start->p->knode_bus : NULL); |
384 | while ((drv = next_driver(&i)) && !error) | 384 | while ((drv = next_driver(&i)) && !error) |
385 | error = fn(drv, data); | 385 | error = fn(drv, data); |
386 | klist_iter_exit(&i); | 386 | klist_iter_exit(&i); |
387 | return error; | 387 | return error; |
388 | } | 388 | } |
389 | EXPORT_SYMBOL_GPL(bus_for_each_drv); | ||
389 | 390 | ||
390 | static int device_add_attrs(struct bus_type *bus, struct device *dev) | 391 | static int device_add_attrs(struct bus_type *bus, struct device *dev) |
391 | { | 392 | { |
@@ -396,7 +397,7 @@ static int device_add_attrs(struct bus_type *bus, struct device *dev) | |||
396 | return 0; | 397 | return 0; |
397 | 398 | ||
398 | for (i = 0; attr_name(bus->dev_attrs[i]); i++) { | 399 | for (i = 0; attr_name(bus->dev_attrs[i]); i++) { |
399 | error = device_create_file(dev,&bus->dev_attrs[i]); | 400 | error = device_create_file(dev, &bus->dev_attrs[i]); |
400 | if (error) { | 401 | if (error) { |
401 | while (--i >= 0) | 402 | while (--i >= 0) |
402 | device_remove_file(dev, &bus->dev_attrs[i]); | 403 | device_remove_file(dev, &bus->dev_attrs[i]); |
@@ -406,13 +407,13 @@ static int device_add_attrs(struct bus_type *bus, struct device *dev) | |||
406 | return error; | 407 | return error; |
407 | } | 408 | } |
408 | 409 | ||
409 | static void device_remove_attrs(struct bus_type * bus, struct device * dev) | 410 | static void device_remove_attrs(struct bus_type *bus, struct device *dev) |
410 | { | 411 | { |
411 | int i; | 412 | int i; |
412 | 413 | ||
413 | if (bus->dev_attrs) { | 414 | if (bus->dev_attrs) { |
414 | for (i = 0; attr_name(bus->dev_attrs[i]); i++) | 415 | for (i = 0; attr_name(bus->dev_attrs[i]); i++) |
415 | device_remove_file(dev,&bus->dev_attrs[i]); | 416 | device_remove_file(dev, &bus->dev_attrs[i]); |
416 | } | 417 | } |
417 | } | 418 | } |
418 | 419 | ||
@@ -420,7 +421,7 @@ static void device_remove_attrs(struct bus_type * bus, struct device * dev) | |||
420 | static int make_deprecated_bus_links(struct device *dev) | 421 | static int make_deprecated_bus_links(struct device *dev) |
421 | { | 422 | { |
422 | return sysfs_create_link(&dev->kobj, | 423 | return sysfs_create_link(&dev->kobj, |
423 | &dev->bus->subsys.kobj, "bus"); | 424 | &dev->bus->p->subsys.kobj, "bus"); |
424 | } | 425 | } |
425 | 426 | ||
426 | static void remove_deprecated_bus_links(struct device *dev) | 427 | static void remove_deprecated_bus_links(struct device *dev) |
@@ -433,28 +434,28 @@ static inline void remove_deprecated_bus_links(struct device *dev) { } | |||
433 | #endif | 434 | #endif |
434 | 435 | ||
435 | /** | 436 | /** |
436 | * bus_add_device - add device to bus | 437 | * bus_add_device - add device to bus |
437 | * @dev: device being added | 438 | * @dev: device being added |
438 | * | 439 | * |
439 | * - Add the device to its bus's list of devices. | 440 | * - Add the device to its bus's list of devices. |
440 | * - Create link to device's bus. | 441 | * - Create link to device's bus. |
441 | */ | 442 | */ |
442 | int bus_add_device(struct device * dev) | 443 | int bus_add_device(struct device *dev) |
443 | { | 444 | { |
444 | struct bus_type * bus = bus_get(dev->bus); | 445 | struct bus_type *bus = bus_get(dev->bus); |
445 | int error = 0; | 446 | int error = 0; |
446 | 447 | ||
447 | if (bus) { | 448 | if (bus) { |
448 | pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id); | 449 | pr_debug("bus: '%s': add device %s\n", bus->name, dev->bus_id); |
449 | error = device_add_attrs(bus, dev); | 450 | error = device_add_attrs(bus, dev); |
450 | if (error) | 451 | if (error) |
451 | goto out_put; | 452 | goto out_put; |
452 | error = sysfs_create_link(&bus->devices.kobj, | 453 | error = sysfs_create_link(&bus->p->devices_kset->kobj, |
453 | &dev->kobj, dev->bus_id); | 454 | &dev->kobj, dev->bus_id); |
454 | if (error) | 455 | if (error) |
455 | goto out_id; | 456 | goto out_id; |
456 | error = sysfs_create_link(&dev->kobj, | 457 | error = sysfs_create_link(&dev->kobj, |
457 | &dev->bus->subsys.kobj, "subsystem"); | 458 | &dev->bus->p->subsys.kobj, "subsystem"); |
458 | if (error) | 459 | if (error) |
459 | goto out_subsys; | 460 | goto out_subsys; |
460 | error = make_deprecated_bus_links(dev); | 461 | error = make_deprecated_bus_links(dev); |
@@ -466,7 +467,7 @@ int bus_add_device(struct device * dev) | |||
466 | out_deprecated: | 467 | out_deprecated: |
467 | sysfs_remove_link(&dev->kobj, "subsystem"); | 468 | sysfs_remove_link(&dev->kobj, "subsystem"); |
468 | out_subsys: | 469 | out_subsys: |
469 | sysfs_remove_link(&bus->devices.kobj, dev->bus_id); | 470 | sysfs_remove_link(&bus->p->devices_kset->kobj, dev->bus_id); |
470 | out_id: | 471 | out_id: |
471 | device_remove_attrs(bus, dev); | 472 | device_remove_attrs(bus, dev); |
472 | out_put: | 473 | out_put: |
@@ -475,56 +476,58 @@ out_put: | |||
475 | } | 476 | } |
476 | 477 | ||
477 | /** | 478 | /** |
478 | * bus_attach_device - add device to bus | 479 | * bus_attach_device - add device to bus |
479 | * @dev: device tried to attach to a driver | 480 | * @dev: device tried to attach to a driver |
480 | * | 481 | * |
481 | * - Add device to bus's list of devices. | 482 | * - Add device to bus's list of devices. |
482 | * - Try to attach to driver. | 483 | * - Try to attach to driver. |
483 | */ | 484 | */ |
484 | void bus_attach_device(struct device * dev) | 485 | void bus_attach_device(struct device *dev) |
485 | { | 486 | { |
486 | struct bus_type *bus = dev->bus; | 487 | struct bus_type *bus = dev->bus; |
487 | int ret = 0; | 488 | int ret = 0; |
488 | 489 | ||
489 | if (bus) { | 490 | if (bus) { |
490 | dev->is_registered = 1; | 491 | dev->is_registered = 1; |
491 | if (bus->drivers_autoprobe) | 492 | if (bus->p->drivers_autoprobe) |
492 | ret = device_attach(dev); | 493 | ret = device_attach(dev); |
493 | WARN_ON(ret < 0); | 494 | WARN_ON(ret < 0); |
494 | if (ret >= 0) | 495 | if (ret >= 0) |
495 | klist_add_tail(&dev->knode_bus, &bus->klist_devices); | 496 | klist_add_tail(&dev->knode_bus, &bus->p->klist_devices); |
496 | else | 497 | else |
497 | dev->is_registered = 0; | 498 | dev->is_registered = 0; |
498 | } | 499 | } |
499 | } | 500 | } |
500 | 501 | ||
501 | /** | 502 | /** |
502 | * bus_remove_device - remove device from bus | 503 | * bus_remove_device - remove device from bus |
503 | * @dev: device to be removed | 504 | * @dev: device to be removed |
504 | * | 505 | * |
505 | * - Remove symlink from bus's directory. | 506 | * - Remove symlink from bus's directory. |
506 | * - Delete device from bus's list. | 507 | * - Delete device from bus's list. |
507 | * - Detach from its driver. | 508 | * - Detach from its driver. |
508 | * - Drop reference taken in bus_add_device(). | 509 | * - Drop reference taken in bus_add_device(). |
509 | */ | 510 | */ |
510 | void bus_remove_device(struct device * dev) | 511 | void bus_remove_device(struct device *dev) |
511 | { | 512 | { |
512 | if (dev->bus) { | 513 | if (dev->bus) { |
513 | sysfs_remove_link(&dev->kobj, "subsystem"); | 514 | sysfs_remove_link(&dev->kobj, "subsystem"); |
514 | remove_deprecated_bus_links(dev); | 515 | remove_deprecated_bus_links(dev); |
515 | sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id); | 516 | sysfs_remove_link(&dev->bus->p->devices_kset->kobj, |
517 | dev->bus_id); | ||
516 | device_remove_attrs(dev->bus, dev); | 518 | device_remove_attrs(dev->bus, dev); |
517 | if (dev->is_registered) { | 519 | if (dev->is_registered) { |
518 | dev->is_registered = 0; | 520 | dev->is_registered = 0; |
519 | klist_del(&dev->knode_bus); | 521 | klist_del(&dev->knode_bus); |
520 | } | 522 | } |
521 | pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id); | 523 | pr_debug("bus: '%s': remove device %s\n", |
524 | dev->bus->name, dev->bus_id); | ||
522 | device_release_driver(dev); | 525 | device_release_driver(dev); |
523 | bus_put(dev->bus); | 526 | bus_put(dev->bus); |
524 | } | 527 | } |
525 | } | 528 | } |
526 | 529 | ||
527 | static int driver_add_attrs(struct bus_type * bus, struct device_driver * drv) | 530 | static int driver_add_attrs(struct bus_type *bus, struct device_driver *drv) |
528 | { | 531 | { |
529 | int error = 0; | 532 | int error = 0; |
530 | int i; | 533 | int i; |
@@ -533,19 +536,19 @@ static int driver_add_attrs(struct bus_type * bus, struct device_driver * drv) | |||
533 | for (i = 0; attr_name(bus->drv_attrs[i]); i++) { | 536 | for (i = 0; attr_name(bus->drv_attrs[i]); i++) { |
534 | error = driver_create_file(drv, &bus->drv_attrs[i]); | 537 | error = driver_create_file(drv, &bus->drv_attrs[i]); |
535 | if (error) | 538 | if (error) |
536 | goto Err; | 539 | goto err; |
537 | } | 540 | } |
538 | } | 541 | } |
539 | Done: | 542 | done: |
540 | return error; | 543 | return error; |
541 | Err: | 544 | err: |
542 | while (--i >= 0) | 545 | while (--i >= 0) |
543 | driver_remove_file(drv, &bus->drv_attrs[i]); | 546 | driver_remove_file(drv, &bus->drv_attrs[i]); |
544 | goto Done; | 547 | goto done; |
545 | } | 548 | } |
546 | 549 | ||
547 | 550 | static void driver_remove_attrs(struct bus_type *bus, | |
548 | static void driver_remove_attrs(struct bus_type * bus, struct device_driver * drv) | 551 | struct device_driver *drv) |
549 | { | 552 | { |
550 | int i; | 553 | int i; |
551 | 554 | ||
@@ -616,39 +619,46 @@ static ssize_t driver_uevent_store(struct device_driver *drv, | |||
616 | enum kobject_action action; | 619 | enum kobject_action action; |
617 | 620 | ||
618 | if (kobject_action_type(buf, count, &action) == 0) | 621 | if (kobject_action_type(buf, count, &action) == 0) |
619 | kobject_uevent(&drv->kobj, action); | 622 | kobject_uevent(&drv->p->kobj, action); |
620 | return count; | 623 | return count; |
621 | } | 624 | } |
622 | static DRIVER_ATTR(uevent, S_IWUSR, NULL, driver_uevent_store); | 625 | static DRIVER_ATTR(uevent, S_IWUSR, NULL, driver_uevent_store); |
623 | 626 | ||
624 | /** | 627 | /** |
625 | * bus_add_driver - Add a driver to the bus. | 628 | * bus_add_driver - Add a driver to the bus. |
626 | * @drv: driver. | 629 | * @drv: driver. |
627 | * | ||
628 | */ | 630 | */ |
629 | int bus_add_driver(struct device_driver *drv) | 631 | int bus_add_driver(struct device_driver *drv) |
630 | { | 632 | { |
631 | struct bus_type * bus = bus_get(drv->bus); | 633 | struct bus_type *bus; |
634 | struct driver_private *priv; | ||
632 | int error = 0; | 635 | int error = 0; |
633 | 636 | ||
637 | bus = bus_get(drv->bus); | ||
634 | if (!bus) | 638 | if (!bus) |
635 | return -EINVAL; | 639 | return -EINVAL; |
636 | 640 | ||
637 | pr_debug("bus %s: add driver %s\n", bus->name, drv->name); | 641 | pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name); |
638 | error = kobject_set_name(&drv->kobj, "%s", drv->name); | 642 | |
639 | if (error) | 643 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
640 | goto out_put_bus; | 644 | if (!priv) |
641 | drv->kobj.kset = &bus->drivers; | 645 | return -ENOMEM; |
642 | error = kobject_register(&drv->kobj); | 646 | |
647 | klist_init(&priv->klist_devices, NULL, NULL); | ||
648 | priv->driver = drv; | ||
649 | drv->p = priv; | ||
650 | priv->kobj.kset = bus->p->drivers_kset; | ||
651 | error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL, | ||
652 | "%s", drv->name); | ||
643 | if (error) | 653 | if (error) |
644 | goto out_put_bus; | 654 | goto out_put_bus; |
645 | 655 | ||
646 | if (drv->bus->drivers_autoprobe) { | 656 | if (drv->bus->p->drivers_autoprobe) { |
647 | error = driver_attach(drv); | 657 | error = driver_attach(drv); |
648 | if (error) | 658 | if (error) |
649 | goto out_unregister; | 659 | goto out_unregister; |
650 | } | 660 | } |
651 | klist_add_tail(&drv->knode_bus, &bus->klist_drivers); | 661 | klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers); |
652 | module_add_driver(drv->owner, drv); | 662 | module_add_driver(drv->owner, drv); |
653 | 663 | ||
654 | error = driver_create_file(drv, &driver_attr_uevent); | 664 | error = driver_create_file(drv, &driver_attr_uevent); |
@@ -669,24 +679,24 @@ int bus_add_driver(struct device_driver *drv) | |||
669 | __FUNCTION__, drv->name); | 679 | __FUNCTION__, drv->name); |
670 | } | 680 | } |
671 | 681 | ||
682 | kobject_uevent(&priv->kobj, KOBJ_ADD); | ||
672 | return error; | 683 | return error; |
673 | out_unregister: | 684 | out_unregister: |
674 | kobject_unregister(&drv->kobj); | 685 | kobject_put(&priv->kobj); |
675 | out_put_bus: | 686 | out_put_bus: |
676 | bus_put(bus); | 687 | bus_put(bus); |
677 | return error; | 688 | return error; |
678 | } | 689 | } |
679 | 690 | ||
680 | /** | 691 | /** |
681 | * bus_remove_driver - delete driver from bus's knowledge. | 692 | * bus_remove_driver - delete driver from bus's knowledge. |
682 | * @drv: driver. | 693 | * @drv: driver. |
683 | * | 694 | * |
684 | * Detach the driver from the devices it controls, and remove | 695 | * Detach the driver from the devices it controls, and remove |
685 | * it from its bus's list of drivers. Finally, we drop the reference | 696 | * it from its bus's list of drivers. Finally, we drop the reference |
686 | * to the bus we took in bus_add_driver(). | 697 | * to the bus we took in bus_add_driver(). |
687 | */ | 698 | */ |
688 | 699 | void bus_remove_driver(struct device_driver *drv) | |
689 | void bus_remove_driver(struct device_driver * drv) | ||
690 | { | 700 | { |
691 | if (!drv->bus) | 701 | if (!drv->bus) |
692 | return; | 702 | return; |
@@ -694,18 +704,17 @@ void bus_remove_driver(struct device_driver * drv) | |||
694 | remove_bind_files(drv); | 704 | remove_bind_files(drv); |
695 | driver_remove_attrs(drv->bus, drv); | 705 | driver_remove_attrs(drv->bus, drv); |
696 | driver_remove_file(drv, &driver_attr_uevent); | 706 | driver_remove_file(drv, &driver_attr_uevent); |
697 | klist_remove(&drv->knode_bus); | 707 | klist_remove(&drv->p->knode_bus); |
698 | pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); | 708 | pr_debug("bus: '%s': remove driver %s\n", drv->bus->name, drv->name); |
699 | driver_detach(drv); | 709 | driver_detach(drv); |
700 | module_remove_driver(drv); | 710 | module_remove_driver(drv); |
701 | kobject_unregister(&drv->kobj); | 711 | kobject_put(&drv->p->kobj); |
702 | bus_put(drv->bus); | 712 | bus_put(drv->bus); |
703 | } | 713 | } |
704 | 714 | ||
705 | |||
706 | /* Helper for bus_rescan_devices's iter */ | 715 | /* Helper for bus_rescan_devices's iter */ |
707 | static int __must_check bus_rescan_devices_helper(struct device *dev, | 716 | static int __must_check bus_rescan_devices_helper(struct device *dev, |
708 | void *data) | 717 | void *data) |
709 | { | 718 | { |
710 | int ret = 0; | 719 | int ret = 0; |
711 | 720 | ||
@@ -727,10 +736,11 @@ static int __must_check bus_rescan_devices_helper(struct device *dev, | |||
727 | * attached and rescan it against existing drivers to see if it matches | 736 | * attached and rescan it against existing drivers to see if it matches |
728 | * any by calling device_attach() for the unbound devices. | 737 | * any by calling device_attach() for the unbound devices. |
729 | */ | 738 | */ |
730 | int bus_rescan_devices(struct bus_type * bus) | 739 | int bus_rescan_devices(struct bus_type *bus) |
731 | { | 740 | { |
732 | return bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper); | 741 | return bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper); |
733 | } | 742 | } |
743 | EXPORT_SYMBOL_GPL(bus_rescan_devices); | ||
734 | 744 | ||
735 | /** | 745 | /** |
736 | * device_reprobe - remove driver for a device and probe for a new driver | 746 | * device_reprobe - remove driver for a device and probe for a new driver |
@@ -755,55 +765,55 @@ int device_reprobe(struct device *dev) | |||
755 | EXPORT_SYMBOL_GPL(device_reprobe); | 765 | EXPORT_SYMBOL_GPL(device_reprobe); |
756 | 766 | ||
757 | /** | 767 | /** |
758 | * find_bus - locate bus by name. | 768 | * find_bus - locate bus by name. |
759 | * @name: name of bus. | 769 | * @name: name of bus. |
760 | * | 770 | * |
761 | * Call kset_find_obj() to iterate over list of buses to | 771 | * Call kset_find_obj() to iterate over list of buses to |
762 | * find a bus by name. Return bus if found. | 772 | * find a bus by name. Return bus if found. |
763 | * | 773 | * |
764 | * Note that kset_find_obj increments bus' reference count. | 774 | * Note that kset_find_obj increments bus' reference count. |
765 | */ | 775 | */ |
766 | #if 0 | 776 | #if 0 |
767 | struct bus_type * find_bus(char * name) | 777 | struct bus_type *find_bus(char *name) |
768 | { | 778 | { |
769 | struct kobject * k = kset_find_obj(&bus_subsys.kset, name); | 779 | struct kobject *k = kset_find_obj(bus_kset, name); |
770 | return k ? to_bus(k) : NULL; | 780 | return k ? to_bus(k) : NULL; |
771 | } | 781 | } |
772 | #endif /* 0 */ | 782 | #endif /* 0 */ |
773 | 783 | ||
774 | 784 | ||
775 | /** | 785 | /** |
776 | * bus_add_attrs - Add default attributes for this bus. | 786 | * bus_add_attrs - Add default attributes for this bus. |
777 | * @bus: Bus that has just been registered. | 787 | * @bus: Bus that has just been registered. |
778 | */ | 788 | */ |
779 | 789 | ||
780 | static int bus_add_attrs(struct bus_type * bus) | 790 | static int bus_add_attrs(struct bus_type *bus) |
781 | { | 791 | { |
782 | int error = 0; | 792 | int error = 0; |
783 | int i; | 793 | int i; |
784 | 794 | ||
785 | if (bus->bus_attrs) { | 795 | if (bus->bus_attrs) { |
786 | for (i = 0; attr_name(bus->bus_attrs[i]); i++) { | 796 | for (i = 0; attr_name(bus->bus_attrs[i]); i++) { |
787 | error = bus_create_file(bus,&bus->bus_attrs[i]); | 797 | error = bus_create_file(bus, &bus->bus_attrs[i]); |
788 | if (error) | 798 | if (error) |
789 | goto Err; | 799 | goto err; |
790 | } | 800 | } |
791 | } | 801 | } |
792 | Done: | 802 | done: |
793 | return error; | 803 | return error; |
794 | Err: | 804 | err: |
795 | while (--i >= 0) | 805 | while (--i >= 0) |
796 | bus_remove_file(bus,&bus->bus_attrs[i]); | 806 | bus_remove_file(bus, &bus->bus_attrs[i]); |
797 | goto Done; | 807 | goto done; |
798 | } | 808 | } |
799 | 809 | ||
800 | static void bus_remove_attrs(struct bus_type * bus) | 810 | static void bus_remove_attrs(struct bus_type *bus) |
801 | { | 811 | { |
802 | int i; | 812 | int i; |
803 | 813 | ||
804 | if (bus->bus_attrs) { | 814 | if (bus->bus_attrs) { |
805 | for (i = 0; attr_name(bus->bus_attrs[i]); i++) | 815 | for (i = 0; attr_name(bus->bus_attrs[i]); i++) |
806 | bus_remove_file(bus,&bus->bus_attrs[i]); | 816 | bus_remove_file(bus, &bus->bus_attrs[i]); |
807 | } | 817 | } |
808 | } | 818 | } |
809 | 819 | ||
@@ -827,32 +837,42 @@ static ssize_t bus_uevent_store(struct bus_type *bus, | |||
827 | enum kobject_action action; | 837 | enum kobject_action action; |
828 | 838 | ||
829 | if (kobject_action_type(buf, count, &action) == 0) | 839 | if (kobject_action_type(buf, count, &action) == 0) |
830 | kobject_uevent(&bus->subsys.kobj, action); | 840 | kobject_uevent(&bus->p->subsys.kobj, action); |
831 | return count; | 841 | return count; |
832 | } | 842 | } |
833 | static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store); | 843 | static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store); |
834 | 844 | ||
835 | /** | 845 | /** |
836 | * bus_register - register a bus with the system. | 846 | * bus_register - register a bus with the system. |
837 | * @bus: bus. | 847 | * @bus: bus. |
838 | * | 848 | * |
839 | * Once we have that, we registered the bus with the kobject | 849 | * Once we have that, we registered the bus with the kobject |
840 | * infrastructure, then register the children subsystems it has: | 850 | * infrastructure, then register the children subsystems it has: |
841 | * the devices and drivers that belong to the bus. | 851 | * the devices and drivers that belong to the bus. |
842 | */ | 852 | */ |
843 | int bus_register(struct bus_type * bus) | 853 | int bus_register(struct bus_type *bus) |
844 | { | 854 | { |
845 | int retval; | 855 | int retval; |
856 | struct bus_type_private *priv; | ||
857 | |||
858 | priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL); | ||
859 | if (!priv) | ||
860 | return -ENOMEM; | ||
846 | 861 | ||
847 | BLOCKING_INIT_NOTIFIER_HEAD(&bus->bus_notifier); | 862 | priv->bus = bus; |
863 | bus->p = priv; | ||
848 | 864 | ||
849 | retval = kobject_set_name(&bus->subsys.kobj, "%s", bus->name); | 865 | BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier); |
866 | |||
867 | retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name); | ||
850 | if (retval) | 868 | if (retval) |
851 | goto out; | 869 | goto out; |
852 | 870 | ||
853 | bus->subsys.kobj.kset = &bus_subsys; | 871 | priv->subsys.kobj.kset = bus_kset; |
872 | priv->subsys.kobj.ktype = &bus_ktype; | ||
873 | priv->drivers_autoprobe = 1; | ||
854 | 874 | ||
855 | retval = subsystem_register(&bus->subsys); | 875 | retval = kset_register(&priv->subsys); |
856 | if (retval) | 876 | if (retval) |
857 | goto out; | 877 | goto out; |
858 | 878 | ||
@@ -860,23 +880,23 @@ int bus_register(struct bus_type * bus) | |||
860 | if (retval) | 880 | if (retval) |
861 | goto bus_uevent_fail; | 881 | goto bus_uevent_fail; |
862 | 882 | ||
863 | kobject_set_name(&bus->devices.kobj, "devices"); | 883 | priv->devices_kset = kset_create_and_add("devices", NULL, |
864 | bus->devices.kobj.parent = &bus->subsys.kobj; | 884 | &priv->subsys.kobj); |
865 | retval = kset_register(&bus->devices); | 885 | if (!priv->devices_kset) { |
866 | if (retval) | 886 | retval = -ENOMEM; |
867 | goto bus_devices_fail; | 887 | goto bus_devices_fail; |
888 | } | ||
868 | 889 | ||
869 | kobject_set_name(&bus->drivers.kobj, "drivers"); | 890 | priv->drivers_kset = kset_create_and_add("drivers", NULL, |
870 | bus->drivers.kobj.parent = &bus->subsys.kobj; | 891 | &priv->subsys.kobj); |
871 | bus->drivers.ktype = &driver_ktype; | 892 | if (!priv->drivers_kset) { |
872 | retval = kset_register(&bus->drivers); | 893 | retval = -ENOMEM; |
873 | if (retval) | ||
874 | goto bus_drivers_fail; | 894 | goto bus_drivers_fail; |
895 | } | ||
875 | 896 | ||
876 | klist_init(&bus->klist_devices, klist_devices_get, klist_devices_put); | 897 | klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put); |
877 | klist_init(&bus->klist_drivers, NULL, NULL); | 898 | klist_init(&priv->klist_drivers, NULL, NULL); |
878 | 899 | ||
879 | bus->drivers_autoprobe = 1; | ||
880 | retval = add_probe_files(bus); | 900 | retval = add_probe_files(bus); |
881 | if (retval) | 901 | if (retval) |
882 | goto bus_probe_files_fail; | 902 | goto bus_probe_files_fail; |
@@ -885,66 +905,73 @@ int bus_register(struct bus_type * bus) | |||
885 | if (retval) | 905 | if (retval) |
886 | goto bus_attrs_fail; | 906 | goto bus_attrs_fail; |
887 | 907 | ||
888 | pr_debug("bus type '%s' registered\n", bus->name); | 908 | pr_debug("bus: '%s': registered\n", bus->name); |
889 | return 0; | 909 | return 0; |
890 | 910 | ||
891 | bus_attrs_fail: | 911 | bus_attrs_fail: |
892 | remove_probe_files(bus); | 912 | remove_probe_files(bus); |
893 | bus_probe_files_fail: | 913 | bus_probe_files_fail: |
894 | kset_unregister(&bus->drivers); | 914 | kset_unregister(bus->p->drivers_kset); |
895 | bus_drivers_fail: | 915 | bus_drivers_fail: |
896 | kset_unregister(&bus->devices); | 916 | kset_unregister(bus->p->devices_kset); |
897 | bus_devices_fail: | 917 | bus_devices_fail: |
898 | bus_remove_file(bus, &bus_attr_uevent); | 918 | bus_remove_file(bus, &bus_attr_uevent); |
899 | bus_uevent_fail: | 919 | bus_uevent_fail: |
900 | subsystem_unregister(&bus->subsys); | 920 | kset_unregister(&bus->p->subsys); |
921 | kfree(bus->p); | ||
901 | out: | 922 | out: |
902 | return retval; | 923 | return retval; |
903 | } | 924 | } |
925 | EXPORT_SYMBOL_GPL(bus_register); | ||
904 | 926 | ||
905 | /** | 927 | /** |
906 | * bus_unregister - remove a bus from the system | 928 | * bus_unregister - remove a bus from the system |
907 | * @bus: bus. | 929 | * @bus: bus. |
908 | * | 930 | * |
909 | * Unregister the child subsystems and the bus itself. | 931 | * Unregister the child subsystems and the bus itself. |
910 | * Finally, we call bus_put() to release the refcount | 932 | * Finally, we call bus_put() to release the refcount |
911 | */ | 933 | */ |
912 | void bus_unregister(struct bus_type * bus) | 934 | void bus_unregister(struct bus_type *bus) |
913 | { | 935 | { |
914 | pr_debug("bus %s: unregistering\n", bus->name); | 936 | pr_debug("bus: '%s': unregistering\n", bus->name); |
915 | bus_remove_attrs(bus); | 937 | bus_remove_attrs(bus); |
916 | remove_probe_files(bus); | 938 | remove_probe_files(bus); |
917 | kset_unregister(&bus->drivers); | 939 | kset_unregister(bus->p->drivers_kset); |
918 | kset_unregister(&bus->devices); | 940 | kset_unregister(bus->p->devices_kset); |
919 | bus_remove_file(bus, &bus_attr_uevent); | 941 | bus_remove_file(bus, &bus_attr_uevent); |
920 | subsystem_unregister(&bus->subsys); | 942 | kset_unregister(&bus->p->subsys); |
943 | kfree(bus->p); | ||
921 | } | 944 | } |
945 | EXPORT_SYMBOL_GPL(bus_unregister); | ||
922 | 946 | ||
923 | int bus_register_notifier(struct bus_type *bus, struct notifier_block *nb) | 947 | int bus_register_notifier(struct bus_type *bus, struct notifier_block *nb) |
924 | { | 948 | { |
925 | return blocking_notifier_chain_register(&bus->bus_notifier, nb); | 949 | return blocking_notifier_chain_register(&bus->p->bus_notifier, nb); |
926 | } | 950 | } |
927 | EXPORT_SYMBOL_GPL(bus_register_notifier); | 951 | EXPORT_SYMBOL_GPL(bus_register_notifier); |
928 | 952 | ||
929 | int bus_unregister_notifier(struct bus_type *bus, struct notifier_block *nb) | 953 | int bus_unregister_notifier(struct bus_type *bus, struct notifier_block *nb) |
930 | { | 954 | { |
931 | return blocking_notifier_chain_unregister(&bus->bus_notifier, nb); | 955 | return blocking_notifier_chain_unregister(&bus->p->bus_notifier, nb); |
932 | } | 956 | } |
933 | EXPORT_SYMBOL_GPL(bus_unregister_notifier); | 957 | EXPORT_SYMBOL_GPL(bus_unregister_notifier); |
934 | 958 | ||
935 | int __init buses_init(void) | 959 | struct kset *bus_get_kset(struct bus_type *bus) |
936 | { | 960 | { |
937 | return subsystem_register(&bus_subsys); | 961 | return &bus->p->subsys; |
938 | } | 962 | } |
963 | EXPORT_SYMBOL_GPL(bus_get_kset); | ||
939 | 964 | ||
965 | struct klist *bus_get_device_klist(struct bus_type *bus) | ||
966 | { | ||
967 | return &bus->p->klist_devices; | ||
968 | } | ||
969 | EXPORT_SYMBOL_GPL(bus_get_device_klist); | ||
940 | 970 | ||
941 | EXPORT_SYMBOL_GPL(bus_for_each_dev); | 971 | int __init buses_init(void) |
942 | EXPORT_SYMBOL_GPL(bus_find_device); | 972 | { |
943 | EXPORT_SYMBOL_GPL(bus_for_each_drv); | 973 | bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL); |
944 | 974 | if (!bus_kset) | |
945 | EXPORT_SYMBOL_GPL(bus_register); | 975 | return -ENOMEM; |
946 | EXPORT_SYMBOL_GPL(bus_unregister); | 976 | return 0; |
947 | EXPORT_SYMBOL_GPL(bus_rescan_devices); | 977 | } |
948 | |||
949 | EXPORT_SYMBOL_GPL(bus_create_file); | ||
950 | EXPORT_SYMBOL_GPL(bus_remove_file); | ||
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; |
diff --git a/drivers/base/core.c b/drivers/base/core.c index 2683eac30c68..edf3bbeb8d6a 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -18,14 +18,14 @@ | |||
18 | #include <linux/string.h> | 18 | #include <linux/string.h> |
19 | #include <linux/kdev_t.h> | 19 | #include <linux/kdev_t.h> |
20 | #include <linux/notifier.h> | 20 | #include <linux/notifier.h> |
21 | 21 | #include <linux/genhd.h> | |
22 | #include <asm/semaphore.h> | 22 | #include <asm/semaphore.h> |
23 | 23 | ||
24 | #include "base.h" | 24 | #include "base.h" |
25 | #include "power/power.h" | 25 | #include "power/power.h" |
26 | 26 | ||
27 | int (*platform_notify)(struct device * dev) = NULL; | 27 | int (*platform_notify)(struct device *dev) = NULL; |
28 | int (*platform_notify_remove)(struct device * dev) = NULL; | 28 | int (*platform_notify_remove)(struct device *dev) = NULL; |
29 | 29 | ||
30 | /* | 30 | /* |
31 | * sysfs bindings for devices. | 31 | * sysfs bindings for devices. |
@@ -51,11 +51,11 @@ EXPORT_SYMBOL(dev_driver_string); | |||
51 | #define to_dev(obj) container_of(obj, struct device, kobj) | 51 | #define to_dev(obj) container_of(obj, struct device, kobj) |
52 | #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) | 52 | #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) |
53 | 53 | ||
54 | static ssize_t | 54 | static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr, |
55 | dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) | 55 | char *buf) |
56 | { | 56 | { |
57 | struct device_attribute * dev_attr = to_dev_attr(attr); | 57 | struct device_attribute *dev_attr = to_dev_attr(attr); |
58 | struct device * dev = to_dev(kobj); | 58 | struct device *dev = to_dev(kobj); |
59 | ssize_t ret = -EIO; | 59 | ssize_t ret = -EIO; |
60 | 60 | ||
61 | if (dev_attr->show) | 61 | if (dev_attr->show) |
@@ -63,12 +63,11 @@ dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) | |||
63 | return ret; | 63 | return ret; |
64 | } | 64 | } |
65 | 65 | ||
66 | static ssize_t | 66 | static ssize_t dev_attr_store(struct kobject *kobj, struct attribute *attr, |
67 | dev_attr_store(struct kobject * kobj, struct attribute * attr, | 67 | const char *buf, size_t count) |
68 | const char * buf, size_t count) | ||
69 | { | 68 | { |
70 | struct device_attribute * dev_attr = to_dev_attr(attr); | 69 | struct device_attribute *dev_attr = to_dev_attr(attr); |
71 | struct device * dev = to_dev(kobj); | 70 | struct device *dev = to_dev(kobj); |
72 | ssize_t ret = -EIO; | 71 | ssize_t ret = -EIO; |
73 | 72 | ||
74 | if (dev_attr->store) | 73 | if (dev_attr->store) |
@@ -90,9 +89,9 @@ static struct sysfs_ops dev_sysfs_ops = { | |||
90 | * reaches 0. We forward the call to the device's release | 89 | * reaches 0. We forward the call to the device's release |
91 | * method, which should handle actually freeing the structure. | 90 | * method, which should handle actually freeing the structure. |
92 | */ | 91 | */ |
93 | static void device_release(struct kobject * kobj) | 92 | static void device_release(struct kobject *kobj) |
94 | { | 93 | { |
95 | struct device * dev = to_dev(kobj); | 94 | struct device *dev = to_dev(kobj); |
96 | 95 | ||
97 | if (dev->release) | 96 | if (dev->release) |
98 | dev->release(dev); | 97 | dev->release(dev); |
@@ -101,8 +100,8 @@ static void device_release(struct kobject * kobj) | |||
101 | else if (dev->class && dev->class->dev_release) | 100 | else if (dev->class && dev->class->dev_release) |
102 | dev->class->dev_release(dev); | 101 | dev->class->dev_release(dev); |
103 | else { | 102 | else { |
104 | printk(KERN_ERR "Device '%s' does not have a release() function, " | 103 | printk(KERN_ERR "Device '%s' does not have a release() " |
105 | "it is broken and must be fixed.\n", | 104 | "function, it is broken and must be fixed.\n", |
106 | dev->bus_id); | 105 | dev->bus_id); |
107 | WARN_ON(1); | 106 | WARN_ON(1); |
108 | } | 107 | } |
@@ -185,7 +184,8 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, | |||
185 | add_uevent_var(env, "PHYSDEVBUS=%s", dev->bus->name); | 184 | add_uevent_var(env, "PHYSDEVBUS=%s", dev->bus->name); |
186 | 185 | ||
187 | if (dev->driver) | 186 | if (dev->driver) |
188 | add_uevent_var(env, "PHYSDEVDRIVER=%s", dev->driver->name); | 187 | add_uevent_var(env, "PHYSDEVDRIVER=%s", |
188 | dev->driver->name); | ||
189 | } | 189 | } |
190 | #endif | 190 | #endif |
191 | 191 | ||
@@ -193,15 +193,16 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, | |||
193 | if (dev->bus && dev->bus->uevent) { | 193 | if (dev->bus && dev->bus->uevent) { |
194 | retval = dev->bus->uevent(dev, env); | 194 | retval = dev->bus->uevent(dev, env); |
195 | if (retval) | 195 | if (retval) |
196 | pr_debug ("%s: bus uevent() returned %d\n", | 196 | pr_debug("device: '%s': %s: bus uevent() returned %d\n", |
197 | __FUNCTION__, retval); | 197 | dev->bus_id, __FUNCTION__, retval); |
198 | } | 198 | } |
199 | 199 | ||
200 | /* have the class specific function add its stuff */ | 200 | /* have the class specific function add its stuff */ |
201 | if (dev->class && dev->class->dev_uevent) { | 201 | if (dev->class && dev->class->dev_uevent) { |
202 | retval = dev->class->dev_uevent(dev, env); | 202 | retval = dev->class->dev_uevent(dev, env); |
203 | if (retval) | 203 | if (retval) |
204 | pr_debug("%s: class uevent() returned %d\n", | 204 | pr_debug("device: '%s': %s: class uevent() " |
205 | "returned %d\n", dev->bus_id, | ||
205 | __FUNCTION__, retval); | 206 | __FUNCTION__, retval); |
206 | } | 207 | } |
207 | 208 | ||
@@ -209,7 +210,8 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, | |||
209 | if (dev->type && dev->type->uevent) { | 210 | if (dev->type && dev->type->uevent) { |
210 | retval = dev->type->uevent(dev, env); | 211 | retval = dev->type->uevent(dev, env); |
211 | if (retval) | 212 | if (retval) |
212 | pr_debug("%s: dev_type uevent() returned %d\n", | 213 | pr_debug("device: '%s': %s: dev_type uevent() " |
214 | "returned %d\n", dev->bus_id, | ||
213 | __FUNCTION__, retval); | 215 | __FUNCTION__, retval); |
214 | } | 216 | } |
215 | 217 | ||
@@ -325,7 +327,8 @@ static int device_add_groups(struct device *dev, | |||
325 | error = sysfs_create_group(&dev->kobj, groups[i]); | 327 | error = sysfs_create_group(&dev->kobj, groups[i]); |
326 | if (error) { | 328 | if (error) { |
327 | while (--i >= 0) | 329 | while (--i >= 0) |
328 | sysfs_remove_group(&dev->kobj, groups[i]); | 330 | sysfs_remove_group(&dev->kobj, |
331 | groups[i]); | ||
329 | break; | 332 | break; |
330 | } | 333 | } |
331 | } | 334 | } |
@@ -401,20 +404,15 @@ static ssize_t show_dev(struct device *dev, struct device_attribute *attr, | |||
401 | static struct device_attribute devt_attr = | 404 | static struct device_attribute devt_attr = |
402 | __ATTR(dev, S_IRUGO, show_dev, NULL); | 405 | __ATTR(dev, S_IRUGO, show_dev, NULL); |
403 | 406 | ||
404 | /* | 407 | /* kset to create /sys/devices/ */ |
405 | * devices_subsys - structure to be registered with kobject core. | 408 | struct kset *devices_kset; |
406 | */ | ||
407 | |||
408 | decl_subsys(devices, &device_ktype, &device_uevent_ops); | ||
409 | |||
410 | 409 | ||
411 | /** | 410 | /** |
412 | * device_create_file - create sysfs attribute file for device. | 411 | * device_create_file - create sysfs attribute file for device. |
413 | * @dev: device. | 412 | * @dev: device. |
414 | * @attr: device attribute descriptor. | 413 | * @attr: device attribute descriptor. |
415 | */ | 414 | */ |
416 | 415 | int device_create_file(struct device *dev, struct device_attribute *attr) | |
417 | int device_create_file(struct device * dev, struct device_attribute * attr) | ||
418 | { | 416 | { |
419 | int error = 0; | 417 | int error = 0; |
420 | if (get_device(dev)) { | 418 | if (get_device(dev)) { |
@@ -425,12 +423,11 @@ int device_create_file(struct device * dev, struct device_attribute * attr) | |||
425 | } | 423 | } |
426 | 424 | ||
427 | /** | 425 | /** |
428 | * device_remove_file - remove sysfs attribute file. | 426 | * device_remove_file - remove sysfs attribute file. |
429 | * @dev: device. | 427 | * @dev: device. |
430 | * @attr: device attribute descriptor. | 428 | * @attr: device attribute descriptor. |
431 | */ | 429 | */ |
432 | 430 | void device_remove_file(struct device *dev, struct device_attribute *attr) | |
433 | void device_remove_file(struct device * dev, struct device_attribute * attr) | ||
434 | { | 431 | { |
435 | if (get_device(dev)) { | 432 | if (get_device(dev)) { |
436 | sysfs_remove_file(&dev->kobj, &attr->attr); | 433 | sysfs_remove_file(&dev->kobj, &attr->attr); |
@@ -511,22 +508,20 @@ static void klist_children_put(struct klist_node *n) | |||
511 | put_device(dev); | 508 | put_device(dev); |
512 | } | 509 | } |
513 | 510 | ||
514 | |||
515 | /** | 511 | /** |
516 | * device_initialize - init device structure. | 512 | * device_initialize - init device structure. |
517 | * @dev: device. | 513 | * @dev: device. |
518 | * | 514 | * |
519 | * This prepares the device for use by other layers, | 515 | * This prepares the device for use by other layers, |
520 | * including adding it to the device hierarchy. | 516 | * including adding it to the device hierarchy. |
521 | * It is the first half of device_register(), if called by | 517 | * It is the first half of device_register(), if called by |
522 | * that, though it can also be called separately, so one | 518 | * that, though it can also be called separately, so one |
523 | * may use @dev's fields (e.g. the refcount). | 519 | * may use @dev's fields (e.g. the refcount). |
524 | */ | 520 | */ |
525 | |||
526 | void device_initialize(struct device *dev) | 521 | void device_initialize(struct device *dev) |
527 | { | 522 | { |
528 | kobj_set_kset_s(dev, devices_subsys); | 523 | dev->kobj.kset = devices_kset; |
529 | kobject_init(&dev->kobj); | 524 | kobject_init(&dev->kobj, &device_ktype); |
530 | klist_init(&dev->klist_children, klist_children_get, | 525 | klist_init(&dev->klist_children, klist_children_get, |
531 | klist_children_put); | 526 | klist_children_put); |
532 | INIT_LIST_HEAD(&dev->dma_pools); | 527 | INIT_LIST_HEAD(&dev->dma_pools); |
@@ -539,36 +534,39 @@ void device_initialize(struct device *dev) | |||
539 | } | 534 | } |
540 | 535 | ||
541 | #ifdef CONFIG_SYSFS_DEPRECATED | 536 | #ifdef CONFIG_SYSFS_DEPRECATED |
542 | static struct kobject * get_device_parent(struct device *dev, | 537 | static struct kobject *get_device_parent(struct device *dev, |
543 | struct device *parent) | 538 | struct device *parent) |
544 | { | 539 | { |
545 | /* | 540 | /* class devices without a parent live in /sys/class/<classname>/ */ |
546 | * Set the parent to the class, not the parent device | ||
547 | * for topmost devices in class hierarchy. | ||
548 | * This keeps sysfs from having a symlink to make old | ||
549 | * udevs happy | ||
550 | */ | ||
551 | if (dev->class && (!parent || parent->class != dev->class)) | 541 | if (dev->class && (!parent || parent->class != dev->class)) |
552 | return &dev->class->subsys.kobj; | 542 | return &dev->class->subsys.kobj; |
543 | /* all other devices keep their parent */ | ||
553 | else if (parent) | 544 | else if (parent) |
554 | return &parent->kobj; | 545 | return &parent->kobj; |
555 | 546 | ||
556 | return NULL; | 547 | return NULL; |
557 | } | 548 | } |
549 | |||
550 | static inline void cleanup_device_parent(struct device *dev) {} | ||
551 | static inline void cleanup_glue_dir(struct device *dev, | ||
552 | struct kobject *glue_dir) {} | ||
558 | #else | 553 | #else |
559 | static struct kobject *virtual_device_parent(struct device *dev) | 554 | static struct kobject *virtual_device_parent(struct device *dev) |
560 | { | 555 | { |
561 | static struct kobject *virtual_dir = NULL; | 556 | static struct kobject *virtual_dir = NULL; |
562 | 557 | ||
563 | if (!virtual_dir) | 558 | if (!virtual_dir) |
564 | virtual_dir = kobject_add_dir(&devices_subsys.kobj, "virtual"); | 559 | virtual_dir = kobject_create_and_add("virtual", |
560 | &devices_kset->kobj); | ||
565 | 561 | ||
566 | return virtual_dir; | 562 | return virtual_dir; |
567 | } | 563 | } |
568 | 564 | ||
569 | static struct kobject * get_device_parent(struct device *dev, | 565 | static struct kobject *get_device_parent(struct device *dev, |
570 | struct device *parent) | 566 | struct device *parent) |
571 | { | 567 | { |
568 | int retval; | ||
569 | |||
572 | if (dev->class) { | 570 | if (dev->class) { |
573 | struct kobject *kobj = NULL; | 571 | struct kobject *kobj = NULL; |
574 | struct kobject *parent_kobj; | 572 | struct kobject *parent_kobj; |
@@ -576,8 +574,8 @@ static struct kobject * get_device_parent(struct device *dev, | |||
576 | 574 | ||
577 | /* | 575 | /* |
578 | * If we have no parent, we live in "virtual". | 576 | * If we have no parent, we live in "virtual". |
579 | * Class-devices with a bus-device as parent, live | 577 | * Class-devices with a non class-device as parent, live |
580 | * in a class-directory to prevent namespace collisions. | 578 | * in a "glue" directory to prevent namespace collisions. |
581 | */ | 579 | */ |
582 | if (parent == NULL) | 580 | if (parent == NULL) |
583 | parent_kobj = virtual_device_parent(dev); | 581 | parent_kobj = virtual_device_parent(dev); |
@@ -598,25 +596,45 @@ static struct kobject * get_device_parent(struct device *dev, | |||
598 | return kobj; | 596 | return kobj; |
599 | 597 | ||
600 | /* or create a new class-directory at the parent device */ | 598 | /* or create a new class-directory at the parent device */ |
601 | return kobject_kset_add_dir(&dev->class->class_dirs, | 599 | k = kobject_create(); |
602 | parent_kobj, dev->class->name); | 600 | if (!k) |
601 | return NULL; | ||
602 | k->kset = &dev->class->class_dirs; | ||
603 | retval = kobject_add(k, parent_kobj, "%s", dev->class->name); | ||
604 | if (retval < 0) { | ||
605 | kobject_put(k); | ||
606 | return NULL; | ||
607 | } | ||
608 | /* do not emit an uevent for this simple "glue" directory */ | ||
609 | return k; | ||
603 | } | 610 | } |
604 | 611 | ||
605 | if (parent) | 612 | if (parent) |
606 | return &parent->kobj; | 613 | return &parent->kobj; |
607 | return NULL; | 614 | return NULL; |
608 | } | 615 | } |
616 | |||
617 | static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir) | ||
618 | { | ||
619 | /* see if we live in a "glue" directory */ | ||
620 | if (!dev->class || glue_dir->kset != &dev->class->class_dirs) | ||
621 | return; | ||
622 | |||
623 | kobject_put(glue_dir); | ||
624 | } | ||
625 | |||
626 | static void cleanup_device_parent(struct device *dev) | ||
627 | { | ||
628 | cleanup_glue_dir(dev, dev->kobj.parent); | ||
629 | } | ||
609 | #endif | 630 | #endif |
610 | 631 | ||
611 | static int setup_parent(struct device *dev, struct device *parent) | 632 | static void setup_parent(struct device *dev, struct device *parent) |
612 | { | 633 | { |
613 | struct kobject *kobj; | 634 | struct kobject *kobj; |
614 | kobj = get_device_parent(dev, parent); | 635 | kobj = get_device_parent(dev, parent); |
615 | if (IS_ERR(kobj)) | ||
616 | return PTR_ERR(kobj); | ||
617 | if (kobj) | 636 | if (kobj) |
618 | dev->kobj.parent = kobj; | 637 | dev->kobj.parent = kobj; |
619 | return 0; | ||
620 | } | 638 | } |
621 | 639 | ||
622 | static int device_add_class_symlinks(struct device *dev) | 640 | static int device_add_class_symlinks(struct device *dev) |
@@ -625,65 +643,76 @@ static int device_add_class_symlinks(struct device *dev) | |||
625 | 643 | ||
626 | if (!dev->class) | 644 | if (!dev->class) |
627 | return 0; | 645 | return 0; |
646 | |||
628 | error = sysfs_create_link(&dev->kobj, &dev->class->subsys.kobj, | 647 | error = sysfs_create_link(&dev->kobj, &dev->class->subsys.kobj, |
629 | "subsystem"); | 648 | "subsystem"); |
630 | if (error) | 649 | if (error) |
631 | goto out; | 650 | goto out; |
632 | /* | 651 | |
633 | * If this is not a "fake" compatible device, then create the | 652 | #ifdef CONFIG_SYSFS_DEPRECATED |
634 | * symlink from the class to the device. | 653 | /* stacked class devices need a symlink in the class directory */ |
635 | */ | 654 | if (dev->kobj.parent != &dev->class->subsys.kobj && |
636 | if (dev->kobj.parent != &dev->class->subsys.kobj) { | 655 | dev->type != &part_type) { |
637 | error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj, | 656 | error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj, |
638 | dev->bus_id); | 657 | dev->bus_id); |
639 | if (error) | 658 | if (error) |
640 | goto out_subsys; | 659 | goto out_subsys; |
641 | } | 660 | } |
642 | if (dev->parent) { | ||
643 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
644 | { | ||
645 | struct device *parent = dev->parent; | ||
646 | char *class_name; | ||
647 | |||
648 | /* | ||
649 | * In old sysfs stacked class devices had 'device' | ||
650 | * link pointing to real device instead of parent | ||
651 | */ | ||
652 | while (parent->class && !parent->bus && parent->parent) | ||
653 | parent = parent->parent; | ||
654 | |||
655 | error = sysfs_create_link(&dev->kobj, | ||
656 | &parent->kobj, | ||
657 | "device"); | ||
658 | if (error) | ||
659 | goto out_busid; | ||
660 | 661 | ||
661 | class_name = make_class_name(dev->class->name, | 662 | if (dev->parent && dev->type != &part_type) { |
662 | &dev->kobj); | 663 | struct device *parent = dev->parent; |
663 | if (class_name) | 664 | char *class_name; |
664 | error = sysfs_create_link(&dev->parent->kobj, | 665 | |
665 | &dev->kobj, class_name); | 666 | /* |
666 | kfree(class_name); | 667 | * stacked class devices have the 'device' link |
667 | if (error) | 668 | * pointing to the bus device instead of the parent |
668 | goto out_device; | 669 | */ |
669 | } | 670 | while (parent->class && !parent->bus && parent->parent) |
670 | #else | 671 | parent = parent->parent; |
671 | error = sysfs_create_link(&dev->kobj, &dev->parent->kobj, | 672 | |
673 | error = sysfs_create_link(&dev->kobj, | ||
674 | &parent->kobj, | ||
672 | "device"); | 675 | "device"); |
673 | if (error) | 676 | if (error) |
674 | goto out_busid; | 677 | goto out_busid; |
675 | #endif | 678 | |
679 | class_name = make_class_name(dev->class->name, | ||
680 | &dev->kobj); | ||
681 | if (class_name) | ||
682 | error = sysfs_create_link(&dev->parent->kobj, | ||
683 | &dev->kobj, class_name); | ||
684 | kfree(class_name); | ||
685 | if (error) | ||
686 | goto out_device; | ||
676 | } | 687 | } |
677 | return 0; | 688 | return 0; |
678 | 689 | ||
679 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
680 | out_device: | 690 | out_device: |
681 | if (dev->parent) | 691 | if (dev->parent && dev->type != &part_type) |
682 | sysfs_remove_link(&dev->kobj, "device"); | 692 | sysfs_remove_link(&dev->kobj, "device"); |
683 | #endif | ||
684 | out_busid: | 693 | out_busid: |
685 | if (dev->kobj.parent != &dev->class->subsys.kobj) | 694 | if (dev->kobj.parent != &dev->class->subsys.kobj && |
695 | dev->type != &part_type) | ||
686 | sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); | 696 | sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); |
697 | #else | ||
698 | /* link in the class directory pointing to the device */ | ||
699 | error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj, | ||
700 | dev->bus_id); | ||
701 | if (error) | ||
702 | goto out_subsys; | ||
703 | |||
704 | if (dev->parent && dev->type != &part_type) { | ||
705 | error = sysfs_create_link(&dev->kobj, &dev->parent->kobj, | ||
706 | "device"); | ||
707 | if (error) | ||
708 | goto out_busid; | ||
709 | } | ||
710 | return 0; | ||
711 | |||
712 | out_busid: | ||
713 | sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); | ||
714 | #endif | ||
715 | |||
687 | out_subsys: | 716 | out_subsys: |
688 | sysfs_remove_link(&dev->kobj, "subsystem"); | 717 | sysfs_remove_link(&dev->kobj, "subsystem"); |
689 | out: | 718 | out: |
@@ -694,8 +723,9 @@ static void device_remove_class_symlinks(struct device *dev) | |||
694 | { | 723 | { |
695 | if (!dev->class) | 724 | if (!dev->class) |
696 | return; | 725 | return; |
697 | if (dev->parent) { | 726 | |
698 | #ifdef CONFIG_SYSFS_DEPRECATED | 727 | #ifdef CONFIG_SYSFS_DEPRECATED |
728 | if (dev->parent && dev->type != &part_type) { | ||
699 | char *class_name; | 729 | char *class_name; |
700 | 730 | ||
701 | class_name = make_class_name(dev->class->name, &dev->kobj); | 731 | class_name = make_class_name(dev->class->name, &dev->kobj); |
@@ -703,45 +733,59 @@ static void device_remove_class_symlinks(struct device *dev) | |||
703 | sysfs_remove_link(&dev->parent->kobj, class_name); | 733 | sysfs_remove_link(&dev->parent->kobj, class_name); |
704 | kfree(class_name); | 734 | kfree(class_name); |
705 | } | 735 | } |
706 | #endif | ||
707 | sysfs_remove_link(&dev->kobj, "device"); | 736 | sysfs_remove_link(&dev->kobj, "device"); |
708 | } | 737 | } |
709 | if (dev->kobj.parent != &dev->class->subsys.kobj) | 738 | |
739 | if (dev->kobj.parent != &dev->class->subsys.kobj && | ||
740 | dev->type != &part_type) | ||
710 | sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); | 741 | sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); |
742 | #else | ||
743 | if (dev->parent && dev->type != &part_type) | ||
744 | sysfs_remove_link(&dev->kobj, "device"); | ||
745 | |||
746 | sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); | ||
747 | #endif | ||
748 | |||
711 | sysfs_remove_link(&dev->kobj, "subsystem"); | 749 | sysfs_remove_link(&dev->kobj, "subsystem"); |
712 | } | 750 | } |
713 | 751 | ||
714 | /** | 752 | /** |
715 | * device_add - add device to device hierarchy. | 753 | * device_add - add device to device hierarchy. |
716 | * @dev: device. | 754 | * @dev: device. |
717 | * | 755 | * |
718 | * This is part 2 of device_register(), though may be called | 756 | * This is part 2 of device_register(), though may be called |
719 | * separately _iff_ device_initialize() has been called separately. | 757 | * separately _iff_ device_initialize() has been called separately. |
720 | * | 758 | * |
721 | * This adds it to the kobject hierarchy via kobject_add(), adds it | 759 | * This adds it to the kobject hierarchy via kobject_add(), adds it |
722 | * to the global and sibling lists for the device, then | 760 | * to the global and sibling lists for the device, then |
723 | * adds it to the other relevant subsystems of the driver model. | 761 | * adds it to the other relevant subsystems of the driver model. |
724 | */ | 762 | */ |
725 | int device_add(struct device *dev) | 763 | int device_add(struct device *dev) |
726 | { | 764 | { |
727 | struct device *parent = NULL; | 765 | struct device *parent = NULL; |
728 | struct class_interface *class_intf; | 766 | struct class_interface *class_intf; |
729 | int error = -EINVAL; | 767 | int error; |
768 | |||
769 | error = pm_sleep_lock(); | ||
770 | if (error) { | ||
771 | dev_warn(dev, "Suspicious %s during suspend\n", __FUNCTION__); | ||
772 | dump_stack(); | ||
773 | return error; | ||
774 | } | ||
730 | 775 | ||
731 | dev = get_device(dev); | 776 | dev = get_device(dev); |
732 | if (!dev || !strlen(dev->bus_id)) | 777 | if (!dev || !strlen(dev->bus_id)) { |
778 | error = -EINVAL; | ||
733 | goto Error; | 779 | goto Error; |
780 | } | ||
734 | 781 | ||
735 | pr_debug("DEV: registering device: ID = '%s'\n", dev->bus_id); | 782 | pr_debug("device: '%s': %s\n", dev->bus_id, __FUNCTION__); |
736 | 783 | ||
737 | parent = get_device(dev->parent); | 784 | parent = get_device(dev->parent); |
738 | error = setup_parent(dev, parent); | 785 | setup_parent(dev, parent); |
739 | if (error) | ||
740 | goto Error; | ||
741 | 786 | ||
742 | /* first, register with generic layer. */ | 787 | /* first, register with generic layer. */ |
743 | kobject_set_name(&dev->kobj, "%s", dev->bus_id); | 788 | error = kobject_add(&dev->kobj, dev->kobj.parent, "%s", dev->bus_id); |
744 | error = kobject_add(&dev->kobj); | ||
745 | if (error) | 789 | if (error) |
746 | goto Error; | 790 | goto Error; |
747 | 791 | ||
@@ -751,7 +795,7 @@ int device_add(struct device *dev) | |||
751 | 795 | ||
752 | /* notify clients of device entry (new way) */ | 796 | /* notify clients of device entry (new way) */ |
753 | if (dev->bus) | 797 | if (dev->bus) |
754 | blocking_notifier_call_chain(&dev->bus->bus_notifier, | 798 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, |
755 | BUS_NOTIFY_ADD_DEVICE, dev); | 799 | BUS_NOTIFY_ADD_DEVICE, dev); |
756 | 800 | ||
757 | error = device_create_file(dev, &uevent_attr); | 801 | error = device_create_file(dev, &uevent_attr); |
@@ -795,13 +839,14 @@ int device_add(struct device *dev) | |||
795 | } | 839 | } |
796 | Done: | 840 | Done: |
797 | put_device(dev); | 841 | put_device(dev); |
842 | pm_sleep_unlock(); | ||
798 | return error; | 843 | return error; |
799 | BusError: | 844 | BusError: |
800 | device_pm_remove(dev); | 845 | device_pm_remove(dev); |
801 | dpm_sysfs_remove(dev); | 846 | dpm_sysfs_remove(dev); |
802 | PMError: | 847 | PMError: |
803 | if (dev->bus) | 848 | if (dev->bus) |
804 | blocking_notifier_call_chain(&dev->bus->bus_notifier, | 849 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, |
805 | BUS_NOTIFY_DEL_DEVICE, dev); | 850 | BUS_NOTIFY_DEL_DEVICE, dev); |
806 | device_remove_attrs(dev); | 851 | device_remove_attrs(dev); |
807 | AttrsError: | 852 | AttrsError: |
@@ -809,124 +854,84 @@ int device_add(struct device *dev) | |||
809 | SymlinkError: | 854 | SymlinkError: |
810 | if (MAJOR(dev->devt)) | 855 | if (MAJOR(dev->devt)) |
811 | device_remove_file(dev, &devt_attr); | 856 | device_remove_file(dev, &devt_attr); |
812 | |||
813 | if (dev->class) { | ||
814 | sysfs_remove_link(&dev->kobj, "subsystem"); | ||
815 | /* If this is not a "fake" compatible device, remove the | ||
816 | * symlink from the class to the device. */ | ||
817 | if (dev->kobj.parent != &dev->class->subsys.kobj) | ||
818 | sysfs_remove_link(&dev->class->subsys.kobj, | ||
819 | dev->bus_id); | ||
820 | if (parent) { | ||
821 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
822 | char *class_name = make_class_name(dev->class->name, | ||
823 | &dev->kobj); | ||
824 | if (class_name) | ||
825 | sysfs_remove_link(&dev->parent->kobj, | ||
826 | class_name); | ||
827 | kfree(class_name); | ||
828 | #endif | ||
829 | sysfs_remove_link(&dev->kobj, "device"); | ||
830 | } | ||
831 | } | ||
832 | ueventattrError: | 857 | ueventattrError: |
833 | device_remove_file(dev, &uevent_attr); | 858 | device_remove_file(dev, &uevent_attr); |
834 | attrError: | 859 | attrError: |
835 | kobject_uevent(&dev->kobj, KOBJ_REMOVE); | 860 | kobject_uevent(&dev->kobj, KOBJ_REMOVE); |
836 | kobject_del(&dev->kobj); | 861 | kobject_del(&dev->kobj); |
837 | Error: | 862 | Error: |
863 | cleanup_device_parent(dev); | ||
838 | if (parent) | 864 | if (parent) |
839 | put_device(parent); | 865 | put_device(parent); |
840 | goto Done; | 866 | goto Done; |
841 | } | 867 | } |
842 | 868 | ||
843 | |||
844 | /** | 869 | /** |
845 | * device_register - register a device with the system. | 870 | * device_register - register a device with the system. |
846 | * @dev: pointer to the device structure | 871 | * @dev: pointer to the device structure |
847 | * | 872 | * |
848 | * This happens in two clean steps - initialize the device | 873 | * This happens in two clean steps - initialize the device |
849 | * and add it to the system. The two steps can be called | 874 | * and add it to the system. The two steps can be called |
850 | * separately, but this is the easiest and most common. | 875 | * separately, but this is the easiest and most common. |
851 | * I.e. you should only call the two helpers separately if | 876 | * I.e. you should only call the two helpers separately if |
852 | * have a clearly defined need to use and refcount the device | 877 | * have a clearly defined need to use and refcount the device |
853 | * before it is added to the hierarchy. | 878 | * before it is added to the hierarchy. |
854 | */ | 879 | */ |
855 | |||
856 | int device_register(struct device *dev) | 880 | int device_register(struct device *dev) |
857 | { | 881 | { |
858 | device_initialize(dev); | 882 | device_initialize(dev); |
859 | return device_add(dev); | 883 | return device_add(dev); |
860 | } | 884 | } |
861 | 885 | ||
862 | |||
863 | /** | 886 | /** |
864 | * get_device - increment reference count for device. | 887 | * get_device - increment reference count for device. |
865 | * @dev: device. | 888 | * @dev: device. |
866 | * | 889 | * |
867 | * This simply forwards the call to kobject_get(), though | 890 | * This simply forwards the call to kobject_get(), though |
868 | * we do take care to provide for the case that we get a NULL | 891 | * we do take care to provide for the case that we get a NULL |
869 | * pointer passed in. | 892 | * pointer passed in. |
870 | */ | 893 | */ |
871 | 894 | struct device *get_device(struct device *dev) | |
872 | struct device * get_device(struct device * dev) | ||
873 | { | 895 | { |
874 | return dev ? to_dev(kobject_get(&dev->kobj)) : NULL; | 896 | return dev ? to_dev(kobject_get(&dev->kobj)) : NULL; |
875 | } | 897 | } |
876 | 898 | ||
877 | |||
878 | /** | 899 | /** |
879 | * put_device - decrement reference count. | 900 | * put_device - decrement reference count. |
880 | * @dev: device in question. | 901 | * @dev: device in question. |
881 | */ | 902 | */ |
882 | void put_device(struct device * dev) | 903 | void put_device(struct device *dev) |
883 | { | 904 | { |
905 | /* might_sleep(); */ | ||
884 | if (dev) | 906 | if (dev) |
885 | kobject_put(&dev->kobj); | 907 | kobject_put(&dev->kobj); |
886 | } | 908 | } |
887 | 909 | ||
888 | |||
889 | /** | 910 | /** |
890 | * device_del - delete device from system. | 911 | * device_del - delete device from system. |
891 | * @dev: device. | 912 | * @dev: device. |
892 | * | 913 | * |
893 | * This is the first part of the device unregistration | 914 | * This is the first part of the device unregistration |
894 | * sequence. This removes the device from the lists we control | 915 | * sequence. This removes the device from the lists we control |
895 | * from here, has it removed from the other driver model | 916 | * from here, has it removed from the other driver model |
896 | * subsystems it was added to in device_add(), and removes it | 917 | * subsystems it was added to in device_add(), and removes it |
897 | * from the kobject hierarchy. | 918 | * from the kobject hierarchy. |
898 | * | 919 | * |
899 | * NOTE: this should be called manually _iff_ device_add() was | 920 | * NOTE: this should be called manually _iff_ device_add() was |
900 | * also called manually. | 921 | * also called manually. |
901 | */ | 922 | */ |
902 | 923 | void device_del(struct device *dev) | |
903 | void device_del(struct device * dev) | ||
904 | { | 924 | { |
905 | struct device * parent = dev->parent; | 925 | struct device *parent = dev->parent; |
906 | struct class_interface *class_intf; | 926 | struct class_interface *class_intf; |
907 | 927 | ||
928 | device_pm_remove(dev); | ||
908 | if (parent) | 929 | if (parent) |
909 | klist_del(&dev->knode_parent); | 930 | klist_del(&dev->knode_parent); |
910 | if (MAJOR(dev->devt)) | 931 | if (MAJOR(dev->devt)) |
911 | device_remove_file(dev, &devt_attr); | 932 | device_remove_file(dev, &devt_attr); |
912 | if (dev->class) { | 933 | if (dev->class) { |
913 | sysfs_remove_link(&dev->kobj, "subsystem"); | 934 | device_remove_class_symlinks(dev); |
914 | /* If this is not a "fake" compatible device, remove the | ||
915 | * symlink from the class to the device. */ | ||
916 | if (dev->kobj.parent != &dev->class->subsys.kobj) | ||
917 | sysfs_remove_link(&dev->class->subsys.kobj, | ||
918 | dev->bus_id); | ||
919 | if (parent) { | ||
920 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
921 | char *class_name = make_class_name(dev->class->name, | ||
922 | &dev->kobj); | ||
923 | if (class_name) | ||
924 | sysfs_remove_link(&dev->parent->kobj, | ||
925 | class_name); | ||
926 | kfree(class_name); | ||
927 | #endif | ||
928 | sysfs_remove_link(&dev->kobj, "device"); | ||
929 | } | ||
930 | 935 | ||
931 | down(&dev->class->sem); | 936 | down(&dev->class->sem); |
932 | /* notify any interfaces that the device is now gone */ | 937 | /* notify any interfaces that the device is now gone */ |
@@ -936,31 +941,6 @@ void device_del(struct device * dev) | |||
936 | /* remove the device from the class list */ | 941 | /* remove the device from the class list */ |
937 | list_del_init(&dev->node); | 942 | list_del_init(&dev->node); |
938 | up(&dev->class->sem); | 943 | up(&dev->class->sem); |
939 | |||
940 | /* If we live in a parent class-directory, unreference it */ | ||
941 | if (dev->kobj.parent->kset == &dev->class->class_dirs) { | ||
942 | struct device *d; | ||
943 | int other = 0; | ||
944 | |||
945 | /* | ||
946 | * if we are the last child of our class, delete | ||
947 | * our class-directory at this parent | ||
948 | */ | ||
949 | down(&dev->class->sem); | ||
950 | list_for_each_entry(d, &dev->class->devices, node) { | ||
951 | if (d == dev) | ||
952 | continue; | ||
953 | if (d->kobj.parent == dev->kobj.parent) { | ||
954 | other = 1; | ||
955 | break; | ||
956 | } | ||
957 | } | ||
958 | if (!other) | ||
959 | kobject_del(dev->kobj.parent); | ||
960 | |||
961 | kobject_put(dev->kobj.parent); | ||
962 | up(&dev->class->sem); | ||
963 | } | ||
964 | } | 944 | } |
965 | device_remove_file(dev, &uevent_attr); | 945 | device_remove_file(dev, &uevent_attr); |
966 | device_remove_attrs(dev); | 946 | device_remove_attrs(dev); |
@@ -979,57 +959,55 @@ void device_del(struct device * dev) | |||
979 | if (platform_notify_remove) | 959 | if (platform_notify_remove) |
980 | platform_notify_remove(dev); | 960 | platform_notify_remove(dev); |
981 | if (dev->bus) | 961 | if (dev->bus) |
982 | blocking_notifier_call_chain(&dev->bus->bus_notifier, | 962 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, |
983 | BUS_NOTIFY_DEL_DEVICE, dev); | 963 | BUS_NOTIFY_DEL_DEVICE, dev); |
984 | device_pm_remove(dev); | ||
985 | kobject_uevent(&dev->kobj, KOBJ_REMOVE); | 964 | kobject_uevent(&dev->kobj, KOBJ_REMOVE); |
965 | cleanup_device_parent(dev); | ||
986 | kobject_del(&dev->kobj); | 966 | kobject_del(&dev->kobj); |
987 | if (parent) | 967 | put_device(parent); |
988 | put_device(parent); | ||
989 | } | 968 | } |
990 | 969 | ||
991 | /** | 970 | /** |
992 | * device_unregister - unregister device from system. | 971 | * device_unregister - unregister device from system. |
993 | * @dev: device going away. | 972 | * @dev: device going away. |
994 | * | 973 | * |
995 | * We do this in two parts, like we do device_register(). First, | 974 | * We do this in two parts, like we do device_register(). First, |
996 | * we remove it from all the subsystems with device_del(), then | 975 | * we remove it from all the subsystems with device_del(), then |
997 | * we decrement the reference count via put_device(). If that | 976 | * we decrement the reference count via put_device(). If that |
998 | * is the final reference count, the device will be cleaned up | 977 | * is the final reference count, the device will be cleaned up |
999 | * via device_release() above. Otherwise, the structure will | 978 | * via device_release() above. Otherwise, the structure will |
1000 | * stick around until the final reference to the device is dropped. | 979 | * stick around until the final reference to the device is dropped. |
1001 | */ | 980 | */ |
1002 | void device_unregister(struct device * dev) | 981 | void device_unregister(struct device *dev) |
1003 | { | 982 | { |
1004 | pr_debug("DEV: Unregistering device. ID = '%s'\n", dev->bus_id); | 983 | pr_debug("device: '%s': %s\n", dev->bus_id, __FUNCTION__); |
1005 | device_del(dev); | 984 | device_del(dev); |
1006 | put_device(dev); | 985 | put_device(dev); |
1007 | } | 986 | } |
1008 | 987 | ||
1009 | 988 | static struct device *next_device(struct klist_iter *i) | |
1010 | static struct device * next_device(struct klist_iter * i) | ||
1011 | { | 989 | { |
1012 | struct klist_node * n = klist_next(i); | 990 | struct klist_node *n = klist_next(i); |
1013 | return n ? container_of(n, struct device, knode_parent) : NULL; | 991 | return n ? container_of(n, struct device, knode_parent) : NULL; |
1014 | } | 992 | } |
1015 | 993 | ||
1016 | /** | 994 | /** |
1017 | * device_for_each_child - device child iterator. | 995 | * device_for_each_child - device child iterator. |
1018 | * @parent: parent struct device. | 996 | * @parent: parent struct device. |
1019 | * @data: data for the callback. | 997 | * @data: data for the callback. |
1020 | * @fn: function to be called for each device. | 998 | * @fn: function to be called for each device. |
1021 | * | 999 | * |
1022 | * Iterate over @parent's child devices, and call @fn for each, | 1000 | * Iterate over @parent's child devices, and call @fn for each, |
1023 | * passing it @data. | 1001 | * passing it @data. |
1024 | * | 1002 | * |
1025 | * We check the return of @fn each time. If it returns anything | 1003 | * We check the return of @fn each time. If it returns anything |
1026 | * other than 0, we break out and return that value. | 1004 | * other than 0, we break out and return that value. |
1027 | */ | 1005 | */ |
1028 | int device_for_each_child(struct device * parent, void * data, | 1006 | int device_for_each_child(struct device *parent, void *data, |
1029 | int (*fn)(struct device *, void *)) | 1007 | int (*fn)(struct device *dev, void *data)) |
1030 | { | 1008 | { |
1031 | struct klist_iter i; | 1009 | struct klist_iter i; |
1032 | struct device * child; | 1010 | struct device *child; |
1033 | int error = 0; | 1011 | int error = 0; |
1034 | 1012 | ||
1035 | klist_iter_init(&parent->klist_children, &i); | 1013 | klist_iter_init(&parent->klist_children, &i); |
@@ -1054,8 +1032,8 @@ int device_for_each_child(struct device * parent, void * data, | |||
1054 | * current device can be obtained, this function will return to the caller | 1032 | * current device can be obtained, this function will return to the caller |
1055 | * and not iterate over any more devices. | 1033 | * and not iterate over any more devices. |
1056 | */ | 1034 | */ |
1057 | struct device * device_find_child(struct device *parent, void *data, | 1035 | struct device *device_find_child(struct device *parent, void *data, |
1058 | int (*match)(struct device *, void *)) | 1036 | int (*match)(struct device *dev, void *data)) |
1059 | { | 1037 | { |
1060 | struct klist_iter i; | 1038 | struct klist_iter i; |
1061 | struct device *child; | 1039 | struct device *child; |
@@ -1073,7 +1051,10 @@ struct device * device_find_child(struct device *parent, void *data, | |||
1073 | 1051 | ||
1074 | int __init devices_init(void) | 1052 | int __init devices_init(void) |
1075 | { | 1053 | { |
1076 | return subsystem_register(&devices_subsys); | 1054 | devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL); |
1055 | if (!devices_kset) | ||
1056 | return -ENOMEM; | ||
1057 | return 0; | ||
1077 | } | 1058 | } |
1078 | 1059 | ||
1079 | EXPORT_SYMBOL_GPL(device_for_each_child); | 1060 | EXPORT_SYMBOL_GPL(device_for_each_child); |
@@ -1094,7 +1075,7 @@ EXPORT_SYMBOL_GPL(device_remove_file); | |||
1094 | 1075 | ||
1095 | static void device_create_release(struct device *dev) | 1076 | static void device_create_release(struct device *dev) |
1096 | { | 1077 | { |
1097 | pr_debug("%s called for %s\n", __FUNCTION__, dev->bus_id); | 1078 | pr_debug("device: '%s': %s\n", dev->bus_id, __FUNCTION__); |
1098 | kfree(dev); | 1079 | kfree(dev); |
1099 | } | 1080 | } |
1100 | 1081 | ||
@@ -1156,14 +1137,11 @@ error: | |||
1156 | EXPORT_SYMBOL_GPL(device_create); | 1137 | EXPORT_SYMBOL_GPL(device_create); |
1157 | 1138 | ||
1158 | /** | 1139 | /** |
1159 | * device_destroy - removes a device that was created with device_create() | 1140 | * find_device - finds a device that was created with device_create() |
1160 | * @class: pointer to the struct class that this device was registered with | 1141 | * @class: pointer to the struct class that this device was registered with |
1161 | * @devt: the dev_t of the device that was previously registered | 1142 | * @devt: the dev_t of the device that was previously registered |
1162 | * | ||
1163 | * This call unregisters and cleans up a device that was created with a | ||
1164 | * call to device_create(). | ||
1165 | */ | 1143 | */ |
1166 | void device_destroy(struct class *class, dev_t devt) | 1144 | static struct device *find_device(struct class *class, dev_t devt) |
1167 | { | 1145 | { |
1168 | struct device *dev = NULL; | 1146 | struct device *dev = NULL; |
1169 | struct device *dev_tmp; | 1147 | struct device *dev_tmp; |
@@ -1176,12 +1154,54 @@ void device_destroy(struct class *class, dev_t devt) | |||
1176 | } | 1154 | } |
1177 | } | 1155 | } |
1178 | up(&class->sem); | 1156 | up(&class->sem); |
1157 | return dev; | ||
1158 | } | ||
1159 | |||
1160 | /** | ||
1161 | * device_destroy - removes a device that was created with device_create() | ||
1162 | * @class: pointer to the struct class that this device was registered with | ||
1163 | * @devt: the dev_t of the device that was previously registered | ||
1164 | * | ||
1165 | * This call unregisters and cleans up a device that was created with a | ||
1166 | * call to device_create(). | ||
1167 | */ | ||
1168 | void device_destroy(struct class *class, dev_t devt) | ||
1169 | { | ||
1170 | struct device *dev; | ||
1179 | 1171 | ||
1172 | dev = find_device(class, devt); | ||
1180 | if (dev) | 1173 | if (dev) |
1181 | device_unregister(dev); | 1174 | device_unregister(dev); |
1182 | } | 1175 | } |
1183 | EXPORT_SYMBOL_GPL(device_destroy); | 1176 | EXPORT_SYMBOL_GPL(device_destroy); |
1184 | 1177 | ||
1178 | #ifdef CONFIG_PM_SLEEP | ||
1179 | /** | ||
1180 | * destroy_suspended_device - asks the PM core to remove a suspended device | ||
1181 | * @class: pointer to the struct class that this device was registered with | ||
1182 | * @devt: the dev_t of the device that was previously registered | ||
1183 | * | ||
1184 | * This call notifies the PM core of the necessity to unregister a suspended | ||
1185 | * device created with a call to device_create() (devices cannot be | ||
1186 | * unregistered directly while suspended, since the PM core holds their | ||
1187 | * semaphores at that time). | ||
1188 | * | ||
1189 | * It can only be called within the scope of a system sleep transition. In | ||
1190 | * practice this means it has to be directly or indirectly invoked either by | ||
1191 | * a suspend or resume method, or by the PM core (e.g. via | ||
1192 | * disable_nonboot_cpus() or enable_nonboot_cpus()). | ||
1193 | */ | ||
1194 | void destroy_suspended_device(struct class *class, dev_t devt) | ||
1195 | { | ||
1196 | struct device *dev; | ||
1197 | |||
1198 | dev = find_device(class, devt); | ||
1199 | if (dev) | ||
1200 | device_pm_schedule_removal(dev); | ||
1201 | } | ||
1202 | EXPORT_SYMBOL_GPL(destroy_suspended_device); | ||
1203 | #endif /* CONFIG_PM_SLEEP */ | ||
1204 | |||
1185 | /** | 1205 | /** |
1186 | * device_rename - renames a device | 1206 | * device_rename - renames a device |
1187 | * @dev: the pointer to the struct device to be renamed | 1207 | * @dev: the pointer to the struct device to be renamed |
@@ -1198,7 +1218,8 @@ int device_rename(struct device *dev, char *new_name) | |||
1198 | if (!dev) | 1218 | if (!dev) |
1199 | return -EINVAL; | 1219 | return -EINVAL; |
1200 | 1220 | ||
1201 | pr_debug("DEVICE: renaming '%s' to '%s'\n", dev->bus_id, new_name); | 1221 | pr_debug("device: '%s': %s: renaming to '%s'\n", dev->bus_id, |
1222 | __FUNCTION__, new_name); | ||
1202 | 1223 | ||
1203 | #ifdef CONFIG_SYSFS_DEPRECATED | 1224 | #ifdef CONFIG_SYSFS_DEPRECATED |
1204 | if ((dev->class) && (dev->parent)) | 1225 | if ((dev->class) && (dev->parent)) |
@@ -1279,8 +1300,7 @@ static int device_move_class_links(struct device *dev, | |||
1279 | class_name); | 1300 | class_name); |
1280 | if (error) | 1301 | if (error) |
1281 | sysfs_remove_link(&dev->kobj, "device"); | 1302 | sysfs_remove_link(&dev->kobj, "device"); |
1282 | } | 1303 | } else |
1283 | else | ||
1284 | error = 0; | 1304 | error = 0; |
1285 | out: | 1305 | out: |
1286 | kfree(class_name); | 1306 | kfree(class_name); |
@@ -1311,16 +1331,13 @@ int device_move(struct device *dev, struct device *new_parent) | |||
1311 | return -EINVAL; | 1331 | return -EINVAL; |
1312 | 1332 | ||
1313 | new_parent = get_device(new_parent); | 1333 | new_parent = get_device(new_parent); |
1314 | new_parent_kobj = get_device_parent (dev, new_parent); | 1334 | new_parent_kobj = get_device_parent(dev, new_parent); |
1315 | if (IS_ERR(new_parent_kobj)) { | 1335 | |
1316 | error = PTR_ERR(new_parent_kobj); | 1336 | pr_debug("device: '%s': %s: moving to '%s'\n", dev->bus_id, |
1317 | put_device(new_parent); | 1337 | __FUNCTION__, new_parent ? new_parent->bus_id : "<NULL>"); |
1318 | goto out; | ||
1319 | } | ||
1320 | pr_debug("DEVICE: moving '%s' to '%s'\n", dev->bus_id, | ||
1321 | new_parent ? new_parent->bus_id : "<NULL>"); | ||
1322 | error = kobject_move(&dev->kobj, new_parent_kobj); | 1338 | error = kobject_move(&dev->kobj, new_parent_kobj); |
1323 | if (error) { | 1339 | if (error) { |
1340 | cleanup_glue_dir(dev, new_parent_kobj); | ||
1324 | put_device(new_parent); | 1341 | put_device(new_parent); |
1325 | goto out; | 1342 | goto out; |
1326 | } | 1343 | } |
@@ -1343,6 +1360,7 @@ int device_move(struct device *dev, struct device *new_parent) | |||
1343 | klist_add_tail(&dev->knode_parent, | 1360 | klist_add_tail(&dev->knode_parent, |
1344 | &old_parent->klist_children); | 1361 | &old_parent->klist_children); |
1345 | } | 1362 | } |
1363 | cleanup_glue_dir(dev, new_parent_kobj); | ||
1346 | put_device(new_parent); | 1364 | put_device(new_parent); |
1347 | goto out; | 1365 | goto out; |
1348 | } | 1366 | } |
@@ -1352,5 +1370,23 @@ out: | |||
1352 | put_device(dev); | 1370 | put_device(dev); |
1353 | return error; | 1371 | return error; |
1354 | } | 1372 | } |
1355 | |||
1356 | EXPORT_SYMBOL_GPL(device_move); | 1373 | EXPORT_SYMBOL_GPL(device_move); |
1374 | |||
1375 | /** | ||
1376 | * device_shutdown - call ->shutdown() on each device to shutdown. | ||
1377 | */ | ||
1378 | void device_shutdown(void) | ||
1379 | { | ||
1380 | struct device *dev, *devn; | ||
1381 | |||
1382 | list_for_each_entry_safe_reverse(dev, devn, &devices_kset->list, | ||
1383 | kobj.entry) { | ||
1384 | if (dev->bus && dev->bus->shutdown) { | ||
1385 | dev_dbg(dev, "shutdown\n"); | ||
1386 | dev->bus->shutdown(dev); | ||
1387 | } else if (dev->driver && dev->driver->shutdown) { | ||
1388 | dev_dbg(dev, "shutdown\n"); | ||
1389 | dev->driver->shutdown(dev); | ||
1390 | } | ||
1391 | } | ||
1392 | } | ||
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 40545071e3c9..c5885f5ce0ac 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include "base.h" | 14 | #include "base.h" |
15 | 15 | ||
16 | struct sysdev_class cpu_sysdev_class = { | 16 | struct sysdev_class cpu_sysdev_class = { |
17 | set_kset_name("cpu"), | 17 | .name = "cpu", |
18 | }; | 18 | }; |
19 | EXPORT_SYMBOL(cpu_sysdev_class); | 19 | EXPORT_SYMBOL(cpu_sysdev_class); |
20 | 20 | ||
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 7ac474db88c5..a5cde94bb982 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -1,18 +1,20 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/base/dd.c - The core device/driver interactions. | 2 | * drivers/base/dd.c - The core device/driver interactions. |
3 | * | 3 | * |
4 | * This file contains the (sometimes tricky) code that controls the | 4 | * This file contains the (sometimes tricky) code that controls the |
5 | * interactions between devices and drivers, which primarily includes | 5 | * interactions between devices and drivers, which primarily includes |
6 | * driver binding and unbinding. | 6 | * driver binding and unbinding. |
7 | * | 7 | * |
8 | * All of this code used to exist in drivers/base/bus.c, but was | 8 | * All of this code used to exist in drivers/base/bus.c, but was |
9 | * relocated to here in the name of compartmentalization (since it wasn't | 9 | * relocated to here in the name of compartmentalization (since it wasn't |
10 | * strictly code just for the 'struct bus_type'. | 10 | * strictly code just for the 'struct bus_type'. |
11 | * | 11 | * |
12 | * Copyright (c) 2002-5 Patrick Mochel | 12 | * Copyright (c) 2002-5 Patrick Mochel |
13 | * Copyright (c) 2002-3 Open Source Development Labs | 13 | * Copyright (c) 2002-3 Open Source Development Labs |
14 | * Copyright (c) 2007 Greg Kroah-Hartman <gregkh@suse.de> | ||
15 | * Copyright (c) 2007 Novell Inc. | ||
14 | * | 16 | * |
15 | * This file is released under the GPLv2 | 17 | * This file is released under the GPLv2 |
16 | */ | 18 | */ |
17 | 19 | ||
18 | #include <linux/device.h> | 20 | #include <linux/device.h> |
@@ -23,8 +25,6 @@ | |||
23 | #include "base.h" | 25 | #include "base.h" |
24 | #include "power/power.h" | 26 | #include "power/power.h" |
25 | 27 | ||
26 | #define to_drv(node) container_of(node, struct device_driver, kobj.entry) | ||
27 | |||
28 | 28 | ||
29 | static void driver_bound(struct device *dev) | 29 | static void driver_bound(struct device *dev) |
30 | { | 30 | { |
@@ -34,27 +34,27 @@ static void driver_bound(struct device *dev) | |||
34 | return; | 34 | return; |
35 | } | 35 | } |
36 | 36 | ||
37 | pr_debug("bound device '%s' to driver '%s'\n", | 37 | pr_debug("driver: '%s': %s: bound to device '%s'\n", dev->bus_id, |
38 | dev->bus_id, dev->driver->name); | 38 | __FUNCTION__, dev->driver->name); |
39 | 39 | ||
40 | if (dev->bus) | 40 | if (dev->bus) |
41 | blocking_notifier_call_chain(&dev->bus->bus_notifier, | 41 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, |
42 | BUS_NOTIFY_BOUND_DRIVER, dev); | 42 | BUS_NOTIFY_BOUND_DRIVER, dev); |
43 | 43 | ||
44 | klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices); | 44 | klist_add_tail(&dev->knode_driver, &dev->driver->p->klist_devices); |
45 | } | 45 | } |
46 | 46 | ||
47 | static int driver_sysfs_add(struct device *dev) | 47 | static int driver_sysfs_add(struct device *dev) |
48 | { | 48 | { |
49 | int ret; | 49 | int ret; |
50 | 50 | ||
51 | ret = sysfs_create_link(&dev->driver->kobj, &dev->kobj, | 51 | ret = sysfs_create_link(&dev->driver->p->kobj, &dev->kobj, |
52 | kobject_name(&dev->kobj)); | 52 | kobject_name(&dev->kobj)); |
53 | if (ret == 0) { | 53 | if (ret == 0) { |
54 | ret = sysfs_create_link(&dev->kobj, &dev->driver->kobj, | 54 | ret = sysfs_create_link(&dev->kobj, &dev->driver->p->kobj, |
55 | "driver"); | 55 | "driver"); |
56 | if (ret) | 56 | if (ret) |
57 | sysfs_remove_link(&dev->driver->kobj, | 57 | sysfs_remove_link(&dev->driver->p->kobj, |
58 | kobject_name(&dev->kobj)); | 58 | kobject_name(&dev->kobj)); |
59 | } | 59 | } |
60 | return ret; | 60 | return ret; |
@@ -65,24 +65,24 @@ static void driver_sysfs_remove(struct device *dev) | |||
65 | struct device_driver *drv = dev->driver; | 65 | struct device_driver *drv = dev->driver; |
66 | 66 | ||
67 | if (drv) { | 67 | if (drv) { |
68 | sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj)); | 68 | sysfs_remove_link(&drv->p->kobj, kobject_name(&dev->kobj)); |
69 | sysfs_remove_link(&dev->kobj, "driver"); | 69 | sysfs_remove_link(&dev->kobj, "driver"); |
70 | } | 70 | } |
71 | } | 71 | } |
72 | 72 | ||
73 | /** | 73 | /** |
74 | * device_bind_driver - bind a driver to one device. | 74 | * device_bind_driver - bind a driver to one device. |
75 | * @dev: device. | 75 | * @dev: device. |
76 | * | 76 | * |
77 | * Allow manual attachment of a driver to a device. | 77 | * Allow manual attachment of a driver to a device. |
78 | * Caller must have already set @dev->driver. | 78 | * Caller must have already set @dev->driver. |
79 | * | 79 | * |
80 | * Note that this does not modify the bus reference count | 80 | * Note that this does not modify the bus reference count |
81 | * nor take the bus's rwsem. Please verify those are accounted | 81 | * nor take the bus's rwsem. Please verify those are accounted |
82 | * for before calling this. (It is ok to call with no other effort | 82 | * for before calling this. (It is ok to call with no other effort |
83 | * from a driver's probe() method.) | 83 | * from a driver's probe() method.) |
84 | * | 84 | * |
85 | * This function must be called with @dev->sem held. | 85 | * This function must be called with @dev->sem held. |
86 | */ | 86 | */ |
87 | int device_bind_driver(struct device *dev) | 87 | int device_bind_driver(struct device *dev) |
88 | { | 88 | { |
@@ -93,6 +93,7 @@ int device_bind_driver(struct device *dev) | |||
93 | driver_bound(dev); | 93 | driver_bound(dev); |
94 | return ret; | 94 | return ret; |
95 | } | 95 | } |
96 | EXPORT_SYMBOL_GPL(device_bind_driver); | ||
96 | 97 | ||
97 | static atomic_t probe_count = ATOMIC_INIT(0); | 98 | static atomic_t probe_count = ATOMIC_INIT(0); |
98 | static DECLARE_WAIT_QUEUE_HEAD(probe_waitqueue); | 99 | static DECLARE_WAIT_QUEUE_HEAD(probe_waitqueue); |
@@ -102,8 +103,8 @@ static int really_probe(struct device *dev, struct device_driver *drv) | |||
102 | int ret = 0; | 103 | int ret = 0; |
103 | 104 | ||
104 | atomic_inc(&probe_count); | 105 | atomic_inc(&probe_count); |
105 | pr_debug("%s: Probing driver %s with device %s\n", | 106 | pr_debug("bus: '%s': %s: probing driver %s with device %s\n", |
106 | drv->bus->name, drv->name, dev->bus_id); | 107 | drv->bus->name, __FUNCTION__, drv->name, dev->bus_id); |
107 | WARN_ON(!list_empty(&dev->devres_head)); | 108 | WARN_ON(!list_empty(&dev->devres_head)); |
108 | 109 | ||
109 | dev->driver = drv; | 110 | dev->driver = drv; |
@@ -125,8 +126,8 @@ static int really_probe(struct device *dev, struct device_driver *drv) | |||
125 | 126 | ||
126 | driver_bound(dev); | 127 | driver_bound(dev); |
127 | ret = 1; | 128 | ret = 1; |
128 | pr_debug("%s: Bound Device %s to Driver %s\n", | 129 | pr_debug("bus: '%s': %s: bound device %s to driver %s\n", |
129 | drv->bus->name, dev->bus_id, drv->name); | 130 | drv->bus->name, __FUNCTION__, dev->bus_id, drv->name); |
130 | goto done; | 131 | goto done; |
131 | 132 | ||
132 | probe_failed: | 133 | probe_failed: |
@@ -183,7 +184,7 @@ int driver_probe_done(void) | |||
183 | * This function must be called with @dev->sem held. When called for a | 184 | * This function must be called with @dev->sem held. When called for a |
184 | * USB interface, @dev->parent->sem must be held as well. | 185 | * USB interface, @dev->parent->sem must be held as well. |
185 | */ | 186 | */ |
186 | int driver_probe_device(struct device_driver * drv, struct device * dev) | 187 | int driver_probe_device(struct device_driver *drv, struct device *dev) |
187 | { | 188 | { |
188 | int ret = 0; | 189 | int ret = 0; |
189 | 190 | ||
@@ -192,8 +193,8 @@ int driver_probe_device(struct device_driver * drv, struct device * dev) | |||
192 | if (drv->bus->match && !drv->bus->match(dev, drv)) | 193 | if (drv->bus->match && !drv->bus->match(dev, drv)) |
193 | goto done; | 194 | goto done; |
194 | 195 | ||
195 | pr_debug("%s: Matched Device %s with Driver %s\n", | 196 | pr_debug("bus: '%s': %s: matched device %s with driver %s\n", |
196 | drv->bus->name, dev->bus_id, drv->name); | 197 | drv->bus->name, __FUNCTION__, dev->bus_id, drv->name); |
197 | 198 | ||
198 | ret = really_probe(dev, drv); | 199 | ret = really_probe(dev, drv); |
199 | 200 | ||
@@ -201,27 +202,27 @@ done: | |||
201 | return ret; | 202 | return ret; |
202 | } | 203 | } |
203 | 204 | ||
204 | static int __device_attach(struct device_driver * drv, void * data) | 205 | static int __device_attach(struct device_driver *drv, void *data) |
205 | { | 206 | { |
206 | struct device * dev = data; | 207 | struct device *dev = data; |
207 | return driver_probe_device(drv, dev); | 208 | return driver_probe_device(drv, dev); |
208 | } | 209 | } |
209 | 210 | ||
210 | /** | 211 | /** |
211 | * device_attach - try to attach device to a driver. | 212 | * device_attach - try to attach device to a driver. |
212 | * @dev: device. | 213 | * @dev: device. |
213 | * | 214 | * |
214 | * Walk the list of drivers that the bus has and call | 215 | * Walk the list of drivers that the bus has and call |
215 | * driver_probe_device() for each pair. If a compatible | 216 | * driver_probe_device() for each pair. If a compatible |
216 | * pair is found, break out and return. | 217 | * pair is found, break out and return. |
217 | * | 218 | * |
218 | * Returns 1 if the device was bound to a driver; | 219 | * Returns 1 if the device was bound to a driver; |
219 | * 0 if no matching device was found; | 220 | * 0 if no matching device was found; |
220 | * -ENODEV if the device is not registered. | 221 | * -ENODEV if the device is not registered. |
221 | * | 222 | * |
222 | * When called for a USB interface, @dev->parent->sem must be held. | 223 | * When called for a USB interface, @dev->parent->sem must be held. |
223 | */ | 224 | */ |
224 | int device_attach(struct device * dev) | 225 | int device_attach(struct device *dev) |
225 | { | 226 | { |
226 | int ret = 0; | 227 | int ret = 0; |
227 | 228 | ||
@@ -240,10 +241,11 @@ int device_attach(struct device * dev) | |||
240 | up(&dev->sem); | 241 | up(&dev->sem); |
241 | return ret; | 242 | return ret; |
242 | } | 243 | } |
244 | EXPORT_SYMBOL_GPL(device_attach); | ||
243 | 245 | ||
244 | static int __driver_attach(struct device * dev, void * data) | 246 | static int __driver_attach(struct device *dev, void *data) |
245 | { | 247 | { |
246 | struct device_driver * drv = data; | 248 | struct device_driver *drv = data; |
247 | 249 | ||
248 | /* | 250 | /* |
249 | * Lock device and try to bind to it. We drop the error | 251 | * Lock device and try to bind to it. We drop the error |
@@ -268,35 +270,35 @@ static int __driver_attach(struct device * dev, void * data) | |||
268 | } | 270 | } |
269 | 271 | ||
270 | /** | 272 | /** |
271 | * driver_attach - try to bind driver to devices. | 273 | * driver_attach - try to bind driver to devices. |
272 | * @drv: driver. | 274 | * @drv: driver. |
273 | * | 275 | * |
274 | * Walk the list of devices that the bus has on it and try to | 276 | * Walk the list of devices that the bus has on it and try to |
275 | * match the driver with each one. If driver_probe_device() | 277 | * match the driver with each one. If driver_probe_device() |
276 | * returns 0 and the @dev->driver is set, we've found a | 278 | * returns 0 and the @dev->driver is set, we've found a |
277 | * compatible pair. | 279 | * compatible pair. |
278 | */ | 280 | */ |
279 | int driver_attach(struct device_driver * drv) | 281 | int driver_attach(struct device_driver *drv) |
280 | { | 282 | { |
281 | return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach); | 283 | return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach); |
282 | } | 284 | } |
285 | EXPORT_SYMBOL_GPL(driver_attach); | ||
283 | 286 | ||
284 | /* | 287 | /* |
285 | * __device_release_driver() must be called with @dev->sem held. | 288 | * __device_release_driver() must be called with @dev->sem held. |
286 | * When called for a USB interface, @dev->parent->sem must be held as well. | 289 | * When called for a USB interface, @dev->parent->sem must be held as well. |
287 | */ | 290 | */ |
288 | static void __device_release_driver(struct device * dev) | 291 | static void __device_release_driver(struct device *dev) |
289 | { | 292 | { |
290 | struct device_driver * drv; | 293 | struct device_driver *drv; |
291 | 294 | ||
292 | drv = get_driver(dev->driver); | 295 | drv = dev->driver; |
293 | if (drv) { | 296 | if (drv) { |
294 | driver_sysfs_remove(dev); | 297 | driver_sysfs_remove(dev); |
295 | sysfs_remove_link(&dev->kobj, "driver"); | 298 | sysfs_remove_link(&dev->kobj, "driver"); |
296 | klist_remove(&dev->knode_driver); | ||
297 | 299 | ||
298 | if (dev->bus) | 300 | if (dev->bus) |
299 | blocking_notifier_call_chain(&dev->bus->bus_notifier, | 301 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, |
300 | BUS_NOTIFY_UNBIND_DRIVER, | 302 | BUS_NOTIFY_UNBIND_DRIVER, |
301 | dev); | 303 | dev); |
302 | 304 | ||
@@ -306,18 +308,18 @@ static void __device_release_driver(struct device * dev) | |||
306 | drv->remove(dev); | 308 | drv->remove(dev); |
307 | devres_release_all(dev); | 309 | devres_release_all(dev); |
308 | dev->driver = NULL; | 310 | dev->driver = NULL; |
309 | put_driver(drv); | 311 | klist_remove(&dev->knode_driver); |
310 | } | 312 | } |
311 | } | 313 | } |
312 | 314 | ||
313 | /** | 315 | /** |
314 | * device_release_driver - manually detach device from driver. | 316 | * device_release_driver - manually detach device from driver. |
315 | * @dev: device. | 317 | * @dev: device. |
316 | * | 318 | * |
317 | * Manually detach device from driver. | 319 | * Manually detach device from driver. |
318 | * When called for a USB interface, @dev->parent->sem must be held. | 320 | * When called for a USB interface, @dev->parent->sem must be held. |
319 | */ | 321 | */ |
320 | void device_release_driver(struct device * dev) | 322 | void device_release_driver(struct device *dev) |
321 | { | 323 | { |
322 | /* | 324 | /* |
323 | * If anyone calls device_release_driver() recursively from | 325 | * If anyone calls device_release_driver() recursively from |
@@ -328,26 +330,26 @@ void device_release_driver(struct device * dev) | |||
328 | __device_release_driver(dev); | 330 | __device_release_driver(dev); |
329 | up(&dev->sem); | 331 | up(&dev->sem); |
330 | } | 332 | } |
331 | 333 | EXPORT_SYMBOL_GPL(device_release_driver); | |
332 | 334 | ||
333 | /** | 335 | /** |
334 | * driver_detach - detach driver from all devices it controls. | 336 | * driver_detach - detach driver from all devices it controls. |
335 | * @drv: driver. | 337 | * @drv: driver. |
336 | */ | 338 | */ |
337 | void driver_detach(struct device_driver * drv) | 339 | void driver_detach(struct device_driver *drv) |
338 | { | 340 | { |
339 | struct device * dev; | 341 | struct device *dev; |
340 | 342 | ||
341 | for (;;) { | 343 | for (;;) { |
342 | spin_lock(&drv->klist_devices.k_lock); | 344 | spin_lock(&drv->p->klist_devices.k_lock); |
343 | if (list_empty(&drv->klist_devices.k_list)) { | 345 | if (list_empty(&drv->p->klist_devices.k_list)) { |
344 | spin_unlock(&drv->klist_devices.k_lock); | 346 | spin_unlock(&drv->p->klist_devices.k_lock); |
345 | break; | 347 | break; |
346 | } | 348 | } |
347 | dev = list_entry(drv->klist_devices.k_list.prev, | 349 | dev = list_entry(drv->p->klist_devices.k_list.prev, |
348 | struct device, knode_driver.n_node); | 350 | struct device, knode_driver.n_node); |
349 | get_device(dev); | 351 | get_device(dev); |
350 | spin_unlock(&drv->klist_devices.k_lock); | 352 | spin_unlock(&drv->p->klist_devices.k_lock); |
351 | 353 | ||
352 | if (dev->parent) /* Needed for USB */ | 354 | if (dev->parent) /* Needed for USB */ |
353 | down(&dev->parent->sem); | 355 | down(&dev->parent->sem); |
@@ -360,9 +362,3 @@ void driver_detach(struct device_driver * drv) | |||
360 | put_device(dev); | 362 | put_device(dev); |
361 | } | 363 | } |
362 | } | 364 | } |
363 | |||
364 | EXPORT_SYMBOL_GPL(device_bind_driver); | ||
365 | EXPORT_SYMBOL_GPL(device_release_driver); | ||
366 | EXPORT_SYMBOL_GPL(device_attach); | ||
367 | EXPORT_SYMBOL_GPL(driver_attach); | ||
368 | |||
diff --git a/drivers/base/driver.c b/drivers/base/driver.c index eb11475293ed..a35f04121a00 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c | |||
@@ -3,6 +3,8 @@ | |||
3 | * | 3 | * |
4 | * Copyright (c) 2002-3 Patrick Mochel | 4 | * Copyright (c) 2002-3 Patrick Mochel |
5 | * Copyright (c) 2002-3 Open Source Development Labs | 5 | * Copyright (c) 2002-3 Open Source Development Labs |
6 | * Copyright (c) 2007 Greg Kroah-Hartman <gregkh@suse.de> | ||
7 | * Copyright (c) 2007 Novell Inc. | ||
6 | * | 8 | * |
7 | * This file is released under the GPLv2 | 9 | * This file is released under the GPLv2 |
8 | * | 10 | * |
@@ -15,46 +17,42 @@ | |||
15 | #include "base.h" | 17 | #include "base.h" |
16 | 18 | ||
17 | #define to_dev(node) container_of(node, struct device, driver_list) | 19 | #define to_dev(node) container_of(node, struct device, driver_list) |
18 | #define to_drv(obj) container_of(obj, struct device_driver, kobj) | ||
19 | 20 | ||
20 | 21 | ||
21 | static struct device * next_device(struct klist_iter * i) | 22 | static struct device *next_device(struct klist_iter *i) |
22 | { | 23 | { |
23 | struct klist_node * n = klist_next(i); | 24 | struct klist_node *n = klist_next(i); |
24 | return n ? container_of(n, struct device, knode_driver) : NULL; | 25 | return n ? container_of(n, struct device, knode_driver) : NULL; |
25 | } | 26 | } |
26 | 27 | ||
27 | /** | 28 | /** |
28 | * driver_for_each_device - Iterator for devices bound to a driver. | 29 | * driver_for_each_device - Iterator for devices bound to a driver. |
29 | * @drv: Driver we're iterating. | 30 | * @drv: Driver we're iterating. |
30 | * @start: Device to begin with | 31 | * @start: Device to begin with |
31 | * @data: Data to pass to the callback. | 32 | * @data: Data to pass to the callback. |
32 | * @fn: Function to call for each device. | 33 | * @fn: Function to call for each device. |
33 | * | 34 | * |
34 | * Iterate over the @drv's list of devices calling @fn for each one. | 35 | * Iterate over the @drv's list of devices calling @fn for each one. |
35 | */ | 36 | */ |
36 | 37 | int driver_for_each_device(struct device_driver *drv, struct device *start, | |
37 | int driver_for_each_device(struct device_driver * drv, struct device * start, | 38 | void *data, int (*fn)(struct device *, void *)) |
38 | void * data, int (*fn)(struct device *, void *)) | ||
39 | { | 39 | { |
40 | struct klist_iter i; | 40 | struct klist_iter i; |
41 | struct device * dev; | 41 | struct device *dev; |
42 | int error = 0; | 42 | int error = 0; |
43 | 43 | ||
44 | if (!drv) | 44 | if (!drv) |
45 | return -EINVAL; | 45 | return -EINVAL; |
46 | 46 | ||
47 | klist_iter_init_node(&drv->klist_devices, &i, | 47 | klist_iter_init_node(&drv->p->klist_devices, &i, |
48 | start ? &start->knode_driver : NULL); | 48 | start ? &start->knode_driver : NULL); |
49 | while ((dev = next_device(&i)) && !error) | 49 | while ((dev = next_device(&i)) && !error) |
50 | error = fn(dev, data); | 50 | error = fn(dev, data); |
51 | klist_iter_exit(&i); | 51 | klist_iter_exit(&i); |
52 | return error; | 52 | return error; |
53 | } | 53 | } |
54 | |||
55 | EXPORT_SYMBOL_GPL(driver_for_each_device); | 54 | EXPORT_SYMBOL_GPL(driver_for_each_device); |
56 | 55 | ||
57 | |||
58 | /** | 56 | /** |
59 | * driver_find_device - device iterator for locating a particular device. | 57 | * driver_find_device - device iterator for locating a particular device. |
60 | * @drv: The device's driver | 58 | * @drv: The device's driver |
@@ -70,9 +68,9 @@ EXPORT_SYMBOL_GPL(driver_for_each_device); | |||
70 | * if it does. If the callback returns non-zero, this function will | 68 | * if it does. If the callback returns non-zero, this function will |
71 | * return to the caller and not iterate over any more devices. | 69 | * return to the caller and not iterate over any more devices. |
72 | */ | 70 | */ |
73 | struct device * driver_find_device(struct device_driver *drv, | 71 | struct device *driver_find_device(struct device_driver *drv, |
74 | struct device * start, void * data, | 72 | struct device *start, void *data, |
75 | int (*match)(struct device *, void *)) | 73 | int (*match)(struct device *dev, void *data)) |
76 | { | 74 | { |
77 | struct klist_iter i; | 75 | struct klist_iter i; |
78 | struct device *dev; | 76 | struct device *dev; |
@@ -80,7 +78,7 @@ struct device * driver_find_device(struct device_driver *drv, | |||
80 | if (!drv) | 78 | if (!drv) |
81 | return NULL; | 79 | return NULL; |
82 | 80 | ||
83 | klist_iter_init_node(&drv->klist_devices, &i, | 81 | klist_iter_init_node(&drv->p->klist_devices, &i, |
84 | (start ? &start->knode_driver : NULL)); | 82 | (start ? &start->knode_driver : NULL)); |
85 | while ((dev = next_device(&i))) | 83 | while ((dev = next_device(&i))) |
86 | if (match(dev, data) && get_device(dev)) | 84 | if (match(dev, data) && get_device(dev)) |
@@ -91,111 +89,179 @@ struct device * driver_find_device(struct device_driver *drv, | |||
91 | EXPORT_SYMBOL_GPL(driver_find_device); | 89 | EXPORT_SYMBOL_GPL(driver_find_device); |
92 | 90 | ||
93 | /** | 91 | /** |
94 | * driver_create_file - create sysfs file for driver. | 92 | * driver_create_file - create sysfs file for driver. |
95 | * @drv: driver. | 93 | * @drv: driver. |
96 | * @attr: driver attribute descriptor. | 94 | * @attr: driver attribute descriptor. |
97 | */ | 95 | */ |
98 | 96 | int driver_create_file(struct device_driver *drv, | |
99 | int driver_create_file(struct device_driver * drv, struct driver_attribute * attr) | 97 | struct driver_attribute *attr) |
100 | { | 98 | { |
101 | int error; | 99 | int error; |
102 | if (get_driver(drv)) { | 100 | if (get_driver(drv)) { |
103 | error = sysfs_create_file(&drv->kobj, &attr->attr); | 101 | error = sysfs_create_file(&drv->p->kobj, &attr->attr); |
104 | put_driver(drv); | 102 | put_driver(drv); |
105 | } else | 103 | } else |
106 | error = -EINVAL; | 104 | error = -EINVAL; |
107 | return error; | 105 | return error; |
108 | } | 106 | } |
109 | 107 | EXPORT_SYMBOL_GPL(driver_create_file); | |
110 | 108 | ||
111 | /** | 109 | /** |
112 | * driver_remove_file - remove sysfs file for driver. | 110 | * driver_remove_file - remove sysfs file for driver. |
113 | * @drv: driver. | 111 | * @drv: driver. |
114 | * @attr: driver attribute descriptor. | 112 | * @attr: driver attribute descriptor. |
115 | */ | 113 | */ |
116 | 114 | void driver_remove_file(struct device_driver *drv, | |
117 | void driver_remove_file(struct device_driver * drv, struct driver_attribute * attr) | 115 | struct driver_attribute *attr) |
118 | { | 116 | { |
119 | if (get_driver(drv)) { | 117 | if (get_driver(drv)) { |
120 | sysfs_remove_file(&drv->kobj, &attr->attr); | 118 | sysfs_remove_file(&drv->p->kobj, &attr->attr); |
121 | put_driver(drv); | 119 | put_driver(drv); |
122 | } | 120 | } |
123 | } | 121 | } |
124 | 122 | EXPORT_SYMBOL_GPL(driver_remove_file); | |
125 | 123 | ||
126 | /** | 124 | /** |
127 | * get_driver - increment driver reference count. | 125 | * driver_add_kobj - add a kobject below the specified driver |
128 | * @drv: driver. | 126 | * |
127 | * You really don't want to do this, this is only here due to one looney | ||
128 | * iseries driver, go poke those developers if you are annoyed about | ||
129 | * this... | ||
129 | */ | 130 | */ |
130 | struct device_driver * get_driver(struct device_driver * drv) | 131 | int driver_add_kobj(struct device_driver *drv, struct kobject *kobj, |
132 | const char *fmt, ...) | ||
131 | { | 133 | { |
132 | return drv ? to_drv(kobject_get(&drv->kobj)) : NULL; | 134 | va_list args; |
135 | char *name; | ||
136 | |||
137 | va_start(args, fmt); | ||
138 | name = kvasprintf(GFP_KERNEL, fmt, args); | ||
139 | va_end(args); | ||
140 | |||
141 | if (!name) | ||
142 | return -ENOMEM; | ||
143 | |||
144 | return kobject_add(kobj, &drv->p->kobj, "%s", name); | ||
133 | } | 145 | } |
146 | EXPORT_SYMBOL_GPL(driver_add_kobj); | ||
147 | |||
148 | /** | ||
149 | * get_driver - increment driver reference count. | ||
150 | * @drv: driver. | ||
151 | */ | ||
152 | struct device_driver *get_driver(struct device_driver *drv) | ||
153 | { | ||
154 | if (drv) { | ||
155 | struct driver_private *priv; | ||
156 | struct kobject *kobj; | ||
134 | 157 | ||
158 | kobj = kobject_get(&drv->p->kobj); | ||
159 | priv = to_driver(kobj); | ||
160 | return priv->driver; | ||
161 | } | ||
162 | return NULL; | ||
163 | } | ||
164 | EXPORT_SYMBOL_GPL(get_driver); | ||
135 | 165 | ||
136 | /** | 166 | /** |
137 | * put_driver - decrement driver's refcount. | 167 | * put_driver - decrement driver's refcount. |
138 | * @drv: driver. | 168 | * @drv: driver. |
139 | */ | 169 | */ |
140 | void put_driver(struct device_driver * drv) | 170 | void put_driver(struct device_driver *drv) |
171 | { | ||
172 | kobject_put(&drv->p->kobj); | ||
173 | } | ||
174 | EXPORT_SYMBOL_GPL(put_driver); | ||
175 | |||
176 | static int driver_add_groups(struct device_driver *drv, | ||
177 | struct attribute_group **groups) | ||
141 | { | 178 | { |
142 | kobject_put(&drv->kobj); | 179 | int error = 0; |
180 | int i; | ||
181 | |||
182 | if (groups) { | ||
183 | for (i = 0; groups[i]; i++) { | ||
184 | error = sysfs_create_group(&drv->p->kobj, groups[i]); | ||
185 | if (error) { | ||
186 | while (--i >= 0) | ||
187 | sysfs_remove_group(&drv->p->kobj, | ||
188 | groups[i]); | ||
189 | break; | ||
190 | } | ||
191 | } | ||
192 | } | ||
193 | return error; | ||
194 | } | ||
195 | |||
196 | static void driver_remove_groups(struct device_driver *drv, | ||
197 | struct attribute_group **groups) | ||
198 | { | ||
199 | int i; | ||
200 | |||
201 | if (groups) | ||
202 | for (i = 0; groups[i]; i++) | ||
203 | sysfs_remove_group(&drv->p->kobj, groups[i]); | ||
143 | } | 204 | } |
144 | 205 | ||
145 | /** | 206 | /** |
146 | * driver_register - register driver with bus | 207 | * driver_register - register driver with bus |
147 | * @drv: driver to register | 208 | * @drv: driver to register |
148 | * | 209 | * |
149 | * We pass off most of the work to the bus_add_driver() call, | 210 | * We pass off most of the work to the bus_add_driver() call, |
150 | * since most of the things we have to do deal with the bus | 211 | * since most of the things we have to do deal with the bus |
151 | * structures. | 212 | * structures. |
152 | */ | 213 | */ |
153 | int driver_register(struct device_driver * drv) | 214 | int driver_register(struct device_driver *drv) |
154 | { | 215 | { |
216 | int ret; | ||
217 | |||
155 | if ((drv->bus->probe && drv->probe) || | 218 | if ((drv->bus->probe && drv->probe) || |
156 | (drv->bus->remove && drv->remove) || | 219 | (drv->bus->remove && drv->remove) || |
157 | (drv->bus->shutdown && drv->shutdown)) { | 220 | (drv->bus->shutdown && drv->shutdown)) |
158 | printk(KERN_WARNING "Driver '%s' needs updating - please use bus_type methods\n", drv->name); | 221 | printk(KERN_WARNING "Driver '%s' needs updating - please use " |
159 | } | 222 | "bus_type methods\n", drv->name); |
160 | klist_init(&drv->klist_devices, NULL, NULL); | 223 | ret = bus_add_driver(drv); |
161 | return bus_add_driver(drv); | 224 | if (ret) |
225 | return ret; | ||
226 | ret = driver_add_groups(drv, drv->groups); | ||
227 | if (ret) | ||
228 | bus_remove_driver(drv); | ||
229 | return ret; | ||
162 | } | 230 | } |
231 | EXPORT_SYMBOL_GPL(driver_register); | ||
163 | 232 | ||
164 | /** | 233 | /** |
165 | * driver_unregister - remove driver from system. | 234 | * driver_unregister - remove driver from system. |
166 | * @drv: driver. | 235 | * @drv: driver. |
167 | * | 236 | * |
168 | * Again, we pass off most of the work to the bus-level call. | 237 | * Again, we pass off most of the work to the bus-level call. |
169 | */ | 238 | */ |
170 | 239 | void driver_unregister(struct device_driver *drv) | |
171 | void driver_unregister(struct device_driver * drv) | ||
172 | { | 240 | { |
241 | driver_remove_groups(drv, drv->groups); | ||
173 | bus_remove_driver(drv); | 242 | bus_remove_driver(drv); |
174 | } | 243 | } |
244 | EXPORT_SYMBOL_GPL(driver_unregister); | ||
175 | 245 | ||
176 | /** | 246 | /** |
177 | * driver_find - locate driver on a bus by its name. | 247 | * driver_find - locate driver on a bus by its name. |
178 | * @name: name of the driver. | 248 | * @name: name of the driver. |
179 | * @bus: bus to scan for the driver. | 249 | * @bus: bus to scan for the driver. |
180 | * | 250 | * |
181 | * Call kset_find_obj() to iterate over list of drivers on | 251 | * Call kset_find_obj() to iterate over list of drivers on |
182 | * a bus to find driver by name. Return driver if found. | 252 | * a bus to find driver by name. Return driver if found. |
183 | * | 253 | * |
184 | * Note that kset_find_obj increments driver's reference count. | 254 | * Note that kset_find_obj increments driver's reference count. |
185 | */ | 255 | */ |
186 | struct device_driver *driver_find(const char *name, struct bus_type *bus) | 256 | struct device_driver *driver_find(const char *name, struct bus_type *bus) |
187 | { | 257 | { |
188 | struct kobject *k = kset_find_obj(&bus->drivers, name); | 258 | struct kobject *k = kset_find_obj(bus->p->drivers_kset, name); |
189 | if (k) | 259 | struct driver_private *priv; |
190 | return to_drv(k); | 260 | |
261 | if (k) { | ||
262 | priv = to_driver(k); | ||
263 | return priv->driver; | ||
264 | } | ||
191 | return NULL; | 265 | return NULL; |
192 | } | 266 | } |
193 | |||
194 | EXPORT_SYMBOL_GPL(driver_register); | ||
195 | EXPORT_SYMBOL_GPL(driver_unregister); | ||
196 | EXPORT_SYMBOL_GPL(get_driver); | ||
197 | EXPORT_SYMBOL_GPL(put_driver); | ||
198 | EXPORT_SYMBOL_GPL(driver_find); | 267 | EXPORT_SYMBOL_GPL(driver_find); |
199 | |||
200 | EXPORT_SYMBOL_GPL(driver_create_file); | ||
201 | EXPORT_SYMBOL_GPL(driver_remove_file); | ||
diff --git a/drivers/base/firmware.c b/drivers/base/firmware.c index 90c862932169..113815556809 100644 --- a/drivers/base/firmware.c +++ b/drivers/base/firmware.c | |||
@@ -3,11 +3,11 @@ | |||
3 | * | 3 | * |
4 | * Copyright (c) 2002-3 Patrick Mochel | 4 | * Copyright (c) 2002-3 Patrick Mochel |
5 | * Copyright (c) 2002-3 Open Source Development Labs | 5 | * Copyright (c) 2002-3 Open Source Development Labs |
6 | * Copyright (c) 2007 Greg Kroah-Hartman <gregkh@suse.de> | ||
7 | * Copyright (c) 2007 Novell Inc. | ||
6 | * | 8 | * |
7 | * This file is released under the GPLv2 | 9 | * This file is released under the GPLv2 |
8 | * | ||
9 | */ | 10 | */ |
10 | |||
11 | #include <linux/kobject.h> | 11 | #include <linux/kobject.h> |
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
@@ -15,23 +15,13 @@ | |||
15 | 15 | ||
16 | #include "base.h" | 16 | #include "base.h" |
17 | 17 | ||
18 | static decl_subsys(firmware, NULL, NULL); | 18 | struct kobject *firmware_kobj; |
19 | 19 | EXPORT_SYMBOL_GPL(firmware_kobj); | |
20 | int firmware_register(struct kset *s) | ||
21 | { | ||
22 | kobj_set_kset_s(s, firmware_subsys); | ||
23 | return subsystem_register(s); | ||
24 | } | ||
25 | |||
26 | void firmware_unregister(struct kset *s) | ||
27 | { | ||
28 | subsystem_unregister(s); | ||
29 | } | ||
30 | 20 | ||
31 | int __init firmware_init(void) | 21 | int __init firmware_init(void) |
32 | { | 22 | { |
33 | return subsystem_register(&firmware_subsys); | 23 | firmware_kobj = kobject_create_and_add("firmware", NULL); |
24 | if (!firmware_kobj) | ||
25 | return -ENOMEM; | ||
26 | return 0; | ||
34 | } | 27 | } |
35 | |||
36 | EXPORT_SYMBOL_GPL(firmware_register); | ||
37 | EXPORT_SYMBOL_GPL(firmware_unregister); | ||
diff --git a/drivers/base/hypervisor.c b/drivers/base/hypervisor.c index 7080b413ddc9..6428cba3aadd 100644 --- a/drivers/base/hypervisor.c +++ b/drivers/base/hypervisor.c | |||
@@ -2,19 +2,23 @@ | |||
2 | * hypervisor.c - /sys/hypervisor subsystem. | 2 | * hypervisor.c - /sys/hypervisor subsystem. |
3 | * | 3 | * |
4 | * Copyright (C) IBM Corp. 2006 | 4 | * Copyright (C) IBM Corp. 2006 |
5 | * Copyright (C) 2007 Greg Kroah-Hartman <gregkh@suse.de> | ||
6 | * Copyright (C) 2007 Novell Inc. | ||
5 | * | 7 | * |
6 | * This file is released under the GPLv2 | 8 | * This file is released under the GPLv2 |
7 | */ | 9 | */ |
8 | 10 | ||
9 | #include <linux/kobject.h> | 11 | #include <linux/kobject.h> |
10 | #include <linux/device.h> | 12 | #include <linux/device.h> |
11 | |||
12 | #include "base.h" | 13 | #include "base.h" |
13 | 14 | ||
14 | decl_subsys(hypervisor, NULL, NULL); | 15 | struct kobject *hypervisor_kobj; |
15 | EXPORT_SYMBOL_GPL(hypervisor_subsys); | 16 | EXPORT_SYMBOL_GPL(hypervisor_kobj); |
16 | 17 | ||
17 | int __init hypervisor_init(void) | 18 | int __init hypervisor_init(void) |
18 | { | 19 | { |
19 | return subsystem_register(&hypervisor_subsys); | 20 | hypervisor_kobj = kobject_create_and_add("hypervisor", NULL); |
21 | if (!hypervisor_kobj) | ||
22 | return -ENOMEM; | ||
23 | return 0; | ||
20 | } | 24 | } |
diff --git a/drivers/base/init.c b/drivers/base/init.c index 37138154f9e8..7bd9b6a5b01f 100644 --- a/drivers/base/init.c +++ b/drivers/base/init.c | |||
@@ -1,10 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * | ||
3 | * Copyright (c) 2002-3 Patrick Mochel | 2 | * Copyright (c) 2002-3 Patrick Mochel |
4 | * Copyright (c) 2002-3 Open Source Development Labs | 3 | * Copyright (c) 2002-3 Open Source Development Labs |
5 | * | 4 | * |
6 | * This file is released under the GPLv2 | 5 | * This file is released under the GPLv2 |
7 | * | ||
8 | */ | 6 | */ |
9 | 7 | ||
10 | #include <linux/device.h> | 8 | #include <linux/device.h> |
@@ -14,12 +12,11 @@ | |||
14 | #include "base.h" | 12 | #include "base.h" |
15 | 13 | ||
16 | /** | 14 | /** |
17 | * driver_init - initialize driver model. | 15 | * driver_init - initialize driver model. |
18 | * | 16 | * |
19 | * Call the driver model init functions to initialize their | 17 | * Call the driver model init functions to initialize their |
20 | * subsystems. Called early from init/main.c. | 18 | * subsystems. Called early from init/main.c. |
21 | */ | 19 | */ |
22 | |||
23 | void __init driver_init(void) | 20 | void __init driver_init(void) |
24 | { | 21 | { |
25 | /* These are the core pieces */ | 22 | /* These are the core pieces */ |
@@ -36,5 +33,4 @@ void __init driver_init(void) | |||
36 | system_bus_init(); | 33 | system_bus_init(); |
37 | cpu_dev_init(); | 34 | cpu_dev_init(); |
38 | memory_dev_init(); | 35 | memory_dev_init(); |
39 | attribute_container_init(); | ||
40 | } | 36 | } |
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 7868707c7eda..7ae413fdd5fc 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #define MEMORY_CLASS_NAME "memory" | 26 | #define MEMORY_CLASS_NAME "memory" |
27 | 27 | ||
28 | static struct sysdev_class memory_sysdev_class = { | 28 | static struct sysdev_class memory_sysdev_class = { |
29 | set_kset_name(MEMORY_CLASS_NAME), | 29 | .name = MEMORY_CLASS_NAME, |
30 | }; | 30 | }; |
31 | 31 | ||
32 | static const char *memory_uevent_name(struct kset *kset, struct kobject *kobj) | 32 | static const char *memory_uevent_name(struct kset *kset, struct kobject *kobj) |
diff --git a/drivers/base/module.c b/drivers/base/module.c new file mode 100644 index 000000000000..103be9cacb05 --- /dev/null +++ b/drivers/base/module.c | |||
@@ -0,0 +1,94 @@ | |||
1 | /* | ||
2 | * module.c - module sysfs fun for drivers | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | * | ||
6 | */ | ||
7 | #include <linux/device.h> | ||
8 | #include <linux/module.h> | ||
9 | #include <linux/errno.h> | ||
10 | #include <linux/string.h> | ||
11 | #include "base.h" | ||
12 | |||
13 | static char *make_driver_name(struct device_driver *drv) | ||
14 | { | ||
15 | char *driver_name; | ||
16 | |||
17 | driver_name = kmalloc(strlen(drv->name) + strlen(drv->bus->name) + 2, | ||
18 | GFP_KERNEL); | ||
19 | if (!driver_name) | ||
20 | return NULL; | ||
21 | |||
22 | sprintf(driver_name, "%s:%s", drv->bus->name, drv->name); | ||
23 | return driver_name; | ||
24 | } | ||
25 | |||
26 | static void module_create_drivers_dir(struct module_kobject *mk) | ||
27 | { | ||
28 | if (!mk || mk->drivers_dir) | ||
29 | return; | ||
30 | |||
31 | mk->drivers_dir = kobject_create_and_add("drivers", &mk->kobj); | ||
32 | } | ||
33 | |||
34 | void module_add_driver(struct module *mod, struct device_driver *drv) | ||
35 | { | ||
36 | char *driver_name; | ||
37 | int no_warn; | ||
38 | struct module_kobject *mk = NULL; | ||
39 | |||
40 | if (!drv) | ||
41 | return; | ||
42 | |||
43 | if (mod) | ||
44 | mk = &mod->mkobj; | ||
45 | else if (drv->mod_name) { | ||
46 | struct kobject *mkobj; | ||
47 | |||
48 | /* Lookup built-in module entry in /sys/modules */ | ||
49 | mkobj = kset_find_obj(module_kset, drv->mod_name); | ||
50 | if (mkobj) { | ||
51 | mk = container_of(mkobj, struct module_kobject, kobj); | ||
52 | /* remember our module structure */ | ||
53 | drv->p->mkobj = mk; | ||
54 | /* kset_find_obj took a reference */ | ||
55 | kobject_put(mkobj); | ||
56 | } | ||
57 | } | ||
58 | |||
59 | if (!mk) | ||
60 | return; | ||
61 | |||
62 | /* Don't check return codes; these calls are idempotent */ | ||
63 | no_warn = sysfs_create_link(&drv->p->kobj, &mk->kobj, "module"); | ||
64 | driver_name = make_driver_name(drv); | ||
65 | if (driver_name) { | ||
66 | module_create_drivers_dir(mk); | ||
67 | no_warn = sysfs_create_link(mk->drivers_dir, &drv->p->kobj, | ||
68 | driver_name); | ||
69 | kfree(driver_name); | ||
70 | } | ||
71 | } | ||
72 | |||
73 | void module_remove_driver(struct device_driver *drv) | ||
74 | { | ||
75 | struct module_kobject *mk = NULL; | ||
76 | char *driver_name; | ||
77 | |||
78 | if (!drv) | ||
79 | return; | ||
80 | |||
81 | sysfs_remove_link(&drv->p->kobj, "module"); | ||
82 | |||
83 | if (drv->owner) | ||
84 | mk = &drv->owner->mkobj; | ||
85 | else if (drv->p->mkobj) | ||
86 | mk = drv->p->mkobj; | ||
87 | if (mk && mk->drivers_dir) { | ||
88 | driver_name = make_driver_name(drv); | ||
89 | if (driver_name) { | ||
90 | sysfs_remove_link(mk->drivers_dir, driver_name); | ||
91 | kfree(driver_name); | ||
92 | } | ||
93 | } | ||
94 | } | ||
diff --git a/drivers/base/node.c b/drivers/base/node.c index 88eeed72b5d6..e59861f18ce5 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include <linux/device.h> | 15 | #include <linux/device.h> |
16 | 16 | ||
17 | static struct sysdev_class node_class = { | 17 | static struct sysdev_class node_class = { |
18 | set_kset_name("node"), | 18 | .name = "node", |
19 | }; | 19 | }; |
20 | 20 | ||
21 | 21 | ||
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index fb5609241482..efaf282c438c 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -20,7 +20,8 @@ | |||
20 | 20 | ||
21 | #include "base.h" | 21 | #include "base.h" |
22 | 22 | ||
23 | #define to_platform_driver(drv) (container_of((drv), struct platform_driver, driver)) | 23 | #define to_platform_driver(drv) (container_of((drv), struct platform_driver, \ |
24 | driver)) | ||
24 | 25 | ||
25 | struct device platform_bus = { | 26 | struct device platform_bus = { |
26 | .bus_id = "platform", | 27 | .bus_id = "platform", |
@@ -28,14 +29,13 @@ struct device platform_bus = { | |||
28 | EXPORT_SYMBOL_GPL(platform_bus); | 29 | EXPORT_SYMBOL_GPL(platform_bus); |
29 | 30 | ||
30 | /** | 31 | /** |
31 | * platform_get_resource - get a resource for a device | 32 | * platform_get_resource - get a resource for a device |
32 | * @dev: platform device | 33 | * @dev: platform device |
33 | * @type: resource type | 34 | * @type: resource type |
34 | * @num: resource index | 35 | * @num: resource index |
35 | */ | 36 | */ |
36 | struct resource * | 37 | struct resource *platform_get_resource(struct platform_device *dev, |
37 | platform_get_resource(struct platform_device *dev, unsigned int type, | 38 | unsigned int type, unsigned int num) |
38 | unsigned int num) | ||
39 | { | 39 | { |
40 | int i; | 40 | int i; |
41 | 41 | ||
@@ -43,8 +43,7 @@ platform_get_resource(struct platform_device *dev, unsigned int type, | |||
43 | struct resource *r = &dev->resource[i]; | 43 | struct resource *r = &dev->resource[i]; |
44 | 44 | ||
45 | if ((r->flags & (IORESOURCE_IO|IORESOURCE_MEM| | 45 | if ((r->flags & (IORESOURCE_IO|IORESOURCE_MEM| |
46 | IORESOURCE_IRQ|IORESOURCE_DMA)) | 46 | IORESOURCE_IRQ|IORESOURCE_DMA)) == type) |
47 | == type) | ||
48 | if (num-- == 0) | 47 | if (num-- == 0) |
49 | return r; | 48 | return r; |
50 | } | 49 | } |
@@ -53,9 +52,9 @@ platform_get_resource(struct platform_device *dev, unsigned int type, | |||
53 | EXPORT_SYMBOL_GPL(platform_get_resource); | 52 | EXPORT_SYMBOL_GPL(platform_get_resource); |
54 | 53 | ||
55 | /** | 54 | /** |
56 | * platform_get_irq - get an IRQ for a device | 55 | * platform_get_irq - get an IRQ for a device |
57 | * @dev: platform device | 56 | * @dev: platform device |
58 | * @num: IRQ number index | 57 | * @num: IRQ number index |
59 | */ | 58 | */ |
60 | int platform_get_irq(struct platform_device *dev, unsigned int num) | 59 | int platform_get_irq(struct platform_device *dev, unsigned int num) |
61 | { | 60 | { |
@@ -66,14 +65,13 @@ int platform_get_irq(struct platform_device *dev, unsigned int num) | |||
66 | EXPORT_SYMBOL_GPL(platform_get_irq); | 65 | EXPORT_SYMBOL_GPL(platform_get_irq); |
67 | 66 | ||
68 | /** | 67 | /** |
69 | * platform_get_resource_byname - get a resource for a device by name | 68 | * platform_get_resource_byname - get a resource for a device by name |
70 | * @dev: platform device | 69 | * @dev: platform device |
71 | * @type: resource type | 70 | * @type: resource type |
72 | * @name: resource name | 71 | * @name: resource name |
73 | */ | 72 | */ |
74 | struct resource * | 73 | struct resource *platform_get_resource_byname(struct platform_device *dev, |
75 | platform_get_resource_byname(struct platform_device *dev, unsigned int type, | 74 | unsigned int type, char *name) |
76 | char *name) | ||
77 | { | 75 | { |
78 | int i; | 76 | int i; |
79 | 77 | ||
@@ -90,22 +88,23 @@ platform_get_resource_byname(struct platform_device *dev, unsigned int type, | |||
90 | EXPORT_SYMBOL_GPL(platform_get_resource_byname); | 88 | EXPORT_SYMBOL_GPL(platform_get_resource_byname); |
91 | 89 | ||
92 | /** | 90 | /** |
93 | * platform_get_irq - get an IRQ for a device | 91 | * platform_get_irq - get an IRQ for a device |
94 | * @dev: platform device | 92 | * @dev: platform device |
95 | * @name: IRQ name | 93 | * @name: IRQ name |
96 | */ | 94 | */ |
97 | int platform_get_irq_byname(struct platform_device *dev, char *name) | 95 | int platform_get_irq_byname(struct platform_device *dev, char *name) |
98 | { | 96 | { |
99 | struct resource *r = platform_get_resource_byname(dev, IORESOURCE_IRQ, name); | 97 | struct resource *r = platform_get_resource_byname(dev, IORESOURCE_IRQ, |
98 | name); | ||
100 | 99 | ||
101 | return r ? r->start : -ENXIO; | 100 | return r ? r->start : -ENXIO; |
102 | } | 101 | } |
103 | EXPORT_SYMBOL_GPL(platform_get_irq_byname); | 102 | EXPORT_SYMBOL_GPL(platform_get_irq_byname); |
104 | 103 | ||
105 | /** | 104 | /** |
106 | * platform_add_devices - add a numbers of platform devices | 105 | * platform_add_devices - add a numbers of platform devices |
107 | * @devs: array of platform devices to add | 106 | * @devs: array of platform devices to add |
108 | * @num: number of platform devices in array | 107 | * @num: number of platform devices in array |
109 | */ | 108 | */ |
110 | int platform_add_devices(struct platform_device **devs, int num) | 109 | int platform_add_devices(struct platform_device **devs, int num) |
111 | { | 110 | { |
@@ -130,12 +129,11 @@ struct platform_object { | |||
130 | }; | 129 | }; |
131 | 130 | ||
132 | /** | 131 | /** |
133 | * platform_device_put | 132 | * platform_device_put |
134 | * @pdev: platform device to free | 133 | * @pdev: platform device to free |
135 | * | 134 | * |
136 | * Free all memory associated with a platform device. This function | 135 | * Free all memory associated with a platform device. This function must |
137 | * must _only_ be externally called in error cases. All other usage | 136 | * _only_ be externally called in error cases. All other usage is a bug. |
138 | * is a bug. | ||
139 | */ | 137 | */ |
140 | void platform_device_put(struct platform_device *pdev) | 138 | void platform_device_put(struct platform_device *pdev) |
141 | { | 139 | { |
@@ -146,7 +144,8 @@ EXPORT_SYMBOL_GPL(platform_device_put); | |||
146 | 144 | ||
147 | static void platform_device_release(struct device *dev) | 145 | static void platform_device_release(struct device *dev) |
148 | { | 146 | { |
149 | struct platform_object *pa = container_of(dev, struct platform_object, pdev.dev); | 147 | struct platform_object *pa = container_of(dev, struct platform_object, |
148 | pdev.dev); | ||
150 | 149 | ||
151 | kfree(pa->pdev.dev.platform_data); | 150 | kfree(pa->pdev.dev.platform_data); |
152 | kfree(pa->pdev.resource); | 151 | kfree(pa->pdev.resource); |
@@ -154,12 +153,12 @@ static void platform_device_release(struct device *dev) | |||
154 | } | 153 | } |
155 | 154 | ||
156 | /** | 155 | /** |
157 | * platform_device_alloc | 156 | * platform_device_alloc |
158 | * @name: base name of the device we're adding | 157 | * @name: base name of the device we're adding |
159 | * @id: instance id | 158 | * @id: instance id |
160 | * | 159 | * |
161 | * Create a platform device object which can have other objects attached | 160 | * Create a platform device object which can have other objects attached |
162 | * to it, and which will have attached objects freed when it is released. | 161 | * to it, and which will have attached objects freed when it is released. |
163 | */ | 162 | */ |
164 | struct platform_device *platform_device_alloc(const char *name, int id) | 163 | struct platform_device *platform_device_alloc(const char *name, int id) |
165 | { | 164 | { |
@@ -179,16 +178,17 @@ struct platform_device *platform_device_alloc(const char *name, int id) | |||
179 | EXPORT_SYMBOL_GPL(platform_device_alloc); | 178 | EXPORT_SYMBOL_GPL(platform_device_alloc); |
180 | 179 | ||
181 | /** | 180 | /** |
182 | * platform_device_add_resources | 181 | * platform_device_add_resources |
183 | * @pdev: platform device allocated by platform_device_alloc to add resources to | 182 | * @pdev: platform device allocated by platform_device_alloc to add resources to |
184 | * @res: set of resources that needs to be allocated for the device | 183 | * @res: set of resources that needs to be allocated for the device |
185 | * @num: number of resources | 184 | * @num: number of resources |
186 | * | 185 | * |
187 | * Add a copy of the resources to the platform device. The memory | 186 | * Add a copy of the resources to the platform device. The memory |
188 | * associated with the resources will be freed when the platform | 187 | * associated with the resources will be freed when the platform device is |
189 | * device is released. | 188 | * released. |
190 | */ | 189 | */ |
191 | int platform_device_add_resources(struct platform_device *pdev, struct resource *res, unsigned int num) | 190 | int platform_device_add_resources(struct platform_device *pdev, |
191 | struct resource *res, unsigned int num) | ||
192 | { | 192 | { |
193 | struct resource *r; | 193 | struct resource *r; |
194 | 194 | ||
@@ -203,16 +203,17 @@ int platform_device_add_resources(struct platform_device *pdev, struct resource | |||
203 | EXPORT_SYMBOL_GPL(platform_device_add_resources); | 203 | EXPORT_SYMBOL_GPL(platform_device_add_resources); |
204 | 204 | ||
205 | /** | 205 | /** |
206 | * platform_device_add_data | 206 | * platform_device_add_data |
207 | * @pdev: platform device allocated by platform_device_alloc to add resources to | 207 | * @pdev: platform device allocated by platform_device_alloc to add resources to |
208 | * @data: platform specific data for this platform device | 208 | * @data: platform specific data for this platform device |
209 | * @size: size of platform specific data | 209 | * @size: size of platform specific data |
210 | * | 210 | * |
211 | * Add a copy of platform specific data to the platform device's platform_data | 211 | * Add a copy of platform specific data to the platform device's |
212 | * pointer. The memory associated with the platform data will be freed | 212 | * platform_data pointer. The memory associated with the platform data |
213 | * when the platform device is released. | 213 | * will be freed when the platform device is released. |
214 | */ | 214 | */ |
215 | int platform_device_add_data(struct platform_device *pdev, const void *data, size_t size) | 215 | int platform_device_add_data(struct platform_device *pdev, const void *data, |
216 | size_t size) | ||
216 | { | 217 | { |
217 | void *d; | 218 | void *d; |
218 | 219 | ||
@@ -226,11 +227,11 @@ int platform_device_add_data(struct platform_device *pdev, const void *data, siz | |||
226 | EXPORT_SYMBOL_GPL(platform_device_add_data); | 227 | EXPORT_SYMBOL_GPL(platform_device_add_data); |
227 | 228 | ||
228 | /** | 229 | /** |
229 | * platform_device_add - add a platform device to device hierarchy | 230 | * platform_device_add - add a platform device to device hierarchy |
230 | * @pdev: platform device we're adding | 231 | * @pdev: platform device we're adding |
231 | * | 232 | * |
232 | * This is part 2 of platform_device_register(), though may be called | 233 | * This is part 2 of platform_device_register(), though may be called |
233 | * separately _iff_ pdev was allocated by platform_device_alloc(). | 234 | * separately _iff_ pdev was allocated by platform_device_alloc(). |
234 | */ | 235 | */ |
235 | int platform_device_add(struct platform_device *pdev) | 236 | int platform_device_add(struct platform_device *pdev) |
236 | { | 237 | { |
@@ -289,13 +290,12 @@ int platform_device_add(struct platform_device *pdev) | |||
289 | EXPORT_SYMBOL_GPL(platform_device_add); | 290 | EXPORT_SYMBOL_GPL(platform_device_add); |
290 | 291 | ||
291 | /** | 292 | /** |
292 | * platform_device_del - remove a platform-level device | 293 | * platform_device_del - remove a platform-level device |
293 | * @pdev: platform device we're removing | 294 | * @pdev: platform device we're removing |
294 | * | 295 | * |
295 | * Note that this function will also release all memory- and port-based | 296 | * Note that this function will also release all memory- and port-based |
296 | * resources owned by the device (@dev->resource). This function | 297 | * resources owned by the device (@dev->resource). This function must |
297 | * must _only_ be externally called in error cases. All other usage | 298 | * _only_ be externally called in error cases. All other usage is a bug. |
298 | * is a bug. | ||
299 | */ | 299 | */ |
300 | void platform_device_del(struct platform_device *pdev) | 300 | void platform_device_del(struct platform_device *pdev) |
301 | { | 301 | { |
@@ -314,11 +314,10 @@ void platform_device_del(struct platform_device *pdev) | |||
314 | EXPORT_SYMBOL_GPL(platform_device_del); | 314 | EXPORT_SYMBOL_GPL(platform_device_del); |
315 | 315 | ||
316 | /** | 316 | /** |
317 | * platform_device_register - add a platform-level device | 317 | * platform_device_register - add a platform-level device |
318 | * @pdev: platform device we're adding | 318 | * @pdev: platform device we're adding |
319 | * | ||
320 | */ | 319 | */ |
321 | int platform_device_register(struct platform_device * pdev) | 320 | int platform_device_register(struct platform_device *pdev) |
322 | { | 321 | { |
323 | device_initialize(&pdev->dev); | 322 | device_initialize(&pdev->dev); |
324 | return platform_device_add(pdev); | 323 | return platform_device_add(pdev); |
@@ -326,14 +325,14 @@ int platform_device_register(struct platform_device * pdev) | |||
326 | EXPORT_SYMBOL_GPL(platform_device_register); | 325 | EXPORT_SYMBOL_GPL(platform_device_register); |
327 | 326 | ||
328 | /** | 327 | /** |
329 | * platform_device_unregister - unregister a platform-level device | 328 | * platform_device_unregister - unregister a platform-level device |
330 | * @pdev: platform device we're unregistering | 329 | * @pdev: platform device we're unregistering |
331 | * | 330 | * |
332 | * Unregistration is done in 2 steps. First we release all resources | 331 | * Unregistration is done in 2 steps. First we release all resources |
333 | * and remove it from the subsystem, then we drop reference count by | 332 | * and remove it from the subsystem, then we drop reference count by |
334 | * calling platform_device_put(). | 333 | * calling platform_device_put(). |
335 | */ | 334 | */ |
336 | void platform_device_unregister(struct platform_device * pdev) | 335 | void platform_device_unregister(struct platform_device *pdev) |
337 | { | 336 | { |
338 | platform_device_del(pdev); | 337 | platform_device_del(pdev); |
339 | platform_device_put(pdev); | 338 | platform_device_put(pdev); |
@@ -341,27 +340,29 @@ void platform_device_unregister(struct platform_device * pdev) | |||
341 | EXPORT_SYMBOL_GPL(platform_device_unregister); | 340 | EXPORT_SYMBOL_GPL(platform_device_unregister); |
342 | 341 | ||
343 | /** | 342 | /** |
344 | * platform_device_register_simple | 343 | * platform_device_register_simple |
345 | * @name: base name of the device we're adding | 344 | * @name: base name of the device we're adding |
346 | * @id: instance id | 345 | * @id: instance id |
347 | * @res: set of resources that needs to be allocated for the device | 346 | * @res: set of resources that needs to be allocated for the device |
348 | * @num: number of resources | 347 | * @num: number of resources |
349 | * | 348 | * |
350 | * This function creates a simple platform device that requires minimal | 349 | * This function creates a simple platform device that requires minimal |
351 | * resource and memory management. Canned release function freeing | 350 | * resource and memory management. Canned release function freeing memory |
352 | * memory allocated for the device allows drivers using such devices | 351 | * allocated for the device allows drivers using such devices to be |
353 | * to be unloaded without waiting for the last reference to the device | 352 | * unloaded without waiting for the last reference to the device to be |
354 | * to be dropped. | 353 | * dropped. |
355 | * | 354 | * |
356 | * This interface is primarily intended for use with legacy drivers | 355 | * This interface is primarily intended for use with legacy drivers which |
357 | * which probe hardware directly. Because such drivers create sysfs | 356 | * probe hardware directly. Because such drivers create sysfs device nodes |
358 | * device nodes themselves, rather than letting system infrastructure | 357 | * themselves, rather than letting system infrastructure handle such device |
359 | * handle such device enumeration tasks, they don't fully conform to | 358 | * enumeration tasks, they don't fully conform to the Linux driver model. |
360 | * the Linux driver model. In particular, when such drivers are built | 359 | * In particular, when such drivers are built as modules, they can't be |
361 | * as modules, they can't be "hotplugged". | 360 | * "hotplugged". |
362 | */ | 361 | */ |
363 | struct platform_device *platform_device_register_simple(char *name, int id, | 362 | struct platform_device *platform_device_register_simple(const char *name, |
364 | struct resource *res, unsigned int num) | 363 | int id, |
364 | struct resource *res, | ||
365 | unsigned int num) | ||
365 | { | 366 | { |
366 | struct platform_device *pdev; | 367 | struct platform_device *pdev; |
367 | int retval; | 368 | int retval; |
@@ -436,8 +437,8 @@ static int platform_drv_resume(struct device *_dev) | |||
436 | } | 437 | } |
437 | 438 | ||
438 | /** | 439 | /** |
439 | * platform_driver_register | 440 | * platform_driver_register |
440 | * @drv: platform driver structure | 441 | * @drv: platform driver structure |
441 | */ | 442 | */ |
442 | int platform_driver_register(struct platform_driver *drv) | 443 | int platform_driver_register(struct platform_driver *drv) |
443 | { | 444 | { |
@@ -457,8 +458,8 @@ int platform_driver_register(struct platform_driver *drv) | |||
457 | EXPORT_SYMBOL_GPL(platform_driver_register); | 458 | EXPORT_SYMBOL_GPL(platform_driver_register); |
458 | 459 | ||
459 | /** | 460 | /** |
460 | * platform_driver_unregister | 461 | * platform_driver_unregister |
461 | * @drv: platform driver structure | 462 | * @drv: platform driver structure |
462 | */ | 463 | */ |
463 | void platform_driver_unregister(struct platform_driver *drv) | 464 | void platform_driver_unregister(struct platform_driver *drv) |
464 | { | 465 | { |
@@ -497,12 +498,12 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv, | |||
497 | * if the probe was successful, and make sure any forced probes of | 498 | * if the probe was successful, and make sure any forced probes of |
498 | * new devices fail. | 499 | * new devices fail. |
499 | */ | 500 | */ |
500 | spin_lock(&platform_bus_type.klist_drivers.k_lock); | 501 | spin_lock(&platform_bus_type.p->klist_drivers.k_lock); |
501 | drv->probe = NULL; | 502 | drv->probe = NULL; |
502 | if (code == 0 && list_empty(&drv->driver.klist_devices.k_list)) | 503 | if (code == 0 && list_empty(&drv->driver.p->klist_devices.k_list)) |
503 | retval = -ENODEV; | 504 | retval = -ENODEV; |
504 | drv->driver.probe = platform_drv_probe_fail; | 505 | drv->driver.probe = platform_drv_probe_fail; |
505 | spin_unlock(&platform_bus_type.klist_drivers.k_lock); | 506 | spin_unlock(&platform_bus_type.p->klist_drivers.k_lock); |
506 | 507 | ||
507 | if (code != retval) | 508 | if (code != retval) |
508 | platform_driver_unregister(drv); | 509 | platform_driver_unregister(drv); |
@@ -516,8 +517,8 @@ EXPORT_SYMBOL_GPL(platform_driver_probe); | |||
516 | * (b) sysfs attribute lets new-style coldplug recover from hotplug events | 517 | * (b) sysfs attribute lets new-style coldplug recover from hotplug events |
517 | * mishandled before system is fully running: "modprobe $(cat modalias)" | 518 | * mishandled before system is fully running: "modprobe $(cat modalias)" |
518 | */ | 519 | */ |
519 | static ssize_t | 520 | static ssize_t modalias_show(struct device *dev, struct device_attribute *a, |
520 | modalias_show(struct device *dev, struct device_attribute *a, char *buf) | 521 | char *buf) |
521 | { | 522 | { |
522 | struct platform_device *pdev = to_platform_device(dev); | 523 | struct platform_device *pdev = to_platform_device(dev); |
523 | int len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name); | 524 | int len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name); |
@@ -538,26 +539,24 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
538 | return 0; | 539 | return 0; |
539 | } | 540 | } |
540 | 541 | ||
541 | |||
542 | /** | 542 | /** |
543 | * platform_match - bind platform device to platform driver. | 543 | * platform_match - bind platform device to platform driver. |
544 | * @dev: device. | 544 | * @dev: device. |
545 | * @drv: driver. | 545 | * @drv: driver. |
546 | * | 546 | * |
547 | * Platform device IDs are assumed to be encoded like this: | 547 | * Platform device IDs are assumed to be encoded like this: |
548 | * "<name><instance>", where <name> is a short description of the | 548 | * "<name><instance>", where <name> is a short description of the type of |
549 | * type of device, like "pci" or "floppy", and <instance> is the | 549 | * device, like "pci" or "floppy", and <instance> is the enumerated |
550 | * enumerated instance of the device, like '0' or '42'. | 550 | * instance of the device, like '0' or '42'. Driver IDs are simply |
551 | * Driver IDs are simply "<name>". | 551 | * "<name>". So, extract the <name> from the platform_device structure, |
552 | * So, extract the <name> from the platform_device structure, | 552 | * and compare it against the name of the driver. Return whether they match |
553 | * and compare it against the name of the driver. Return whether | 553 | * or not. |
554 | * they match or not. | ||
555 | */ | 554 | */ |
556 | 555 | static int platform_match(struct device *dev, struct device_driver *drv) | |
557 | static int platform_match(struct device * dev, struct device_driver * drv) | ||
558 | { | 556 | { |
559 | struct platform_device *pdev = container_of(dev, struct platform_device, dev); | 557 | struct platform_device *pdev; |
560 | 558 | ||
559 | pdev = container_of(dev, struct platform_device, dev); | ||
561 | return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0); | 560 | return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0); |
562 | } | 561 | } |
563 | 562 | ||
@@ -574,9 +573,10 @@ static int platform_suspend(struct device *dev, pm_message_t mesg) | |||
574 | static int platform_suspend_late(struct device *dev, pm_message_t mesg) | 573 | static int platform_suspend_late(struct device *dev, pm_message_t mesg) |
575 | { | 574 | { |
576 | struct platform_driver *drv = to_platform_driver(dev->driver); | 575 | struct platform_driver *drv = to_platform_driver(dev->driver); |
577 | struct platform_device *pdev = container_of(dev, struct platform_device, dev); | 576 | struct platform_device *pdev; |
578 | int ret = 0; | 577 | int ret = 0; |
579 | 578 | ||
579 | pdev = container_of(dev, struct platform_device, dev); | ||
580 | if (dev->driver && drv->suspend_late) | 580 | if (dev->driver && drv->suspend_late) |
581 | ret = drv->suspend_late(pdev, mesg); | 581 | ret = drv->suspend_late(pdev, mesg); |
582 | 582 | ||
@@ -586,16 +586,17 @@ static int platform_suspend_late(struct device *dev, pm_message_t mesg) | |||
586 | static int platform_resume_early(struct device *dev) | 586 | static int platform_resume_early(struct device *dev) |
587 | { | 587 | { |
588 | struct platform_driver *drv = to_platform_driver(dev->driver); | 588 | struct platform_driver *drv = to_platform_driver(dev->driver); |
589 | struct platform_device *pdev = container_of(dev, struct platform_device, dev); | 589 | struct platform_device *pdev; |
590 | int ret = 0; | 590 | int ret = 0; |
591 | 591 | ||
592 | pdev = container_of(dev, struct platform_device, dev); | ||
592 | if (dev->driver && drv->resume_early) | 593 | if (dev->driver && drv->resume_early) |
593 | ret = drv->resume_early(pdev); | 594 | ret = drv->resume_early(pdev); |
594 | 595 | ||
595 | return ret; | 596 | return ret; |
596 | } | 597 | } |
597 | 598 | ||
598 | static int platform_resume(struct device * dev) | 599 | static int platform_resume(struct device *dev) |
599 | { | 600 | { |
600 | int ret = 0; | 601 | int ret = 0; |
601 | 602 | ||
diff --git a/drivers/base/power/Makefile b/drivers/base/power/Makefile index 44504e6618fb..06a86fe6a78d 100644 --- a/drivers/base/power/Makefile +++ b/drivers/base/power/Makefile | |||
@@ -1,4 +1,3 @@ | |||
1 | obj-y := shutdown.o | ||
2 | obj-$(CONFIG_PM) += sysfs.o | 1 | obj-$(CONFIG_PM) += sysfs.o |
3 | obj-$(CONFIG_PM_SLEEP) += main.o | 2 | obj-$(CONFIG_PM_SLEEP) += main.o |
4 | obj-$(CONFIG_PM_TRACE) += trace.o | 3 | obj-$(CONFIG_PM_TRACE) += trace.o |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 691ffb64cc37..200ed5fafd50 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -24,20 +24,45 @@ | |||
24 | #include <linux/mutex.h> | 24 | #include <linux/mutex.h> |
25 | #include <linux/pm.h> | 25 | #include <linux/pm.h> |
26 | #include <linux/resume-trace.h> | 26 | #include <linux/resume-trace.h> |
27 | #include <linux/rwsem.h> | ||
27 | 28 | ||
28 | #include "../base.h" | 29 | #include "../base.h" |
29 | #include "power.h" | 30 | #include "power.h" |
30 | 31 | ||
32 | /* | ||
33 | * The entries in the dpm_active list are in a depth first order, simply | ||
34 | * because children are guaranteed to be discovered after parents, and | ||
35 | * are inserted at the back of the list on discovery. | ||
36 | * | ||
37 | * All the other lists are kept in the same order, for consistency. | ||
38 | * However the lists aren't always traversed in the same order. | ||
39 | * Semaphores must be acquired from the top (i.e., front) down | ||
40 | * and released in the opposite order. Devices must be suspended | ||
41 | * from the bottom (i.e., end) up and resumed in the opposite order. | ||
42 | * That way no parent will be suspended while it still has an active | ||
43 | * child. | ||
44 | * | ||
45 | * Since device_pm_add() may be called with a device semaphore held, | ||
46 | * we must never try to acquire a device semaphore while holding | ||
47 | * dpm_list_mutex. | ||
48 | */ | ||
49 | |||
31 | LIST_HEAD(dpm_active); | 50 | LIST_HEAD(dpm_active); |
51 | static LIST_HEAD(dpm_locked); | ||
32 | static LIST_HEAD(dpm_off); | 52 | static LIST_HEAD(dpm_off); |
33 | static LIST_HEAD(dpm_off_irq); | 53 | static LIST_HEAD(dpm_off_irq); |
54 | static LIST_HEAD(dpm_destroy); | ||
34 | 55 | ||
35 | static DEFINE_MUTEX(dpm_mtx); | ||
36 | static DEFINE_MUTEX(dpm_list_mtx); | 56 | static DEFINE_MUTEX(dpm_list_mtx); |
37 | 57 | ||
38 | int (*platform_enable_wakeup)(struct device *dev, int is_on); | 58 | static DECLARE_RWSEM(pm_sleep_rwsem); |
39 | 59 | ||
60 | int (*platform_enable_wakeup)(struct device *dev, int is_on); | ||
40 | 61 | ||
62 | /** | ||
63 | * device_pm_add - add a device to the list of active devices | ||
64 | * @dev: Device to be added to the list | ||
65 | */ | ||
41 | void device_pm_add(struct device *dev) | 66 | void device_pm_add(struct device *dev) |
42 | { | 67 | { |
43 | pr_debug("PM: Adding info for %s:%s\n", | 68 | pr_debug("PM: Adding info for %s:%s\n", |
@@ -48,8 +73,36 @@ void device_pm_add(struct device *dev) | |||
48 | mutex_unlock(&dpm_list_mtx); | 73 | mutex_unlock(&dpm_list_mtx); |
49 | } | 74 | } |
50 | 75 | ||
76 | /** | ||
77 | * device_pm_remove - remove a device from the list of active devices | ||
78 | * @dev: Device to be removed from the list | ||
79 | * | ||
80 | * This function also removes the device's PM-related sysfs attributes. | ||
81 | */ | ||
51 | void device_pm_remove(struct device *dev) | 82 | void device_pm_remove(struct device *dev) |
52 | { | 83 | { |
84 | /* | ||
85 | * If this function is called during a suspend, it will be blocked, | ||
86 | * because we're holding the device's semaphore at that time, which may | ||
87 | * lead to a deadlock. In that case we want to print a warning. | ||
88 | * However, it may also be called by unregister_dropped_devices() with | ||
89 | * the device's semaphore released, in which case the warning should | ||
90 | * not be printed. | ||
91 | */ | ||
92 | if (down_trylock(&dev->sem)) { | ||
93 | if (down_read_trylock(&pm_sleep_rwsem)) { | ||
94 | /* No suspend in progress, wait on dev->sem */ | ||
95 | down(&dev->sem); | ||
96 | up_read(&pm_sleep_rwsem); | ||
97 | } else { | ||
98 | /* Suspend in progress, we may deadlock */ | ||
99 | dev_warn(dev, "Suspicious %s during suspend\n", | ||
100 | __FUNCTION__); | ||
101 | dump_stack(); | ||
102 | /* The user has been warned ... */ | ||
103 | down(&dev->sem); | ||
104 | } | ||
105 | } | ||
53 | pr_debug("PM: Removing info for %s:%s\n", | 106 | pr_debug("PM: Removing info for %s:%s\n", |
54 | dev->bus ? dev->bus->name : "No Bus", | 107 | dev->bus ? dev->bus->name : "No Bus", |
55 | kobject_name(&dev->kobj)); | 108 | kobject_name(&dev->kobj)); |
@@ -57,25 +110,124 @@ void device_pm_remove(struct device *dev) | |||
57 | dpm_sysfs_remove(dev); | 110 | dpm_sysfs_remove(dev); |
58 | list_del_init(&dev->power.entry); | 111 | list_del_init(&dev->power.entry); |
59 | mutex_unlock(&dpm_list_mtx); | 112 | mutex_unlock(&dpm_list_mtx); |
113 | up(&dev->sem); | ||
114 | } | ||
115 | |||
116 | /** | ||
117 | * device_pm_schedule_removal - schedule the removal of a suspended device | ||
118 | * @dev: Device to destroy | ||
119 | * | ||
120 | * Moves the device to the dpm_destroy list for further processing by | ||
121 | * unregister_dropped_devices(). | ||
122 | */ | ||
123 | void device_pm_schedule_removal(struct device *dev) | ||
124 | { | ||
125 | pr_debug("PM: Preparing for removal: %s:%s\n", | ||
126 | dev->bus ? dev->bus->name : "No Bus", | ||
127 | kobject_name(&dev->kobj)); | ||
128 | mutex_lock(&dpm_list_mtx); | ||
129 | list_move_tail(&dev->power.entry, &dpm_destroy); | ||
130 | mutex_unlock(&dpm_list_mtx); | ||
131 | } | ||
132 | |||
133 | /** | ||
134 | * pm_sleep_lock - mutual exclusion for registration and suspend | ||
135 | * | ||
136 | * Returns 0 if no suspend is underway and device registration | ||
137 | * may proceed, otherwise -EBUSY. | ||
138 | */ | ||
139 | int pm_sleep_lock(void) | ||
140 | { | ||
141 | if (down_read_trylock(&pm_sleep_rwsem)) | ||
142 | return 0; | ||
143 | |||
144 | return -EBUSY; | ||
145 | } | ||
146 | |||
147 | /** | ||
148 | * pm_sleep_unlock - mutual exclusion for registration and suspend | ||
149 | * | ||
150 | * This routine undoes the effect of device_pm_add_lock | ||
151 | * when a device's registration is complete. | ||
152 | */ | ||
153 | void pm_sleep_unlock(void) | ||
154 | { | ||
155 | up_read(&pm_sleep_rwsem); | ||
60 | } | 156 | } |
61 | 157 | ||
62 | 158 | ||
63 | /*------------------------- Resume routines -------------------------*/ | 159 | /*------------------------- Resume routines -------------------------*/ |
64 | 160 | ||
65 | /** | 161 | /** |
66 | * resume_device - Restore state for one device. | 162 | * resume_device_early - Power on one device (early resume). |
67 | * @dev: Device. | 163 | * @dev: Device. |
68 | * | 164 | * |
165 | * Must be called with interrupts disabled. | ||
69 | */ | 166 | */ |
70 | 167 | static int resume_device_early(struct device *dev) | |
71 | static int resume_device(struct device * dev) | ||
72 | { | 168 | { |
73 | int error = 0; | 169 | int error = 0; |
74 | 170 | ||
75 | TRACE_DEVICE(dev); | 171 | TRACE_DEVICE(dev); |
76 | TRACE_RESUME(0); | 172 | TRACE_RESUME(0); |
77 | 173 | ||
78 | down(&dev->sem); | 174 | if (dev->bus && dev->bus->resume_early) { |
175 | dev_dbg(dev, "EARLY resume\n"); | ||
176 | error = dev->bus->resume_early(dev); | ||
177 | } | ||
178 | |||
179 | TRACE_RESUME(error); | ||
180 | return error; | ||
181 | } | ||
182 | |||
183 | /** | ||
184 | * dpm_power_up - Power on all regular (non-sysdev) devices. | ||
185 | * | ||
186 | * Walk the dpm_off_irq list and power each device up. This | ||
187 | * is used for devices that required they be powered down with | ||
188 | * interrupts disabled. As devices are powered on, they are moved | ||
189 | * to the dpm_off list. | ||
190 | * | ||
191 | * Must be called with interrupts disabled and only one CPU running. | ||
192 | */ | ||
193 | static void dpm_power_up(void) | ||
194 | { | ||
195 | |||
196 | while (!list_empty(&dpm_off_irq)) { | ||
197 | struct list_head *entry = dpm_off_irq.next; | ||
198 | struct device *dev = to_device(entry); | ||
199 | |||
200 | list_move_tail(entry, &dpm_off); | ||
201 | resume_device_early(dev); | ||
202 | } | ||
203 | } | ||
204 | |||
205 | /** | ||
206 | * device_power_up - Turn on all devices that need special attention. | ||
207 | * | ||
208 | * Power on system devices, then devices that required we shut them down | ||
209 | * with interrupts disabled. | ||
210 | * | ||
211 | * Must be called with interrupts disabled. | ||
212 | */ | ||
213 | void device_power_up(void) | ||
214 | { | ||
215 | sysdev_resume(); | ||
216 | dpm_power_up(); | ||
217 | } | ||
218 | EXPORT_SYMBOL_GPL(device_power_up); | ||
219 | |||
220 | /** | ||
221 | * resume_device - Restore state for one device. | ||
222 | * @dev: Device. | ||
223 | * | ||
224 | */ | ||
225 | static int resume_device(struct device *dev) | ||
226 | { | ||
227 | int error = 0; | ||
228 | |||
229 | TRACE_DEVICE(dev); | ||
230 | TRACE_RESUME(0); | ||
79 | 231 | ||
80 | if (dev->bus && dev->bus->resume) { | 232 | if (dev->bus && dev->bus->resume) { |
81 | dev_dbg(dev,"resuming\n"); | 233 | dev_dbg(dev,"resuming\n"); |
@@ -92,126 +244,94 @@ static int resume_device(struct device * dev) | |||
92 | error = dev->class->resume(dev); | 244 | error = dev->class->resume(dev); |
93 | } | 245 | } |
94 | 246 | ||
95 | up(&dev->sem); | ||
96 | |||
97 | TRACE_RESUME(error); | 247 | TRACE_RESUME(error); |
98 | return error; | 248 | return error; |
99 | } | 249 | } |
100 | 250 | ||
101 | 251 | /** | |
102 | static int resume_device_early(struct device * dev) | 252 | * dpm_resume - Resume every device. |
103 | { | 253 | * |
104 | int error = 0; | 254 | * Resume the devices that have either not gone through |
105 | 255 | * the late suspend, or that did go through it but also | |
106 | TRACE_DEVICE(dev); | 256 | * went through the early resume. |
107 | TRACE_RESUME(0); | 257 | * |
108 | if (dev->bus && dev->bus->resume_early) { | 258 | * Take devices from the dpm_off_list, resume them, |
109 | dev_dbg(dev,"EARLY resume\n"); | 259 | * and put them on the dpm_locked list. |
110 | error = dev->bus->resume_early(dev); | ||
111 | } | ||
112 | TRACE_RESUME(error); | ||
113 | return error; | ||
114 | } | ||
115 | |||
116 | /* | ||
117 | * Resume the devices that have either not gone through | ||
118 | * the late suspend, or that did go through it but also | ||
119 | * went through the early resume | ||
120 | */ | 260 | */ |
121 | static void dpm_resume(void) | 261 | static void dpm_resume(void) |
122 | { | 262 | { |
123 | mutex_lock(&dpm_list_mtx); | 263 | mutex_lock(&dpm_list_mtx); |
124 | while(!list_empty(&dpm_off)) { | 264 | while(!list_empty(&dpm_off)) { |
125 | struct list_head * entry = dpm_off.next; | 265 | struct list_head *entry = dpm_off.next; |
126 | struct device * dev = to_device(entry); | 266 | struct device *dev = to_device(entry); |
127 | |||
128 | get_device(dev); | ||
129 | list_move_tail(entry, &dpm_active); | ||
130 | 267 | ||
268 | list_move_tail(entry, &dpm_locked); | ||
131 | mutex_unlock(&dpm_list_mtx); | 269 | mutex_unlock(&dpm_list_mtx); |
132 | resume_device(dev); | 270 | resume_device(dev); |
133 | mutex_lock(&dpm_list_mtx); | 271 | mutex_lock(&dpm_list_mtx); |
134 | put_device(dev); | ||
135 | } | 272 | } |
136 | mutex_unlock(&dpm_list_mtx); | 273 | mutex_unlock(&dpm_list_mtx); |
137 | } | 274 | } |
138 | 275 | ||
139 | |||
140 | /** | 276 | /** |
141 | * device_resume - Restore state of each device in system. | 277 | * unlock_all_devices - Release each device's semaphore |
142 | * | 278 | * |
143 | * Walk the dpm_off list, remove each entry, resume the device, | 279 | * Go through the dpm_off list. Put each device on the dpm_active |
144 | * then add it to the dpm_active list. | 280 | * list and unlock it. |
145 | */ | 281 | */ |
146 | 282 | static void unlock_all_devices(void) | |
147 | void device_resume(void) | ||
148 | { | 283 | { |
149 | might_sleep(); | 284 | mutex_lock(&dpm_list_mtx); |
150 | mutex_lock(&dpm_mtx); | 285 | while (!list_empty(&dpm_locked)) { |
151 | dpm_resume(); | 286 | struct list_head *entry = dpm_locked.prev; |
152 | mutex_unlock(&dpm_mtx); | 287 | struct device *dev = to_device(entry); |
153 | } | ||
154 | |||
155 | EXPORT_SYMBOL_GPL(device_resume); | ||
156 | 288 | ||
289 | list_move(entry, &dpm_active); | ||
290 | up(&dev->sem); | ||
291 | } | ||
292 | mutex_unlock(&dpm_list_mtx); | ||
293 | } | ||
157 | 294 | ||
158 | /** | 295 | /** |
159 | * dpm_power_up - Power on some devices. | 296 | * unregister_dropped_devices - Unregister devices scheduled for removal |
160 | * | ||
161 | * Walk the dpm_off_irq list and power each device up. This | ||
162 | * is used for devices that required they be powered down with | ||
163 | * interrupts disabled. As devices are powered on, they are moved | ||
164 | * to the dpm_active list. | ||
165 | * | 297 | * |
166 | * Interrupts must be disabled when calling this. | 298 | * Unregister all devices on the dpm_destroy list. |
167 | */ | 299 | */ |
168 | 300 | static void unregister_dropped_devices(void) | |
169 | static void dpm_power_up(void) | ||
170 | { | 301 | { |
171 | while(!list_empty(&dpm_off_irq)) { | 302 | mutex_lock(&dpm_list_mtx); |
172 | struct list_head * entry = dpm_off_irq.next; | 303 | while (!list_empty(&dpm_destroy)) { |
173 | struct device * dev = to_device(entry); | 304 | struct list_head *entry = dpm_destroy.next; |
305 | struct device *dev = to_device(entry); | ||
174 | 306 | ||
175 | list_move_tail(entry, &dpm_off); | 307 | up(&dev->sem); |
176 | resume_device_early(dev); | 308 | mutex_unlock(&dpm_list_mtx); |
309 | /* This also removes the device from the list */ | ||
310 | device_unregister(dev); | ||
311 | mutex_lock(&dpm_list_mtx); | ||
177 | } | 312 | } |
313 | mutex_unlock(&dpm_list_mtx); | ||
178 | } | 314 | } |
179 | 315 | ||
180 | |||
181 | /** | 316 | /** |
182 | * device_power_up - Turn on all devices that need special attention. | 317 | * device_resume - Restore state of each device in system. |
183 | * | 318 | * |
184 | * Power on system devices then devices that required we shut them down | 319 | * Resume all the devices, unlock them all, and allow new |
185 | * with interrupts disabled. | 320 | * devices to be registered once again. |
186 | * Called with interrupts disabled. | ||
187 | */ | 321 | */ |
188 | 322 | void device_resume(void) | |
189 | void device_power_up(void) | ||
190 | { | 323 | { |
191 | sysdev_resume(); | 324 | might_sleep(); |
192 | dpm_power_up(); | 325 | dpm_resume(); |
326 | unlock_all_devices(); | ||
327 | unregister_dropped_devices(); | ||
328 | up_write(&pm_sleep_rwsem); | ||
193 | } | 329 | } |
194 | 330 | EXPORT_SYMBOL_GPL(device_resume); | |
195 | EXPORT_SYMBOL_GPL(device_power_up); | ||
196 | 331 | ||
197 | 332 | ||
198 | /*------------------------- Suspend routines -------------------------*/ | 333 | /*------------------------- Suspend routines -------------------------*/ |
199 | 334 | ||
200 | /* | ||
201 | * The entries in the dpm_active list are in a depth first order, simply | ||
202 | * because children are guaranteed to be discovered after parents, and | ||
203 | * are inserted at the back of the list on discovery. | ||
204 | * | ||
205 | * All list on the suspend path are done in reverse order, so we operate | ||
206 | * on the leaves of the device tree (or forests, depending on how you want | ||
207 | * to look at it ;) first. As nodes are removed from the back of the list, | ||
208 | * they are inserted into the front of their destintation lists. | ||
209 | * | ||
210 | * Things are the reverse on the resume path - iterations are done in | ||
211 | * forward order, and nodes are inserted at the back of their destination | ||
212 | * lists. This way, the ancestors will be accessed before their descendents. | ||
213 | */ | ||
214 | |||
215 | static inline char *suspend_verb(u32 event) | 335 | static inline char *suspend_verb(u32 event) |
216 | { | 336 | { |
217 | switch (event) { | 337 | switch (event) { |
@@ -222,7 +342,6 @@ static inline char *suspend_verb(u32 event) | |||
222 | } | 342 | } |
223 | } | 343 | } |
224 | 344 | ||
225 | |||
226 | static void | 345 | static void |
227 | suspend_device_dbg(struct device *dev, pm_message_t state, char *info) | 346 | suspend_device_dbg(struct device *dev, pm_message_t state, char *info) |
228 | { | 347 | { |
@@ -232,16 +351,73 @@ suspend_device_dbg(struct device *dev, pm_message_t state, char *info) | |||
232 | } | 351 | } |
233 | 352 | ||
234 | /** | 353 | /** |
235 | * suspend_device - Save state of one device. | 354 | * suspend_device_late - Shut down one device (late suspend). |
236 | * @dev: Device. | 355 | * @dev: Device. |
237 | * @state: Power state device is entering. | 356 | * @state: Power state device is entering. |
357 | * | ||
358 | * This is called with interrupts off and only a single CPU running. | ||
238 | */ | 359 | */ |
360 | static int suspend_device_late(struct device *dev, pm_message_t state) | ||
361 | { | ||
362 | int error = 0; | ||
239 | 363 | ||
240 | static int suspend_device(struct device * dev, pm_message_t state) | 364 | if (dev->bus && dev->bus->suspend_late) { |
365 | suspend_device_dbg(dev, state, "LATE "); | ||
366 | error = dev->bus->suspend_late(dev, state); | ||
367 | suspend_report_result(dev->bus->suspend_late, error); | ||
368 | } | ||
369 | return error; | ||
370 | } | ||
371 | |||
372 | /** | ||
373 | * device_power_down - Shut down special devices. | ||
374 | * @state: Power state to enter. | ||
375 | * | ||
376 | * Power down devices that require interrupts to be disabled | ||
377 | * and move them from the dpm_off list to the dpm_off_irq list. | ||
378 | * Then power down system devices. | ||
379 | * | ||
380 | * Must be called with interrupts disabled and only one CPU running. | ||
381 | */ | ||
382 | int device_power_down(pm_message_t state) | ||
383 | { | ||
384 | int error = 0; | ||
385 | |||
386 | while (!list_empty(&dpm_off)) { | ||
387 | struct list_head *entry = dpm_off.prev; | ||
388 | struct device *dev = to_device(entry); | ||
389 | |||
390 | list_del_init(&dev->power.entry); | ||
391 | error = suspend_device_late(dev, state); | ||
392 | if (error) { | ||
393 | printk(KERN_ERR "Could not power down device %s: " | ||
394 | "error %d\n", | ||
395 | kobject_name(&dev->kobj), error); | ||
396 | if (list_empty(&dev->power.entry)) | ||
397 | list_add(&dev->power.entry, &dpm_off); | ||
398 | break; | ||
399 | } | ||
400 | if (list_empty(&dev->power.entry)) | ||
401 | list_add(&dev->power.entry, &dpm_off_irq); | ||
402 | } | ||
403 | |||
404 | if (!error) | ||
405 | error = sysdev_suspend(state); | ||
406 | if (error) | ||
407 | dpm_power_up(); | ||
408 | return error; | ||
409 | } | ||
410 | EXPORT_SYMBOL_GPL(device_power_down); | ||
411 | |||
412 | /** | ||
413 | * suspend_device - Save state of one device. | ||
414 | * @dev: Device. | ||
415 | * @state: Power state device is entering. | ||
416 | */ | ||
417 | int suspend_device(struct device *dev, pm_message_t state) | ||
241 | { | 418 | { |
242 | int error = 0; | 419 | int error = 0; |
243 | 420 | ||
244 | down(&dev->sem); | ||
245 | if (dev->power.power_state.event) { | 421 | if (dev->power.power_state.event) { |
246 | dev_dbg(dev, "PM: suspend %d-->%d\n", | 422 | dev_dbg(dev, "PM: suspend %d-->%d\n", |
247 | dev->power.power_state.event, state.event); | 423 | dev->power.power_state.event, state.event); |
@@ -264,123 +440,105 @@ static int suspend_device(struct device * dev, pm_message_t state) | |||
264 | error = dev->bus->suspend(dev, state); | 440 | error = dev->bus->suspend(dev, state); |
265 | suspend_report_result(dev->bus->suspend, error); | 441 | suspend_report_result(dev->bus->suspend, error); |
266 | } | 442 | } |
267 | up(&dev->sem); | ||
268 | return error; | ||
269 | } | ||
270 | |||
271 | |||
272 | /* | ||
273 | * This is called with interrupts off, only a single CPU | ||
274 | * running. We can't acquire a mutex or semaphore (and we don't | ||
275 | * need the protection) | ||
276 | */ | ||
277 | static int suspend_device_late(struct device *dev, pm_message_t state) | ||
278 | { | ||
279 | int error = 0; | ||
280 | |||
281 | if (dev->bus && dev->bus->suspend_late) { | ||
282 | suspend_device_dbg(dev, state, "LATE "); | ||
283 | error = dev->bus->suspend_late(dev, state); | ||
284 | suspend_report_result(dev->bus->suspend_late, error); | ||
285 | } | ||
286 | return error; | 443 | return error; |
287 | } | 444 | } |
288 | 445 | ||
289 | /** | 446 | /** |
290 | * device_suspend - Save state and stop all devices in system. | 447 | * dpm_suspend - Suspend every device. |
291 | * @state: Power state to put each device in. | 448 | * @state: Power state to put each device in. |
292 | * | 449 | * |
293 | * Walk the dpm_active list, call ->suspend() for each device, and move | 450 | * Walk the dpm_locked list. Suspend each device and move it |
294 | * it to the dpm_off list. | 451 | * to the dpm_off list. |
295 | * | 452 | * |
296 | * (For historical reasons, if it returns -EAGAIN, that used to mean | 453 | * (For historical reasons, if it returns -EAGAIN, that used to mean |
297 | * that the device would be called again with interrupts disabled. | 454 | * that the device would be called again with interrupts disabled. |
298 | * These days, we use the "suspend_late()" callback for that, so we | 455 | * These days, we use the "suspend_late()" callback for that, so we |
299 | * print a warning and consider it an error). | 456 | * print a warning and consider it an error). |
300 | * | ||
301 | * If we get a different error, try and back out. | ||
302 | * | ||
303 | * If we hit a failure with any of the devices, call device_resume() | ||
304 | * above to bring the suspended devices back to life. | ||
305 | * | ||
306 | */ | 457 | */ |
307 | 458 | static int dpm_suspend(pm_message_t state) | |
308 | int device_suspend(pm_message_t state) | ||
309 | { | 459 | { |
310 | int error = 0; | 460 | int error = 0; |
311 | 461 | ||
312 | might_sleep(); | ||
313 | mutex_lock(&dpm_mtx); | ||
314 | mutex_lock(&dpm_list_mtx); | 462 | mutex_lock(&dpm_list_mtx); |
315 | while (!list_empty(&dpm_active) && error == 0) { | 463 | while (!list_empty(&dpm_locked)) { |
316 | struct list_head * entry = dpm_active.prev; | 464 | struct list_head *entry = dpm_locked.prev; |
317 | struct device * dev = to_device(entry); | 465 | struct device *dev = to_device(entry); |
318 | 466 | ||
319 | get_device(dev); | 467 | list_del_init(&dev->power.entry); |
320 | mutex_unlock(&dpm_list_mtx); | 468 | mutex_unlock(&dpm_list_mtx); |
321 | |||
322 | error = suspend_device(dev, state); | 469 | error = suspend_device(dev, state); |
323 | 470 | if (error) { | |
324 | mutex_lock(&dpm_list_mtx); | ||
325 | |||
326 | /* Check if the device got removed */ | ||
327 | if (!list_empty(&dev->power.entry)) { | ||
328 | /* Move it to the dpm_off list */ | ||
329 | if (!error) | ||
330 | list_move(&dev->power.entry, &dpm_off); | ||
331 | } | ||
332 | if (error) | ||
333 | printk(KERN_ERR "Could not suspend device %s: " | 471 | printk(KERN_ERR "Could not suspend device %s: " |
334 | "error %d%s\n", | 472 | "error %d%s\n", |
335 | kobject_name(&dev->kobj), error, | 473 | kobject_name(&dev->kobj), |
336 | error == -EAGAIN ? " (please convert to suspend_late)" : ""); | 474 | error, |
337 | put_device(dev); | 475 | (error == -EAGAIN ? |
476 | " (please convert to suspend_late)" : | ||
477 | "")); | ||
478 | mutex_lock(&dpm_list_mtx); | ||
479 | if (list_empty(&dev->power.entry)) | ||
480 | list_add(&dev->power.entry, &dpm_locked); | ||
481 | mutex_unlock(&dpm_list_mtx); | ||
482 | break; | ||
483 | } | ||
484 | mutex_lock(&dpm_list_mtx); | ||
485 | if (list_empty(&dev->power.entry)) | ||
486 | list_add(&dev->power.entry, &dpm_off); | ||
338 | } | 487 | } |
339 | mutex_unlock(&dpm_list_mtx); | 488 | mutex_unlock(&dpm_list_mtx); |
340 | if (error) | ||
341 | dpm_resume(); | ||
342 | 489 | ||
343 | mutex_unlock(&dpm_mtx); | ||
344 | return error; | 490 | return error; |
345 | } | 491 | } |
346 | 492 | ||
347 | EXPORT_SYMBOL_GPL(device_suspend); | ||
348 | |||
349 | /** | 493 | /** |
350 | * device_power_down - Shut down special devices. | 494 | * lock_all_devices - Acquire every device's semaphore |
351 | * @state: Power state to enter. | ||
352 | * | 495 | * |
353 | * Walk the dpm_off_irq list, calling ->power_down() for each device that | 496 | * Go through the dpm_active list. Carefully lock each device's |
354 | * couldn't power down the device with interrupts enabled. When we're | 497 | * semaphore and put it in on the dpm_locked list. |
355 | * done, power down system devices. | ||
356 | */ | 498 | */ |
357 | 499 | static void lock_all_devices(void) | |
358 | int device_power_down(pm_message_t state) | ||
359 | { | 500 | { |
360 | int error = 0; | 501 | mutex_lock(&dpm_list_mtx); |
361 | struct device * dev; | 502 | while (!list_empty(&dpm_active)) { |
503 | struct list_head *entry = dpm_active.next; | ||
504 | struct device *dev = to_device(entry); | ||
362 | 505 | ||
363 | while (!list_empty(&dpm_off)) { | 506 | /* Required locking order is dev->sem first, |
364 | struct list_head * entry = dpm_off.prev; | 507 | * then dpm_list_mutex. Hence this awkward code. |
508 | */ | ||
509 | get_device(dev); | ||
510 | mutex_unlock(&dpm_list_mtx); | ||
511 | down(&dev->sem); | ||
512 | mutex_lock(&dpm_list_mtx); | ||
365 | 513 | ||
366 | dev = to_device(entry); | 514 | if (list_empty(entry)) |
367 | error = suspend_device_late(dev, state); | 515 | up(&dev->sem); /* Device was removed */ |
368 | if (error) | 516 | else |
369 | goto Error; | 517 | list_move_tail(entry, &dpm_locked); |
370 | list_move(&dev->power.entry, &dpm_off_irq); | 518 | put_device(dev); |
371 | } | 519 | } |
520 | mutex_unlock(&dpm_list_mtx); | ||
521 | } | ||
522 | |||
523 | /** | ||
524 | * device_suspend - Save state and stop all devices in system. | ||
525 | * | ||
526 | * Prevent new devices from being registered, then lock all devices | ||
527 | * and suspend them. | ||
528 | */ | ||
529 | int device_suspend(pm_message_t state) | ||
530 | { | ||
531 | int error; | ||
372 | 532 | ||
373 | error = sysdev_suspend(state); | 533 | might_sleep(); |
374 | Done: | 534 | down_write(&pm_sleep_rwsem); |
535 | lock_all_devices(); | ||
536 | error = dpm_suspend(state); | ||
537 | if (error) | ||
538 | device_resume(); | ||
375 | return error; | 539 | return error; |
376 | Error: | ||
377 | printk(KERN_ERR "Could not power down device %s: " | ||
378 | "error %d\n", kobject_name(&dev->kobj), error); | ||
379 | dpm_power_up(); | ||
380 | goto Done; | ||
381 | } | 540 | } |
382 | 541 | EXPORT_SYMBOL_GPL(device_suspend); | |
383 | EXPORT_SYMBOL_GPL(device_power_down); | ||
384 | 542 | ||
385 | void __suspend_report_result(const char *function, void *fn, int ret) | 543 | void __suspend_report_result(const char *function, void *fn, int ret) |
386 | { | 544 | { |
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h index 379da4e958e0..6f0dfca8ebdd 100644 --- a/drivers/base/power/power.h +++ b/drivers/base/power/power.h | |||
@@ -1,10 +1,3 @@ | |||
1 | /* | ||
2 | * shutdown.c | ||
3 | */ | ||
4 | |||
5 | extern void device_shutdown(void); | ||
6 | |||
7 | |||
8 | #ifdef CONFIG_PM_SLEEP | 1 | #ifdef CONFIG_PM_SLEEP |
9 | 2 | ||
10 | /* | 3 | /* |
@@ -20,6 +13,9 @@ static inline struct device *to_device(struct list_head *entry) | |||
20 | 13 | ||
21 | extern void device_pm_add(struct device *); | 14 | extern void device_pm_add(struct device *); |
22 | extern void device_pm_remove(struct device *); | 15 | extern void device_pm_remove(struct device *); |
16 | extern void device_pm_schedule_removal(struct device *); | ||
17 | extern int pm_sleep_lock(void); | ||
18 | extern void pm_sleep_unlock(void); | ||
23 | 19 | ||
24 | #else /* CONFIG_PM_SLEEP */ | 20 | #else /* CONFIG_PM_SLEEP */ |
25 | 21 | ||
@@ -32,6 +28,15 @@ static inline void device_pm_remove(struct device *dev) | |||
32 | { | 28 | { |
33 | } | 29 | } |
34 | 30 | ||
31 | static inline int pm_sleep_lock(void) | ||
32 | { | ||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | static inline void pm_sleep_unlock(void) | ||
37 | { | ||
38 | } | ||
39 | |||
35 | #endif | 40 | #endif |
36 | 41 | ||
37 | #ifdef CONFIG_PM | 42 | #ifdef CONFIG_PM |
diff --git a/drivers/base/power/shutdown.c b/drivers/base/power/shutdown.c deleted file mode 100644 index 56e8eaaac012..000000000000 --- a/drivers/base/power/shutdown.c +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | /* | ||
2 | * shutdown.c - power management functions for the device tree. | ||
3 | * | ||
4 | * Copyright (c) 2002-3 Patrick Mochel | ||
5 | * 2002-3 Open Source Development Lab | ||
6 | * | ||
7 | * This file is released under the GPLv2 | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/device.h> | ||
12 | #include <asm/semaphore.h> | ||
13 | |||
14 | #include "../base.h" | ||
15 | #include "power.h" | ||
16 | |||
17 | #define to_dev(node) container_of(node, struct device, kobj.entry) | ||
18 | |||
19 | |||
20 | /** | ||
21 | * We handle system devices differently - we suspend and shut them | ||
22 | * down last and resume them first. That way, we don't do anything stupid like | ||
23 | * shutting down the interrupt controller before any devices.. | ||
24 | * | ||
25 | * Note that there are not different stages for power management calls - | ||
26 | * they only get one called once when interrupts are disabled. | ||
27 | */ | ||
28 | |||
29 | |||
30 | /** | ||
31 | * device_shutdown - call ->shutdown() on each device to shutdown. | ||
32 | */ | ||
33 | void device_shutdown(void) | ||
34 | { | ||
35 | struct device * dev, *devn; | ||
36 | |||
37 | list_for_each_entry_safe_reverse(dev, devn, &devices_subsys.list, | ||
38 | kobj.entry) { | ||
39 | if (dev->bus && dev->bus->shutdown) { | ||
40 | dev_dbg(dev, "shutdown\n"); | ||
41 | dev->bus->shutdown(dev); | ||
42 | } else if (dev->driver && dev->driver->shutdown) { | ||
43 | dev_dbg(dev, "shutdown\n"); | ||
44 | dev->driver->shutdown(dev); | ||
45 | } | ||
46 | } | ||
47 | } | ||
48 | |||
diff --git a/drivers/base/sys.c b/drivers/base/sys.c index ac7ff6d0c6e5..2f79c55acdcc 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c | |||
@@ -25,8 +25,6 @@ | |||
25 | 25 | ||
26 | #include "base.h" | 26 | #include "base.h" |
27 | 27 | ||
28 | extern struct kset devices_subsys; | ||
29 | |||
30 | #define to_sysdev(k) container_of(k, struct sys_device, kobj) | 28 | #define to_sysdev(k) container_of(k, struct sys_device, kobj) |
31 | #define to_sysdev_attr(a) container_of(a, struct sysdev_attribute, attr) | 29 | #define to_sysdev_attr(a) container_of(a, struct sysdev_attribute, attr) |
32 | 30 | ||
@@ -128,18 +126,17 @@ void sysdev_class_remove_file(struct sysdev_class *c, | |||
128 | } | 126 | } |
129 | EXPORT_SYMBOL_GPL(sysdev_class_remove_file); | 127 | EXPORT_SYMBOL_GPL(sysdev_class_remove_file); |
130 | 128 | ||
131 | /* | 129 | static struct kset *system_kset; |
132 | * declare system_subsys | ||
133 | */ | ||
134 | static decl_subsys(system, &ktype_sysdev_class, NULL); | ||
135 | 130 | ||
136 | int sysdev_class_register(struct sysdev_class * cls) | 131 | int sysdev_class_register(struct sysdev_class * cls) |
137 | { | 132 | { |
138 | pr_debug("Registering sysdev class '%s'\n", | 133 | pr_debug("Registering sysdev class '%s'\n", |
139 | kobject_name(&cls->kset.kobj)); | 134 | kobject_name(&cls->kset.kobj)); |
140 | INIT_LIST_HEAD(&cls->drivers); | 135 | INIT_LIST_HEAD(&cls->drivers); |
141 | cls->kset.kobj.parent = &system_subsys.kobj; | 136 | cls->kset.kobj.parent = &system_kset->kobj; |
142 | cls->kset.kobj.kset = &system_subsys; | 137 | cls->kset.kobj.ktype = &ktype_sysdev_class; |
138 | cls->kset.kobj.kset = system_kset; | ||
139 | kobject_set_name(&cls->kset.kobj, cls->name); | ||
143 | return kset_register(&cls->kset); | 140 | return kset_register(&cls->kset); |
144 | } | 141 | } |
145 | 142 | ||
@@ -228,20 +225,15 @@ int sysdev_register(struct sys_device * sysdev) | |||
228 | if (!cls) | 225 | if (!cls) |
229 | return -EINVAL; | 226 | return -EINVAL; |
230 | 227 | ||
228 | pr_debug("Registering sys device '%s'\n", kobject_name(&sysdev->kobj)); | ||
229 | |||
231 | /* Make sure the kset is set */ | 230 | /* Make sure the kset is set */ |
232 | sysdev->kobj.kset = &cls->kset; | 231 | sysdev->kobj.kset = &cls->kset; |
233 | 232 | ||
234 | /* But make sure we point to the right type for sysfs translation */ | ||
235 | sysdev->kobj.ktype = &ktype_sysdev; | ||
236 | error = kobject_set_name(&sysdev->kobj, "%s%d", | ||
237 | kobject_name(&cls->kset.kobj), sysdev->id); | ||
238 | if (error) | ||
239 | return error; | ||
240 | |||
241 | pr_debug("Registering sys device '%s'\n", kobject_name(&sysdev->kobj)); | ||
242 | |||
243 | /* Register the object */ | 233 | /* Register the object */ |
244 | error = kobject_register(&sysdev->kobj); | 234 | error = kobject_init_and_add(&sysdev->kobj, &ktype_sysdev, NULL, |
235 | "%s%d", kobject_name(&cls->kset.kobj), | ||
236 | sysdev->id); | ||
245 | 237 | ||
246 | if (!error) { | 238 | if (!error) { |
247 | struct sysdev_driver * drv; | 239 | struct sysdev_driver * drv; |
@@ -258,6 +250,7 @@ int sysdev_register(struct sys_device * sysdev) | |||
258 | } | 250 | } |
259 | mutex_unlock(&sysdev_drivers_lock); | 251 | mutex_unlock(&sysdev_drivers_lock); |
260 | } | 252 | } |
253 | kobject_uevent(&sysdev->kobj, KOBJ_ADD); | ||
261 | return error; | 254 | return error; |
262 | } | 255 | } |
263 | 256 | ||
@@ -272,7 +265,7 @@ void sysdev_unregister(struct sys_device * sysdev) | |||
272 | } | 265 | } |
273 | mutex_unlock(&sysdev_drivers_lock); | 266 | mutex_unlock(&sysdev_drivers_lock); |
274 | 267 | ||
275 | kobject_unregister(&sysdev->kobj); | 268 | kobject_put(&sysdev->kobj); |
276 | } | 269 | } |
277 | 270 | ||
278 | 271 | ||
@@ -298,8 +291,7 @@ void sysdev_shutdown(void) | |||
298 | pr_debug("Shutting Down System Devices\n"); | 291 | pr_debug("Shutting Down System Devices\n"); |
299 | 292 | ||
300 | mutex_lock(&sysdev_drivers_lock); | 293 | mutex_lock(&sysdev_drivers_lock); |
301 | list_for_each_entry_reverse(cls, &system_subsys.list, | 294 | list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) { |
302 | kset.kobj.entry) { | ||
303 | struct sys_device * sysdev; | 295 | struct sys_device * sysdev; |
304 | 296 | ||
305 | pr_debug("Shutting down type '%s':\n", | 297 | pr_debug("Shutting down type '%s':\n", |
@@ -361,9 +353,7 @@ int sysdev_suspend(pm_message_t state) | |||
361 | 353 | ||
362 | pr_debug("Suspending System Devices\n"); | 354 | pr_debug("Suspending System Devices\n"); |
363 | 355 | ||
364 | list_for_each_entry_reverse(cls, &system_subsys.list, | 356 | list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) { |
365 | kset.kobj.entry) { | ||
366 | |||
367 | pr_debug("Suspending type '%s':\n", | 357 | pr_debug("Suspending type '%s':\n", |
368 | kobject_name(&cls->kset.kobj)); | 358 | kobject_name(&cls->kset.kobj)); |
369 | 359 | ||
@@ -414,8 +404,7 @@ aux_driver: | |||
414 | } | 404 | } |
415 | 405 | ||
416 | /* resume other classes */ | 406 | /* resume other classes */ |
417 | list_for_each_entry_continue(cls, &system_subsys.list, | 407 | list_for_each_entry_continue(cls, &system_kset->list, kset.kobj.entry) { |
418 | kset.kobj.entry) { | ||
419 | list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) { | 408 | list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) { |
420 | pr_debug(" %s\n", kobject_name(&err_dev->kobj)); | 409 | pr_debug(" %s\n", kobject_name(&err_dev->kobj)); |
421 | __sysdev_resume(err_dev); | 410 | __sysdev_resume(err_dev); |
@@ -440,7 +429,7 @@ int sysdev_resume(void) | |||
440 | 429 | ||
441 | pr_debug("Resuming System Devices\n"); | 430 | pr_debug("Resuming System Devices\n"); |
442 | 431 | ||
443 | list_for_each_entry(cls, &system_subsys.list, kset.kobj.entry) { | 432 | list_for_each_entry(cls, &system_kset->list, kset.kobj.entry) { |
444 | struct sys_device * sysdev; | 433 | struct sys_device * sysdev; |
445 | 434 | ||
446 | pr_debug("Resuming type '%s':\n", | 435 | pr_debug("Resuming type '%s':\n", |
@@ -458,8 +447,10 @@ int sysdev_resume(void) | |||
458 | 447 | ||
459 | int __init system_bus_init(void) | 448 | int __init system_bus_init(void) |
460 | { | 449 | { |
461 | system_subsys.kobj.parent = &devices_subsys.kobj; | 450 | system_kset = kset_create_and_add("system", NULL, &devices_kset->kobj); |
462 | return subsystem_register(&system_subsys); | 451 | if (!system_kset) |
452 | return -ENOMEM; | ||
453 | return 0; | ||
463 | } | 454 | } |
464 | 455 | ||
465 | EXPORT_SYMBOL_GPL(sysdev_register); | 456 | EXPORT_SYMBOL_GPL(sysdev_register); |