Skip to content

Commit

Permalink
PM: Simplify the new suspend/hibernation framework for devices
Browse files Browse the repository at this point in the history
PM: Simplify the new suspend/hibernation framework for devices

Following the discussion at the Kernel Summit, simplify the new
device PM framework by merging 'struct pm_ops' and
'struct pm_ext_ops' and removing pointers to 'struct pm_ext_ops'
from 'struct platform_driver' and 'struct pci_driver'.

After this change, the suspend/hibernation callbacks will only
reside in 'struct device_driver' as well as at the bus type/
device class/device type level.  Accordingly, PCI and platform
device drivers are now expected to put their suspend/hibernation
callbacks into the 'struct device_driver' embedded in
'struct pci_driver' or 'struct platform_driver', respectively.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@suse.cz>
Cc: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Rafael J. Wysocki authored and Greg Kroah-Hartman committed Jan 6, 2009
1 parent 238c6d5 commit adf0949
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 151 deletions.
115 changes: 60 additions & 55 deletions drivers/base/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -503,8 +503,6 @@ int platform_driver_register(struct platform_driver *drv)
drv->driver.suspend = platform_drv_suspend;
if (drv->resume)
drv->driver.resume = platform_drv_resume;
if (drv->pm)
drv->driver.pm = &drv->pm->base;
return driver_register(&drv->driver);
}
EXPORT_SYMBOL_GPL(platform_driver_register);
Expand Down Expand Up @@ -686,7 +684,10 @@ static int platform_pm_suspend(struct device *dev)
struct device_driver *drv = dev->driver;
int ret = 0;

if (drv && drv->pm) {
if (!drv)
return 0;

if (drv->pm) {
if (drv->pm->suspend)
ret = drv->pm->suspend(dev);
} else {
Expand All @@ -698,16 +699,15 @@ static int platform_pm_suspend(struct device *dev)

static int platform_pm_suspend_noirq(struct device *dev)
{
struct platform_driver *pdrv;
struct device_driver *drv = dev->driver;
int ret = 0;

if (!dev->driver)
if (!drv)
return 0;

pdrv = to_platform_driver(dev->driver);
if (pdrv->pm) {
if (pdrv->pm->suspend_noirq)
ret = pdrv->pm->suspend_noirq(dev);
if (drv->pm) {
if (drv->pm->suspend_noirq)
ret = drv->pm->suspend_noirq(dev);
} else {
ret = platform_legacy_suspend_late(dev, PMSG_SUSPEND);
}
Expand All @@ -720,7 +720,10 @@ static int platform_pm_resume(struct device *dev)
struct device_driver *drv = dev->driver;
int ret = 0;

if (drv && drv->pm) {
if (!drv)
return 0;

if (drv->pm) {
if (drv->pm->resume)
ret = drv->pm->resume(dev);
} else {
Expand All @@ -732,16 +735,15 @@ static int platform_pm_resume(struct device *dev)

static int platform_pm_resume_noirq(struct device *dev)
{
struct platform_driver *pdrv;
struct device_driver *drv = dev->driver;
int ret = 0;

if (!dev->driver)
if (!drv)
return 0;

pdrv = to_platform_driver(dev->driver);
if (pdrv->pm) {
if (pdrv->pm->resume_noirq)
ret = pdrv->pm->resume_noirq(dev);
if (drv->pm) {
if (drv->pm->resume_noirq)
ret = drv->pm->resume_noirq(dev);
} else {
ret = platform_legacy_resume_early(dev);
}
Expand Down Expand Up @@ -780,16 +782,15 @@ static int platform_pm_freeze(struct device *dev)

static int platform_pm_freeze_noirq(struct device *dev)
{
struct platform_driver *pdrv;
struct device_driver *drv = dev->driver;
int ret = 0;

if (!dev->driver)
if (!drv)
return 0;

pdrv = to_platform_driver(dev->driver);
if (pdrv->pm) {
if (pdrv->pm->freeze_noirq)
ret = pdrv->pm->freeze_noirq(dev);
if (drv->pm) {
if (drv->pm->freeze_noirq)
ret = drv->pm->freeze_noirq(dev);
} else {
ret = platform_legacy_suspend_late(dev, PMSG_FREEZE);
}
Expand All @@ -802,7 +803,10 @@ static int platform_pm_thaw(struct device *dev)
struct device_driver *drv = dev->driver;
int ret = 0;

if (drv && drv->pm) {
if (!drv)
return 0;

if (drv->pm) {
if (drv->pm->thaw)
ret = drv->pm->thaw(dev);
} else {
Expand All @@ -814,16 +818,15 @@ static int platform_pm_thaw(struct device *dev)

static int platform_pm_thaw_noirq(struct device *dev)
{
struct platform_driver *pdrv;
struct device_driver *drv = dev->driver;
int ret = 0;

if (!dev->driver)
if (!drv)
return 0;

pdrv = to_platform_driver(dev->driver);
if (pdrv->pm) {
if (pdrv->pm->thaw_noirq)
ret = pdrv->pm->thaw_noirq(dev);
if (drv->pm) {
if (drv->pm->thaw_noirq)
ret = drv->pm->thaw_noirq(dev);
} else {
ret = platform_legacy_resume_early(dev);
}
Expand All @@ -836,7 +839,10 @@ static int platform_pm_poweroff(struct device *dev)
struct device_driver *drv = dev->driver;
int ret = 0;

if (drv && drv->pm) {
if (!drv)
return 0;

if (drv->pm) {
if (drv->pm->poweroff)
ret = drv->pm->poweroff(dev);
} else {
Expand All @@ -848,16 +854,15 @@ static int platform_pm_poweroff(struct device *dev)

static int platform_pm_poweroff_noirq(struct device *dev)
{
struct platform_driver *pdrv;
struct device_driver *drv = dev->driver;
int ret = 0;

if (!dev->driver)
if (!drv)
return 0;

pdrv = to_platform_driver(dev->driver);
if (pdrv->pm) {
if (pdrv->pm->poweroff_noirq)
ret = pdrv->pm->poweroff_noirq(dev);
if (drv->pm) {
if (drv->pm->poweroff_noirq)
ret = drv->pm->poweroff_noirq(dev);
} else {
ret = platform_legacy_suspend_late(dev, PMSG_HIBERNATE);
}
Expand All @@ -870,7 +875,10 @@ static int platform_pm_restore(struct device *dev)
struct device_driver *drv = dev->driver;
int ret = 0;

if (drv && drv->pm) {
if (!drv)
return 0;

if (drv->pm) {
if (drv->pm->restore)
ret = drv->pm->restore(dev);
} else {
Expand All @@ -882,16 +890,15 @@ static int platform_pm_restore(struct device *dev)

static int platform_pm_restore_noirq(struct device *dev)
{
struct platform_driver *pdrv;
struct device_driver *drv = dev->driver;
int ret = 0;

if (!dev->driver)
if (!drv)
return 0;

pdrv = to_platform_driver(dev->driver);
if (pdrv->pm) {
if (pdrv->pm->restore_noirq)
ret = pdrv->pm->restore_noirq(dev);
if (drv->pm) {
if (drv->pm->restore_noirq)
ret = drv->pm->restore_noirq(dev);
} else {
ret = platform_legacy_resume_early(dev);
}
Expand All @@ -912,17 +919,15 @@ static int platform_pm_restore_noirq(struct device *dev)

#endif /* !CONFIG_HIBERNATION */

static struct pm_ext_ops platform_pm_ops = {
.base = {
.prepare = platform_pm_prepare,
.complete = platform_pm_complete,
.suspend = platform_pm_suspend,
.resume = platform_pm_resume,
.freeze = platform_pm_freeze,
.thaw = platform_pm_thaw,
.poweroff = platform_pm_poweroff,
.restore = platform_pm_restore,
},
static struct dev_pm_ops platform_dev_pm_ops = {
.prepare = platform_pm_prepare,
.complete = platform_pm_complete,
.suspend = platform_pm_suspend,
.resume = platform_pm_resume,
.freeze = platform_pm_freeze,
.thaw = platform_pm_thaw,
.poweroff = platform_pm_poweroff,
.restore = platform_pm_restore,
.suspend_noirq = platform_pm_suspend_noirq,
.resume_noirq = platform_pm_resume_noirq,
.freeze_noirq = platform_pm_freeze_noirq,
Expand All @@ -931,7 +936,7 @@ static struct pm_ext_ops platform_pm_ops = {
.restore_noirq = platform_pm_restore_noirq,
};

#define PLATFORM_PM_OPS_PTR &platform_pm_ops
#define PLATFORM_PM_OPS_PTR (&platform_dev_pm_ops)

#else /* !CONFIG_PM_SLEEP */

Expand Down
19 changes: 10 additions & 9 deletions drivers/base/power/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ void device_pm_remove(struct device *dev)
* @ops: PM operations to choose from.
* @state: PM transition of the system being carried out.
*/
static int pm_op(struct device *dev, struct pm_ops *ops, pm_message_t state)
static int pm_op(struct device *dev, struct dev_pm_ops *ops,
pm_message_t state)
{
int error = 0;

Expand Down Expand Up @@ -174,7 +175,7 @@ static int pm_op(struct device *dev, struct pm_ops *ops, pm_message_t state)
* The operation is executed with interrupts disabled by the only remaining
* functional CPU in the system.
*/
static int pm_noirq_op(struct device *dev, struct pm_ext_ops *ops,
static int pm_noirq_op(struct device *dev, struct dev_pm_ops *ops,
pm_message_t state)
{
int error = 0;
Expand Down Expand Up @@ -354,7 +355,7 @@ static int resume_device(struct device *dev, pm_message_t state)
if (dev->bus) {
if (dev->bus->pm) {
pm_dev_dbg(dev, state, "");
error = pm_op(dev, &dev->bus->pm->base, state);
error = pm_op(dev, dev->bus->pm, state);
} else if (dev->bus->resume) {
pm_dev_dbg(dev, state, "legacy ");
error = dev->bus->resume(dev);
Expand Down Expand Up @@ -451,9 +452,9 @@ static void complete_device(struct device *dev, pm_message_t state)
dev->type->pm->complete(dev);
}

if (dev->bus && dev->bus->pm && dev->bus->pm->base.complete) {
if (dev->bus && dev->bus->pm && dev->bus->pm->complete) {
pm_dev_dbg(dev, state, "completing ");
dev->bus->pm->base.complete(dev);
dev->bus->pm->complete(dev);
}

up(&dev->sem);
Expand Down Expand Up @@ -624,7 +625,7 @@ static int suspend_device(struct device *dev, pm_message_t state)
if (dev->bus) {
if (dev->bus->pm) {
pm_dev_dbg(dev, state, "");
error = pm_op(dev, &dev->bus->pm->base, state);
error = pm_op(dev, dev->bus->pm, state);
} else if (dev->bus->suspend) {
pm_dev_dbg(dev, state, "legacy ");
error = dev->bus->suspend(dev, state);
Expand Down Expand Up @@ -685,10 +686,10 @@ static int prepare_device(struct device *dev, pm_message_t state)

down(&dev->sem);

if (dev->bus && dev->bus->pm && dev->bus->pm->base.prepare) {
if (dev->bus && dev->bus->pm && dev->bus->pm->prepare) {
pm_dev_dbg(dev, state, "preparing ");
error = dev->bus->pm->base.prepare(dev);
suspend_report_result(dev->bus->pm->base.prepare, error);
error = dev->bus->pm->prepare(dev);
suspend_report_result(dev->bus->pm->prepare, error);
if (error)
goto End;
}
Expand Down
Loading

0 comments on commit adf0949

Please sign in to comment.