Skip to content

Commit

Permalink
Driver core: create lock/unlock functions for struct device
Browse files Browse the repository at this point in the history
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 <[email protected]>
Cc: Jean Delvare <[email protected]>
Cc: Dave Young <[email protected]>
Cc: Ming Lei <[email protected]>
Cc: Jiri Kosina <[email protected]>
Cc: Phil Carmody <[email protected]>
Cc: Arjan van de Ven <[email protected]>
Cc: Cornelia Huck <[email protected]>
Cc: Rafael J. Wysocki <[email protected]>
Cc: Pavel Machek <[email protected]>
Cc: Len Brown <[email protected]>
Cc: Magnus Damm <[email protected]>
Cc: Alan Stern <[email protected]>
Cc: Randy Dunlap <[email protected]>
Cc: Stefan Richter <[email protected]>
Cc: David Brownell <[email protected]>
Cc: Vegard Nossum <[email protected]>
Cc: Jesse Barnes <[email protected]>
Cc: Alex Chiang <[email protected]>
Cc: Kenji Kaneshige <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Andrew Patterson <[email protected]>
Cc: Yu Zhao <[email protected]>
Cc: Dominik Brodowski <[email protected]>
Cc: Samuel Ortiz <[email protected]>
Cc: Wolfram Sang <[email protected]>
Cc: CHENG Renquan <[email protected]>
Cc: Oliver Neukum <[email protected]>
Cc: Frans Pop <[email protected]>
Cc: David Vrabel <[email protected]>
Cc: Kay Sievers <[email protected]>
Cc: Sarah Sharp <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
gregkh committed Mar 8, 2010
1 parent 62e877b commit 8e9394c
Show file tree
Hide file tree
Showing 13 changed files with 76 additions and 63 deletions.
20 changes: 10 additions & 10 deletions drivers/base/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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 */
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
}
Expand Down
38 changes: 19 additions & 19 deletions drivers/base/dd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
Expand All @@ -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);
Expand All @@ -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;
}
Expand All @@ -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)
{
Expand Down Expand Up @@ -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)
{
Expand All @@ -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);

Expand All @@ -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);
}
}
Expand Down
20 changes: 10 additions & 10 deletions drivers/base/power/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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 ");
Expand All @@ -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);
}

/**
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 ");
Expand All @@ -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;
}
Expand Down
5 changes: 2 additions & 3 deletions drivers/firewire/core-device.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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;
Expand Down
5 changes: 2 additions & 3 deletions drivers/ieee1394/nodemgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions drivers/pci/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
4 changes: 2 additions & 2 deletions drivers/pci/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
}

Expand Down
8 changes: 4 additions & 4 deletions drivers/pcmcia/ds.c
Original file line number Diff line number Diff line change
Expand Up @@ -971,19 +971,19 @@ 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;
}

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;
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/usb/core/driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions drivers/uwb/umc-bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
4 changes: 2 additions & 2 deletions drivers/uwb/uwb-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__ */
Loading

0 comments on commit 8e9394c

Please sign in to comment.