Skip to content

Commit

Permalink
PM / Domains: Use subsystem runtime suspend/resume callbacks by default
Browse files Browse the repository at this point in the history
Currently, the default "save state" and "restore state" routines
for generic PM domains, pm_genpd_default_save_state() and
pm_genpd_default_restore_state(), respectively, only use runtime PM
callbacks provided by device drivers, but in general those callbacks
need not provide the entire necessary functionality.  Namely, in
general it may be necessary to execute subsystem (i.e. device type,
device class or bus type) callbacks that will carry out all of the
necessary operations.

For this reason, modify pm_genpd_default_save_state() and
pm_genpd_default_restore_state() to execute subsystem callbacks,
if they are provided, and fall back to driver callbacks otherwise.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
  • Loading branch information
Rafael J. Wysocki committed Jul 1, 2012
1 parent 6887a41 commit 0b58974
Showing 1 changed file with 24 additions and 8 deletions.
32 changes: 24 additions & 8 deletions drivers/base/power/domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -1615,16 +1615,24 @@ EXPORT_SYMBOL_GPL(__pm_genpd_remove_callbacks);
static int pm_genpd_default_save_state(struct device *dev)
{
int (*cb)(struct device *__dev);
struct device_driver *drv = dev->driver;

cb = dev_gpd_data(dev)->ops.save_state;
if (cb)
return cb(dev);

if (drv && drv->pm && drv->pm->runtime_suspend)
return drv->pm->runtime_suspend(dev);
if (dev->type && dev->type->pm)
cb = dev->type->pm->runtime_suspend;
else if (dev->class && dev->class->pm)
cb = dev->class->pm->runtime_suspend;
else if (dev->bus && dev->bus->pm)
cb = dev->bus->pm->runtime_suspend;
else
cb = NULL;

return 0;
if (!cb && dev->driver && dev->driver->pm)
cb = dev->driver->pm->runtime_suspend;

return cb ? cb(dev) : 0;
}

/**
Expand All @@ -1634,16 +1642,24 @@ static int pm_genpd_default_save_state(struct device *dev)
static int pm_genpd_default_restore_state(struct device *dev)
{
int (*cb)(struct device *__dev);
struct device_driver *drv = dev->driver;

cb = dev_gpd_data(dev)->ops.restore_state;
if (cb)
return cb(dev);

if (drv && drv->pm && drv->pm->runtime_resume)
return drv->pm->runtime_resume(dev);
if (dev->type && dev->type->pm)
cb = dev->type->pm->runtime_resume;
else if (dev->class && dev->class->pm)
cb = dev->class->pm->runtime_resume;
else if (dev->bus && dev->bus->pm)
cb = dev->bus->pm->runtime_resume;
else
cb = NULL;

return 0;
if (!cb && dev->driver && dev->driver->pm)
cb = dev->driver->pm->runtime_resume;

return cb ? cb(dev) : 0;
}

#ifdef CONFIG_PM_SLEEP
Expand Down

0 comments on commit 0b58974

Please sign in to comment.