diff options
-rw-r--r-- | drivers/base/power/domain.c | 34 |
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 | */ | ||
787 | static 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 | } |