]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
Merge branch 'packaging' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek...
[karo-tx-linux.git] / arch / arm / mach-omap2 / clockdomain2xxx_3xxx.c
index 08c87fe3da123ac99e26c85a9e4fa4a6777a61bd..48d0db7e6069c90eff01a245153dba465b562b27 100644 (file)
@@ -128,6 +128,89 @@ static int omap2_clkdm_wakeup(struct clockdomain *clkdm)
        return 0;
 }
 
+static void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
+{
+       if (atomic_read(&clkdm->usecount) > 0)
+               _clkdm_add_autodeps(clkdm);
+
+       omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+                               clkdm->clktrctrl_mask);
+}
+
+static void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
+{
+       omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+                               clkdm->clktrctrl_mask);
+
+       if (atomic_read(&clkdm->usecount) > 0)
+               _clkdm_del_autodeps(clkdm);
+}
+
+static void _enable_hwsup(struct clockdomain *clkdm)
+{
+       if (cpu_is_omap24xx())
+               omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+                                              clkdm->clktrctrl_mask);
+       else if (cpu_is_omap34xx())
+               omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+                                              clkdm->clktrctrl_mask);
+}
+
+static void _disable_hwsup(struct clockdomain *clkdm)
+{
+       if (cpu_is_omap24xx())
+               omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+                                               clkdm->clktrctrl_mask);
+       else if (cpu_is_omap34xx())
+               omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+                                               clkdm->clktrctrl_mask);
+}
+
+
+static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
+{
+       bool hwsup = false;
+
+       if (!clkdm->clktrctrl_mask)
+               return 0;
+
+       hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+                               clkdm->clktrctrl_mask);
+
+       if (hwsup) {
+               /* Disable HW transitions when we are changing deps */
+               _disable_hwsup(clkdm);
+               _clkdm_add_autodeps(clkdm);
+               _enable_hwsup(clkdm);
+       } else {
+               clkdm_wakeup(clkdm);
+       }
+
+       return 0;
+}
+
+static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
+{
+       bool hwsup = false;
+
+       if (!clkdm->clktrctrl_mask)
+               return 0;
+
+       hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+                               clkdm->clktrctrl_mask);
+
+       if (hwsup) {
+               /* Disable HW transitions when we are changing deps */
+               _disable_hwsup(clkdm);
+               _clkdm_del_autodeps(clkdm);
+               _enable_hwsup(clkdm);
+       } else {
+               clkdm_sleep(clkdm);
+       }
+
+       return 0;
+}
+
 static int omap3_clkdm_sleep(struct clockdomain *clkdm)
 {
        omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
@@ -142,6 +225,24 @@ static int omap3_clkdm_wakeup(struct clockdomain *clkdm)
        return 0;
 }
 
+static void omap3_clkdm_allow_idle(struct clockdomain *clkdm)
+{
+       if (atomic_read(&clkdm->usecount) > 0)
+               _clkdm_add_autodeps(clkdm);
+
+       omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+                               clkdm->clktrctrl_mask);
+}
+
+static void omap3_clkdm_deny_idle(struct clockdomain *clkdm)
+{
+       omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+                               clkdm->clktrctrl_mask);
+
+       if (atomic_read(&clkdm->usecount) > 0)
+               _clkdm_del_autodeps(clkdm);
+}
+
 struct clkdm_ops omap2_clkdm_operations = {
        .clkdm_add_wkdep        = omap2_clkdm_add_wkdep,
        .clkdm_del_wkdep        = omap2_clkdm_del_wkdep,
@@ -149,6 +250,10 @@ struct clkdm_ops omap2_clkdm_operations = {
        .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps,
        .clkdm_sleep            = omap2_clkdm_sleep,
        .clkdm_wakeup           = omap2_clkdm_wakeup,
+       .clkdm_allow_idle       = omap2_clkdm_allow_idle,
+       .clkdm_deny_idle        = omap2_clkdm_deny_idle,
+       .clkdm_clk_enable       = omap2_clkdm_clk_enable,
+       .clkdm_clk_disable      = omap2_clkdm_clk_disable,
 };
 
 struct clkdm_ops omap3_clkdm_operations = {
@@ -162,4 +267,8 @@ struct clkdm_ops omap3_clkdm_operations = {
        .clkdm_clear_all_sleepdeps      = omap3_clkdm_clear_all_sleepdeps,
        .clkdm_sleep            = omap3_clkdm_sleep,
        .clkdm_wakeup           = omap3_clkdm_wakeup,
+       .clkdm_allow_idle       = omap3_clkdm_allow_idle,
+       .clkdm_deny_idle        = omap3_clkdm_deny_idle,
+       .clkdm_clk_enable       = omap2_clkdm_clk_enable,
+       .clkdm_clk_disable      = omap2_clkdm_clk_disable,
 };