ARM: tegra: power: Re-factor Tegra3 secondary CPU LP2 entry
Alex Frid [Sun, 29 Jan 2012 01:36:37 +0000 (17:36 -0800)]
When Tegra3 secondary CPU is entering LP2, read TWD timer state
into context structure, rather than separate local variables.

Reviewed-on: http://git-master/r/77957

Change-Id: I237eafc50a11d535b94f334631d039ba9c4bf44b
Signed-off-by: Alex Frid <afrid@nvidia.com>
Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
Reviewed-on: http://git-master/r/78899
Reviewed-by: Automatic_Commit_Validation_User

Rebase-Id: Ra2fb8f72f23c8aac06757aba504623ea45ae4185

arch/arm/mach-tegra/cpuidle-t3.c
arch/arm/mach-tegra/timer.c
arch/arm/mach-tegra/timer.h

index 4915304..0f9f899 100644 (file)
@@ -295,14 +295,15 @@ static void tegra3_idle_enter_lp2_cpu_n(struct cpuidle_device *dev,
 {
 #ifdef CONFIG_SMP
        ktime_t entery_time;
-       u32 twd_cnt;
-       u32 twd_ctrl = readl(twd_base + TWD_TIMER_CONTROL);
+       struct tegra_twd_context twd_context;
        unsigned long twd_rate = clk_get_rate(twd_clk);
 
-       if ((twd_ctrl & TWD_TIMER_CONTROL_ENABLE) &&
-           (twd_ctrl & TWD_TIMER_CONTROL_IT_ENABLE)) {
-               twd_cnt = readl(twd_base + TWD_TIMER_COUNTER);
-               request = div_u64((u64)twd_cnt * 1000000, twd_rate);
+       if (!tegra_twd_get_state(&twd_context)) {
+               if ((twd_context.twd_ctrl & TWD_TIMER_CONTROL_ENABLE) &&
+                   (twd_context.twd_ctrl & TWD_TIMER_CONTROL_IT_ENABLE)) {
+                       request = div_u64((u64)twd_context.twd_cnt * 1000000,
+                                         twd_rate);
+               }
        }
 
        if (request < tegra_lp2_exit_latency) {
index db0d186..a5dde88 100644 (file)
@@ -200,6 +200,15 @@ static void __init tegra_twd_init(void)
                pr_err("twd_local_timer_register failed %d\n", err);
 }
 
+int tegra_twd_get_state(struct tegra_twd_context *context)
+{
+       context->twd_ctrl = readl(twd_base + TWD_TIMER_CONTROL);
+       context->twd_load = readl(twd_base + TWD_TIMER_LOAD);
+       context->twd_cnt = readl(twd_base + TWD_TIMER_COUNTER);
+
+       return 0;
+}
+
 void tegra_twd_suspend(struct tegra_twd_context *context)
 {
        context->twd_ctrl = readl(twd_base + TWD_TIMER_CONTROL);
index 6cd1f37..69c11db 100644 (file)
@@ -38,12 +38,16 @@ void __init tegra3_init_timer(u32 *offset, int *irq, unsigned long rate);
 struct tegra_twd_context {
        u32 twd_ctrl;
        u32 twd_load;
+       u32 twd_cnt;
 };
 
 #ifdef CONFIG_HAVE_ARM_TWD
+int tegra_twd_get_state(struct tegra_twd_context *context);
 void tegra_twd_suspend(struct tegra_twd_context *context);
 void tegra_twd_resume(struct tegra_twd_context *context);
 #else
+static inline int tegra_twd_get_state(struct tegra_twd_context *context)
+{ return -ENODEV; }
 static inline void tegra_twd_suspend(struct tegra_twd_context *context) {}
 static inline void tegra_twd_resume(struct tegra_twd_context *context) {}
 #endif