diff options
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); |