diff options
Diffstat (limited to 'drivers/base/bus.c')
-rw-r--r-- | drivers/base/bus.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 80ce88de56f..aa27f76d28c 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -283,18 +283,22 @@ void device_bind_driver(struct device * dev) */ int driver_probe_device(struct device_driver * drv, struct device * dev) { + int error = 0; + if (drv->bus->match && !drv->bus->match(dev, drv)) return -ENODEV; + down(&dev->sem); dev->driver = drv; if (drv->probe) { - int error = drv->probe(dev); + error = drv->probe(dev); if (error) { dev->driver = NULL; + up(&dev->sem); return error; } } - + up(&dev->sem); device_bind_driver(dev); return 0; } @@ -385,7 +389,10 @@ void driver_attach(struct device_driver * drv) void device_release_driver(struct device * dev) { - struct device_driver * drv = dev->driver; + struct device_driver * drv; + + down(&dev->sem); + drv = dev->driver; if (drv) { sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj)); sysfs_remove_link(&dev->kobj, "driver"); @@ -394,6 +401,7 @@ void device_release_driver(struct device * dev) drv->remove(dev); dev->driver = NULL; } + up(&dev->sem); } |