aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/power/domain.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index ba3487c9835b..55c39f5b7a59 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -777,6 +777,32 @@ static void pm_genpd_sync_poweroff(struct generic_pm_domain *genpd)
777} 777}
778 778
779/** 779/**
780 * pm_genpd_sync_poweron - Synchronously power on a PM domain and its masters.
781 * @genpd: PM domain to power on.
782 *
783 * This function is only called in "noirq" stage of system power transitions, so
784 * it need not acquire locks (all of the "noirq" callbacks are executed
785 * sequentially, so it is guaranteed that it will never run twice in parallel).
786 */
787static void pm_genpd_sync_poweron(struct generic_pm_domain *genpd)
788{
789 struct gpd_link *link;
790
791 if (genpd->status != GPD_STATE_POWER_OFF)
792 return;
793
794 list_for_each_entry(link, &genpd->slave_links, slave_node) {
795 pm_genpd_sync_poweron(link->master);
796 genpd_sd_counter_inc(link->master);
797 }
798
799 if (genpd->power_on)
800 genpd->power_on(genpd);
801
802 genpd->status = GPD_STATE_ACTIVE;
803}
804
805/**
780 * resume_needed - Check whether to resume a device before system suspend. 806 * resume_needed - Check whether to resume a device before system suspend.
781 * @dev: Device to check. 807 * @dev: Device to check.
782 * @genpd: PM domain the device belongs to. 808 * @genpd: PM domain the device belongs to.
@@ -979,7 +1005,7 @@ static int pm_genpd_resume_noirq(struct device *dev)
979 * guaranteed that this function will never run twice in parallel for 1005 * guaranteed that this function will never run twice in parallel for
980 * the same PM domain, so it is not necessary to use locking here. 1006 * the same PM domain, so it is not necessary to use locking here.
981 */ 1007 */
982 pm_genpd_poweron(genpd); 1008 pm_genpd_sync_poweron(genpd);
983 genpd->suspended_count--; 1009 genpd->suspended_count--;
984 1010
985 return genpd_start_dev(genpd, dev); 1011 return genpd_start_dev(genpd, dev);
@@ -1186,8 +1212,8 @@ static int pm_genpd_restore_noirq(struct device *dev)
1186 if (genpd->suspended_count++ == 0) { 1212 if (genpd->suspended_count++ == 0) {
1187 /* 1213 /*
1188 * The boot kernel might put the domain into arbitrary state, 1214 * The boot kernel might put the domain into arbitrary state,
1189 * so make it appear as powered off to pm_genpd_poweron(), so 1215 * so make it appear as powered off to pm_genpd_sync_poweron(),
1190 * that it tries to power it on in case it was really off. 1216 * so that it tries to power it on in case it was really off.
1191 */ 1217 */
1192 genpd->status = GPD_STATE_POWER_OFF; 1218 genpd->status = GPD_STATE_POWER_OFF;
1193 if (genpd->suspend_power_off) { 1219 if (genpd->suspend_power_off) {
@@ -1205,7 +1231,7 @@ static int pm_genpd_restore_noirq(struct device *dev)
1205 if (genpd->suspend_power_off) 1231 if (genpd->suspend_power_off)
1206 return 0; 1232 return 0;
1207 1233
1208 pm_genpd_poweron(genpd); 1234 pm_genpd_sync_poweron(genpd);
1209 1235
1210 return dev_gpd_data(dev)->always_on ? 0 : genpd_start_dev(genpd, dev); 1236 return dev_gpd_data(dev)->always_on ? 0 : genpd_start_dev(genpd, dev);
1211} 1237}