Fix the OMAP serial driver to work correctly on OMAP4 when booting
with DT. Basic build, boot, and PM test logs are here - unfortunately, not for the DT case yet: http://www.pwsan.com/omap/testlogs/uart_idle_fix_v3.10-rc/20130519164010/ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAABAgAGBQJRmVyFAAoJEMePsQ0LvSpL7esP/3Jxl0XhCHnZdS19Ts+wg3Uj u1kfLN5WVaPEuXbBEuM/wEnMcSuWeAxhJEwEFvVURfVmUkbSWpQ9vRtXNFlbKAro qiAG7Rc+9dqZqzpgSn7iV/KhxZiYu7du1zMJP1tR15QLlswJtuLhG4D3im6SZ7qh QQ/iESsQp7fzASguv6Bo8piw3M7PIF7zgRw5zki2dQBowGqHqQcKFcQgDADeeIg/ dToCKRJb91F9/von8D7D8TvRLo0DS/uxTVLvXLteB8hqIbLXJel6llYanw3JFZyt 1D6Ygml4RQUlLYhq4ERkAsMtb8s9cwk/IvkAyksCytORG7s5+4jFxKhAu+6P8tjv caf5yQNT8qtRgyB7QGA0F75tNKV8Nm4j3BpyYLz1690ZC6tDV3+9QQOnEj6YR6bJ X7+x0eoRrJS3ZUakTdDZSBXW4YxWZUHNzbpSpwDEQKaMgR2FLq0dbDYMqYUkMHNH FL+0mfeXMcg8NBaZfGyxwjsxme6aN4LuJ3SsLVSFjDA9qNXqFE4DARAZwyiQixGG f8z5KfLhKr+zI+iiuK439U4f6AW7uguHHvUL8eEzyjEA++TvSm0TzZURafX5Ldhh U8y3vudHAszZr6gLEBqUsvJZBmNWPVhkL5m8PRFOBIJqjqS3dyh/zbA+gB3TNRcM gLdggBxEL2w8ESpWj+UH =DRuE -----END PGP SIGNATURE----- Merge tag 'omap-fixes-a-for-3.10-rc' of git://git.kernel.org/pub/scm/linux/kernel/git/pjw/omap-pending into fixes From Paul Walmsley: Fix the OMAP serial driver to work correctly on OMAP4 when booting with DT. * tag 'omap-fixes-a-for-3.10-rc' of git://git.kernel.org/pub/scm/linux/kernel/git/pjw/omap-pending: ARM: OMAP2+: hwmod: Remove sysc slave idle and auto idle apis SERIAL: OMAP: Remove the slave idle handling from the driver ARM: OMAP2+: serial: Remove the un-used slave idle hooks ARM: OMAP2+: hwmod-data: UART IP needs software control to manage sidle modes ARM: OMAP2+: hwmod: Add a new flag to handle SIDLE in SWSUP only in active ARM: OMAP2+: hwmod: Fix sidle programming in _enable_sysc()/_idle_sysc() Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
commit
25625c9334
|
@ -1356,13 +1356,27 @@ static void _enable_sysc(struct omap_hwmod *oh)
|
||||||
|
|
||||||
clkdm = _get_clkdm(oh);
|
clkdm = _get_clkdm(oh);
|
||||||
if (sf & SYSC_HAS_SIDLEMODE) {
|
if (sf & SYSC_HAS_SIDLEMODE) {
|
||||||
|
if (oh->flags & HWMOD_SWSUP_SIDLE ||
|
||||||
|
oh->flags & HWMOD_SWSUP_SIDLE_ACT) {
|
||||||
|
idlemode = HWMOD_IDLEMODE_NO;
|
||||||
|
} else {
|
||||||
|
if (sf & SYSC_HAS_ENAWAKEUP)
|
||||||
|
_enable_wakeup(oh, &v);
|
||||||
|
if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
|
||||||
|
idlemode = HWMOD_IDLEMODE_SMART_WKUP;
|
||||||
|
else
|
||||||
|
idlemode = HWMOD_IDLEMODE_SMART;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is special handling for some IPs like
|
||||||
|
* 32k sync timer. Force them to idle!
|
||||||
|
*/
|
||||||
clkdm_act = (clkdm && clkdm->flags & CLKDM_ACTIVE_WITH_MPU);
|
clkdm_act = (clkdm && clkdm->flags & CLKDM_ACTIVE_WITH_MPU);
|
||||||
if (clkdm_act && !(oh->class->sysc->idlemodes &
|
if (clkdm_act && !(oh->class->sysc->idlemodes &
|
||||||
(SIDLE_SMART | SIDLE_SMART_WKUP)))
|
(SIDLE_SMART | SIDLE_SMART_WKUP)))
|
||||||
idlemode = HWMOD_IDLEMODE_FORCE;
|
idlemode = HWMOD_IDLEMODE_FORCE;
|
||||||
else
|
|
||||||
idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ?
|
|
||||||
HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART;
|
|
||||||
_set_slave_idlemode(oh, idlemode, &v);
|
_set_slave_idlemode(oh, idlemode, &v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1391,10 +1405,6 @@ static void _enable_sysc(struct omap_hwmod *oh)
|
||||||
(sf & SYSC_HAS_CLOCKACTIVITY))
|
(sf & SYSC_HAS_CLOCKACTIVITY))
|
||||||
_set_clockactivity(oh, oh->class->sysc->clockact, &v);
|
_set_clockactivity(oh, oh->class->sysc->clockact, &v);
|
||||||
|
|
||||||
/* If slave is in SMARTIDLE, also enable wakeup */
|
|
||||||
if ((sf & SYSC_HAS_SIDLEMODE) && !(oh->flags & HWMOD_SWSUP_SIDLE))
|
|
||||||
_enable_wakeup(oh, &v);
|
|
||||||
|
|
||||||
_write_sysconfig(v, oh);
|
_write_sysconfig(v, oh);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1430,13 +1440,16 @@ static void _idle_sysc(struct omap_hwmod *oh)
|
||||||
sf = oh->class->sysc->sysc_flags;
|
sf = oh->class->sysc->sysc_flags;
|
||||||
|
|
||||||
if (sf & SYSC_HAS_SIDLEMODE) {
|
if (sf & SYSC_HAS_SIDLEMODE) {
|
||||||
/* XXX What about HWMOD_IDLEMODE_SMART_WKUP? */
|
if (oh->flags & HWMOD_SWSUP_SIDLE) {
|
||||||
if (oh->flags & HWMOD_SWSUP_SIDLE ||
|
|
||||||
!(oh->class->sysc->idlemodes &
|
|
||||||
(SIDLE_SMART | SIDLE_SMART_WKUP)))
|
|
||||||
idlemode = HWMOD_IDLEMODE_FORCE;
|
idlemode = HWMOD_IDLEMODE_FORCE;
|
||||||
else
|
} else {
|
||||||
idlemode = HWMOD_IDLEMODE_SMART;
|
if (sf & SYSC_HAS_ENAWAKEUP)
|
||||||
|
_enable_wakeup(oh, &v);
|
||||||
|
if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
|
||||||
|
idlemode = HWMOD_IDLEMODE_SMART_WKUP;
|
||||||
|
else
|
||||||
|
idlemode = HWMOD_IDLEMODE_SMART;
|
||||||
|
}
|
||||||
_set_slave_idlemode(oh, idlemode, &v);
|
_set_slave_idlemode(oh, idlemode, &v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1455,10 +1468,6 @@ static void _idle_sysc(struct omap_hwmod *oh)
|
||||||
_set_master_standbymode(oh, idlemode, &v);
|
_set_master_standbymode(oh, idlemode, &v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If slave is in SMARTIDLE, also enable wakeup */
|
|
||||||
if ((sf & SYSC_HAS_SIDLEMODE) && !(oh->flags & HWMOD_SWSUP_SIDLE))
|
|
||||||
_enable_wakeup(oh, &v);
|
|
||||||
|
|
||||||
_write_sysconfig(v, oh);
|
_write_sysconfig(v, oh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2245,42 +2254,6 @@ static int _idle(struct omap_hwmod *oh)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* omap_hwmod_set_ocp_autoidle - set the hwmod's OCP autoidle bit
|
|
||||||
* @oh: struct omap_hwmod *
|
|
||||||
* @autoidle: desired AUTOIDLE bitfield value (0 or 1)
|
|
||||||
*
|
|
||||||
* Sets the IP block's OCP autoidle bit in hardware, and updates our
|
|
||||||
* local copy. Intended to be used by drivers that require
|
|
||||||
* direct manipulation of the AUTOIDLE bits.
|
|
||||||
* Returns -EINVAL if @oh is null or is not in the ENABLED state, or passes
|
|
||||||
* along the return value from _set_module_autoidle().
|
|
||||||
*
|
|
||||||
* Any users of this function should be scrutinized carefully.
|
|
||||||
*/
|
|
||||||
int omap_hwmod_set_ocp_autoidle(struct omap_hwmod *oh, u8 autoidle)
|
|
||||||
{
|
|
||||||
u32 v;
|
|
||||||
int retval = 0;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (!oh || oh->_state != _HWMOD_STATE_ENABLED)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&oh->_lock, flags);
|
|
||||||
|
|
||||||
v = oh->_sysc_cache;
|
|
||||||
|
|
||||||
retval = _set_module_autoidle(oh, autoidle, &v);
|
|
||||||
|
|
||||||
if (!retval)
|
|
||||||
_write_sysconfig(v, oh);
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&oh->_lock, flags);
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* _shutdown - shutdown an omap_hwmod
|
* _shutdown - shutdown an omap_hwmod
|
||||||
* @oh: struct omap_hwmod *
|
* @oh: struct omap_hwmod *
|
||||||
|
@ -3179,38 +3152,6 @@ error:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* omap_hwmod_set_slave_idlemode - set the hwmod's OCP slave idlemode
|
|
||||||
* @oh: struct omap_hwmod *
|
|
||||||
* @idlemode: SIDLEMODE field bits (shifted to bit 0)
|
|
||||||
*
|
|
||||||
* Sets the IP block's OCP slave idlemode in hardware, and updates our
|
|
||||||
* local copy. Intended to be used by drivers that have some erratum
|
|
||||||
* that requires direct manipulation of the SIDLEMODE bits. Returns
|
|
||||||
* -EINVAL if @oh is null, or passes along the return value from
|
|
||||||
* _set_slave_idlemode().
|
|
||||||
*
|
|
||||||
* XXX Does this function have any current users? If not, we should
|
|
||||||
* remove it; it is better to let the rest of the hwmod code handle this.
|
|
||||||
* Any users of this function should be scrutinized carefully.
|
|
||||||
*/
|
|
||||||
int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode)
|
|
||||||
{
|
|
||||||
u32 v;
|
|
||||||
int retval = 0;
|
|
||||||
|
|
||||||
if (!oh)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
v = oh->_sysc_cache;
|
|
||||||
|
|
||||||
retval = _set_slave_idlemode(oh, idlemode, &v);
|
|
||||||
if (!retval)
|
|
||||||
_write_sysconfig(v, oh);
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* omap_hwmod_lookup - look up a registered omap_hwmod by name
|
* omap_hwmod_lookup - look up a registered omap_hwmod by name
|
||||||
* @name: name of the omap_hwmod to look up
|
* @name: name of the omap_hwmod to look up
|
||||||
|
|
|
@ -463,6 +463,9 @@ struct omap_hwmod_omap4_prcm {
|
||||||
* is kept in force-standby mode. Failing to do so causes PM problems
|
* is kept in force-standby mode. Failing to do so causes PM problems
|
||||||
* with musb on OMAP3630 at least. Note that musb has a dedicated register
|
* with musb on OMAP3630 at least. Note that musb has a dedicated register
|
||||||
* to control MSTANDBY signal when MIDLEMODE is set to force-standby.
|
* to control MSTANDBY signal when MIDLEMODE is set to force-standby.
|
||||||
|
* HWMOD_SWSUP_SIDLE_ACT: omap_hwmod code should manually bring the module
|
||||||
|
* out of idle, but rely on smart-idle to the put it back in idle,
|
||||||
|
* so the wakeups are still functional (Only known case for now is UART)
|
||||||
*/
|
*/
|
||||||
#define HWMOD_SWSUP_SIDLE (1 << 0)
|
#define HWMOD_SWSUP_SIDLE (1 << 0)
|
||||||
#define HWMOD_SWSUP_MSTANDBY (1 << 1)
|
#define HWMOD_SWSUP_MSTANDBY (1 << 1)
|
||||||
|
@ -476,6 +479,7 @@ struct omap_hwmod_omap4_prcm {
|
||||||
#define HWMOD_EXT_OPT_MAIN_CLK (1 << 9)
|
#define HWMOD_EXT_OPT_MAIN_CLK (1 << 9)
|
||||||
#define HWMOD_BLOCK_WFI (1 << 10)
|
#define HWMOD_BLOCK_WFI (1 << 10)
|
||||||
#define HWMOD_FORCE_MSTANDBY (1 << 11)
|
#define HWMOD_FORCE_MSTANDBY (1 << 11)
|
||||||
|
#define HWMOD_SWSUP_SIDLE_ACT (1 << 12)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* omap_hwmod._int_flags definitions
|
* omap_hwmod._int_flags definitions
|
||||||
|
@ -641,9 +645,6 @@ int omap_hwmod_read_hardreset(struct omap_hwmod *oh, const char *name);
|
||||||
int omap_hwmod_enable_clocks(struct omap_hwmod *oh);
|
int omap_hwmod_enable_clocks(struct omap_hwmod *oh);
|
||||||
int omap_hwmod_disable_clocks(struct omap_hwmod *oh);
|
int omap_hwmod_disable_clocks(struct omap_hwmod *oh);
|
||||||
|
|
||||||
int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode);
|
|
||||||
int omap_hwmod_set_ocp_autoidle(struct omap_hwmod *oh, u8 autoidle);
|
|
||||||
|
|
||||||
int omap_hwmod_reset(struct omap_hwmod *oh);
|
int omap_hwmod_reset(struct omap_hwmod *oh);
|
||||||
void omap_hwmod_ocp_barrier(struct omap_hwmod *oh);
|
void omap_hwmod_ocp_barrier(struct omap_hwmod *oh);
|
||||||
|
|
||||||
|
|
|
@ -512,6 +512,7 @@ struct omap_hwmod omap2xxx_uart1_hwmod = {
|
||||||
.mpu_irqs = omap2_uart1_mpu_irqs,
|
.mpu_irqs = omap2_uart1_mpu_irqs,
|
||||||
.sdma_reqs = omap2_uart1_sdma_reqs,
|
.sdma_reqs = omap2_uart1_sdma_reqs,
|
||||||
.main_clk = "uart1_fck",
|
.main_clk = "uart1_fck",
|
||||||
|
.flags = HWMOD_SWSUP_SIDLE_ACT,
|
||||||
.prcm = {
|
.prcm = {
|
||||||
.omap2 = {
|
.omap2 = {
|
||||||
.module_offs = CORE_MOD,
|
.module_offs = CORE_MOD,
|
||||||
|
@ -531,6 +532,7 @@ struct omap_hwmod omap2xxx_uart2_hwmod = {
|
||||||
.mpu_irqs = omap2_uart2_mpu_irqs,
|
.mpu_irqs = omap2_uart2_mpu_irqs,
|
||||||
.sdma_reqs = omap2_uart2_sdma_reqs,
|
.sdma_reqs = omap2_uart2_sdma_reqs,
|
||||||
.main_clk = "uart2_fck",
|
.main_clk = "uart2_fck",
|
||||||
|
.flags = HWMOD_SWSUP_SIDLE_ACT,
|
||||||
.prcm = {
|
.prcm = {
|
||||||
.omap2 = {
|
.omap2 = {
|
||||||
.module_offs = CORE_MOD,
|
.module_offs = CORE_MOD,
|
||||||
|
@ -550,6 +552,7 @@ struct omap_hwmod omap2xxx_uart3_hwmod = {
|
||||||
.mpu_irqs = omap2_uart3_mpu_irqs,
|
.mpu_irqs = omap2_uart3_mpu_irqs,
|
||||||
.sdma_reqs = omap2_uart3_sdma_reqs,
|
.sdma_reqs = omap2_uart3_sdma_reqs,
|
||||||
.main_clk = "uart3_fck",
|
.main_clk = "uart3_fck",
|
||||||
|
.flags = HWMOD_SWSUP_SIDLE_ACT,
|
||||||
.prcm = {
|
.prcm = {
|
||||||
.omap2 = {
|
.omap2 = {
|
||||||
.module_offs = CORE_MOD,
|
.module_offs = CORE_MOD,
|
||||||
|
|
|
@ -1995,6 +1995,7 @@ static struct omap_hwmod am33xx_uart1_hwmod = {
|
||||||
.name = "uart1",
|
.name = "uart1",
|
||||||
.class = &uart_class,
|
.class = &uart_class,
|
||||||
.clkdm_name = "l4_wkup_clkdm",
|
.clkdm_name = "l4_wkup_clkdm",
|
||||||
|
.flags = HWMOD_SWSUP_SIDLE_ACT,
|
||||||
.mpu_irqs = am33xx_uart1_irqs,
|
.mpu_irqs = am33xx_uart1_irqs,
|
||||||
.sdma_reqs = uart1_edma_reqs,
|
.sdma_reqs = uart1_edma_reqs,
|
||||||
.main_clk = "dpll_per_m2_div4_wkupdm_ck",
|
.main_clk = "dpll_per_m2_div4_wkupdm_ck",
|
||||||
|
@ -2015,6 +2016,7 @@ static struct omap_hwmod am33xx_uart2_hwmod = {
|
||||||
.name = "uart2",
|
.name = "uart2",
|
||||||
.class = &uart_class,
|
.class = &uart_class,
|
||||||
.clkdm_name = "l4ls_clkdm",
|
.clkdm_name = "l4ls_clkdm",
|
||||||
|
.flags = HWMOD_SWSUP_SIDLE_ACT,
|
||||||
.mpu_irqs = am33xx_uart2_irqs,
|
.mpu_irqs = am33xx_uart2_irqs,
|
||||||
.sdma_reqs = uart1_edma_reqs,
|
.sdma_reqs = uart1_edma_reqs,
|
||||||
.main_clk = "dpll_per_m2_div4_ck",
|
.main_clk = "dpll_per_m2_div4_ck",
|
||||||
|
@ -2042,6 +2044,7 @@ static struct omap_hwmod am33xx_uart3_hwmod = {
|
||||||
.name = "uart3",
|
.name = "uart3",
|
||||||
.class = &uart_class,
|
.class = &uart_class,
|
||||||
.clkdm_name = "l4ls_clkdm",
|
.clkdm_name = "l4ls_clkdm",
|
||||||
|
.flags = HWMOD_SWSUP_SIDLE_ACT,
|
||||||
.mpu_irqs = am33xx_uart3_irqs,
|
.mpu_irqs = am33xx_uart3_irqs,
|
||||||
.sdma_reqs = uart3_edma_reqs,
|
.sdma_reqs = uart3_edma_reqs,
|
||||||
.main_clk = "dpll_per_m2_div4_ck",
|
.main_clk = "dpll_per_m2_div4_ck",
|
||||||
|
@ -2062,6 +2065,7 @@ static struct omap_hwmod am33xx_uart4_hwmod = {
|
||||||
.name = "uart4",
|
.name = "uart4",
|
||||||
.class = &uart_class,
|
.class = &uart_class,
|
||||||
.clkdm_name = "l4ls_clkdm",
|
.clkdm_name = "l4ls_clkdm",
|
||||||
|
.flags = HWMOD_SWSUP_SIDLE_ACT,
|
||||||
.mpu_irqs = am33xx_uart4_irqs,
|
.mpu_irqs = am33xx_uart4_irqs,
|
||||||
.sdma_reqs = uart1_edma_reqs,
|
.sdma_reqs = uart1_edma_reqs,
|
||||||
.main_clk = "dpll_per_m2_div4_ck",
|
.main_clk = "dpll_per_m2_div4_ck",
|
||||||
|
@ -2082,6 +2086,7 @@ static struct omap_hwmod am33xx_uart5_hwmod = {
|
||||||
.name = "uart5",
|
.name = "uart5",
|
||||||
.class = &uart_class,
|
.class = &uart_class,
|
||||||
.clkdm_name = "l4ls_clkdm",
|
.clkdm_name = "l4ls_clkdm",
|
||||||
|
.flags = HWMOD_SWSUP_SIDLE_ACT,
|
||||||
.mpu_irqs = am33xx_uart5_irqs,
|
.mpu_irqs = am33xx_uart5_irqs,
|
||||||
.sdma_reqs = uart1_edma_reqs,
|
.sdma_reqs = uart1_edma_reqs,
|
||||||
.main_clk = "dpll_per_m2_div4_ck",
|
.main_clk = "dpll_per_m2_div4_ck",
|
||||||
|
@ -2102,6 +2107,7 @@ static struct omap_hwmod am33xx_uart6_hwmod = {
|
||||||
.name = "uart6",
|
.name = "uart6",
|
||||||
.class = &uart_class,
|
.class = &uart_class,
|
||||||
.clkdm_name = "l4ls_clkdm",
|
.clkdm_name = "l4ls_clkdm",
|
||||||
|
.flags = HWMOD_SWSUP_SIDLE_ACT,
|
||||||
.mpu_irqs = am33xx_uart6_irqs,
|
.mpu_irqs = am33xx_uart6_irqs,
|
||||||
.sdma_reqs = uart1_edma_reqs,
|
.sdma_reqs = uart1_edma_reqs,
|
||||||
.main_clk = "dpll_per_m2_div4_ck",
|
.main_clk = "dpll_per_m2_div4_ck",
|
||||||
|
|
|
@ -490,6 +490,7 @@ static struct omap_hwmod omap3xxx_uart1_hwmod = {
|
||||||
.mpu_irqs = omap2_uart1_mpu_irqs,
|
.mpu_irqs = omap2_uart1_mpu_irqs,
|
||||||
.sdma_reqs = omap2_uart1_sdma_reqs,
|
.sdma_reqs = omap2_uart1_sdma_reqs,
|
||||||
.main_clk = "uart1_fck",
|
.main_clk = "uart1_fck",
|
||||||
|
.flags = HWMOD_SWSUP_SIDLE_ACT,
|
||||||
.prcm = {
|
.prcm = {
|
||||||
.omap2 = {
|
.omap2 = {
|
||||||
.module_offs = CORE_MOD,
|
.module_offs = CORE_MOD,
|
||||||
|
@ -508,6 +509,7 @@ static struct omap_hwmod omap3xxx_uart2_hwmod = {
|
||||||
.mpu_irqs = omap2_uart2_mpu_irqs,
|
.mpu_irqs = omap2_uart2_mpu_irqs,
|
||||||
.sdma_reqs = omap2_uart2_sdma_reqs,
|
.sdma_reqs = omap2_uart2_sdma_reqs,
|
||||||
.main_clk = "uart2_fck",
|
.main_clk = "uart2_fck",
|
||||||
|
.flags = HWMOD_SWSUP_SIDLE_ACT,
|
||||||
.prcm = {
|
.prcm = {
|
||||||
.omap2 = {
|
.omap2 = {
|
||||||
.module_offs = CORE_MOD,
|
.module_offs = CORE_MOD,
|
||||||
|
@ -526,6 +528,7 @@ static struct omap_hwmod omap3xxx_uart3_hwmod = {
|
||||||
.mpu_irqs = omap2_uart3_mpu_irqs,
|
.mpu_irqs = omap2_uart3_mpu_irqs,
|
||||||
.sdma_reqs = omap2_uart3_sdma_reqs,
|
.sdma_reqs = omap2_uart3_sdma_reqs,
|
||||||
.main_clk = "uart3_fck",
|
.main_clk = "uart3_fck",
|
||||||
|
.flags = HWMOD_SWSUP_SIDLE_ACT,
|
||||||
.prcm = {
|
.prcm = {
|
||||||
.omap2 = {
|
.omap2 = {
|
||||||
.module_offs = OMAP3430_PER_MOD,
|
.module_offs = OMAP3430_PER_MOD,
|
||||||
|
@ -555,6 +558,7 @@ static struct omap_hwmod omap36xx_uart4_hwmod = {
|
||||||
.mpu_irqs = uart4_mpu_irqs,
|
.mpu_irqs = uart4_mpu_irqs,
|
||||||
.sdma_reqs = uart4_sdma_reqs,
|
.sdma_reqs = uart4_sdma_reqs,
|
||||||
.main_clk = "uart4_fck",
|
.main_clk = "uart4_fck",
|
||||||
|
.flags = HWMOD_SWSUP_SIDLE_ACT,
|
||||||
.prcm = {
|
.prcm = {
|
||||||
.omap2 = {
|
.omap2 = {
|
||||||
.module_offs = OMAP3430_PER_MOD,
|
.module_offs = OMAP3430_PER_MOD,
|
||||||
|
|
|
@ -3434,6 +3434,7 @@ static struct omap_hwmod omap44xx_uart1_hwmod = {
|
||||||
.name = "uart1",
|
.name = "uart1",
|
||||||
.class = &omap44xx_uart_hwmod_class,
|
.class = &omap44xx_uart_hwmod_class,
|
||||||
.clkdm_name = "l4_per_clkdm",
|
.clkdm_name = "l4_per_clkdm",
|
||||||
|
.flags = HWMOD_SWSUP_SIDLE_ACT,
|
||||||
.mpu_irqs = omap44xx_uart1_irqs,
|
.mpu_irqs = omap44xx_uart1_irqs,
|
||||||
.sdma_reqs = omap44xx_uart1_sdma_reqs,
|
.sdma_reqs = omap44xx_uart1_sdma_reqs,
|
||||||
.main_clk = "func_48m_fclk",
|
.main_clk = "func_48m_fclk",
|
||||||
|
@ -3462,6 +3463,7 @@ static struct omap_hwmod omap44xx_uart2_hwmod = {
|
||||||
.name = "uart2",
|
.name = "uart2",
|
||||||
.class = &omap44xx_uart_hwmod_class,
|
.class = &omap44xx_uart_hwmod_class,
|
||||||
.clkdm_name = "l4_per_clkdm",
|
.clkdm_name = "l4_per_clkdm",
|
||||||
|
.flags = HWMOD_SWSUP_SIDLE_ACT,
|
||||||
.mpu_irqs = omap44xx_uart2_irqs,
|
.mpu_irqs = omap44xx_uart2_irqs,
|
||||||
.sdma_reqs = omap44xx_uart2_sdma_reqs,
|
.sdma_reqs = omap44xx_uart2_sdma_reqs,
|
||||||
.main_clk = "func_48m_fclk",
|
.main_clk = "func_48m_fclk",
|
||||||
|
@ -3490,7 +3492,8 @@ static struct omap_hwmod omap44xx_uart3_hwmod = {
|
||||||
.name = "uart3",
|
.name = "uart3",
|
||||||
.class = &omap44xx_uart_hwmod_class,
|
.class = &omap44xx_uart_hwmod_class,
|
||||||
.clkdm_name = "l4_per_clkdm",
|
.clkdm_name = "l4_per_clkdm",
|
||||||
.flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
|
.flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET |
|
||||||
|
HWMOD_SWSUP_SIDLE_ACT,
|
||||||
.mpu_irqs = omap44xx_uart3_irqs,
|
.mpu_irqs = omap44xx_uart3_irqs,
|
||||||
.sdma_reqs = omap44xx_uart3_sdma_reqs,
|
.sdma_reqs = omap44xx_uart3_sdma_reqs,
|
||||||
.main_clk = "func_48m_fclk",
|
.main_clk = "func_48m_fclk",
|
||||||
|
@ -3519,6 +3522,7 @@ static struct omap_hwmod omap44xx_uart4_hwmod = {
|
||||||
.name = "uart4",
|
.name = "uart4",
|
||||||
.class = &omap44xx_uart_hwmod_class,
|
.class = &omap44xx_uart_hwmod_class,
|
||||||
.clkdm_name = "l4_per_clkdm",
|
.clkdm_name = "l4_per_clkdm",
|
||||||
|
.flags = HWMOD_SWSUP_SIDLE_ACT,
|
||||||
.mpu_irqs = omap44xx_uart4_irqs,
|
.mpu_irqs = omap44xx_uart4_irqs,
|
||||||
.sdma_reqs = omap44xx_uart4_sdma_reqs,
|
.sdma_reqs = omap44xx_uart4_sdma_reqs,
|
||||||
.main_clk = "func_48m_fclk",
|
.main_clk = "func_48m_fclk",
|
||||||
|
|
|
@ -95,38 +95,9 @@ static void omap_uart_enable_wakeup(struct device *dev, bool enable)
|
||||||
omap_hwmod_disable_wakeup(od->hwmods[0]);
|
omap_hwmod_disable_wakeup(od->hwmods[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Errata i291: [UART]:Cannot Acknowledge Idle Requests
|
|
||||||
* in Smartidle Mode When Configured for DMA Operations.
|
|
||||||
* WA: configure uart in force idle mode.
|
|
||||||
*/
|
|
||||||
static void omap_uart_set_noidle(struct device *dev)
|
|
||||||
{
|
|
||||||
struct platform_device *pdev = to_platform_device(dev);
|
|
||||||
struct omap_device *od = to_omap_device(pdev);
|
|
||||||
|
|
||||||
omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_NO);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void omap_uart_set_smartidle(struct device *dev)
|
|
||||||
{
|
|
||||||
struct platform_device *pdev = to_platform_device(dev);
|
|
||||||
struct omap_device *od = to_omap_device(pdev);
|
|
||||||
u8 idlemode;
|
|
||||||
|
|
||||||
if (od->hwmods[0]->class->sysc->idlemodes & SIDLE_SMART_WKUP)
|
|
||||||
idlemode = HWMOD_IDLEMODE_SMART_WKUP;
|
|
||||||
else
|
|
||||||
idlemode = HWMOD_IDLEMODE_SMART;
|
|
||||||
|
|
||||||
omap_hwmod_set_slave_idlemode(od->hwmods[0], idlemode);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
static void omap_uart_enable_wakeup(struct device *dev, bool enable)
|
static void omap_uart_enable_wakeup(struct device *dev, bool enable)
|
||||||
{}
|
{}
|
||||||
static void omap_uart_set_noidle(struct device *dev) {}
|
|
||||||
static void omap_uart_set_smartidle(struct device *dev) {}
|
|
||||||
#endif /* CONFIG_PM */
|
#endif /* CONFIG_PM */
|
||||||
|
|
||||||
#ifdef CONFIG_OMAP_MUX
|
#ifdef CONFIG_OMAP_MUX
|
||||||
|
@ -299,8 +270,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata,
|
||||||
omap_up.uartclk = OMAP24XX_BASE_BAUD * 16;
|
omap_up.uartclk = OMAP24XX_BASE_BAUD * 16;
|
||||||
omap_up.flags = UPF_BOOT_AUTOCONF;
|
omap_up.flags = UPF_BOOT_AUTOCONF;
|
||||||
omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count;
|
omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count;
|
||||||
omap_up.set_forceidle = omap_uart_set_smartidle;
|
|
||||||
omap_up.set_noidle = omap_uart_set_noidle;
|
|
||||||
omap_up.enable_wakeup = omap_uart_enable_wakeup;
|
omap_up.enable_wakeup = omap_uart_enable_wakeup;
|
||||||
omap_up.dma_rx_buf_size = info->dma_rx_buf_size;
|
omap_up.dma_rx_buf_size = info->dma_rx_buf_size;
|
||||||
omap_up.dma_rx_timeout = info->dma_rx_timeout;
|
omap_up.dma_rx_timeout = info->dma_rx_timeout;
|
||||||
|
|
|
@ -202,26 +202,6 @@ static int serial_omap_get_context_loss_count(struct uart_omap_port *up)
|
||||||
return pdata->get_context_loss_count(up->dev);
|
return pdata->get_context_loss_count(up->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void serial_omap_set_forceidle(struct uart_omap_port *up)
|
|
||||||
{
|
|
||||||
struct omap_uart_port_info *pdata = up->dev->platform_data;
|
|
||||||
|
|
||||||
if (!pdata || !pdata->set_forceidle)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pdata->set_forceidle(up->dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void serial_omap_set_noidle(struct uart_omap_port *up)
|
|
||||||
{
|
|
||||||
struct omap_uart_port_info *pdata = up->dev->platform_data;
|
|
||||||
|
|
||||||
if (!pdata || !pdata->set_noidle)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pdata->set_noidle(up->dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable)
|
static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable)
|
||||||
{
|
{
|
||||||
struct omap_uart_port_info *pdata = up->dev->platform_data;
|
struct omap_uart_port_info *pdata = up->dev->platform_data;
|
||||||
|
@ -298,8 +278,6 @@ static void serial_omap_stop_tx(struct uart_port *port)
|
||||||
serial_out(up, UART_IER, up->ier);
|
serial_out(up, UART_IER, up->ier);
|
||||||
}
|
}
|
||||||
|
|
||||||
serial_omap_set_forceidle(up);
|
|
||||||
|
|
||||||
pm_runtime_mark_last_busy(up->dev);
|
pm_runtime_mark_last_busy(up->dev);
|
||||||
pm_runtime_put_autosuspend(up->dev);
|
pm_runtime_put_autosuspend(up->dev);
|
||||||
}
|
}
|
||||||
|
@ -364,7 +342,6 @@ static void serial_omap_start_tx(struct uart_port *port)
|
||||||
|
|
||||||
pm_runtime_get_sync(up->dev);
|
pm_runtime_get_sync(up->dev);
|
||||||
serial_omap_enable_ier_thri(up);
|
serial_omap_enable_ier_thri(up);
|
||||||
serial_omap_set_noidle(up);
|
|
||||||
pm_runtime_mark_last_busy(up->dev);
|
pm_runtime_mark_last_busy(up->dev);
|
||||||
pm_runtime_put_autosuspend(up->dev);
|
pm_runtime_put_autosuspend(up->dev);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,8 +43,6 @@ struct omap_uart_port_info {
|
||||||
int DTR_present;
|
int DTR_present;
|
||||||
|
|
||||||
int (*get_context_loss_count)(struct device *);
|
int (*get_context_loss_count)(struct device *);
|
||||||
void (*set_forceidle)(struct device *);
|
|
||||||
void (*set_noidle)(struct device *);
|
|
||||||
void (*enable_wakeup)(struct device *, bool);
|
void (*enable_wakeup)(struct device *, bool);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue