|
@@ -238,3 +238,83 @@ static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
|
|
|
* around
|
|
|
*/
|
|
|
if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
|
|
|
+ (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
|
|
|
+ omap3xxx_clkdm_wakeup(clkdm);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
|
|
+ clkdm->clktrctrl_mask);
|
|
|
+
|
|
|
+ if (hwsup) {
|
|
|
+ /* Disable HW transitions when we are changing deps */
|
|
|
+ omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
|
|
+ clkdm->clktrctrl_mask);
|
|
|
+ _clkdm_add_autodeps(clkdm);
|
|
|
+ omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
|
|
+ clkdm->clktrctrl_mask);
|
|
|
+ } else {
|
|
|
+ if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
|
|
|
+ omap3xxx_clkdm_wakeup(clkdm);
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
|
|
|
+{
|
|
|
+ bool hwsup = false;
|
|
|
+
|
|
|
+ if (!clkdm->clktrctrl_mask)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
|
|
|
+ * more details on the unpleasant problem this is working
|
|
|
+ * around
|
|
|
+ */
|
|
|
+ if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
|
|
|
+ !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
|
|
|
+ omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
|
|
+ clkdm->clktrctrl_mask);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
|
|
+ clkdm->clktrctrl_mask);
|
|
|
+
|
|
|
+ if (hwsup) {
|
|
|
+ /* Disable HW transitions when we are changing deps */
|
|
|
+ omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
|
|
+ clkdm->clktrctrl_mask);
|
|
|
+ _clkdm_del_autodeps(clkdm);
|
|
|
+ omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
|
|
+ clkdm->clktrctrl_mask);
|
|
|
+ } else {
|
|
|
+ if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
|
|
|
+ omap3xxx_clkdm_sleep(clkdm);
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+struct clkdm_ops omap3_clkdm_operations = {
|
|
|
+ .clkdm_add_wkdep = omap2_clkdm_add_wkdep,
|
|
|
+ .clkdm_del_wkdep = omap2_clkdm_del_wkdep,
|
|
|
+ .clkdm_read_wkdep = omap2_clkdm_read_wkdep,
|
|
|
+ .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps,
|
|
|
+ .clkdm_add_sleepdep = omap3xxx_clkdm_add_sleepdep,
|
|
|
+ .clkdm_del_sleepdep = omap3xxx_clkdm_del_sleepdep,
|
|
|
+ .clkdm_read_sleepdep = omap3xxx_clkdm_read_sleepdep,
|
|
|
+ .clkdm_clear_all_sleepdeps = omap3xxx_clkdm_clear_all_sleepdeps,
|
|
|
+ .clkdm_sleep = omap3xxx_clkdm_sleep,
|
|
|
+ .clkdm_wakeup = omap3xxx_clkdm_wakeup,
|
|
|
+ .clkdm_allow_idle = omap3xxx_clkdm_allow_idle,
|
|
|
+ .clkdm_deny_idle = omap3xxx_clkdm_deny_idle,
|
|
|
+ .clkdm_clk_enable = omap3xxx_clkdm_clk_enable,
|
|
|
+ .clkdm_clk_disable = omap3xxx_clkdm_clk_disable,
|
|
|
+};
|
|
|
+
|
|
|
+/*
|
|
|
+ * Context save/restore code - OMAP3 only
|
|
|
+ */
|