diff options
| author | Vladimir Tsunaev <vladimirt@motorola.com> | 2014-06-30 12:33:40 -0400 |
|---|---|---|
| committer | Vladimir Tsunaev <vladimirt@motorola.com> | 2014-06-30 15:20:14 -0400 |
| commit | 4ef0c4d2561955eeafc1585627736c561ea65bb7 (patch) | |
| tree | 66cdef689301dd5dda29681514f0a6b0f54be04d /arch/arm/mach-omap2/serial.c | |
| parent | 6bf795f69fc73cd5c0834256cb1c0b212eaee14d (diff) | |
| download | olio-linux-3.10-4ef0c4d2561955eeafc1585627736c561ea65bb7.tar.xz olio-linux-3.10-4ef0c4d2561955eeafc1585627736c561ea65bb7.zip | |
IKXCLOCK-2630 serial: Failed to hit offmode due to UART1 being non-idle
When c55 driver is changing pad configuration than PRCM detects
wake event from pad and it happens after PRCM get suspended
Evidence of this behavior is line:
"omap34xx_do_sram_idle: OMAP3_PRM_IRQENABLE_MPU_OFFSET 0x00000000"
and status bit in:
PRM__CORE (48004a00) b0 => 0x00002000 0x00000000)
As result event still pending and system can not get into requested
low power state.
UART1 is not wakeup-capable and to avoid this false wake ups the wakeup
event has to be disabled in all levels (uart module and PRCM module).
Change-Id: I9aba9503f91ddd15965d23755f3293c0f333adc2
Signed-off-by: Vladimir Tsunaev <vladimirt@motorola.com>
Diffstat (limited to 'arch/arm/mach-omap2/serial.c')
| -rw-r--r-- | arch/arm/mach-omap2/serial.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 80cd45fa8d8..b570d93cbb7 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -22,6 +22,7 @@ #include <linux/clk.h> #include <linux/io.h> #include <linux/delay.h> +#include <linux/spinlock.h> #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/pm_runtime.h> @@ -94,10 +95,35 @@ void omap_uart_enable_wakeup(struct device *dev, bool enable) else omap_hwmod_disable_wakeup(od->hwmods[0]); } +void omap_uart_remove_wakeup(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct omap_device *od = to_omap_device(pdev); + struct omap_hwmod *oh = od->hwmods[0]; + u16 offs; + unsigned long flags; + + spin_lock_irqsave(&oh->_lock, flags); + omap_hwmod_disable_wakeup(oh); + if (oh->class->sysc) + oh->class->sysc->sysc_flags &= ~SYSC_HAS_ENAWAKEUP; + offs = (oh->prcm.omap2.prcm_reg_id == 3) ? + OMAP3430ES2_PM_WKEN3 : PM_WKEN1; + omap2_prm_clear_mod_reg_bits((1<<oh->prcm.omap2.module_bit), + oh->prcm.omap2.module_offs, offs); + offs = (oh->prcm.omap2.prcm_reg_id == 3) ? + OMAP3430ES2_PM_WKST3 : PM_WKST1; + omap2_prm_set_mod_reg_bits((1<<oh->prcm.omap2.module_bit), + oh->prcm.omap2.module_offs, offs); + spin_unlock_irqrestore(&oh->_lock, flags); +} #else void omap_uart_enable_wakeup(struct device *dev, bool enable) {} +void omap_uart_remove_wakeup(struct device *dev) +{ +} #endif /* CONFIG_PM */ #ifdef CONFIG_OMAP_MUX |