From af70316af182f4716cc5eec7e0d27fc731d164bd Mon Sep 17 00:00:00 2001 From: "mochel@digitalimplant.org" Date: Mon, 21 Mar 2005 10:41:04 -0800 Subject: [PATCH] Add a semaphore to struct device to synchronize calls to its driver. This adds a per-device semaphore that is taken before every call from the core to a driver method. This prevents e.g. simultaneous calls to the ->suspend() or ->resume() and ->probe() or ->release(), potentially saving a whole lot of headaches. It also moves us a step closer to removing the bus rwsem, since it protects the fields in struct device that are modified by the core. Signed-off-by: Patrick Mochel Signed-off-by: Greg Kroah-Hartman --- drivers/base/power/resume.c | 8 ++++++-- drivers/base/power/suspend.c | 3 ++- 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers/base/power') diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c index 26468971ef5a..bdd96b03b885 100644 --- a/drivers/base/power/resume.c +++ b/drivers/base/power/resume.c @@ -22,6 +22,9 @@ extern int sysdev_resume(void); int resume_device(struct device * dev) { + int error = 0; + + down(&dev->sem); if (dev->power.pm_parent && dev->power.pm_parent->power.power_state) { dev_err(dev, "PM: resume from %d, parent %s still %d\n", @@ -31,9 +34,10 @@ int resume_device(struct device * dev) } if (dev->bus && dev->bus->resume) { dev_dbg(dev,"resuming\n"); - return dev->bus->resume(dev); + error = dev->bus->resume(dev); } - return 0; + up(&dev->sem); + return error; } diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c index 0ec44ef840be..807e13fb205b 100644 --- a/drivers/base/power/suspend.c +++ b/drivers/base/power/suspend.c @@ -39,6 +39,7 @@ int suspend_device(struct device * dev, pm_message_t state) { int error = 0; + down(&dev->sem); if (dev->power.power_state) { dev_dbg(dev, "PM: suspend %d-->%d\n", dev->power.power_state, state); @@ -58,7 +59,7 @@ int suspend_device(struct device * dev, pm_message_t state) dev_dbg(dev, "suspending\n"); error = dev->bus->suspend(dev, state); } - + up(&dev->sem); return error; } -- cgit v1.2.2 From 74880c063b06efd103c924abfe19d9d8fa4864c4 Mon Sep 17 00:00:00 2001 From: Yani Ioannou Date: Tue, 17 May 2005 06:41:12 -0400 Subject: [PATCH] Driver Core: drivers/base - drivers/i2c/chips/adm1026.c: update device attribute callbacks Signed-off-by: Yani Ioannou Signed-off-by: Greg Kroah-Hartman --- drivers/base/power/sysfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/base/power') diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c index 6ac96349a8e8..f82b3df9545f 100644 --- a/drivers/base/power/sysfs.c +++ b/drivers/base/power/sysfs.c @@ -24,12 +24,12 @@ * low-power state. */ -static ssize_t state_show(struct device * dev, char * buf) +static ssize_t state_show(struct device * dev, struct device_attribute *attr, char * buf) { return sprintf(buf, "%u\n", dev->power.power_state); } -static ssize_t state_store(struct device * dev, const char * buf, size_t n) +static ssize_t state_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t n) { u32 state; char * rest; -- cgit v1.2.2 From 42b16c051c3f462095fb8c9bad1bc05b34518cb9 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 31 May 2005 17:08:49 +1000 Subject: [PATCH] Driver core: Don't "lose" devices on suspend on failure I think we need this patch or we might "lose" devices to the dpm_irq_off list if a failure occurs during the suspend process. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Greg Kroah-Hartman --- drivers/base/power/suspend.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers/base/power') diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c index 807e13fb205b..2ccee3763acf 100644 --- a/drivers/base/power/suspend.c +++ b/drivers/base/power/suspend.c @@ -114,8 +114,19 @@ int device_suspend(pm_message_t state) put_device(dev); } up(&dpm_list_sem); - if (error) + if (error) { + /* we failed... before resuming, bring back devices from + * dpm_off_irq list back to main dpm_off list, we do want + * to call resume() on them, in case they partially suspended + * despite returning -EAGAIN + */ + while (!list_empty(&dpm_off_irq)) { + struct list_head * entry = dpm_off_irq.next; + list_del(entry); + list_add(entry, &dpm_off); + } dpm_resume(); + } up(&dpm_sem); return error; } -- cgit v1.2.2