aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2012-06-27 17:25:59 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2012-07-01 07:30:59 -0400
commit67699c5f0c68f5dc49e92b172d372c99cdd2bf09 (patch)
tree91be1b7151671a8066cabba083ec68b4832d164f /drivers/acpi
parent707156e600dbfd89e129239ee1d1d934cbe2119c (diff)
ACPI / PM: Make acpi_bus_type use driver struct dev_pm_ops callbacks
Modify acpi_bus_type so that it executes PM callbacks provided by drivers through their struct dev_pm_ops objects, if present, while still allowing the legacy ACPI PM callbacks to take precedence. This will make it possible to convert ACPI drivers one by one to handling PM through struct dev_pm_ops instead of the legacy way. The code added by this change is temporary and will be removed when all of the drivers in question have been switched over to the PM handling based on struct dev_pm_ops. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/scan.c60
1 files changed, 47 insertions, 13 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 7c37be53334d..af924ba85148 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -290,27 +290,61 @@ static void acpi_device_release(struct device *dev)
290 kfree(acpi_dev); 290 kfree(acpi_dev);
291} 291}
292 292
293static int acpi_device_suspend(struct device *dev) 293#define ACPI_DEV_PM_CALLBACK(dev, callback, legacy_cb) \
294({ \
295 struct acpi_device *__acpi_dev = to_acpi_device(dev); \
296 struct acpi_driver *__acpi_drv = __acpi_dev->driver; \
297 struct device_driver *__drv = dev->driver; \
298 int __ret; \
299 \
300 if (__acpi_drv && __acpi_drv->ops.legacy_cb) \
301 __ret = __acpi_drv->ops.legacy_cb(__acpi_dev); \
302 else if (__drv && __drv->pm && __drv->pm->callback) \
303 __ret = __drv->pm->callback(dev); \
304 else \
305 __ret = 0; \
306 \
307 __ret; \
308})
309
310static int acpi_pm_suspend(struct device *dev)
294{ 311{
295 struct acpi_device *acpi_dev = to_acpi_device(dev); 312 return ACPI_DEV_PM_CALLBACK(dev, suspend, suspend);
296 struct acpi_driver *acpi_drv = acpi_dev->driver; 313}
297 314
298 if (acpi_drv && acpi_drv->ops.suspend) 315static int acpi_pm_resume(struct device *dev)
299 return acpi_drv->ops.suspend(acpi_dev); 316{
300 return 0; 317 return ACPI_DEV_PM_CALLBACK(dev, resume, resume);
301} 318}
302 319
303static int acpi_device_resume(struct device *dev) 320static int acpi_pm_freeze(struct device *dev)
304{ 321{
305 struct acpi_device *acpi_dev = to_acpi_device(dev); 322 return ACPI_DEV_PM_CALLBACK(dev, freeze, suspend);
306 struct acpi_driver *acpi_drv = acpi_dev->driver; 323}
307 324
308 if (acpi_drv && acpi_drv->ops.resume) 325static int acpi_pm_thaw(struct device *dev)
309 return acpi_drv->ops.resume(acpi_dev); 326{
310 return 0; 327 return ACPI_DEV_PM_CALLBACK(dev, thaw, resume);
328}
329
330static int acpi_pm_poweroff(struct device *dev)
331{
332 return ACPI_DEV_PM_CALLBACK(dev, poweroff, suspend);
311} 333}
312 334
313static SIMPLE_DEV_PM_OPS(acpi_bus_pm, acpi_device_suspend, acpi_device_resume); 335static int acpi_pm_restore(struct device *dev)
336{
337 return ACPI_DEV_PM_CALLBACK(dev, restore, resume);
338}
339
340static const struct dev_pm_ops acpi_bus_pm = {
341 .suspend = acpi_pm_suspend,
342 .resume = acpi_pm_resume,
343 .freeze = acpi_pm_freeze,
344 .thaw = acpi_pm_thaw,
345 .poweroff = acpi_pm_poweroff,
346 .restore = acpi_pm_restore,
347};
314 348
315static int acpi_bus_match(struct device *dev, struct device_driver *drv) 349static int acpi_bus_match(struct device *dev, struct device_driver *drv)
316{ 350{