Skip to content

Commit 122a223

Browse files
storulfrafaeljw
authored andcommitted
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 <[email protected]> Reviewed-by: Kevin Hilman <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 4d23a5e commit 122a223

File tree

1 file changed

+27
-4
lines changed

1 file changed

+27
-4
lines changed

drivers/base/power/domain.c

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,7 @@ static int pm_genpd_prepare(struct device *dev)
761761
static int pm_genpd_suspend_noirq(struct device *dev)
762762
{
763763
struct generic_pm_domain *genpd;
764+
int ret;
764765

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

@@ -771,6 +772,12 @@ static int pm_genpd_suspend_noirq(struct device *dev)
771772
if (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev))
772773
return 0;
773774

775+
if (genpd->dev_ops.stop && genpd->dev_ops.start) {
776+
ret = pm_runtime_force_suspend(dev);
777+
if (ret)
778+
return ret;
779+
}
780+
774781
/*
775782
* Since all of the "noirq" callbacks are executed sequentially, it is
776783
* guaranteed that this function will never run twice in parallel for
@@ -791,6 +798,7 @@ static int pm_genpd_suspend_noirq(struct device *dev)
791798
static int pm_genpd_resume_noirq(struct device *dev)
792799
{
793800
struct generic_pm_domain *genpd;
801+
int ret = 0;
794802

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

@@ -809,7 +817,10 @@ static int pm_genpd_resume_noirq(struct device *dev)
809817
pm_genpd_sync_poweron(genpd, true);
810818
genpd->suspended_count--;
811819

812-
return 0;
820+
if (genpd->dev_ops.stop && genpd->dev_ops.start)
821+
ret = pm_runtime_force_resume(dev);
822+
823+
return ret;
813824
}
814825

815826
/**
@@ -824,14 +835,18 @@ static int pm_genpd_resume_noirq(struct device *dev)
824835
static int pm_genpd_freeze_noirq(struct device *dev)
825836
{
826837
struct generic_pm_domain *genpd;
838+
int ret = 0;
827839

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

830842
genpd = dev_to_genpd(dev);
831843
if (IS_ERR(genpd))
832844
return -EINVAL;
833845

834-
return 0;
846+
if (genpd->dev_ops.stop && genpd->dev_ops.start)
847+
ret = pm_runtime_force_suspend(dev);
848+
849+
return ret;
835850
}
836851

837852
/**
@@ -844,14 +859,18 @@ static int pm_genpd_freeze_noirq(struct device *dev)
844859
static int pm_genpd_thaw_noirq(struct device *dev)
845860
{
846861
struct generic_pm_domain *genpd;
862+
int ret = 0;
847863

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

850866
genpd = dev_to_genpd(dev);
851867
if (IS_ERR(genpd))
852868
return -EINVAL;
853869

854-
return 0;
870+
if (genpd->dev_ops.stop && genpd->dev_ops.start)
871+
ret = pm_runtime_force_resume(dev);
872+
873+
return ret;
855874
}
856875

857876
/**
@@ -864,6 +883,7 @@ static int pm_genpd_thaw_noirq(struct device *dev)
864883
static int pm_genpd_restore_noirq(struct device *dev)
865884
{
866885
struct generic_pm_domain *genpd;
886+
int ret = 0;
867887

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

@@ -889,7 +909,10 @@ static int pm_genpd_restore_noirq(struct device *dev)
889909

890910
pm_genpd_sync_poweron(genpd, true);
891911

892-
return 0;
912+
if (genpd->dev_ops.stop && genpd->dev_ops.start)
913+
ret = pm_runtime_force_resume(dev);
914+
915+
return ret;
893916
}
894917

895918
/**

0 commit comments

Comments
 (0)