ARM: tegra: power: add partition power check before suspend
Jin Qian [Wed, 16 Mar 2011 19:30:41 +0000 (12:30 -0700)]
Original-Change-Id: Ie4b29d1119bc2f640891525ab781c8de1bf64ddf
Reviewed-on: http://git-master/r/23215
Tested-by: Jin Qian <jqian@nvidia.com>
Reviewed-by: Scott Williams <scwilliams@nvidia.com>
Original-Change-Id: Idc616485ecdb9e7c39728409d91a511e1de79e05

Rebase-Id: Rd61725b233749ea76467686439b92ac22b65f424

arch/arm/mach-tegra/include/mach/powergate.h
arch/arm/mach-tegra/pm.c
arch/arm/mach-tegra/powergate.c

index 06763fe..968b17e 100644 (file)
@@ -47,6 +47,7 @@ int tegra_powergate_is_powered(int id);
 int tegra_powergate_power_on(int id);
 int tegra_powergate_power_off(int id);
 int tegra_powergate_remove_clamping(int id);
+const char* tegra_powergate_get_name(int id);
 
 /* Must be called with clk disabled, and returns with clk enabled */
 int tegra_powergate_sequence_power_up(int id, struct clk *clk);
index db68289..46026b9 100644 (file)
@@ -49,6 +49,7 @@
 #include <asm/tlbflush.h>
 
 #include <mach/irqs.h>
+#include <mach/powergate.h>
 
 #include "board.h"
 #include "clock.h"
@@ -180,6 +181,31 @@ static unsigned long tegra_cluster_switch_times[tegra_cluster_switch_time_id_max
 #define tegra_cluster_switch_time(flags, id) do {} while(0)
 #endif
 
+static void tegra_suspend_check_pwr_stats(void)
+{
+       /* cpus and l2 are powered off later */
+       unsigned long pwrgate_partid_mask =
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
+               (1 << TEGRA_POWERGATE_HEG)      |
+               (1 << TEGRA_POWERGATE_SATA)     |
+               (1 << TEGRA_POWERGATE_3D1)      |
+#endif
+               (1 << TEGRA_POWERGATE_3D)       |
+               (1 << TEGRA_POWERGATE_VENC)     |
+               (1 << TEGRA_POWERGATE_PCIE)     |
+               (1 << TEGRA_POWERGATE_VDEC)     |
+               (1 << TEGRA_POWERGATE_MPE);
+       
+       int partid;
+
+       for_each_set_bit(partid, &pwrgate_partid_mask, BITS_PER_LONG)
+               if (tegra_powergate_is_powered(partid) == 1)
+                       pr_warning("partition %s is left on before suspend\n",
+                               tegra_powergate_get_name(partid));
+
+       return;
+}
+
 unsigned long tegra_cpu_power_good_time(void)
 {
        if (WARN_ON_ONCE(!pdata))
@@ -672,6 +698,9 @@ static int tegra_suspend_enter(suspend_state_t state)
                mode = TEGRA_SUSPEND_LP1;
        }
 
+       if ((mode == TEGRA_SUSPEND_LP0) || (mode == TEGRA_SUSPEND_LP1))
+               tegra_suspend_check_pwr_stats();
+
        tegra_common_suspend();
 
        pr_info("Entering suspend state %s\n", lp_state[mode]);
index 464e28f..adff436 100644 (file)
@@ -205,11 +205,13 @@ int __init tegra_powergate_init(void)
        switch (tegra_chip_id) {
        case TEGRA20:
                tegra_num_powerdomains = 7;
+               powergate_name = powergate_name_t20;
                break;
        case TEGRA30:
                tegra_num_powerdomains = 14;
                tegra_num_cpu_domains = 4;
                tegra_cpu_domains = tegra30_cpu_domains;
+               powergate_name = powergate_name_t30;
                break;
        default:
                /* Unknown Tegra variant. Disable powergating */
@@ -220,8 +222,6 @@ int __init tegra_powergate_init(void)
        return 0;
 }
 
-#ifdef CONFIG_DEBUG_FS
-
 static const char * const *powergate_name;
 
 static const char * const powergate_name_t20[] = {
@@ -251,6 +251,16 @@ static const char * const powergate_name_t30[] = {
        [TEGRA_POWERGATE_3D1]   = "3d1",
 };
 
+const char* tegra_powergate_get_name(int id)
+{
+       if (id < 0 || id >= TEGRA_NUM_POWERGATE)
+               return "invalid";
+
+       return powergate_name[id];
+}
+
+#ifdef CONFIG_DEBUG_FS
+
 static int powergate_show(struct seq_file *s, void *data)
 {
        int i;
@@ -280,15 +290,6 @@ int __init tegra_powergate_debugfs_init(void)
 {
        struct dentry *d;
 
-       switch (tegra_chip_id) {
-       case TEGRA20:
-               powergate_name = powergate_name_t20;
-               break;
-       case TEGRA30:
-               powergate_name = powergate_name_t30;
-               break;
-       }
-
        if (powergate_name) {
                d = debugfs_create_file("powergate", S_IRUGO, NULL, NULL,
                        &powergate_fops);