Skip to content

Commit

Permalink
PM / Domains: Call driver's noirq callbacks
Browse files Browse the repository at this point in the history
Currently genpd installs its own noirq callbacks, but never calls down
to the driver's corresponding callbacks. Add these calls.

Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  • Loading branch information
Mikko Perttunen authored and Rafael J. Wysocki committed Jun 28, 2017
1 parent d8600c8 commit 10da654
Showing 1 changed file with 59 additions and 9 deletions.
68 changes: 59 additions & 9 deletions drivers/base/power/domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -902,26 +902,33 @@ static int pm_genpd_prepare(struct device *dev)
}

/**
* pm_genpd_suspend_noirq - Completion of suspend of device in an I/O PM domain.
* genpd_finish_suspend - Completion of suspend or hibernation of device in an
* I/O pm domain.
* @dev: Device to suspend.
* @poweroff: Specifies if this is a poweroff_noirq or suspend_noirq callback.
*
* Stop the device and remove power from the domain if all devices in it have
* been stopped.
*/
static int pm_genpd_suspend_noirq(struct device *dev)
static int genpd_finish_suspend(struct device *dev, bool poweroff)
{
struct generic_pm_domain *genpd;
int ret;

dev_dbg(dev, "%s()\n", __func__);

genpd = dev_to_genpd(dev);
if (IS_ERR(genpd))
return -EINVAL;

if (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev))
return 0;

if (poweroff)
ret = pm_generic_poweroff_noirq(dev);
else
ret = pm_generic_suspend_noirq(dev);
if (ret)
return ret;

if (genpd->dev_ops.stop && genpd->dev_ops.start) {
ret = pm_runtime_force_suspend(dev);
if (ret)
Expand All @@ -936,6 +943,20 @@ static int pm_genpd_suspend_noirq(struct device *dev)
return 0;
}

/**
* pm_genpd_suspend_noirq - Completion of suspend of device in an I/O PM domain.
* @dev: Device to suspend.
*
* Stop the device and remove power from the domain if all devices in it have
* been stopped.
*/
static int pm_genpd_suspend_noirq(struct device *dev)
{
dev_dbg(dev, "%s()\n", __func__);

return genpd_finish_suspend(dev, false);
}

/**
* pm_genpd_resume_noirq - Start of resume of device in an I/O PM domain.
* @dev: Device to resume.
Expand Down Expand Up @@ -964,6 +985,10 @@ static int pm_genpd_resume_noirq(struct device *dev)
if (genpd->dev_ops.stop && genpd->dev_ops.start)
ret = pm_runtime_force_resume(dev);

ret = pm_generic_resume_noirq(dev);
if (ret)
return ret;

return ret;
}

Expand All @@ -987,6 +1012,10 @@ static int pm_genpd_freeze_noirq(struct device *dev)
if (IS_ERR(genpd))
return -EINVAL;

ret = pm_generic_freeze_noirq(dev);
if (ret)
return ret;

if (genpd->dev_ops.stop && genpd->dev_ops.start)
ret = pm_runtime_force_suspend(dev);

Expand All @@ -1011,10 +1040,28 @@ static int pm_genpd_thaw_noirq(struct device *dev)
if (IS_ERR(genpd))
return -EINVAL;

if (genpd->dev_ops.stop && genpd->dev_ops.start)
if (genpd->dev_ops.stop && genpd->dev_ops.start) {
ret = pm_runtime_force_resume(dev);
if (ret)
return ret;
}

return ret;
return pm_generic_thaw_noirq(dev);
}

/**
* pm_genpd_poweroff_noirq - Completion of hibernation of device in an
* I/O PM domain.
* @dev: Device to poweroff.
*
* Stop the device and remove power from the domain if all devices in it have
* been stopped.
*/
static int pm_genpd_poweroff_noirq(struct device *dev)
{
dev_dbg(dev, "%s()\n", __func__);

return genpd_finish_suspend(dev, true);
}

/**
Expand Down Expand Up @@ -1051,10 +1098,13 @@ static int pm_genpd_restore_noirq(struct device *dev)
genpd_sync_power_on(genpd, true, 0);
genpd_unlock(genpd);

if (genpd->dev_ops.stop && genpd->dev_ops.start)
if (genpd->dev_ops.stop && genpd->dev_ops.start) {
ret = pm_runtime_force_resume(dev);
if (ret)
return ret;
}

return ret;
return pm_generic_restore_noirq(dev);
}

/**
Expand Down Expand Up @@ -1496,7 +1546,7 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
genpd->domain.ops.resume_noirq = pm_genpd_resume_noirq;
genpd->domain.ops.freeze_noirq = pm_genpd_freeze_noirq;
genpd->domain.ops.thaw_noirq = pm_genpd_thaw_noirq;
genpd->domain.ops.poweroff_noirq = pm_genpd_suspend_noirq;
genpd->domain.ops.poweroff_noirq = pm_genpd_poweroff_noirq;
genpd->domain.ops.restore_noirq = pm_genpd_restore_noirq;
genpd->domain.ops.complete = pm_genpd_complete;

Expand Down

0 comments on commit 10da654

Please sign in to comment.