diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-26 14:17:04 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-26 14:17:04 -0400 |
commit | 0c93ea4064a209cdc36de8a9a3003d43d08f46f7 (patch) | |
tree | ff19952407c523a1349ef56c05993416dd28437e /drivers/base/dd.c | |
parent | bc2fd381d8f9dbeb181f82286cdca1567e3d0def (diff) | |
parent | e6e66b02e11563abdb7f69dcb7a2efbd8d577e77 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6: (61 commits)
Dynamic debug: fix pr_fmt() build error
Dynamic debug: allow simple quoting of words
dynamic debug: update docs
dynamic debug: combine dprintk and dynamic printk
sysfs: fix some bin_vm_ops errors
kobject: don't block for each kobject_uevent
sysfs: only allow one scheduled removal callback per kobj
Driver core: Fix device_move() vs. dpm list ordering, v2
Driver core: some cleanup on drivers/base/sys.c
Driver core: implement uevent suppress in kobject
vcs: hook sysfs devices into object lifetime instead of "binding"
driver core: fix passing platform_data
driver core: move platform_data into platform_device
sysfs: don't block indefinitely for unmapped files.
driver core: move knode_bus into private structure
driver core: move knode_driver into private structure
driver core: move klist_children into private structure
driver core: create a private portion of struct device
driver core: remove polling for driver_probe_done(v5)
sysfs: reference sysfs_dirent from sysfs inodes
...
Fixed conflicts in drivers/sh/maple/maple.c manually
Diffstat (limited to 'drivers/base/dd.c')
-rw-r--r-- | drivers/base/dd.c | 40 |
1 files changed, 17 insertions, 23 deletions
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 135231239103..f17c3266a0e0 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -30,7 +30,7 @@ | |||
30 | 30 | ||
31 | static void driver_bound(struct device *dev) | 31 | static void driver_bound(struct device *dev) |
32 | { | 32 | { |
33 | if (klist_node_attached(&dev->knode_driver)) { | 33 | if (klist_node_attached(&dev->p->knode_driver)) { |
34 | printk(KERN_WARNING "%s: device %s already bound\n", | 34 | printk(KERN_WARNING "%s: device %s already bound\n", |
35 | __func__, kobject_name(&dev->kobj)); | 35 | __func__, kobject_name(&dev->kobj)); |
36 | return; | 36 | return; |
@@ -43,7 +43,7 @@ static void driver_bound(struct device *dev) | |||
43 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, | 43 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, |
44 | BUS_NOTIFY_BOUND_DRIVER, dev); | 44 | BUS_NOTIFY_BOUND_DRIVER, dev); |
45 | 45 | ||
46 | klist_add_tail(&dev->knode_driver, &dev->driver->p->klist_devices); | 46 | klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices); |
47 | } | 47 | } |
48 | 48 | ||
49 | static int driver_sysfs_add(struct device *dev) | 49 | static int driver_sysfs_add(struct device *dev) |
@@ -172,16 +172,12 @@ int driver_probe_done(void) | |||
172 | /** | 172 | /** |
173 | * wait_for_device_probe | 173 | * wait_for_device_probe |
174 | * Wait for device probing to be completed. | 174 | * Wait for device probing to be completed. |
175 | * | ||
176 | * Note: this function polls at 100 msec intervals. | ||
177 | */ | 175 | */ |
178 | int wait_for_device_probe(void) | 176 | void wait_for_device_probe(void) |
179 | { | 177 | { |
180 | /* wait for the known devices to complete their probing */ | 178 | /* wait for the known devices to complete their probing */ |
181 | while (driver_probe_done() != 0) | 179 | wait_event(probe_waitqueue, atomic_read(&probe_count) == 0); |
182 | msleep(100); | ||
183 | async_synchronize_full(); | 180 | async_synchronize_full(); |
184 | return 0; | ||
185 | } | 181 | } |
186 | 182 | ||
187 | /** | 183 | /** |
@@ -189,14 +185,8 @@ int wait_for_device_probe(void) | |||
189 | * @drv: driver to bind a device to | 185 | * @drv: driver to bind a device to |
190 | * @dev: device to try to bind to the driver | 186 | * @dev: device to try to bind to the driver |
191 | * | 187 | * |
192 | * First, we call the bus's match function, if one present, which should | 188 | * This function returns -ENODEV if the device is not registered, |
193 | * compare the device IDs the driver supports with the device IDs of the | 189 | * 1 if the device is bound sucessfully and 0 otherwise. |
194 | * device. Note we don't do this ourselves because we don't know the | ||
195 | * format of the ID structures, nor what is to be considered a match and | ||
196 | * what is not. | ||
197 | * | ||
198 | * This function returns 1 if a match is found, -ENODEV if the device is | ||
199 | * not registered, and 0 otherwise. | ||
200 | * | 190 | * |
201 | * This function must be called with @dev->sem held. When called for a | 191 | * This function must be called with @dev->sem held. When called for a |
202 | * USB interface, @dev->parent->sem must be held as well. | 192 | * USB interface, @dev->parent->sem must be held as well. |
@@ -207,21 +197,22 @@ int driver_probe_device(struct device_driver *drv, struct device *dev) | |||
207 | 197 | ||
208 | if (!device_is_registered(dev)) | 198 | if (!device_is_registered(dev)) |
209 | return -ENODEV; | 199 | return -ENODEV; |
210 | if (drv->bus->match && !drv->bus->match(dev, drv)) | ||
211 | goto done; | ||
212 | 200 | ||
213 | pr_debug("bus: '%s': %s: matched device %s with driver %s\n", | 201 | pr_debug("bus: '%s': %s: matched device %s with driver %s\n", |
214 | drv->bus->name, __func__, dev_name(dev), drv->name); | 202 | drv->bus->name, __func__, dev_name(dev), drv->name); |
215 | 203 | ||
216 | ret = really_probe(dev, drv); | 204 | ret = really_probe(dev, drv); |
217 | 205 | ||
218 | done: | ||
219 | return ret; | 206 | return ret; |
220 | } | 207 | } |
221 | 208 | ||
222 | static int __device_attach(struct device_driver *drv, void *data) | 209 | static int __device_attach(struct device_driver *drv, void *data) |
223 | { | 210 | { |
224 | struct device *dev = data; | 211 | struct device *dev = data; |
212 | |||
213 | if (!driver_match_device(drv, dev)) | ||
214 | return 0; | ||
215 | |||
225 | return driver_probe_device(drv, dev); | 216 | return driver_probe_device(drv, dev); |
226 | } | 217 | } |
227 | 218 | ||
@@ -274,7 +265,7 @@ static int __driver_attach(struct device *dev, void *data) | |||
274 | * is an error. | 265 | * is an error. |
275 | */ | 266 | */ |
276 | 267 | ||
277 | if (drv->bus->match && !drv->bus->match(dev, drv)) | 268 | if (!driver_match_device(drv, dev)) |
278 | return 0; | 269 | return 0; |
279 | 270 | ||
280 | if (dev->parent) /* Needed for USB */ | 271 | if (dev->parent) /* Needed for USB */ |
@@ -327,7 +318,7 @@ static void __device_release_driver(struct device *dev) | |||
327 | drv->remove(dev); | 318 | drv->remove(dev); |
328 | devres_release_all(dev); | 319 | devres_release_all(dev); |
329 | dev->driver = NULL; | 320 | dev->driver = NULL; |
330 | klist_remove(&dev->knode_driver); | 321 | klist_remove(&dev->p->knode_driver); |
331 | } | 322 | } |
332 | } | 323 | } |
333 | 324 | ||
@@ -357,6 +348,7 @@ EXPORT_SYMBOL_GPL(device_release_driver); | |||
357 | */ | 348 | */ |
358 | void driver_detach(struct device_driver *drv) | 349 | void driver_detach(struct device_driver *drv) |
359 | { | 350 | { |
351 | struct device_private *dev_prv; | ||
360 | struct device *dev; | 352 | struct device *dev; |
361 | 353 | ||
362 | for (;;) { | 354 | for (;;) { |
@@ -365,8 +357,10 @@ void driver_detach(struct device_driver *drv) | |||
365 | spin_unlock(&drv->p->klist_devices.k_lock); | 357 | spin_unlock(&drv->p->klist_devices.k_lock); |
366 | break; | 358 | break; |
367 | } | 359 | } |
368 | dev = list_entry(drv->p->klist_devices.k_list.prev, | 360 | dev_prv = list_entry(drv->p->klist_devices.k_list.prev, |
369 | struct device, knode_driver.n_node); | 361 | struct device_private, |
362 | knode_driver.n_node); | ||
363 | dev = dev_prv->device; | ||
370 | get_device(dev); | 364 | get_device(dev); |
371 | spin_unlock(&drv->p->klist_devices.k_lock); | 365 | spin_unlock(&drv->p->klist_devices.k_lock); |
372 | 366 | ||