From c13ef442ea6a92abdb466e80d45ae1540a31392f Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 27 Nov 2011 13:11:44 +0100 Subject: [PATCH] --- yaml --- r: 280411 b: refs/heads/master c: ecf00475f229fcf06362412ad2d15a3267e354a1 h: refs/heads/master i: 280409: fd48e3d9da992663cc8f3635d0c469e662b21eda 280407: 8adbcacf278d81e6db6887966433889e7ae0b516 v: v3 --- [refs] | 2 +- trunk/drivers/base/power/domain.c | 68 +++++++++++++++++++++++++------ trunk/include/linux/pm_domain.h | 2 + 3 files changed, 59 insertions(+), 13 deletions(-) diff --git a/[refs] b/[refs] index d129aed1d5f2..5e20f6a3bc7c 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: d5e4cbfe2049fca375cb19c4bc0cf676e8b4a88a +refs/heads/master: ecf00475f229fcf06362412ad2d15a3267e354a1 diff --git a/trunk/drivers/base/power/domain.c b/trunk/drivers/base/power/domain.c index 94afaa2686a6..3c9451b10427 100644 --- a/trunk/drivers/base/power/domain.c +++ b/trunk/drivers/base/power/domain.c @@ -56,6 +56,16 @@ static int genpd_start_dev(struct generic_pm_domain *genpd, struct device *dev) return GENPD_DEV_CALLBACK(genpd, int, start, dev); } +static int genpd_save_dev(struct generic_pm_domain *genpd, struct device *dev) +{ + return GENPD_DEV_CALLBACK(genpd, int, save_state, dev); +} + +static int genpd_restore_dev(struct generic_pm_domain *genpd, struct device *dev) +{ + return GENPD_DEV_CALLBACK(genpd, int, restore_state, dev); +} + static bool genpd_sd_counter_dec(struct generic_pm_domain *genpd) { bool ret = false; @@ -217,7 +227,6 @@ static int __pm_genpd_save_device(struct pm_domain_data *pdd, { struct generic_pm_domain_data *gpd_data = to_gpd_data(pdd); struct device *dev = pdd->dev; - struct device_driver *drv = dev->driver; int ret = 0; if (gpd_data->need_restore) @@ -225,11 +234,9 @@ static int __pm_genpd_save_device(struct pm_domain_data *pdd, mutex_unlock(&genpd->lock); - if (drv && drv->pm && drv->pm->runtime_suspend) { - genpd_start_dev(genpd, dev); - ret = drv->pm->runtime_suspend(dev); - genpd_stop_dev(genpd, dev); - } + genpd_start_dev(genpd, dev); + ret = genpd_save_dev(genpd, dev); + genpd_stop_dev(genpd, dev); mutex_lock(&genpd->lock); @@ -250,18 +257,15 @@ static void __pm_genpd_restore_device(struct pm_domain_data *pdd, { struct generic_pm_domain_data *gpd_data = to_gpd_data(pdd); struct device *dev = pdd->dev; - struct device_driver *drv = dev->driver; if (!gpd_data->need_restore) return; mutex_unlock(&genpd->lock); - if (drv && drv->pm && drv->pm->runtime_resume) { - genpd_start_dev(genpd, dev); - drv->pm->runtime_resume(dev); - genpd_stop_dev(genpd, dev); - } + genpd_start_dev(genpd, dev); + genpd_restore_dev(genpd, dev); + genpd_stop_dev(genpd, dev); mutex_lock(&genpd->lock); @@ -1357,6 +1361,44 @@ int pm_genpd_remove_callbacks(struct device *dev) } EXPORT_SYMBOL_GPL(pm_genpd_remove_callbacks); +/** + * pm_genpd_default_save_state - Default "save device state" for PM domians. + * @dev: Device to handle. + */ +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); + + return 0; +} + +/** + * pm_genpd_default_restore_state - Default PM domians "restore device state". + * @dev: Device to handle. + */ +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); + + return 0; +} + /** * pm_genpd_init - Initialize a generic I/O PM domain object. * @genpd: PM domain object to initialize. @@ -1400,6 +1442,8 @@ void pm_genpd_init(struct generic_pm_domain *genpd, genpd->domain.ops.restore_noirq = pm_genpd_restore_noirq; genpd->domain.ops.restore = pm_genpd_restore; genpd->domain.ops.complete = pm_genpd_complete; + genpd->dev_ops.save_state = pm_genpd_default_save_state; + genpd->dev_ops.restore_state = pm_genpd_default_restore_state; mutex_lock(&gpd_list_lock); list_add(&genpd->gpd_list_node, &gpd_list); mutex_unlock(&gpd_list_lock); diff --git a/trunk/include/linux/pm_domain.h b/trunk/include/linux/pm_domain.h index 8949d2d202ae..731080dad250 100644 --- a/trunk/include/linux/pm_domain.h +++ b/trunk/include/linux/pm_domain.h @@ -26,6 +26,8 @@ struct dev_power_governor { struct gpd_dev_ops { int (*start)(struct device *dev); int (*stop)(struct device *dev); + int (*save_state)(struct device *dev); + int (*restore_state)(struct device *dev); bool (*active_wakeup)(struct device *dev); };