aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c2
-rw-r--r--arch/arm/mach-shmobile/board-mackerel.c2
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh7372.h2
-rw-r--r--arch/arm/mach-shmobile/pm-sh7372.c56
4 files changed, 50 insertions, 12 deletions
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 5168a0338cf4..264340a60f65 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -1486,6 +1486,6 @@ MACHINE_START(AP4EVB, "ap4evb")
1486 .init_irq = sh7372_init_irq, 1486 .init_irq = sh7372_init_irq,
1487 .handle_irq = shmobile_handle_irq_intc, 1487 .handle_irq = shmobile_handle_irq_intc,
1488 .init_machine = ap4evb_init, 1488 .init_machine = ap4evb_init,
1489 .init_late = shmobile_init_late, 1489 .init_late = sh7372_pm_init_late,
1490 .timer = &shmobile_timer, 1490 .timer = &shmobile_timer,
1491MACHINE_END 1491MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index d1e8fe83588c..f96e41557d65 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -1654,6 +1654,6 @@ MACHINE_START(MACKEREL, "mackerel")
1654 .init_irq = sh7372_init_irq, 1654 .init_irq = sh7372_init_irq,
1655 .handle_irq = shmobile_handle_irq_intc, 1655 .handle_irq = shmobile_handle_irq_intc,
1656 .init_machine = mackerel_init, 1656 .init_machine = mackerel_init,
1657 .init_late = shmobile_init_late, 1657 .init_late = sh7372_pm_init_late,
1658 .timer = &shmobile_timer, 1658 .timer = &shmobile_timer,
1659MACHINE_END 1659MACHINE_END
diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h
index 40beb796d020..eb98b45c5089 100644
--- a/arch/arm/mach-shmobile/include/mach/sh7372.h
+++ b/arch/arm/mach-shmobile/include/mach/sh7372.h
@@ -489,4 +489,6 @@ extern void __init sh7372_init_pm_domains(void);
489static inline void sh7372_init_pm_domains(void) {} 489static inline void sh7372_init_pm_domains(void) {}
490#endif 490#endif
491 491
492extern void __init sh7372_pm_init_late(void);
493
492#endif /* __ASM_SH7372_H__ */ 494#endif /* __ASM_SH7372_H__ */
diff --git a/arch/arm/mach-shmobile/pm-sh7372.c b/arch/arm/mach-shmobile/pm-sh7372.c
index 5cafd35cc411..a7a5e20ae9a0 100644
--- a/arch/arm/mach-shmobile/pm-sh7372.c
+++ b/arch/arm/mach-shmobile/pm-sh7372.c
@@ -339,6 +339,21 @@ static void sh7372_enter_a3sm_common(int pllc0_on)
339 sh7372_set_reset_vector(__pa(sh7372_resume_core_standby_sysc)); 339 sh7372_set_reset_vector(__pa(sh7372_resume_core_standby_sysc));
340 sh7372_enter_sysc(pllc0_on, 1 << 12); 340 sh7372_enter_sysc(pllc0_on, 1 << 12);
341} 341}
342
343static void sh7372_enter_a4s_common(int pllc0_on)
344{
345 sh7372_intca_suspend();
346 sh7372_set_reset_vector(SMFRAM);
347 sh7372_enter_sysc(pllc0_on, 1 << 10);
348 sh7372_intca_resume();
349}
350
351static void sh7372_pm_setup_smfram(void)
352{
353 memcpy((void *)SMFRAM, sh7372_resume_core_standby_sysc, 0x100);
354}
355#else
356static inline void sh7372_pm_setup_smfram(void) {}
342#endif /* CONFIG_SUSPEND || CONFIG_CPU_IDLE */ 357#endif /* CONFIG_SUSPEND || CONFIG_CPU_IDLE */
343 358
344#ifdef CONFIG_CPU_IDLE 359#ifdef CONFIG_CPU_IDLE
@@ -378,11 +393,24 @@ static int sh7372_enter_a3sm_pll_off(struct cpuidle_device *dev,
378 return 3; 393 return 3;
379} 394}
380 395
396static int sh7372_enter_a4s(struct cpuidle_device *dev,
397 struct cpuidle_driver *drv, int index)
398{
399 unsigned long msk, msk2;
400
401 if (!sh7372_sysc_valid(&msk, &msk2))
402 return sh7372_enter_a3sm_pll_off(dev, drv, index);
403
404 sh7372_setup_sysc(msk, msk2);
405 sh7372_enter_a4s_common(0);
406 return 4;
407}
408
381static struct cpuidle_driver sh7372_cpuidle_driver = { 409static struct cpuidle_driver sh7372_cpuidle_driver = {
382 .name = "sh7372_cpuidle", 410 .name = "sh7372_cpuidle",
383 .owner = THIS_MODULE, 411 .owner = THIS_MODULE,
384 .en_core_tk_irqen = 1, 412 .en_core_tk_irqen = 1,
385 .state_count = 4, 413 .state_count = 5,
386 .safe_state_index = 0, /* C1 */ 414 .safe_state_index = 0, /* C1 */
387 .states[0] = ARM_CPUIDLE_WFI_STATE, 415 .states[0] = ARM_CPUIDLE_WFI_STATE,
388 .states[0].enter = shmobile_enter_wfi, 416 .states[0].enter = shmobile_enter_wfi,
@@ -410,6 +438,15 @@ static struct cpuidle_driver sh7372_cpuidle_driver = {
410 .flags = CPUIDLE_FLAG_TIME_VALID, 438 .flags = CPUIDLE_FLAG_TIME_VALID,
411 .enter = sh7372_enter_a3sm_pll_off, 439 .enter = sh7372_enter_a3sm_pll_off,
412 }, 440 },
441 .states[4] = {
442 .name = "C5",
443 .desc = "A4S PLL OFF",
444 .exit_latency = 240,
445 .target_residency = 30 + 240,
446 .flags = CPUIDLE_FLAG_TIME_VALID,
447 .enter = sh7372_enter_a4s,
448 .disabled = true,
449 },
413}; 450};
414 451
415static void sh7372_cpuidle_init(void) 452static void sh7372_cpuidle_init(void)
@@ -421,15 +458,6 @@ static void sh7372_cpuidle_init(void) {}
421#endif 458#endif
422 459
423#ifdef CONFIG_SUSPEND 460#ifdef CONFIG_SUSPEND
424static void sh7372_enter_a4s_common(int pllc0_on)
425{
426 sh7372_intca_suspend();
427 memcpy((void *)SMFRAM, sh7372_resume_core_standby_sysc, 0x100);
428 sh7372_set_reset_vector(SMFRAM);
429 sh7372_enter_sysc(pllc0_on, 1 << 10);
430 sh7372_intca_resume();
431}
432
433static int sh7372_enter_suspend(suspend_state_t suspend_state) 461static int sh7372_enter_suspend(suspend_state_t suspend_state)
434{ 462{
435 unsigned long msk, msk2; 463 unsigned long msk, msk2;
@@ -497,6 +525,14 @@ void __init sh7372_pm_init(void)
497 /* do not convert A3SM, A3SP, A3SG, A4R power down into A4S */ 525 /* do not convert A3SM, A3SP, A3SG, A4R power down into A4S */
498 __raw_writel(0, PDNSEL); 526 __raw_writel(0, PDNSEL);
499 527
528 sh7372_pm_setup_smfram();
529
500 sh7372_suspend_init(); 530 sh7372_suspend_init();
501 sh7372_cpuidle_init(); 531 sh7372_cpuidle_init();
502} 532}
533
534void __init sh7372_pm_init_late(void)
535{
536 shmobile_init_late();
537 pm_genpd_name_attach_cpuidle("A4S", 4);
538}