diff options
author | Mikko Perttunen <mperttunen@nvidia.com> | 2017-06-22 03:18:33 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2017-06-28 19:24:34 -0400 |
commit | 10da65423fdbee185da5bb65f829a9d9312c1198 (patch) | |
tree | 01cea6d79416526ccdd277c486541735a2ecb4d5 | |
parent | d8600c8b0cd11d2249e14bf8b2eccbf4fa0db770 (diff) |
PM / Domains: Call driver's noirq callbacks
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>
-rw-r--r-- | drivers/base/power/domain.c | 68 |
1 files changed, 59 insertions, 9 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 0f7b1bd3680e..bbbb1d72395b 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c | |||
@@ -902,19 +902,19 @@ static int pm_genpd_prepare(struct device *dev) | |||
902 | } | 902 | } |
903 | 903 | ||
904 | /** | 904 | /** |
905 | * pm_genpd_suspend_noirq - Completion of suspend of device in an I/O PM domain. | 905 | * genpd_finish_suspend - Completion of suspend or hibernation of device in an |
906 | * I/O pm domain. | ||
906 | * @dev: Device to suspend. | 907 | * @dev: Device to suspend. |
908 | * @poweroff: Specifies if this is a poweroff_noirq or suspend_noirq callback. | ||
907 | * | 909 | * |
908 | * Stop the device and remove power from the domain if all devices in it have | 910 | * Stop the device and remove power from the domain if all devices in it have |
909 | * been stopped. | 911 | * been stopped. |
910 | */ | 912 | */ |
911 | static int pm_genpd_suspend_noirq(struct device *dev) | 913 | static int genpd_finish_suspend(struct device *dev, bool poweroff) |
912 | { | 914 | { |
913 | struct generic_pm_domain *genpd; | 915 | struct generic_pm_domain *genpd; |
914 | int ret; | 916 | int ret; |
915 | 917 | ||
916 | dev_dbg(dev, "%s()\n", __func__); | ||
917 | |||
918 | genpd = dev_to_genpd(dev); | 918 | genpd = dev_to_genpd(dev); |
919 | if (IS_ERR(genpd)) | 919 | if (IS_ERR(genpd)) |
920 | return -EINVAL; | 920 | return -EINVAL; |
@@ -922,6 +922,13 @@ static int pm_genpd_suspend_noirq(struct device *dev) | |||
922 | if (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev)) | 922 | if (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev)) |
923 | return 0; | 923 | return 0; |
924 | 924 | ||
925 | if (poweroff) | ||
926 | ret = pm_generic_poweroff_noirq(dev); | ||
927 | else | ||
928 | ret = pm_generic_suspend_noirq(dev); | ||
929 | if (ret) | ||
930 | return ret; | ||
931 | |||
925 | if (genpd->dev_ops.stop && genpd->dev_ops.start) { | 932 | if (genpd->dev_ops.stop && genpd->dev_ops.start) { |
926 | ret = pm_runtime_force_suspend(dev); | 933 | ret = pm_runtime_force_suspend(dev); |
927 | if (ret) | 934 | if (ret) |
@@ -937,6 +944,20 @@ static int pm_genpd_suspend_noirq(struct device *dev) | |||
937 | } | 944 | } |
938 | 945 | ||
939 | /** | 946 | /** |
947 | * pm_genpd_suspend_noirq - Completion of suspend of device in an I/O PM domain. | ||
948 | * @dev: Device to suspend. | ||
949 | * | ||
950 | * Stop the device and remove power from the domain if all devices in it have | ||
951 | * been stopped. | ||
952 | */ | ||
953 | static int pm_genpd_suspend_noirq(struct device *dev) | ||
954 | { | ||
955 | dev_dbg(dev, "%s()\n", __func__); | ||
956 | |||
957 | return genpd_finish_suspend(dev, false); | ||
958 | } | ||
959 | |||
960 | /** | ||
940 | * pm_genpd_resume_noirq - Start of resume of device in an I/O PM domain. | 961 | * pm_genpd_resume_noirq - Start of resume of device in an I/O PM domain. |
941 | * @dev: Device to resume. | 962 | * @dev: Device to resume. |
942 | * | 963 | * |
@@ -964,6 +985,10 @@ static int pm_genpd_resume_noirq(struct device *dev) | |||
964 | if (genpd->dev_ops.stop && genpd->dev_ops.start) | 985 | if (genpd->dev_ops.stop && genpd->dev_ops.start) |
965 | ret = pm_runtime_force_resume(dev); | 986 | ret = pm_runtime_force_resume(dev); |
966 | 987 | ||
988 | ret = pm_generic_resume_noirq(dev); | ||
989 | if (ret) | ||
990 | return ret; | ||
991 | |||
967 | return ret; | 992 | return ret; |
968 | } | 993 | } |
969 | 994 | ||
@@ -987,6 +1012,10 @@ static int pm_genpd_freeze_noirq(struct device *dev) | |||
987 | if (IS_ERR(genpd)) | 1012 | if (IS_ERR(genpd)) |
988 | return -EINVAL; | 1013 | return -EINVAL; |
989 | 1014 | ||
1015 | ret = pm_generic_freeze_noirq(dev); | ||
1016 | if (ret) | ||
1017 | return ret; | ||
1018 | |||
990 | if (genpd->dev_ops.stop && genpd->dev_ops.start) | 1019 | if (genpd->dev_ops.stop && genpd->dev_ops.start) |
991 | ret = pm_runtime_force_suspend(dev); | 1020 | ret = pm_runtime_force_suspend(dev); |
992 | 1021 | ||
@@ -1011,10 +1040,28 @@ static int pm_genpd_thaw_noirq(struct device *dev) | |||
1011 | if (IS_ERR(genpd)) | 1040 | if (IS_ERR(genpd)) |
1012 | return -EINVAL; | 1041 | return -EINVAL; |
1013 | 1042 | ||
1014 | if (genpd->dev_ops.stop && genpd->dev_ops.start) | 1043 | if (genpd->dev_ops.stop && genpd->dev_ops.start) { |
1015 | ret = pm_runtime_force_resume(dev); | 1044 | ret = pm_runtime_force_resume(dev); |
1045 | if (ret) | ||
1046 | return ret; | ||
1047 | } | ||
1016 | 1048 | ||
1017 | return ret; | 1049 | return pm_generic_thaw_noirq(dev); |
1050 | } | ||
1051 | |||
1052 | /** | ||
1053 | * pm_genpd_poweroff_noirq - Completion of hibernation of device in an | ||
1054 | * I/O PM domain. | ||
1055 | * @dev: Device to poweroff. | ||
1056 | * | ||
1057 | * Stop the device and remove power from the domain if all devices in it have | ||
1058 | * been stopped. | ||
1059 | */ | ||
1060 | static int pm_genpd_poweroff_noirq(struct device *dev) | ||
1061 | { | ||
1062 | dev_dbg(dev, "%s()\n", __func__); | ||
1063 | |||
1064 | return genpd_finish_suspend(dev, true); | ||
1018 | } | 1065 | } |
1019 | 1066 | ||
1020 | /** | 1067 | /** |
@@ -1051,10 +1098,13 @@ static int pm_genpd_restore_noirq(struct device *dev) | |||
1051 | genpd_sync_power_on(genpd, true, 0); | 1098 | genpd_sync_power_on(genpd, true, 0); |
1052 | genpd_unlock(genpd); | 1099 | genpd_unlock(genpd); |
1053 | 1100 | ||
1054 | if (genpd->dev_ops.stop && genpd->dev_ops.start) | 1101 | if (genpd->dev_ops.stop && genpd->dev_ops.start) { |
1055 | ret = pm_runtime_force_resume(dev); | 1102 | ret = pm_runtime_force_resume(dev); |
1103 | if (ret) | ||
1104 | return ret; | ||
1105 | } | ||
1056 | 1106 | ||
1057 | return ret; | 1107 | return pm_generic_restore_noirq(dev); |
1058 | } | 1108 | } |
1059 | 1109 | ||
1060 | /** | 1110 | /** |
@@ -1496,7 +1546,7 @@ int pm_genpd_init(struct generic_pm_domain *genpd, | |||
1496 | genpd->domain.ops.resume_noirq = pm_genpd_resume_noirq; | 1546 | genpd->domain.ops.resume_noirq = pm_genpd_resume_noirq; |
1497 | genpd->domain.ops.freeze_noirq = pm_genpd_freeze_noirq; | 1547 | genpd->domain.ops.freeze_noirq = pm_genpd_freeze_noirq; |
1498 | genpd->domain.ops.thaw_noirq = pm_genpd_thaw_noirq; | 1548 | genpd->domain.ops.thaw_noirq = pm_genpd_thaw_noirq; |
1499 | genpd->domain.ops.poweroff_noirq = pm_genpd_suspend_noirq; | 1549 | genpd->domain.ops.poweroff_noirq = pm_genpd_poweroff_noirq; |
1500 | genpd->domain.ops.restore_noirq = pm_genpd_restore_noirq; | 1550 | genpd->domain.ops.restore_noirq = pm_genpd_restore_noirq; |
1501 | genpd->domain.ops.complete = pm_genpd_complete; | 1551 | genpd->domain.ops.complete = pm_genpd_complete; |
1502 | 1552 | ||