aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-exynos
diff options
context:
space:
mode:
authorDaniel Lezcano <daniel.lezcano@linaro.org>2014-05-08 17:55:12 -0400
committerKukjin Kim <kgene.kim@samsung.com>2014-05-25 16:21:08 -0400
commit0ebc13e2a2353f76ecdca11cf4d49da0b4e77f09 (patch)
tree20c5c6accf7376210a502e3edc75cf6a7ac657ec /arch/arm/mach-exynos
parent3681bafeb1e4781bdeaecd19aa8c9f6d0db90f6f (diff)
ARM: EXYNOS: Move the power sequence call in the cpu_pm notifier
The code to initiate and exit the powerdown sequence is the same in pm.c and cpuidle.c. Let's split the common part in the pm.c and reuse it from the cpu_pm notifier. That is one more step forward to make the cpuidle driver arch indenpendant. Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org> Reviewed-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> Reviewed-by: Tomasz Figa <t.figa@samsung.com> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
Diffstat (limited to 'arch/arm/mach-exynos')
-rw-r--r--arch/arm/mach-exynos/cpuidle.c22
-rw-r--r--arch/arm/mach-exynos/pm.c27
2 files changed, 22 insertions, 27 deletions
diff --git a/arch/arm/mach-exynos/cpuidle.c b/arch/arm/mach-exynos/cpuidle.c
index eea3eb9cecef..cac51d852605 100644
--- a/arch/arm/mach-exynos/cpuidle.c
+++ b/arch/arm/mach-exynos/cpuidle.c
@@ -29,7 +29,6 @@
29#include <mach/map.h> 29#include <mach/map.h>
30 30
31#include "common.h" 31#include "common.h"
32#include "regs-pmu.h"
33 32
34static int idle_finisher(unsigned long flags) 33static int idle_finisher(unsigned long flags)
35{ 34{
@@ -43,31 +42,10 @@ static int exynos_enter_core0_aftr(struct cpuidle_device *dev,
43 struct cpuidle_driver *drv, 42 struct cpuidle_driver *drv,
44 int index) 43 int index)
45{ 44{
46 unsigned long tmp;
47
48 /* Setting Central Sequence Register for power down mode */
49 tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
50 tmp &= ~S5P_CENTRAL_LOWPWR_CFG;
51 __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
52
53 cpu_pm_enter(); 45 cpu_pm_enter();
54 cpu_suspend(0, idle_finisher); 46 cpu_suspend(0, idle_finisher);
55 cpu_pm_exit(); 47 cpu_pm_exit();
56 48
57 /*
58 * If PMU failed while entering sleep mode, WFI will be
59 * ignored by PMU and then exiting cpu_do_idle().
60 * S5P_CENTRAL_LOWPWR_CFG bit will not be set automatically
61 * in this situation.
62 */
63 tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
64 if (!(tmp & S5P_CENTRAL_LOWPWR_CFG)) {
65 tmp |= S5P_CENTRAL_LOWPWR_CFG;
66 __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
67 /* Clear wakeup state register */
68 __raw_writel(0x0, S5P_WAKEUP_STAT);
69 }
70
71 return index; 49 return index;
72} 50}
73 51
diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
index 179f7e09e20d..8b268b5b42fa 100644
--- a/arch/arm/mach-exynos/pm.c
+++ b/arch/arm/mach-exynos/pm.c
@@ -279,15 +279,21 @@ static void exynos_pm_prepare(void)
279 __raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0); 279 __raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0);
280} 280}
281 281
282static int exynos_pm_suspend(void) 282static void exynos_pm_central_suspend(void)
283{ 283{
284 unsigned long tmp; 284 unsigned long tmp;
285 285
286 /* Setting Central Sequence Register for power down mode */ 286 /* Setting Central Sequence Register for power down mode */
287
288 tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION); 287 tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
289 tmp &= ~S5P_CENTRAL_LOWPWR_CFG; 288 tmp &= ~S5P_CENTRAL_LOWPWR_CFG;
290 __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION); 289 __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
290}
291
292static int exynos_pm_suspend(void)
293{
294 unsigned long tmp;
295
296 exynos_pm_central_suspend();
291 297
292 /* Setting SEQ_OPTION register */ 298 /* Setting SEQ_OPTION register */
293 299
@@ -300,7 +306,7 @@ static int exynos_pm_suspend(void)
300 return 0; 306 return 0;
301} 307}
302 308
303static void exynos_pm_resume(void) 309static int exynos_pm_central_resume(void)
304{ 310{
305 unsigned long tmp; 311 unsigned long tmp;
306 312
@@ -317,9 +323,17 @@ static void exynos_pm_resume(void)
317 /* clear the wakeup state register */ 323 /* clear the wakeup state register */
318 __raw_writel(0x0, S5P_WAKEUP_STAT); 324 __raw_writel(0x0, S5P_WAKEUP_STAT);
319 /* No need to perform below restore code */ 325 /* No need to perform below restore code */
320 goto early_wakeup; 326 return -1;
321 } 327 }
322 328
329 return 0;
330}
331
332static void exynos_pm_resume(void)
333{
334 if (exynos_pm_central_resume())
335 goto early_wakeup;
336
323 if (!soc_is_exynos5250()) 337 if (!soc_is_exynos5250())
324 exynos_cpu_restore_register(); 338 exynos_cpu_restore_register();
325 339
@@ -424,8 +438,10 @@ static int exynos_cpu_pm_notifier(struct notifier_block *self,
424 438
425 switch (cmd) { 439 switch (cmd) {
426 case CPU_PM_ENTER: 440 case CPU_PM_ENTER:
427 if (cpu == 0) 441 if (cpu == 0) {
442 exynos_pm_central_suspend();
428 exynos_cpu_save_register(); 443 exynos_cpu_save_register();
444 }
429 break; 445 break;
430 446
431 case CPU_PM_EXIT: 447 case CPU_PM_EXIT:
@@ -433,6 +449,7 @@ static int exynos_cpu_pm_notifier(struct notifier_block *self,
433 if (!soc_is_exynos5250()) 449 if (!soc_is_exynos5250())
434 scu_enable(S5P_VA_SCU); 450 scu_enable(S5P_VA_SCU);
435 exynos_cpu_restore_register(); 451 exynos_cpu_restore_register();
452 exynos_pm_central_resume();
436 } 453 }
437 break; 454 break;
438 } 455 }