|
@@ -380,6 +380,51 @@ static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * _set_idle_ioring_wakeup - enable/disable IO pad wakeup on hwmod idle for mux
|
|
|
+ * @oh: struct omap_hwmod *
|
|
|
+ * @set_wake: bool value indicating to set (true) or clear (false) wakeup enable
|
|
|
+ *
|
|
|
+ * Set or clear the I/O pad wakeup flag in the mux entries for the
|
|
|
+ * hwmod @oh. This function changes the @oh->mux->pads_dynamic array
|
|
|
+ * in memory. If the hwmod is currently idled, and the new idle
|
|
|
+ * values don't match the previous ones, this function will also
|
|
|
+ * update the SCM PADCTRL registers. Otherwise, if the hwmod is not
|
|
|
+ * currently idled, this function won't touch the hardware: the new
|
|
|
+ * mux settings are written to the SCM PADCTRL registers when the
|
|
|
+ * hwmod is idled. No return value.
|
|
|
+ */
|
|
|
+static void _set_idle_ioring_wakeup(struct omap_hwmod *oh, bool set_wake)
|
|
|
+{
|
|
|
+ struct omap_device_pad *pad;
|
|
|
+ bool change = false;
|
|
|
+ u16 prev_idle;
|
|
|
+ int j;
|
|
|
+
|
|
|
+ if (!oh->mux || !oh->mux->enabled)
|
|
|
+ return;
|
|
|
+
|
|
|
+ for (j = 0; j < oh->mux->nr_pads_dynamic; j++) {
|
|
|
+ pad = oh->mux->pads_dynamic[j];
|
|
|
+
|
|
|
+ if (!(pad->flags & OMAP_DEVICE_PAD_WAKEUP))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ prev_idle = pad->idle;
|
|
|
+
|
|
|
+ if (set_wake)
|
|
|
+ pad->idle |= OMAP_WAKEUP_EN;
|
|
|
+ else
|
|
|
+ pad->idle &= ~OMAP_WAKEUP_EN;
|
|
|
+
|
|
|
+ if (prev_idle != pad->idle)
|
|
|
+ change = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (change && oh->_state == _HWMOD_STATE_IDLE)
|
|
|
+ omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* _enable_wakeup: set OCP_SYSCONFIG.ENAWAKEUP bit in the hardware
|
|
|
* @oh: struct omap_hwmod *
|
|
@@ -2416,6 +2461,7 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
|
|
|
v = oh->_sysc_cache;
|
|
|
_enable_wakeup(oh, &v);
|
|
|
_write_sysconfig(v, oh);
|
|
|
+ _set_idle_ioring_wakeup(oh, true);
|
|
|
spin_unlock_irqrestore(&oh->_lock, flags);
|
|
|
|
|
|
return 0;
|
|
@@ -2446,6 +2492,7 @@ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
|
|
|
v = oh->_sysc_cache;
|
|
|
_disable_wakeup(oh, &v);
|
|
|
_write_sysconfig(v, oh);
|
|
|
+ _set_idle_ioring_wakeup(oh, false);
|
|
|
spin_unlock_irqrestore(&oh->_lock, flags);
|
|
|
|
|
|
return 0;
|