diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2010-02-17 13:57:05 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-03-07 20:04:52 -0500 |
commit | 8e9394ce2412254ec69fd2a4f3e44a66eade2297 (patch) | |
tree | 355f25148b4ce3f5cfebeaf0939d71cb6beaf88b /drivers/base | |
parent | 62e877b893e6350c900d381f353aa62ed48dcc97 (diff) |
Driver core: create lock/unlock functions for struct device
In the future, we are going to be changing the lock type for struct
device (once we get the lockdep infrastructure properly worked out) To
make that changeover easier, and to possibly burry the lock in a
different part of struct device, let's create some functions to lock and
unlock a device so that no out-of-core code needs to be changed in the
future.
This patch creates the device_lock/unlock/trylock() functions, and
converts all in-tree users to them.
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Jean Delvare <khali@linux-fr.org>
Cc: Dave Young <hidave.darkstar@gmail.com>
Cc: Ming Lei <tom.leiming@gmail.com>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: Phil Carmody <ext-phil.2.carmody@nokia.com>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: Rafael J. Wysocki <rjw@sisk.pl>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Len Brown <len.brown@intel.com>
Cc: Magnus Damm <damm@igel.co.jp>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Randy Dunlap <randy.dunlap@oracle.com>
Cc: Stefan Richter <stefanr@s5r6.in-berlin.de>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Cc: Vegard Nossum <vegard.nossum@gmail.com>
Cc: Jesse Barnes <jbarnes@virtuousgeek.org>
Cc: Alex Chiang <achiang@hp.com>
Cc: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andrew Patterson <andrew.patterson@hp.com>
Cc: Yu Zhao <yu.zhao@intel.com>
Cc: Dominik Brodowski <linux@dominikbrodowski.net>
Cc: Samuel Ortiz <sameo@linux.intel.com>
Cc: Wolfram Sang <w.sang@pengutronix.de>
Cc: CHENG Renquan <rqcheng@smu.edu.sg>
Cc: Oliver Neukum <oliver@neukum.org>
Cc: Frans Pop <elendil@planet.nl>
Cc: David Vrabel <david.vrabel@csr.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Cc: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/bus.c | 20 | ||||
-rw-r--r-- | drivers/base/dd.c | 38 | ||||
-rw-r--r-- | drivers/base/power/main.c | 20 |
3 files changed, 39 insertions, 39 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index cca1aa10054c..71f6af5c8b0b 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -173,10 +173,10 @@ static ssize_t driver_unbind(struct device_driver *drv, | |||
173 | dev = bus_find_device_by_name(bus, NULL, buf); | 173 | dev = bus_find_device_by_name(bus, NULL, buf); |
174 | if (dev && dev->driver == drv) { | 174 | if (dev && dev->driver == drv) { |
175 | if (dev->parent) /* Needed for USB */ | 175 | if (dev->parent) /* Needed for USB */ |
176 | down(&dev->parent->sem); | 176 | device_lock(dev->parent); |
177 | device_release_driver(dev); | 177 | device_release_driver(dev); |
178 | if (dev->parent) | 178 | if (dev->parent) |
179 | up(&dev->parent->sem); | 179 | device_unlock(dev->parent); |
180 | err = count; | 180 | err = count; |
181 | } | 181 | } |
182 | put_device(dev); | 182 | put_device(dev); |
@@ -200,12 +200,12 @@ static ssize_t driver_bind(struct device_driver *drv, | |||
200 | dev = bus_find_device_by_name(bus, NULL, buf); | 200 | dev = bus_find_device_by_name(bus, NULL, buf); |
201 | if (dev && dev->driver == NULL && driver_match_device(drv, dev)) { | 201 | if (dev && dev->driver == NULL && driver_match_device(drv, dev)) { |
202 | if (dev->parent) /* Needed for USB */ | 202 | if (dev->parent) /* Needed for USB */ |
203 | down(&dev->parent->sem); | 203 | device_lock(dev->parent); |
204 | down(&dev->sem); | 204 | device_lock(dev); |
205 | err = driver_probe_device(drv, dev); | 205 | err = driver_probe_device(drv, dev); |
206 | up(&dev->sem); | 206 | device_unlock(dev); |
207 | if (dev->parent) | 207 | if (dev->parent) |
208 | up(&dev->parent->sem); | 208 | device_unlock(dev->parent); |
209 | 209 | ||
210 | if (err > 0) { | 210 | if (err > 0) { |
211 | /* success */ | 211 | /* success */ |
@@ -744,10 +744,10 @@ static int __must_check bus_rescan_devices_helper(struct device *dev, | |||
744 | 744 | ||
745 | if (!dev->driver) { | 745 | if (!dev->driver) { |
746 | if (dev->parent) /* Needed for USB */ | 746 | if (dev->parent) /* Needed for USB */ |
747 | down(&dev->parent->sem); | 747 | device_lock(dev->parent); |
748 | ret = device_attach(dev); | 748 | ret = device_attach(dev); |
749 | if (dev->parent) | 749 | if (dev->parent) |
750 | up(&dev->parent->sem); | 750 | device_unlock(dev->parent); |
751 | } | 751 | } |
752 | return ret < 0 ? ret : 0; | 752 | return ret < 0 ? ret : 0; |
753 | } | 753 | } |
@@ -779,10 +779,10 @@ int device_reprobe(struct device *dev) | |||
779 | { | 779 | { |
780 | if (dev->driver) { | 780 | if (dev->driver) { |
781 | if (dev->parent) /* Needed for USB */ | 781 | if (dev->parent) /* Needed for USB */ |
782 | down(&dev->parent->sem); | 782 | device_lock(dev->parent); |
783 | device_release_driver(dev); | 783 | device_release_driver(dev); |
784 | if (dev->parent) | 784 | if (dev->parent) |
785 | up(&dev->parent->sem); | 785 | device_unlock(dev->parent); |
786 | } | 786 | } |
787 | return bus_rescan_devices_helper(dev, NULL); | 787 | return bus_rescan_devices_helper(dev, NULL); |
788 | } | 788 | } |
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index ee95c76bfd3d..c89291f8a16b 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -85,7 +85,7 @@ static void driver_sysfs_remove(struct device *dev) | |||
85 | * for before calling this. (It is ok to call with no other effort | 85 | * for before calling this. (It is ok to call with no other effort |
86 | * from a driver's probe() method.) | 86 | * from a driver's probe() method.) |
87 | * | 87 | * |
88 | * This function must be called with @dev->sem held. | 88 | * This function must be called with the device lock held. |
89 | */ | 89 | */ |
90 | int device_bind_driver(struct device *dev) | 90 | int device_bind_driver(struct device *dev) |
91 | { | 91 | { |
@@ -190,8 +190,8 @@ EXPORT_SYMBOL_GPL(wait_for_device_probe); | |||
190 | * This function returns -ENODEV if the device is not registered, | 190 | * This function returns -ENODEV if the device is not registered, |
191 | * 1 if the device is bound successfully and 0 otherwise. | 191 | * 1 if the device is bound successfully and 0 otherwise. |
192 | * | 192 | * |
193 | * This function must be called with @dev->sem held. When called for a | 193 | * This function must be called with @dev lock held. When called for a |
194 | * USB interface, @dev->parent->sem must be held as well. | 194 | * USB interface, @dev->parent lock must be held as well. |
195 | */ | 195 | */ |
196 | int driver_probe_device(struct device_driver *drv, struct device *dev) | 196 | int driver_probe_device(struct device_driver *drv, struct device *dev) |
197 | { | 197 | { |
@@ -233,13 +233,13 @@ static int __device_attach(struct device_driver *drv, void *data) | |||
233 | * 0 if no matching driver was found; | 233 | * 0 if no matching driver was found; |
234 | * -ENODEV if the device is not registered. | 234 | * -ENODEV if the device is not registered. |
235 | * | 235 | * |
236 | * When called for a USB interface, @dev->parent->sem must be held. | 236 | * When called for a USB interface, @dev->parent lock must be held. |
237 | */ | 237 | */ |
238 | int device_attach(struct device *dev) | 238 | int device_attach(struct device *dev) |
239 | { | 239 | { |
240 | int ret = 0; | 240 | int ret = 0; |
241 | 241 | ||
242 | down(&dev->sem); | 242 | device_lock(dev); |
243 | if (dev->driver) { | 243 | if (dev->driver) { |
244 | ret = device_bind_driver(dev); | 244 | ret = device_bind_driver(dev); |
245 | if (ret == 0) | 245 | if (ret == 0) |
@@ -253,7 +253,7 @@ int device_attach(struct device *dev) | |||
253 | ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); | 253 | ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); |
254 | pm_runtime_put_sync(dev); | 254 | pm_runtime_put_sync(dev); |
255 | } | 255 | } |
256 | up(&dev->sem); | 256 | device_unlock(dev); |
257 | return ret; | 257 | return ret; |
258 | } | 258 | } |
259 | EXPORT_SYMBOL_GPL(device_attach); | 259 | EXPORT_SYMBOL_GPL(device_attach); |
@@ -276,13 +276,13 @@ static int __driver_attach(struct device *dev, void *data) | |||
276 | return 0; | 276 | return 0; |
277 | 277 | ||
278 | if (dev->parent) /* Needed for USB */ | 278 | if (dev->parent) /* Needed for USB */ |
279 | down(&dev->parent->sem); | 279 | device_lock(dev->parent); |
280 | down(&dev->sem); | 280 | device_lock(dev); |
281 | if (!dev->driver) | 281 | if (!dev->driver) |
282 | driver_probe_device(drv, dev); | 282 | driver_probe_device(drv, dev); |
283 | up(&dev->sem); | 283 | device_unlock(dev); |
284 | if (dev->parent) | 284 | if (dev->parent) |
285 | up(&dev->parent->sem); | 285 | device_unlock(dev->parent); |
286 | 286 | ||
287 | return 0; | 287 | return 0; |
288 | } | 288 | } |
@@ -303,8 +303,8 @@ int driver_attach(struct device_driver *drv) | |||
303 | EXPORT_SYMBOL_GPL(driver_attach); | 303 | EXPORT_SYMBOL_GPL(driver_attach); |
304 | 304 | ||
305 | /* | 305 | /* |
306 | * __device_release_driver() must be called with @dev->sem held. | 306 | * __device_release_driver() must be called with @dev lock held. |
307 | * When called for a USB interface, @dev->parent->sem must be held as well. | 307 | * When called for a USB interface, @dev->parent lock must be held as well. |
308 | */ | 308 | */ |
309 | static void __device_release_driver(struct device *dev) | 309 | static void __device_release_driver(struct device *dev) |
310 | { | 310 | { |
@@ -343,7 +343,7 @@ static void __device_release_driver(struct device *dev) | |||
343 | * @dev: device. | 343 | * @dev: device. |
344 | * | 344 | * |
345 | * Manually detach device from driver. | 345 | * Manually detach device from driver. |
346 | * When called for a USB interface, @dev->parent->sem must be held. | 346 | * When called for a USB interface, @dev->parent lock must be held. |
347 | */ | 347 | */ |
348 | void device_release_driver(struct device *dev) | 348 | void device_release_driver(struct device *dev) |
349 | { | 349 | { |
@@ -352,9 +352,9 @@ void device_release_driver(struct device *dev) | |||
352 | * within their ->remove callback for the same device, they | 352 | * within their ->remove callback for the same device, they |
353 | * will deadlock right here. | 353 | * will deadlock right here. |
354 | */ | 354 | */ |
355 | down(&dev->sem); | 355 | device_lock(dev); |
356 | __device_release_driver(dev); | 356 | __device_release_driver(dev); |
357 | up(&dev->sem); | 357 | device_unlock(dev); |
358 | } | 358 | } |
359 | EXPORT_SYMBOL_GPL(device_release_driver); | 359 | EXPORT_SYMBOL_GPL(device_release_driver); |
360 | 360 | ||
@@ -381,13 +381,13 @@ void driver_detach(struct device_driver *drv) | |||
381 | spin_unlock(&drv->p->klist_devices.k_lock); | 381 | spin_unlock(&drv->p->klist_devices.k_lock); |
382 | 382 | ||
383 | if (dev->parent) /* Needed for USB */ | 383 | if (dev->parent) /* Needed for USB */ |
384 | down(&dev->parent->sem); | 384 | device_lock(dev->parent); |
385 | down(&dev->sem); | 385 | device_lock(dev); |
386 | if (dev->driver == drv) | 386 | if (dev->driver == drv) |
387 | __device_release_driver(dev); | 387 | __device_release_driver(dev); |
388 | up(&dev->sem); | 388 | device_unlock(dev); |
389 | if (dev->parent) | 389 | if (dev->parent) |
390 | up(&dev->parent->sem); | 390 | device_unlock(dev->parent); |
391 | put_device(dev); | 391 | put_device(dev); |
392 | } | 392 | } |
393 | } | 393 | } |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 0e26a6f6fd48..d477f4dc5e51 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -35,8 +35,8 @@ | |||
35 | * because children are guaranteed to be discovered after parents, and | 35 | * because children are guaranteed to be discovered after parents, and |
36 | * are inserted at the back of the list on discovery. | 36 | * are inserted at the back of the list on discovery. |
37 | * | 37 | * |
38 | * Since device_pm_add() may be called with a device semaphore held, | 38 | * Since device_pm_add() may be called with a device lock held, |
39 | * we must never try to acquire a device semaphore while holding | 39 | * we must never try to acquire a device lock while holding |
40 | * dpm_list_mutex. | 40 | * dpm_list_mutex. |
41 | */ | 41 | */ |
42 | 42 | ||
@@ -508,7 +508,7 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) | |||
508 | TRACE_RESUME(0); | 508 | TRACE_RESUME(0); |
509 | 509 | ||
510 | dpm_wait(dev->parent, async); | 510 | dpm_wait(dev->parent, async); |
511 | down(&dev->sem); | 511 | device_lock(dev); |
512 | 512 | ||
513 | dev->power.status = DPM_RESUMING; | 513 | dev->power.status = DPM_RESUMING; |
514 | 514 | ||
@@ -543,7 +543,7 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) | |||
543 | } | 543 | } |
544 | } | 544 | } |
545 | End: | 545 | End: |
546 | up(&dev->sem); | 546 | device_unlock(dev); |
547 | complete_all(&dev->power.completion); | 547 | complete_all(&dev->power.completion); |
548 | 548 | ||
549 | TRACE_RESUME(error); | 549 | TRACE_RESUME(error); |
@@ -629,7 +629,7 @@ static void dpm_resume(pm_message_t state) | |||
629 | */ | 629 | */ |
630 | static void device_complete(struct device *dev, pm_message_t state) | 630 | static void device_complete(struct device *dev, pm_message_t state) |
631 | { | 631 | { |
632 | down(&dev->sem); | 632 | device_lock(dev); |
633 | 633 | ||
634 | if (dev->class && dev->class->pm && dev->class->pm->complete) { | 634 | if (dev->class && dev->class->pm && dev->class->pm->complete) { |
635 | pm_dev_dbg(dev, state, "completing class "); | 635 | pm_dev_dbg(dev, state, "completing class "); |
@@ -646,7 +646,7 @@ static void device_complete(struct device *dev, pm_message_t state) | |||
646 | dev->bus->pm->complete(dev); | 646 | dev->bus->pm->complete(dev); |
647 | } | 647 | } |
648 | 648 | ||
649 | up(&dev->sem); | 649 | device_unlock(dev); |
650 | } | 650 | } |
651 | 651 | ||
652 | /** | 652 | /** |
@@ -809,7 +809,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) | |||
809 | int error = 0; | 809 | int error = 0; |
810 | 810 | ||
811 | dpm_wait_for_children(dev, async); | 811 | dpm_wait_for_children(dev, async); |
812 | down(&dev->sem); | 812 | device_lock(dev); |
813 | 813 | ||
814 | if (async_error) | 814 | if (async_error) |
815 | goto End; | 815 | goto End; |
@@ -849,7 +849,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) | |||
849 | dev->power.status = DPM_OFF; | 849 | dev->power.status = DPM_OFF; |
850 | 850 | ||
851 | End: | 851 | End: |
852 | up(&dev->sem); | 852 | device_unlock(dev); |
853 | complete_all(&dev->power.completion); | 853 | complete_all(&dev->power.completion); |
854 | 854 | ||
855 | return error; | 855 | return error; |
@@ -938,7 +938,7 @@ static int device_prepare(struct device *dev, pm_message_t state) | |||
938 | { | 938 | { |
939 | int error = 0; | 939 | int error = 0; |
940 | 940 | ||
941 | down(&dev->sem); | 941 | device_lock(dev); |
942 | 942 | ||
943 | if (dev->bus && dev->bus->pm && dev->bus->pm->prepare) { | 943 | if (dev->bus && dev->bus->pm && dev->bus->pm->prepare) { |
944 | pm_dev_dbg(dev, state, "preparing "); | 944 | pm_dev_dbg(dev, state, "preparing "); |
@@ -962,7 +962,7 @@ static int device_prepare(struct device *dev, pm_message_t state) | |||
962 | suspend_report_result(dev->class->pm->prepare, error); | 962 | suspend_report_result(dev->class->pm->prepare, error); |
963 | } | 963 | } |
964 | End: | 964 | End: |
965 | up(&dev->sem); | 965 | device_unlock(dev); |
966 | 966 | ||
967 | return error; | 967 | return error; |
968 | } | 968 | } |