diff options
Diffstat (limited to 'drivers/base/dd.c')
-rw-r--r-- | drivers/base/dd.c | 164 |
1 files changed, 80 insertions, 84 deletions
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 | |||