diff options
-rw-r--r-- | arch/arm/mach-shmobile/board-ap4evb.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/board-mackerel.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/include/mach/sh7372.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/pm-sh7372.c | 56 |
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, |
1491 | MACHINE_END | 1491 | MACHINE_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, |
1659 | MACHINE_END | 1659 | MACHINE_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); | |||
489 | static inline void sh7372_init_pm_domains(void) {} | 489 | static inline void sh7372_init_pm_domains(void) {} |
490 | #endif | 490 | #endif |
491 | 491 | ||
492 | extern 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 | |||
343 | static 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 | |||
351 | static void sh7372_pm_setup_smfram(void) | ||
352 | { | ||
353 | memcpy((void *)SMFRAM, sh7372_resume_core_standby_sysc, 0x100); | ||
354 | } | ||
355 | #else | ||
356 | static 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 | ||
396 | static 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 | |||
381 | static struct cpuidle_driver sh7372_cpuidle_driver = { | 409 | static 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 | ||
415 | static void sh7372_cpuidle_init(void) | 452 | static 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 |
424 | static 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 | |||
433 | static int sh7372_enter_suspend(suspend_state_t suspend_state) | 461 | static 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 | |||
534 | void __init sh7372_pm_init_late(void) | ||
535 | { | ||
536 | shmobile_init_late(); | ||
537 | pm_genpd_name_attach_cpuidle("A4S", 4); | ||
538 | } | ||