aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/dd.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2009-08-18 17:38:32 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2009-08-22 18:04:44 -0400
commit5e928f77a09a07f9dd595bb8a489965d69a83458 (patch)
treeef53ec90fa3214fd22e36b07c11c06b09e373d8d /drivers/base/dd.c
parent8400146d0dc03590bba051399e4bb7e1cbf1c010 (diff)
PM: Introduce core framework for run-time PM of I/O devices (rev. 17)
Introduce a core framework for run-time power management of I/O devices. Add device run-time PM fields to 'struct dev_pm_info' and device run-time PM callbacks to 'struct dev_pm_ops'. Introduce a run-time PM workqueue and define some device run-time PM helper functions at the core level. Document all these things. Special thanks to Alan Stern for his help with the design and multiple detailed reviews of the pereceding versions of this patch and to Magnus Damm for testing feedback. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Acked-by: Magnus Damm <damm@igel.co.jp>
Diffstat (limited to 'drivers/base/dd.c')
-rw-r--r--drivers/base/dd.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index f0106875f01d..7b34b3a48f67 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -23,6 +23,7 @@
23#include <linux/kthread.h> 23#include <linux/kthread.h>
24#include <linux/wait.h> 24#include <linux/wait.h>
25#include <linux/async.h> 25#include <linux/async.h>
26#include <linux/pm_runtime.h>
26 27
27#include "base.h" 28#include "base.h"
28#include "power/power.h" 29#include "power/power.h"
@@ -202,7 +203,10 @@ int driver_probe_device(struct device_driver *drv, struct device *dev)
202 pr_debug("bus: '%s': %s: matched device %s with driver %s\n", 203 pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
203 drv->bus->name, __func__, dev_name(dev), drv->name); 204 drv->bus->name, __func__, dev_name(dev), drv->name);
204 205
206 pm_runtime_get_noresume(dev);
207 pm_runtime_barrier(dev);
205 ret = really_probe(dev, drv); 208 ret = really_probe(dev, drv);
209 pm_runtime_put_sync(dev);
206 210
207 return ret; 211 return ret;
208} 212}
@@ -245,7 +249,9 @@ int device_attach(struct device *dev)
245 ret = 0; 249 ret = 0;
246 } 250 }
247 } else { 251 } else {
252 pm_runtime_get_noresume(dev);
248 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);
249 } 255 }
250 up(&dev->sem); 256 up(&dev->sem);
251 return ret; 257 return ret;
@@ -306,6 +312,9 @@ static void __device_release_driver(struct device *dev)
306 312
307 drv = dev->driver; 313 drv = dev->driver;
308 if (drv) { 314 if (drv) {
315 pm_runtime_get_noresume(dev);
316 pm_runtime_barrier(dev);
317
309 driver_sysfs_remove(dev); 318 driver_sysfs_remove(dev);
310 319
311 if (dev->bus) 320 if (dev->bus)
@@ -324,6 +333,8 @@ static void __device_release_driver(struct device *dev)
324 blocking_notifier_call_chain(&dev->bus->p->bus_notifier, 333 blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
325 BUS_NOTIFY_UNBOUND_DRIVER, 334 BUS_NOTIFY_UNBOUND_DRIVER,
326 dev); 335 dev);
336
337 pm_runtime_put_sync(dev);
327 } 338 }
328} 339}
329 340