]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - arch/arm/mach-omap2/pm44xx.c
Merge remote-tracking branch 'omap/for-next'
[karo-tx-linux.git] / arch / arm / mach-omap2 / pm44xx.c
index 503097c72b826d0f6ddf96547be2d165156271c2..178e22c146b7acc786ef9c32cae01ca6cdd480b9 100644 (file)
@@ -37,6 +37,16 @@ struct power_state {
        struct list_head node;
 };
 
+/**
+ * struct static_dep_map - Static dependency map
+ * @from:      from clockdomain
+ * @to:                to clockdomain
+  */
+struct static_dep_map {
+       const char *from;
+       const char *to;
+};
+
 static u32 cpu_suspend_state = PWRDM_POWER_OFF;
 
 static LIST_HEAD(pwrst_list);
@@ -148,94 +158,61 @@ static void omap_default_idle(void)
        omap_do_wfi();
 }
 
-/**
- * omap4_init_static_deps - Add OMAP4 static dependencies
- *
- * Add needed static clockdomain dependencies on OMAP4 devices.
- * Return: 0 on success or 'err' on failures
+/*
+ * The dynamic dependency between MPUSS -> MEMIF and
+ * MPUSS -> L4_PER/L3_* and DUCATI -> L3_* doesn't work as
+ * expected. The hardware recommendation is to enable static
+ * dependencies for these to avoid system lock ups or random crashes.
+ * The L4 wakeup depedency is added to workaround the OCP sync hardware
+ * BUG with 32K synctimer which lead to incorrect timer value read
+ * from the 32K counter. The BUG applies for GPTIMER1 and WDT2 which
+ * are part of L4 wakeup clockdomain.
  */
-static inline int omap4_init_static_deps(void)
-{
-       struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm;
-       struct clockdomain *ducati_clkdm, *l3_2_clkdm;
-       int ret = 0;
-
-       if (omap_rev() == OMAP4430_REV_ES1_0) {
-               WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
-               return -ENODEV;
-       }
-
-       pr_err("Power Management for TI OMAP4.\n");
-       /*
-        * OMAP4 chip PM currently works only with certain (newer)
-        * versions of bootloaders. This is due to missing code in the
-        * kernel to properly reset and initialize some devices.
-        * http://www.spinics.net/lists/arm-kernel/msg218641.html
-        */
-       pr_warn("OMAP4 PM: u-boot >= v2012.07 is required for full PM support\n");
-
-       ret = pwrdm_for_each(pwrdms_setup, NULL);
-       if (ret) {
-               pr_err("Failed to setup powerdomains\n");
-               return ret;
-       }
-
-       /*
-        * The dynamic dependency between MPUSS -> MEMIF and
-        * MPUSS -> L4_PER/L3_* and DUCATI -> L3_* doesn't work as
-        * expected. The hardware recommendation is to enable static
-        * dependencies for these to avoid system lock ups or random crashes.
-        * The L4 wakeup depedency is added to workaround the OCP sync hardware
-        * BUG with 32K synctimer which lead to incorrect timer value read
-        * from the 32K counter. The BUG applies for GPTIMER1 and WDT2 which
-        * are part of L4 wakeup clockdomain.
-        */
-       mpuss_clkdm = clkdm_lookup("mpuss_clkdm");
-       emif_clkdm = clkdm_lookup("l3_emif_clkdm");
-       l3_1_clkdm = clkdm_lookup("l3_1_clkdm");
-       l3_2_clkdm = clkdm_lookup("l3_2_clkdm");
-       ducati_clkdm = clkdm_lookup("ducati_clkdm");
-       if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) ||
-               (!l3_2_clkdm) || (!ducati_clkdm))
-               return -EINVAL;
-
-       ret = clkdm_add_wkdep(mpuss_clkdm, emif_clkdm);
-       ret |= clkdm_add_wkdep(mpuss_clkdm, l3_1_clkdm);
-       ret |= clkdm_add_wkdep(mpuss_clkdm, l3_2_clkdm);
-       ret |= clkdm_add_wkdep(ducati_clkdm, l3_1_clkdm);
-       ret |= clkdm_add_wkdep(ducati_clkdm, l3_2_clkdm);
-       if (ret) {
-               pr_err("Failed to add MPUSS -> L3/EMIF/L4PER, DUCATI -> L3 wakeup dependency\n");
-               return -EINVAL;
-       }
+static const struct static_dep_map omap4_static_dep_map[] = {
+       {.from = "mpuss_clkdm", .to = "l3_emif_clkdm"},
+       {.from = "mpuss_clkdm", .to = "l3_1_clkdm"},
+       {.from = "mpuss_clkdm", .to = "l3_2_clkdm"},
+       {.from = "ducati_clkdm", .to = "l3_1_clkdm"},
+       {.from = "ducati_clkdm", .to = "l3_2_clkdm"},
+       {.from  = NULL} /* TERMINATION */
+};
 
-       return ret;
-}
+static const struct static_dep_map omap5_dra7_static_dep_map[] = {
+       {.from = "mpu_clkdm", .to = "emif_clkdm"},
+       {.from  = NULL} /* TERMINATION */
+};
 
 /**
- * omap5_dra7_init_static_deps - Init static clkdm dependencies on OMAP5 and
- *                              DRA7
- *
- * The dynamic dependency between MPUSS -> EMIF is broken and has
- * not worked as expected. The hardware recommendation is to
- * enable static dependencies for these to avoid system
- * lock ups or random crashes.
+ * omap4plus_init_static_deps() - Initialize a static dependency map
+ * @map:       Mapping of clock domains
  */
-static inline int omap5_dra7_init_static_deps(void)
+static inline int omap4plus_init_static_deps(const struct static_dep_map *map)
 {
-       struct clockdomain *mpuss_clkdm, *emif_clkdm;
        int ret;
+       struct clockdomain *from, *to;
 
-       mpuss_clkdm = clkdm_lookup("mpu_clkdm");
-       emif_clkdm = clkdm_lookup("emif_clkdm");
-       if (!mpuss_clkdm || !emif_clkdm)
-               return -EINVAL;
+       if (!map)
+               return 0;
+
+       while (map->from) {
+               from = clkdm_lookup(map->from);
+               to = clkdm_lookup(map->to);
+               if (!from || !to) {
+                       pr_err("Failed lookup %s or %s for wakeup dependency\n",
+                              map->from, map->to);
+                       return -EINVAL;
+               }
+               ret = clkdm_add_wkdep(from, to);
+               if (ret) {
+                       pr_err("Failed to add %s -> %s wakeup dependency(%d)\n",
+                              map->from, map->to, ret);
+                       return ret;
+               }
 
-       ret = clkdm_add_wkdep(mpuss_clkdm, emif_clkdm);
-       if (ret)
-               pr_err("Failed to add MPUSS -> EMIF wakeup dependency\n");
+               map++;
+       }
 
-       return ret;
+       return 0;
 }
 
 /**
@@ -272,6 +249,15 @@ int __init omap4_pm_init(void)
 
        pr_info("Power Management for TI OMAP4+ devices.\n");
 
+       /*
+        * OMAP4 chip PM currently works only with certain (newer)
+        * versions of bootloaders. This is due to missing code in the
+        * kernel to properly reset and initialize some devices.
+        * http://www.spinics.net/lists/arm-kernel/msg218641.html
+        */
+       if (cpu_is_omap44xx())
+               pr_warn("OMAP4 PM: u-boot >= v2012.07 is required for full PM support\n");
+
        ret = pwrdm_for_each(pwrdms_setup, NULL);
        if (ret) {
                pr_err("Failed to setup powerdomains.\n");
@@ -279,9 +265,9 @@ int __init omap4_pm_init(void)
        }
 
        if (cpu_is_omap44xx())
-               ret = omap4_init_static_deps();
+               ret = omap4plus_init_static_deps(omap4_static_dep_map);
        else if (soc_is_omap54xx() || soc_is_dra7xx())
-               ret = omap5_dra7_init_static_deps();
+               ret = omap4plus_init_static_deps(omap5_dra7_static_dep_map);
 
        if (ret) {
                pr_err("Failed to initialise static dependencies.\n");