Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eceec009 authored by Govindraj R's avatar Govindraj R Committed by Paul Walmsley
Browse files

ARM: OMAP2+: hwmod: Add API to enable IO ring wakeup



Add API to enable IO pad wakeup capability based on mux pad and
wake_up enable flag available from hwmod_mux initialization.

Use the wakeup_enable flag and enable wakeup capability for the given
pads. Wakeup capability will be enabled/disabled during hwmod idle
transition based on whether wakeup_flag is set or cleared.  If the
hwmod is currently idled, and any mux values were changed by
_set_idle_ioring_wakeup(), the SCM PADCTRL registers will be updated.

Signed-off-by: default avatarGovindraj.R <govindraj.raja@ti.com>
Signed-off-by: default avatarTero Kristo <t-kristo@ti.com>
Tested-by: default avatarKevin Hilman <khilman@ti.com>
Reviewed-by: default avatarKevin Hilman <khilman@ti.com>
[paul@pwsan.com: rearranged code to limit indentation; cleaned up
 function documentation; removed unused non-static functions; modified
 to search all hwmod pads, not just dynamic remuxing ones; modified to
 update SCM regs if hwmod is currently idle and any pads have changed]
Signed-off-by: default avatarPaul Walmsley <paul@pwsan.com>
parent 96dc19fd
Loading
Loading
Loading
Loading
+47 −0
Original line number Diff line number Diff line
@@ -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;