summaryrefslogtreecommitdiff
path: root/arch/arm/mach-omap2/serial.c
diff options
context:
space:
mode:
authorVladimir Tsunaev <vladimirt@motorola.com>2014-06-30 12:33:40 -0400
committerVladimir Tsunaev <vladimirt@motorola.com>2014-06-30 15:20:14 -0400
commit4ef0c4d2561955eeafc1585627736c561ea65bb7 (patch)
tree66cdef689301dd5dda29681514f0a6b0f54be04d /arch/arm/mach-omap2/serial.c
parent6bf795f69fc73cd5c0834256cb1c0b212eaee14d (diff)
downloadolio-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.c26
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