PM / Domains: Stop/start devices during system PM suspend/resume in genpd
Not all subsystems/drivers that manages devices attached to a genpd makes use of the pm_runtime_force_suspend|resume() helper functions to deal with system PM suspend/resume. In cases like these and when genpd's ->stop|start() callbacks are used for the device, invoke the pm_runtime_force_suspend|resume() helper functions from genpd's "noirq" system PM callbacks. In this way we make sure to "stop" the device on suspend and to "start" it on resume. Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Reviewed-by: Kevin Hilman <khilman@baylibre.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
4d23a5e848
commit
122a22377a
@ -761,6 +761,7 @@ static int pm_genpd_prepare(struct device *dev)
|
|||||||
static int pm_genpd_suspend_noirq(struct device *dev)
|
static int pm_genpd_suspend_noirq(struct device *dev)
|
||||||
{
|
{
|
||||||
struct generic_pm_domain *genpd;
|
struct generic_pm_domain *genpd;
|
||||||
|
int ret;
|
||||||
|
|
||||||
dev_dbg(dev, "%s()\n", __func__);
|
dev_dbg(dev, "%s()\n", __func__);
|
||||||
|
|
||||||
@ -771,6 +772,12 @@ static int pm_genpd_suspend_noirq(struct device *dev)
|
|||||||
if (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev))
|
if (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (genpd->dev_ops.stop && genpd->dev_ops.start) {
|
||||||
|
ret = pm_runtime_force_suspend(dev);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since all of the "noirq" callbacks are executed sequentially, it is
|
* Since all of the "noirq" callbacks are executed sequentially, it is
|
||||||
* guaranteed that this function will never run twice in parallel for
|
* guaranteed that this function will never run twice in parallel for
|
||||||
@ -791,6 +798,7 @@ static int pm_genpd_suspend_noirq(struct device *dev)
|
|||||||
static int pm_genpd_resume_noirq(struct device *dev)
|
static int pm_genpd_resume_noirq(struct device *dev)
|
||||||
{
|
{
|
||||||
struct generic_pm_domain *genpd;
|
struct generic_pm_domain *genpd;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
dev_dbg(dev, "%s()\n", __func__);
|
dev_dbg(dev, "%s()\n", __func__);
|
||||||
|
|
||||||
@ -809,7 +817,10 @@ static int pm_genpd_resume_noirq(struct device *dev)
|
|||||||
pm_genpd_sync_poweron(genpd, true);
|
pm_genpd_sync_poweron(genpd, true);
|
||||||
genpd->suspended_count--;
|
genpd->suspended_count--;
|
||||||
|
|
||||||
return 0;
|
if (genpd->dev_ops.stop && genpd->dev_ops.start)
|
||||||
|
ret = pm_runtime_force_resume(dev);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -824,6 +835,7 @@ static int pm_genpd_resume_noirq(struct device *dev)
|
|||||||
static int pm_genpd_freeze_noirq(struct device *dev)
|
static int pm_genpd_freeze_noirq(struct device *dev)
|
||||||
{
|
{
|
||||||
struct generic_pm_domain *genpd;
|
struct generic_pm_domain *genpd;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
dev_dbg(dev, "%s()\n", __func__);
|
dev_dbg(dev, "%s()\n", __func__);
|
||||||
|
|
||||||
@ -831,7 +843,10 @@ static int pm_genpd_freeze_noirq(struct device *dev)
|
|||||||
if (IS_ERR(genpd))
|
if (IS_ERR(genpd))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
return 0;
|
if (genpd->dev_ops.stop && genpd->dev_ops.start)
|
||||||
|
ret = pm_runtime_force_suspend(dev);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -844,6 +859,7 @@ static int pm_genpd_freeze_noirq(struct device *dev)
|
|||||||
static int pm_genpd_thaw_noirq(struct device *dev)
|
static int pm_genpd_thaw_noirq(struct device *dev)
|
||||||
{
|
{
|
||||||
struct generic_pm_domain *genpd;
|
struct generic_pm_domain *genpd;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
dev_dbg(dev, "%s()\n", __func__);
|
dev_dbg(dev, "%s()\n", __func__);
|
||||||
|
|
||||||
@ -851,7 +867,10 @@ static int pm_genpd_thaw_noirq(struct device *dev)
|
|||||||
if (IS_ERR(genpd))
|
if (IS_ERR(genpd))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
return 0;
|
if (genpd->dev_ops.stop && genpd->dev_ops.start)
|
||||||
|
ret = pm_runtime_force_resume(dev);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -864,6 +883,7 @@ static int pm_genpd_thaw_noirq(struct device *dev)
|
|||||||
static int pm_genpd_restore_noirq(struct device *dev)
|
static int pm_genpd_restore_noirq(struct device *dev)
|
||||||
{
|
{
|
||||||
struct generic_pm_domain *genpd;
|
struct generic_pm_domain *genpd;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
dev_dbg(dev, "%s()\n", __func__);
|
dev_dbg(dev, "%s()\n", __func__);
|
||||||
|
|
||||||
@ -889,7 +909,10 @@ static int pm_genpd_restore_noirq(struct device *dev)
|
|||||||
|
|
||||||
pm_genpd_sync_poweron(genpd, true);
|
pm_genpd_sync_poweron(genpd, true);
|
||||||
|
|
||||||
return 0;
|
if (genpd->dev_ops.stop && genpd->dev_ops.start)
|
||||||
|
ret = pm_runtime_force_resume(dev);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user