OMAP: clockdomain: Arch specific funcs for clkdm_clk_enable/disable
[pandora-kernel.git] / arch / arm / mach-omap2 / clockdomain2xxx_3xxx.c
index 25c27a5..48d0db7 100644 (file)
@@ -146,6 +146,71 @@ static void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
                _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,
@@ -187,6 +252,8 @@ struct clkdm_ops omap2_clkdm_operations = {
        .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 = {
@@ -202,4 +269,6 @@ struct clkdm_ops omap3_clkdm_operations = {
        .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,
 };