Driver core: create lock/unlock functions for struct device
authorGreg Kroah-Hartman <gregkh@suse.de>
Wed, 17 Feb 2010 18:57:05 +0000 (10:57 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 8 Mar 2010 01:04:52 +0000 (17:04 -0800)
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>
13 files changed:
drivers/base/bus.c
drivers/base/dd.c
drivers/base/power/main.c
drivers/firewire/core-device.c
drivers/ieee1394/nodemgr.c
drivers/pci/bus.c
drivers/pci/pci.c
drivers/pcmcia/ds.c
drivers/usb/core/driver.c
drivers/uwb/umc-bus.c
drivers/uwb/uwb-internal.h
include/linux/device.h
include/linux/usb.h

index cca1aa10054c3971016ef8bda828c7824c17f64a..71f6af5c8b0bdfda4fce6fd9bf83cb82ebdadcf7 100644 (file)
@@ -173,10 +173,10 @@ static ssize_t driver_unbind(struct device_driver *drv,
        dev = bus_find_device_by_name(bus, NULL, buf);
        if (dev && dev->driver == drv) {
                if (dev->parent)        /* Needed for USB */
-                       down(&dev->parent->sem);
+                       device_lock(dev->parent);
                device_release_driver(dev);
                if (dev->parent)
-                       up(&dev->parent->sem);
+                       device_unlock(dev->parent);
                err = count;
        }
        put_device(dev);
@@ -200,12 +200,12 @@ static ssize_t driver_bind(struct device_driver *drv,
        dev = bus_find_device_by_name(bus, NULL, buf);
        if (dev && dev->driver == NULL && driver_match_device(drv, dev)) {
                if (dev->parent)        /* Needed for USB */
-                       down(&dev->parent->sem);
-               down(&dev->sem);
+                       device_lock(dev->parent);
+               device_lock(dev);
                err = driver_probe_device(drv, dev);
-               up(&dev->sem);
+               device_unlock(dev);
                if (dev->parent)
-                       up(&dev->parent->sem);
+                       device_unlock(dev->parent);
 
                if (err > 0) {
                        /* success */
@@ -744,10 +744,10 @@ static int __must_check bus_rescan_devices_helper(struct device *dev,
 
        if (!dev->driver) {
                if (dev->parent)        /* Needed for USB */
-                       down(&dev->parent->sem);
+                       device_lock(dev->parent);
                ret = device_attach(dev);
                if (dev->parent)
-                       up(&dev->parent->sem);
+                       device_unlock(dev->parent);
        }
        return ret < 0 ? ret : 0;
 }
@@ -779,10 +779,10 @@ int device_reprobe(struct device *dev)
 {
        if (dev->driver) {
                if (dev->parent)        /* Needed for USB */
-                       down(&dev->parent->sem);
+                       device_lock(dev->parent);
                device_release_driver(dev);
                if (dev->parent)
-                       up(&dev->parent->sem);
+                       device_unlock(dev->parent);
        }
        return bus_rescan_devices_helper(dev, NULL);
 }
index ee95c76bfd3dbb0b7ecdee8b02d9da078d6ed7eb..c89291f8a16bb09749664f9717c98c55a8176a18 100644 (file)
@@ -85,7 +85,7 @@ static void driver_sysfs_remove(struct device *dev)
  * for before calling this. (It is ok to call with no other effort
  * from a driver's probe() method.)
  *
- * This function must be called with @dev->sem held.
+ * This function must be called with the device lock held.
  */
 int device_bind_driver(struct device *dev)
 {
@@ -190,8 +190,8 @@ EXPORT_SYMBOL_GPL(wait_for_device_probe);
  * This function returns -ENODEV if the device is not registered,
  * 1 if the device is bound successfully 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.
+ * This function must be called with @dev lock held.  When called for a
+ * USB interface, @dev->parent lock must be held as well.
  */
 int driver_probe_device(struct device_driver *drv, struct device *dev)
 {
@@ -233,13 +233,13 @@ static int __device_attach(struct device_driver *drv, void *data)
  * 0 if no matching driver was found;
  * -ENODEV if the device is not registered.
  *
- * When called for a USB interface, @dev->parent->sem must be held.
+ * When called for a USB interface, @dev->parent lock must be held.
  */
 int device_attach(struct device *dev)
 {
        int ret = 0;
 
-       down(&dev->sem);
+       device_lock(dev);
        if (dev->driver) {
                ret = device_bind_driver(dev);
                if (ret == 0)
@@ -253,7 +253,7 @@ int device_attach(struct device *dev)
                ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
                pm_runtime_put_sync(dev);
        }
-       up(&dev->sem);
+       device_unlock(dev);
        return ret;
 }
 EXPORT_SYMBOL_GPL(device_attach);
@@ -276,13 +276,13 @@ static int __driver_attach(struct device *dev, void *data)
                return 0;
 
        if (dev->parent)        /* Needed for USB */
-               down(&dev->parent->sem);
-       down(&dev->sem);
+               device_lock(dev->parent);
+       device_lock(dev);
        if (!dev->driver)
                driver_probe_device(drv, dev);
-       up(&dev->sem);
+       device_unlock(dev);
        if (dev->parent)
-               up(&dev->parent->sem);
+               device_unlock(dev->parent);
 
        return 0;
 }
@@ -303,8 +303,8 @@ int driver_attach(struct device_driver *drv)
 EXPORT_SYMBOL_GPL(driver_attach);
 
 /*
- * __device_release_driver() must be called with @dev->sem held.
- * When called for a USB interface, @dev->parent->sem must be held as well.
+ * __device_release_driver() must be called with @dev lock held.
+ * When called for a USB interface, @dev->parent lock must be held as well.
  */
 static void __device_release_driver(struct device *dev)
 {
@@ -343,7 +343,7 @@ static void __device_release_driver(struct device *dev)
  * @dev: device.
  *
  * Manually detach device from driver.
- * When called for a USB interface, @dev->parent->sem must be held.
+ * When called for a USB interface, @dev->parent lock must be held.
  */
 void device_release_driver(struct device *dev)
 {
@@ -352,9 +352,9 @@ void device_release_driver(struct device *dev)
         * within their ->remove callback for the same device, they
         * will deadlock right here.
         */
-       down(&dev->sem);
+       device_lock(dev);
        __device_release_driver(dev);
-       up(&dev->sem);
+       device_unlock(dev);
 }
 EXPORT_SYMBOL_GPL(device_release_driver);
 
@@ -381,13 +381,13 @@ void driver_detach(struct device_driver *drv)
                spin_unlock(&drv->p->klist_devices.k_lock);
 
                if (dev->parent)        /* Needed for USB */
-                       down(&dev->parent->sem);
-               down(&dev->sem);
+                       device_lock(dev->parent);
+               device_lock(dev);
                if (dev->driver == drv)
                        __device_release_driver(dev);
-               up(&dev->sem);
+               device_unlock(dev);
                if (dev->parent)
-                       up(&dev->parent->sem);
+                       device_unlock(dev->parent);
                put_device(dev);
        }
 }
index 0e26a6f6fd48193e5c5fd3cec6a20269a4a5ddc9..d477f4dc5e514b202aaaa1efe0a6b20b3eeb62e3 100644 (file)
@@ -35,8 +35,8 @@
  * because children are guaranteed to be discovered after parents, and
  * are inserted at the back of the list on discovery.
  *
- * Since device_pm_add() may be called with a device semaphore held,
- * we must never try to acquire a device semaphore while holding
+ * Since device_pm_add() may be called with a device lock held,
+ * we must never try to acquire a device lock while holding
  * dpm_list_mutex.
  */
 
@@ -508,7 +508,7 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
        TRACE_RESUME(0);
 
        dpm_wait(dev->parent, async);
-       down(&dev->sem);
+       device_lock(dev);
 
        dev->power.status = DPM_RESUMING;
 
@@ -543,7 +543,7 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
                }
        }
  End:
-       up(&dev->sem);
+       device_unlock(dev);
        complete_all(&dev->power.completion);
 
        TRACE_RESUME(error);
@@ -629,7 +629,7 @@ static void dpm_resume(pm_message_t state)
  */
 static void device_complete(struct device *dev, pm_message_t state)
 {
-       down(&dev->sem);
+       device_lock(dev);
 
        if (dev->class && dev->class->pm && dev->class->pm->complete) {
                pm_dev_dbg(dev, state, "completing class ");
@@ -646,7 +646,7 @@ static void device_complete(struct device *dev, pm_message_t state)
                dev->bus->pm->complete(dev);
        }
 
-       up(&dev->sem);
+       device_unlock(dev);
 }
 
 /**
@@ -809,7 +809,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
        int error = 0;
 
        dpm_wait_for_children(dev, async);
-       down(&dev->sem);
+       device_lock(dev);
 
        if (async_error)
                goto End;
@@ -849,7 +849,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
                dev->power.status = DPM_OFF;
 
  End:
-       up(&dev->sem);
+       device_unlock(dev);
        complete_all(&dev->power.completion);
 
        return error;
@@ -938,7 +938,7 @@ static int device_prepare(struct device *dev, pm_message_t state)
 {
        int error = 0;
 
-       down(&dev->sem);
+       device_lock(dev);
 
        if (dev->bus && dev->bus->pm && dev->bus->pm->prepare) {
                pm_dev_dbg(dev, state, "preparing ");
@@ -962,7 +962,7 @@ static int device_prepare(struct device *dev, pm_message_t state)
                suspend_report_result(dev->class->pm->prepare, error);
        }
  End:
-       up(&dev->sem);
+       device_unlock(dev);
 
        return error;
 }
index 014cabd3afda56122bb433646a71f0180b3252e5..5db0518c66da687068c5ede57bce232fb4463283 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/rwsem.h>
-#include <linux/semaphore.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/workqueue.h>
@@ -828,9 +827,9 @@ static int update_unit(struct device *dev, void *data)
        struct fw_driver *driver = (struct fw_driver *)dev->driver;
 
        if (is_fw_unit(dev) && driver != NULL && driver->update != NULL) {
-               down(&dev->sem);
+               device_lock(dev);
                driver->update(unit);
-               up(&dev->sem);
+               device_unlock(dev);
        }
 
        return 0;
index 5122b5a8aa2db1aea54221a70377a70d6e6ed021..18350213479e2ebc1c476765b12b14382f0d183d 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/moduleparam.h>
 #include <linux/mutex.h>
 #include <linux/freezer.h>
-#include <linux/semaphore.h>
 #include <asm/atomic.h>
 
 #include "csr.h"
@@ -1397,9 +1396,9 @@ static int update_pdrv(struct device *dev, void *data)
                        pdrv = container_of(drv, struct hpsb_protocol_driver,
                                            driver);
                        if (pdrv->update) {
-                               down(&ud->device.sem);
+                               device_lock(&ud->device);
                                error = pdrv->update(ud);
-                               up(&ud->device.sem);
+                               device_unlock(&ud->device);
                        }
                        if (error)
                                device_release_driver(&ud->device);
index 712250f5874a88f0acd238429cd6237139a986f9..26301cb25e7f7cc682bd0f5ce102466a7810088b 100644 (file)
@@ -288,9 +288,9 @@ void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *),
                        next = dev->bus_list.next;
 
                /* Run device routines with the device locked */
-               down(&dev->dev.sem);
+               device_lock(&dev->dev);
                retval = cb(dev, userdata);
-               up(&dev->dev.sem);
+               device_unlock(&dev->dev);
                if (retval)
                        break;
        }
index 77b493b3d97b12de09bc4796711407648aa99aab..897fa5ccdb789d56724a5e2504a99836f6076baf 100644 (file)
@@ -2486,7 +2486,7 @@ static int pci_dev_reset(struct pci_dev *dev, int probe)
        if (!probe) {
                pci_block_user_cfg_access(dev);
                /* block PM suspend, driver probe, etc. */
-               down(&dev->dev.sem);
+               device_lock(&dev->dev);
        }
 
        rc = pci_dev_specific_reset(dev, probe);
@@ -2508,7 +2508,7 @@ static int pci_dev_reset(struct pci_dev *dev, int probe)
        rc = pci_parent_bus_reset(dev, probe);
 done:
        if (!probe) {
-               up(&dev->dev.sem);
+               device_unlock(&dev->dev);
                pci_unblock_user_cfg_access(dev);
        }
 
index 0f98be4450b7a0e01a31e90542011bf46f47a4b2..ad93ebd7b2a2f8d3e5cdd65b07bff388d49e3db2 100644 (file)
@@ -971,9 +971,9 @@ static int runtime_suspend(struct device *dev)
 {
        int rc;
 
-       down(&dev->sem);
+       device_lock(dev);
        rc = pcmcia_dev_suspend(dev, PMSG_SUSPEND);
-       up(&dev->sem);
+       device_unlock(dev);
        return rc;
 }
 
@@ -981,9 +981,9 @@ static int runtime_resume(struct device *dev)
 {
        int rc;
 
-       down(&dev->sem);
+       device_lock(dev);
        rc = pcmcia_dev_resume(dev);
-       up(&dev->sem);
+       device_unlock(dev);
        return rc;
 }
 
index a7037bf81688df84e47db4f9289841bb918aed86..f3c233806fa3415a5489842f3ccbf4030da55f8f 100644 (file)
@@ -489,10 +489,10 @@ void usb_driver_release_interface(struct usb_driver *driver,
        if (device_is_registered(dev)) {
                device_release_driver(dev);
        } else {
-               down(&dev->sem);
+               device_lock(dev);
                usb_unbind_interface(dev);
                dev->driver = NULL;
-               up(&dev->sem);
+               device_unlock(dev);
        }
 }
 EXPORT_SYMBOL_GPL(usb_driver_release_interface);
index cdd6c8efc9f8ccadef82a989f2269ffd17f01151..5fad4e791b3ed348da0ae2b93ab4b4cd8e2f16b3 100644 (file)
@@ -62,12 +62,12 @@ int umc_controller_reset(struct umc_dev *umc)
        struct device *parent = umc->dev.parent;
        int ret = 0;
 
-       if(down_trylock(&parent->sem))
+       if (device_trylock(parent))
                return -EAGAIN;
        ret = device_for_each_child(parent, parent, umc_bus_pre_reset_helper);
        if (ret >= 0)
                ret = device_for_each_child(parent, parent, umc_bus_post_reset_helper);
-       up(&parent->sem);
+       device_unlock(parent);
 
        return ret;
 }
index d5bcfc1c227a5ec0ef691a55981242baee4c9443..157485c862c0ba1b3f76425f0e0b39a0efb962eb 100644 (file)
@@ -366,12 +366,12 @@ struct dentry *uwb_dbg_create_pal_dir(struct uwb_pal *pal);
 
 static inline void uwb_dev_lock(struct uwb_dev *uwb_dev)
 {
-       down(&uwb_dev->dev.sem);
+       device_lock(&uwb_dev->dev);
 }
 
 static inline void uwb_dev_unlock(struct uwb_dev *uwb_dev)
 {
-       up(&uwb_dev->dev.sem);
+       device_unlock(&uwb_dev->dev);
 }
 
 #endif /* #ifndef __UWB_INTERNAL_H__ */
index f95d5bfe8248b2508d3cba47e70a0e8f8581eadd..182192892d45cf6db1e0c2cacb5a96835084a36d 100644 (file)
@@ -106,7 +106,7 @@ extern int bus_unregister_notifier(struct bus_type *bus,
 
 /* All 4 notifers below get called with the target struct device *
  * as an argument. Note that those functions are likely to be called
- * with the device semaphore held in the core, so be careful.
+ * with the device lock held in the core, so be careful.
  */
 #define BUS_NOTIFY_ADD_DEVICE          0x00000001 /* device added */
 #define BUS_NOTIFY_DEL_DEVICE          0x00000002 /* device removed */
@@ -508,6 +508,21 @@ static inline bool device_async_suspend_enabled(struct device *dev)
        return !!dev->power.async_suspend;
 }
 
+static inline void device_lock(struct device *dev)
+{
+       down(&dev->sem);
+}
+
+static inline int device_trylock(struct device *dev)
+{
+       return down_trylock(&dev->sem);
+}
+
+static inline void device_unlock(struct device *dev)
+{
+       up(&dev->sem);
+}
+
 void driver_init(void);
 
 /*
index 3492abf82e75907210bc1acfff6e960811f5a1e8..8c9f053111bb8002d332749a36403cef7b7bb0a0 100644 (file)
@@ -512,9 +512,9 @@ extern struct usb_device *usb_get_dev(struct usb_device *dev);
 extern void usb_put_dev(struct usb_device *dev);
 
 /* USB device locking */
-#define usb_lock_device(udev)          down(&(udev)->dev.sem)
-#define usb_unlock_device(udev)                up(&(udev)->dev.sem)
-#define usb_trylock_device(udev)       down_trylock(&(udev)->dev.sem)
+#define usb_lock_device(udev)          device_lock(&(udev)->dev)
+#define usb_unlock_device(udev)                device_unlock(&(udev)->dev)
+#define usb_trylock_device(udev)       device_trylock(&(udev)->dev)
 extern int usb_lock_device_for_reset(struct usb_device *udev,
                                     const struct usb_interface *iface);