diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-26 19:17:04 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-26 19:17:04 +0100 |
commit | 0c93ea4064a209cdc36de8a9a3003d43d08f46f7 (patch) | |
tree | ff19952407c523a1349ef56c05993416dd28437e /drivers/base/dd.c | |
parent | Merge git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6 (diff) | |
parent | Dynamic debug: fix pr_fmt() build error (diff) | |
download | linux-0c93ea4064a209cdc36de8a9a3003d43d08f46f7.tar.xz linux-0c93ea4064a209cdc36de8a9a3003d43d08f46f7.zip |
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 @@ static void driver_bound(struct device *dev) { - if (klist_node_attached(&dev->knode_driver)) { + if (klist_node_attached(&dev->p->knode_driver)) { printk(KERN_WARNING "%s: device %s already bound\n", __func__, kobject_name(&dev->kobj)); return; @@ -43,7 +43,7 @@ static void driver_bound(struct device *dev) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_BOUND_DRIVER, dev); - klist_add_tail(&dev->knode_driver, &dev->driver->p->klist_devices); + klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices); } static int driver_sysfs_add(struct device *dev) @@ -172,16 +172,12 @@ int driver_probe_done(void) /** * wait_for_device_probe * Wait for device probing to be completed. - * - * Note: this function polls at 100 msec intervals. */ -int wait_for_device_probe(void) +void wait_for_device_probe(void) { /* wait for the known devices to complete their probing */ - while (driver_probe_done() != 0) - msleep(100); + wait_event(probe_waitqueue, atomic_read(&probe_count) == 0); async_synchronize_full(); - return 0; } /** @@ -189,14 +185,8 @@ int wait_for_device_probe(void) * @drv: driver to bind a device to * @dev: device to try to bind to the driver * - * First, we call the bus's match function, if one present, which should - * compare the device IDs the driver supports with the device IDs of the - * device. Note we don't do this ourselves because we don't know the - * format of the ID structures, nor what is to be considered a match and - * what is not. - * - * This function returns 1 if a match is found, -ENODEV if the device is - * not registered, and 0 otherwise. + * This function returns -ENODEV if the device is not registered, + * 1 if the device is bound sucessfully and 0 otherwise. * * This function must be called with @dev->sem held. When called for a * 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) if (!device_is_registered(dev)) return -ENODEV; - if (drv->bus->match && !drv->bus->match(dev, drv)) - goto done; pr_debug("bus: '%s': %s: matched device %s with driver %s\n", drv->bus->name, __func__, dev_name(dev), drv->name); ret = really_probe(dev, drv); -done: return ret; } static int __device_attach(struct device_driver *drv, void *data) { struct device *dev = data; + + if (!driver_match_device(drv, dev)) + return 0; + return driver_probe_device(drv, dev); } @@ -274,7 +265,7 @@ static int __driver_attach(struct device *dev, void *data) * is an error. */ - if (drv->bus->match && !drv->bus->match(dev, drv)) + if (!driver_match_device(drv, dev)) return 0; if (dev->parent) /* Needed for USB */ @@ -327,7 +318,7 @@ static void __device_release_driver(struct device *dev) drv->remove(dev); devres_release_all(dev); dev->driver = NULL; - klist_remove(&dev->knode_driver); + klist_remove(&dev->p->knode_driver); } } @@ -357,6 +348,7 @@ EXPORT_SYMBOL_GPL(device_release_driver); */ void driver_detach(struct device_driver *drv) { + struct device_private *dev_prv; struct device *dev; for (;;) { @@ -365,8 +357,10 @@ void driver_detach(struct device_driver *drv) spin_unlock(&drv->p->klist_devices.k_lock); break; } - dev = list_entry(drv->p->klist_devices.k_list.prev, - struct device, knode_driver.n_node); + dev_prv = list_entry(drv->p->klist_devices.k_list.prev, + struct device_private, + knode_driver.n_node); + dev = dev_prv->device; get_device(dev); spin_unlock(&drv->p->klist_devices.k_lock); |