diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2011-12-22 19:23:39 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2011-12-25 17:39:27 -0500 |
commit | 767c0f3aed74be56f268709f5347e6c86d52b408 (patch) | |
tree | 95064f1a46ddf9497178db52c7e2292a7d52a3df /arch/arm/mach-shmobile/pm-sh7372.c | |
parent | 0f966d74cf77a9140a025464a287e1d2fee8a1fc (diff) |
PM / shmobile: Remove the stay_on flag from SH7372's PM domains
SH7372 uses two independent mechanisms for ensuring that power
domains will never be turned off: the stay_on flag and the "always
on" domain governor. Moreover, the "always on" governor is only taken
into accout by runtime PM code paths, while the stay_on flag affects
all attempts to turn the given domain off. Thus setting the stay_on
flag causes the "always on" governor to be unnecessary, which is
quite confusing.
However, the stay_on flag is currently only set for two domains: A3SP
and A4S. Moreover, it only is set for the A3SP domain if
console_suspend_enabled is set, so stay_on won't be necessary for
that domain any more if console_suspend_enabled is checked directly
in its .suspend() routine. [This requires domain .suspend() to
return a result, but that is a minor modification.] Analogously,
stay_on won't be necessary for the A4S domain if it's .suspend()
routine always returns an error code.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Magnus Damm <damm@opensource.se>
Diffstat (limited to 'arch/arm/mach-shmobile/pm-sh7372.c')
-rw-r--r-- | arch/arm/mach-shmobile/pm-sh7372.c | 49 |
1 files changed, 28 insertions, 21 deletions
diff --git a/arch/arm/mach-shmobile/pm-sh7372.c b/arch/arm/mach-shmobile/pm-sh7372.c index 1e659d7360d1..7fda2301c9b2 100644 --- a/arch/arm/mach-shmobile/pm-sh7372.c +++ b/arch/arm/mach-shmobile/pm-sh7372.c | |||
@@ -82,11 +82,12 @@ static int pd_power_down(struct generic_pm_domain *genpd) | |||
82 | struct sh7372_pm_domain *sh7372_pd = to_sh7372_pd(genpd); | 82 | struct sh7372_pm_domain *sh7372_pd = to_sh7372_pd(genpd); |
83 | unsigned int mask = 1 << sh7372_pd->bit_shift; | 83 | unsigned int mask = 1 << sh7372_pd->bit_shift; |
84 | 84 | ||
85 | if (sh7372_pd->suspend) | 85 | if (sh7372_pd->suspend) { |
86 | sh7372_pd->suspend(); | 86 | int ret = sh7372_pd->suspend(); |
87 | 87 | ||
88 | if (sh7372_pd->stay_on) | 88 | if (ret) |
89 | return 0; | 89 | return ret; |
90 | } | ||
90 | 91 | ||
91 | if (__raw_readl(PSTR) & mask) { | 92 | if (__raw_readl(PSTR) & mask) { |
92 | unsigned int retry_count; | 93 | unsigned int retry_count; |
@@ -113,9 +114,6 @@ static int __pd_power_up(struct sh7372_pm_domain *sh7372_pd, bool do_resume) | |||
113 | unsigned int retry_count; | 114 | unsigned int retry_count; |
114 | int ret = 0; | 115 | int ret = 0; |
115 | 116 | ||
116 | if (sh7372_pd->stay_on) | ||
117 | goto out; | ||
118 | |||
119 | if (__raw_readl(PSTR) & mask) | 117 | if (__raw_readl(PSTR) & mask) |
120 | goto out; | 118 | goto out; |
121 | 119 | ||
@@ -148,10 +146,11 @@ static int pd_power_up(struct generic_pm_domain *genpd) | |||
148 | return __pd_power_up(to_sh7372_pd(genpd), true); | 146 | return __pd_power_up(to_sh7372_pd(genpd), true); |
149 | } | 147 | } |
150 | 148 | ||
151 | static void sh7372_a4r_suspend(void) | 149 | static int sh7372_a4r_suspend(void) |
152 | { | 150 | { |
153 | sh7372_intcs_suspend(); | 151 | sh7372_intcs_suspend(); |
154 | __raw_writel(0x300fffff, WUPRMSK); /* avoid wakeup */ | 152 | __raw_writel(0x300fffff, WUPRMSK); /* avoid wakeup */ |
153 | return 0; | ||
155 | } | 154 | } |
156 | 155 | ||
157 | static bool pd_active_wakeup(struct device *dev) | 156 | static bool pd_active_wakeup(struct device *dev) |
@@ -243,7 +242,6 @@ struct sh7372_pm_domain sh7372_a4r = { | |||
243 | .gov = &pm_domain_always_on_gov, | 242 | .gov = &pm_domain_always_on_gov, |
244 | .suspend = sh7372_a4r_suspend, | 243 | .suspend = sh7372_a4r_suspend, |
245 | .resume = sh7372_intcs_resume, | 244 | .resume = sh7372_intcs_resume, |
246 | .stay_on = true, | ||
247 | }; | 245 | }; |
248 | 246 | ||
249 | struct sh7372_pm_domain sh7372_a3rv = { | 247 | struct sh7372_pm_domain sh7372_a3rv = { |
@@ -256,29 +254,40 @@ struct sh7372_pm_domain sh7372_a3ri = { | |||
256 | .bit_shift = 8, | 254 | .bit_shift = 8, |
257 | }; | 255 | }; |
258 | 256 | ||
257 | static int sh7372_a4s_suspend(void) | ||
258 | { | ||
259 | /* | ||
260 | * The A4S domain contains the CPU core and therefore it should | ||
261 | * only be turned off if the CPU is in use. | ||
262 | */ | ||
263 | return -EBUSY; | ||
264 | } | ||
265 | |||
259 | struct sh7372_pm_domain sh7372_a4s = { | 266 | struct sh7372_pm_domain sh7372_a4s = { |
260 | .genpd.name = "A4S", | 267 | .genpd.name = "A4S", |
261 | .bit_shift = 10, | 268 | .bit_shift = 10, |
262 | .gov = &pm_domain_always_on_gov, | 269 | .gov = &pm_domain_always_on_gov, |
263 | .no_debug = true, | 270 | .no_debug = true, |
264 | .stay_on = true, | 271 | .suspend = sh7372_a4s_suspend, |
265 | }; | 272 | }; |
266 | 273 | ||
274 | static int sh7372_a3sp_suspend(void) | ||
275 | { | ||
276 | /* | ||
277 | * Serial consoles make use of SCIF hardware located in A3SP, | ||
278 | * keep such power domain on if "no_console_suspend" is set. | ||
279 | */ | ||
280 | return console_suspend_enabled ? -EBUSY : 0; | ||
281 | } | ||
282 | |||
267 | struct sh7372_pm_domain sh7372_a3sp = { | 283 | struct sh7372_pm_domain sh7372_a3sp = { |
268 | .genpd.name = "A3SP", | 284 | .genpd.name = "A3SP", |
269 | .bit_shift = 11, | 285 | .bit_shift = 11, |
270 | .gov = &pm_domain_always_on_gov, | 286 | .gov = &pm_domain_always_on_gov, |
271 | .no_debug = true, | 287 | .no_debug = true, |
288 | .suspend = sh7372_a3sp_suspend, | ||
272 | }; | 289 | }; |
273 | 290 | ||
274 | static void sh7372_a3sp_init(void) | ||
275 | { | ||
276 | /* serial consoles make use of SCIF hardware located in A3SP, | ||
277 | * keep such power domain on if "no_console_suspend" is set. | ||
278 | */ | ||
279 | sh7372_a3sp.stay_on = !console_suspend_enabled; | ||
280 | } | ||
281 | |||
282 | struct sh7372_pm_domain sh7372_a3sg = { | 291 | struct sh7372_pm_domain sh7372_a3sg = { |
283 | .genpd.name = "A3SG", | 292 | .genpd.name = "A3SG", |
284 | .bit_shift = 13, | 293 | .bit_shift = 13, |
@@ -508,7 +517,7 @@ static int sh7372_enter_suspend(suspend_state_t suspend_state) | |||
508 | /* convert INTC mask and sense to SYSC mask and sense */ | 517 | /* convert INTC mask and sense to SYSC mask and sense */ |
509 | sh7372_setup_sysc(msk, msk2); | 518 | sh7372_setup_sysc(msk, msk2); |
510 | 519 | ||
511 | if (!sh7372_a3sp.stay_on && | 520 | if (!console_suspend_enabled && |
512 | sh7372_a4s.genpd.status == GPD_STATE_POWER_OFF) { | 521 | sh7372_a4s.genpd.status == GPD_STATE_POWER_OFF) { |
513 | /* enter A4S sleep with PLLC0 off */ | 522 | /* enter A4S sleep with PLLC0 off */ |
514 | pr_debug("entering A4S\n"); | 523 | pr_debug("entering A4S\n"); |
@@ -544,8 +553,6 @@ void __init sh7372_pm_init(void) | |||
544 | /* do not convert A3SM, A3SP, A3SG, A4R power down into A4S */ | 553 | /* do not convert A3SM, A3SP, A3SG, A4R power down into A4S */ |
545 | __raw_writel(0, PDNSEL); | 554 | __raw_writel(0, PDNSEL); |
546 | 555 | ||
547 | sh7372_a3sp_init(); | ||
548 | |||
549 | sh7372_suspend_init(); | 556 | sh7372_suspend_init(); |
550 | sh7372_cpuidle_init(); | 557 | sh7372_cpuidle_init(); |
551 | } | 558 | } |