ARM: tegra: Idle event wakeup timer
Scott Williams [Fri, 22 Jul 2011 00:06:46 +0000 (17:06 -0700)]
Change-Id: If072ef10f02d5be7560fdf42584ab11b2a863481
Signed-off-by: Scott Williams <scwilliams@nvidia.com>
DW: Split into logical changes
Signed-off-by: Dan Willemsen <dwillemsen@nvidia.com>

Rebase-Id: Rf1ace67e281b1581501aaa936cd9137d326f2c4a

arch/arm/mach-tegra/cpuidle-t2.c
arch/arm/mach-tegra/pm-t3.c
arch/arm/mach-tegra/pm.c
arch/arm/mach-tegra/pm.h

index bfd9551..4666aec 100644 (file)
@@ -136,7 +136,7 @@ static int tegra2_reset_other_cpus(int cpu)
 #endif
 
 static int tegra2_idle_lp2_last(struct cpuidle_device *dev,
-                       struct cpuidle_state *state)
+                       struct cpuidle_state *state, s64 request)
 {
        int i;
 
@@ -146,7 +146,7 @@ static int tegra2_idle_lp2_last(struct cpuidle_device *dev,
        if (tegra2_reset_other_cpus(dev->cpu))
                return -EBUSY;
 
-       tegra_idle_lp2_last(0);
+       tegra_idle_lp2_last(request, 0);
 
        for_each_online_cpu(i) {
                if (i != dev->cpu) {
@@ -161,12 +161,13 @@ static int tegra2_idle_lp2_last(struct cpuidle_device *dev,
 void tegra2_idle_lp2(struct cpuidle_device *dev,
                        struct cpuidle_state *state)
 {
+       s64 request = ktime_to_us(tick_nohz_get_sleep_length());
        bool last_cpu = tegra_set_cpu_in_lp2(dev->cpu);
 
        cpu_pm_enter();
 
        if (last_cpu) {
-               if (tegra2_idle_lp2_last(dev, state) < 0) {
+               if (tegra2_idle_lp2_last(dev, state, request) < 0) {
                        int i;
                        for_each_online_cpu(i) {
                                if (i != dev->cpu) {
index 5055c8a..ff46f57 100644 (file)
@@ -311,7 +311,7 @@ int tegra_cluster_control(unsigned int us, unsigned int flags)
                if (us)
                        tegra_lp2_set_trigger(0);
        } else
-               tegra_idle_lp2_last(flags);
+               tegra_idle_lp2_last(0, flags);
        local_irq_enable();
 
        DEBUG_CLUSTER(("%s: %s\r\n", __func__, is_lp_cluster() ? "LP" : "G"));
index e295cbf..f3b8787 100644 (file)
@@ -414,7 +414,7 @@ bool tegra_set_cpu_in_lp2(int cpu)
        return last_cpu;
 }
 
-void tegra_idle_lp2_last(unsigned int flags)
+void tegra_idle_lp2_last(unsigned int sleep_time, unsigned int flags)
 {
        u32 reg;
 
@@ -431,8 +431,8 @@ void tegra_idle_lp2_last(unsigned int flags)
        writel(virt_to_phys(tegra_resume), evp_reset);
 
        /*
-        * we can use the locked call here, because all other cpus are in reset
-        * and irqs are disabled
+        * We can use clk_get_rate_all_locked() here, because all other cpus
+        * are in LP2 state and irqs are disabled
         */
        set_power_timers(pdata->cpu_timer, pdata->cpu_off_timer,
                clk_get_rate_all_locked(tegra_pclk));
@@ -440,6 +440,9 @@ void tegra_idle_lp2_last(unsigned int flags)
        if (flags & TEGRA_POWER_CLUSTER_MASK)
                tegra_cluster_switch_prolog(reg);
 
+       if (sleep_time)
+               tegra_lp2_set_trigger(sleep_time);
+
        cpu_cluster_pm_enter();
 
        suspend_cpu_complex();
@@ -455,6 +458,9 @@ void tegra_idle_lp2_last(unsigned int flags)
        restore_cpu_complex();
        cpu_cluster_pm_exit();
 
+       if (sleep_time)
+               tegra_lp2_set_trigger(0);
+
        if (flags & TEGRA_POWER_CLUSTER_MASK)
                tegra_cluster_switch_epilog(reg);
 
index 6d7ca28..350c745 100644 (file)
@@ -95,8 +95,10 @@ u64 tegra_rtc_read_ms(void);
  */
 extern void (*tegra_deep_sleep)(int);
 
-void tegra_idle_lp2_last(unsigned int flags);
+void tegra_idle_lp2_last(unsigned int us, unsigned int flags);
+
 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
+
 #define INSTRUMENT_CLUSTER_SWITCH 0    /* Must be zero for ARCH_TEGRA_2x_SOC */
 #define DEBUG_CLUSTER_SWITCH 0         /* Must be zero for ARCH_TEGRA_2x_SOC */
 #define PARAMETERIZE_CLUSTER_SWITCH 0  /* Must be zero for ARCH_TEGRA_2x_SOC */