ARM: tegra: add support for powergate skip list
Mayuresh Kulkarni [Tue, 14 May 2013 12:14:47 +0000 (17:14 +0530)]
- the idea is to add the power gate ids to a skip list
and expose this list via pg_ops
- the core code checks if current id is in skip list.
if it is then, it skips power gate or ungate operation
of the current id

bug 1249871

Change-Id: I3df270cfe1c853b554086688b485562a211ec2a5
Signed-off-by: Mayuresh Kulkarni <mkulkarni@nvidia.com>
Reviewed-on: http://git-master/r/228373
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>

arch/arm/mach-tegra/powergate-priv.h
arch/arm/mach-tegra/powergate-t12x.c
arch/arm/mach-tegra/powergate.c

index dd427b0..faa6ee8 100644 (file)
@@ -103,7 +103,10 @@ struct powergate_ops {
        int (*powergate_mc_flush_done)(int id);
 
        int (*powergate_init_refcount)(void);
+
        bool (*powergate_check_clamping)(int id);
+
+       bool (*powergate_skip)(int id);
 };
 
 void get_clk_info(struct powergate_partition_info *pg_info);
index ccb740f..89ea3c7 100644 (file)
@@ -511,6 +511,30 @@ spinlock_t *tegra12x_get_powergate_lock(void)
        return &tegra12x_powergate_lock;
 }
 
+bool tegra12x_powergate_skip(int id)
+{
+       switch (id) {
+       case TEGRA_POWERGATE_VDEC:
+       case TEGRA_POWERGATE_VENC:
+       case TEGRA_POWERGATE_DISA:
+       case TEGRA_POWERGATE_DISB:
+       case TEGRA_POWERGATE_XUSBA:
+       case TEGRA_POWERGATE_XUSBB:
+       case TEGRA_POWERGATE_XUSBC:
+#ifdef CONFIG_ARCH_TEGRA_HAS_PCIE
+       case TEGRA_POWERGATE_PCIE:
+#endif
+#ifdef CONFIG_ARCH_TEGRA_HAS_SATA
+       case TEGRA_POWERGATE_SATA:
+#endif
+       case TEGRA_POWERGATE_SOR:
+               return true;
+
+       default:
+               return false;
+       }
+}
+
 static struct powergate_ops tegra12x_powergate_ops = {
        .soc_name = "tegra12x",
 
@@ -530,6 +554,8 @@ static struct powergate_ops tegra12x_powergate_ops = {
 
        .powergate_mc_flush = tegra12x_powergate_mc_flush,
        .powergate_mc_flush_done = tegra12x_powergate_mc_flush_done,
+
+       .powergate_skip = tegra12x_powergate_skip,
 };
 
 struct powergate_ops *tegra12x_powergate_init_chip_support(void)
index ab06837..de2e001 100644 (file)
@@ -336,6 +336,12 @@ int tegra_powergate_remove_clamping(int id)
        return 0;
 }
 
+static inline bool tegra_powergate_check_skip_list(int id)
+{
+       return pg_ops->powergate_skip ?
+               pg_ops->powergate_skip(id) : false;
+}
+
 /* EXTERNALY VISIBLE APIS */
 
 bool tegra_powergate_is_powered(int id)
@@ -389,6 +395,10 @@ int tegra_powergate_partition(int id)
                return -EINVAL;
        }
 
+       if (tegra_powergate_check_skip_list(id))
+               printk_once("%s: %s is in powergate skip list\n", __func__,
+                       tegra_powergate_get_name(id));
+
        if (pg_ops->powergate_partition)
                return pg_ops->powergate_partition(id);
        else
@@ -410,6 +420,10 @@ int tegra_unpowergate_partition(int id)
                return -EINVAL;
        }
 
+       if (tegra_powergate_check_skip_list(id))
+               printk_once("%s: %s is in powergate skip list\n", __func__,
+                       tegra_powergate_get_name(id));
+
        if (pg_ops->unpowergate_partition)
                return pg_ops->unpowergate_partition(id);
        else
@@ -431,6 +445,10 @@ int tegra_powergate_partition_with_clk_off(int id)
                return -EINVAL;
        }
 
+       if (tegra_powergate_check_skip_list(id))
+               printk_once("%s: %s is in powergate skip list\n", __func__,
+                       tegra_powergate_get_name(id));
+
        if (pg_ops->powergate_partition_with_clk_off)
                return pg_ops->powergate_partition_with_clk_off(id);
        else
@@ -452,6 +470,10 @@ int tegra_unpowergate_partition_with_clk_on(int id)
                return -EINVAL;
        }
 
+       if (tegra_powergate_check_skip_list(id))
+               printk_once("%s: %s is in powergate skip list\n", __func__,
+                       tegra_powergate_get_name(id));
+
        if (pg_ops->unpowergate_partition_with_clk_on)
                return pg_ops->unpowergate_partition_with_clk_on(id);
        else
@@ -616,6 +638,7 @@ static int powergate_show(struct seq_file *s, void *data)
 {
        int i;
        const char *name;
+       bool is_pg_skip;
 
        if (!pg_ops) {
                seq_printf(s, "This SOC doesn't support powergating\n");
@@ -627,9 +650,13 @@ static int powergate_show(struct seq_file *s, void *data)
 
        for (i = 0; i < pg_ops->num_powerdomains; i++) {
                name = tegra_powergate_get_name(i);
-               if (name)
+               if (name) {
+                       is_pg_skip = tegra_powergate_check_skip_list(i);
                        seq_printf(s, " %9s %7s\n", name,
-                               tegra_powergate_is_powered(i) ? "yes" : "no");
+                               (is_pg_skip ? "skip" : \
+                               (tegra_powergate_is_powered(i) ? \
+                               "yes" : "no")));
+               }
        }
 
        return 0;