diff options
| author | Mike Waychison <michael.waychison@sun.com> | 2005-03-08 17:52:29 -0800 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2005-03-08 17:52:29 -0800 |
| commit | db36587d7fea5d9fba0e85a10b82ef134db81aab (patch) | |
| tree | 45cd10e44840a57f5c7e7f6e21f2da0e0dfb0f0c | |
| parent | 67642d35e2172ab56ddc26eeba02a0427d4816c6 (diff) | |
[PATCH] driver core: clean driver unload
Get rid of semaphore abuse by converting device_driver->unload_sem
semaphore to device_driver->unloaded completion.
This should get rid of any confusion as well as save a few bytes in the
process.
Signed-off-by: Mike Waychison <michael.waychison@sun.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
| -rw-r--r-- | drivers/base/bus.c | 2 | ||||
| -rw-r--r-- | drivers/base/driver.c | 13 | ||||
| -rw-r--r-- | include/linux/device.h | 2 |
3 files changed, 8 insertions, 9 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 3da24059bdf1..d04fbbdc6298 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -65,7 +65,7 @@ static struct sysfs_ops driver_sysfs_ops = { static void driver_release(struct kobject * kobj) { struct device_driver * drv = to_driver(kobj); - up(&drv->unload_sem); + complete(&drv->unloaded); } static struct kobj_type ktype_driver = { diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 9556f912f960..3b269f7e5213 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -79,14 +79,14 @@ void put_driver(struct device_driver * drv) * since most of the things we have to do deal with the bus * structures. * - * The one interesting aspect is that we initialize @drv->unload_sem - * to a locked state here. It will be unlocked when the driver - * reference count reaches 0. + * The one interesting aspect is that we setup @drv->unloaded + * as a completion that gets complete when the driver reference + * count reaches 0. */ int driver_register(struct device_driver * drv) { INIT_LIST_HEAD(&drv->devices); - init_MUTEX_LOCKED(&drv->unload_sem); + init_completion(&drv->unloaded); return bus_add_driver(drv); } @@ -97,7 +97,7 @@ int driver_register(struct device_driver * drv) * * Again, we pass off most of the work to the bus-level call. * - * Though, once that is done, we attempt to take @drv->unload_sem. + * Though, once that is done, we wait until @drv->unloaded is completed. * This will block until the driver refcount reaches 0, and it is * released. Only modular drivers will call this function, and we * have to guarantee that it won't complete, letting the driver @@ -107,8 +107,7 @@ int driver_register(struct device_driver * drv) void driver_unregister(struct device_driver * drv) { bus_remove_driver(drv); - down(&drv->unload_sem); - up(&drv->unload_sem); + wait_for_completion(&drv->unloaded); } /** diff --git a/include/linux/device.h b/include/linux/device.h index acec2a761ea0..e98232688899 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -102,7 +102,7 @@ struct device_driver { char * name; struct bus_type * bus; - struct semaphore unload_sem; + struct completion unloaded; struct kobject kobj; struct list_head devices; |
