ARM: tegra: power: Restore LP2 in idle protections
Scott Williams [Wed, 29 Jun 2011 21:57:29 +0000 (14:57 -0700)]
Restore the code that was dropped in the port to Linux 2.6.39 that
protects against using LP2 mode for idle when the platform suspend
mode has disallowed the use of LP2 mode.

Also cleans up some warning messages.

Change-Id: I357210b8a272c10bf7c1e773342dc864bbddb74e
Reviewed-on: http://git-master/r/40463
Tested-by: Daniel Willemsen <dwillemsen@nvidia.com>
Reviewed-by: Scott Williams <scwilliams@nvidia.com>
Reviewed-by: Daniel Willemsen <dwillemsen@nvidia.com>

Rebase-Id: R6a60e3f0f2ebf06ec9701475af41679c24ef80ab

arch/arm/mach-tegra/cpuidle.c
arch/arm/mach-tegra/pm.c
arch/arm/mach-tegra/sleep.h

index 73f5986..54622e2 100644 (file)
@@ -94,6 +94,11 @@ struct cpuidle_driver tegra_idle_driver = {
 
 static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device);
 
+void tegra_lp2_in_idle(bool enable)
+{
+       lp2_in_idle = enable;
+}
+
 static inline unsigned int time_to_bin(unsigned int time)
 {
        return fls(time);
@@ -129,7 +134,7 @@ static int tegra_idle_enter_lp2(struct cpuidle_device *dev,
        ktime_t enter, exit;
        s64 us;
 
-       if (lp2_disabled_by_suspend)
+       if (!lp2_in_idle || lp2_disabled_by_suspend)
                return tegra_idle_enter_lp3(dev, state);
 
        local_irq_disable();
@@ -181,6 +186,7 @@ static int __init tegra_cpuidle_init(void)
        struct cpuidle_device *dev;
        struct cpuidle_driver *drv = &tegra_idle_driver;
 
+       /* !!!FIXME!!! Add tegra_lp2_power_off_time */
        tegra_lp2_min_residency = tegra_cpu_lp2_min_residency();
 
        tegra_idle_driver.states[1].exit_latency = tegra_cpu_power_good_time();
index f90e2a0..140926e 100644 (file)
@@ -858,14 +858,15 @@ void __init tegra_init_suspend(struct tegra_suspend_platform_data *plat)
            (tegra_revision == TEGRA_REVISION_A01) &&
            (plat->suspend_mode == TEGRA_SUSPEND_LP0)) {
                /* Tegra 3 A01 supports only LP1 */
-               pr_warning("Suspend mode LP0 is not supported on A01\n");
-               pr_warning("Disabling LP0\n");
+               pr_warning("%s: Suspend mode LP0 is not supported on A01 "
+                          "-- disabling LP0\n", __func__);
                plat->suspend_mode = TEGRA_SUSPEND_LP1;
        }
 
        if (plat->suspend_mode == TEGRA_SUSPEND_LP0 && !tegra_lp0_vec_size) {
-               pr_warning("Suspend mode LP0 requested, no lp0_vec\n");
-               pr_warning("Disabling LP0\n");
+               pr_warning("%s: Suspend mode LP0 requested, no lp0_vec "
+                          "provided by bootlader -- disabling LP0\n",
+                          __func__);
                plat->suspend_mode = TEGRA_SUSPEND_LP1;
        }
 
@@ -874,10 +875,11 @@ void __init tegra_init_suspend(struct tegra_suspend_platform_data *plat)
        iram_save = kmalloc(iram_save_size, GFP_KERNEL);
        if (!iram_save) {
                pr_err("%s: unable to allocate memory for SDRAM self-refresh "
-                      "LP0/LP1 unavailable\n", __func__);
+                      "-- LP0/LP1 unavailable\n", __func__);
                plat->suspend_mode = TEGRA_SUSPEND_LP2;
        }
 
+       /* !!!FIXME!!! THIS IS TEGRA2 ONLY */
        /* Initialize scratch registers used for CPU LP2 synchronization */
        writel(0, pmc + PMC_SCRATCH37);
        writel(0, pmc + PMC_SCRATCH38);
@@ -925,9 +927,21 @@ void __init tegra_init_suspend(struct tegra_suspend_platform_data *plat)
        if (suspend_kobj) {
                if (sysfs_create_file(suspend_kobj, \
                                                &suspend_mode_attribute.attr))
-                       pr_err("%s: sysfs_create_file suspend type failed!", \
+                       pr_err("%s: sysfs_create_file suspend type failed!\n",
                                                                __func__);
        }
+#else
+       if ((plat->suspend_mode == TEGRA_SUSPEND_LP0) ||
+           (plat->suspend_mode == TEGRA_SUSPEND_LP1)) {
+               pr_warning("%s: Suspend mode LP0 or LP1 requires "
+                          "CONFIG_PM_SLEEP -- limiting to LP2\n", __func__);
+               plat->suspend_mode = TEGRA_SUSPEND_LP2;
+       }
+#endif
+
+#ifdef CONFIG_CPU_IDLE
+       if (plat->suspend_mode == TEGRA_SUSPEND_NONE)
+               tegra_lp2_in_idle(false);
 #endif
 
        current_suspend_mode = plat->suspend_mode;
index 65e33c3..f2123b3 100644 (file)
@@ -112,6 +112,8 @@ extern void tegra_lp1_reset;
 extern void tegra_iram_start;
 extern void tegra_iram_end;
 
+void tegra_lp2_in_idle(bool enable);
+
 void tegra_sleep_wfi(unsigned long v2p);
 void tegra_sleep_cpu(unsigned long v2p);
 void tegra_sleep_core(unsigned long v2p);