aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-shmobile/pm-sh7372.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2011-12-22 19:23:39 -0500
committerRafael J. Wysocki <rjw@sisk.pl>2011-12-25 17:39:27 -0500
commit767c0f3aed74be56f268709f5347e6c86d52b408 (patch)
tree95064f1a46ddf9497178db52c7e2292a7d52a3df /arch/arm/mach-shmobile/pm-sh7372.c
parent0f966d74cf77a9140a025464a287e1d2fee8a1fc (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.c49
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
151static void sh7372_a4r_suspend(void) 149static 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
157static bool pd_active_wakeup(struct device *dev) 156static 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
249struct sh7372_pm_domain sh7372_a3rv = { 247struct 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
257static 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
259struct sh7372_pm_domain sh7372_a4s = { 266struct 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
274static 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
267struct sh7372_pm_domain sh7372_a3sp = { 283struct 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
274static 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
282struct sh7372_pm_domain sh7372_a3sg = { 291struct 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}