aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/omap_hwmod_reset.c
diff options
context:
space:
mode:
authorDave Gerlach <d-gerlach@ti.com>2018-06-21 05:13:08 -0400
committerTony Lindgren <tony@atomide.com>2018-07-03 04:46:52 -0400
commit6d609b35c815ba20132b7b64bcca04516bb17c56 (patch)
tree1902092256e2b4825e309c5049757297c085d0d4 /arch/arm/mach-omap2/omap_hwmod_reset.c
parentce397d215ccd07b8ae3f71db689aedb85d56ab40 (diff)
ARM: hwmod: RTC: Don't assume lock/unlock will be called with irq enabled
When the RTC lock and unlock functions were introduced it was likely assumed that they would always be called from irq enabled context, hence the use of local_irq_disable/enable. This is no longer true as the RTC+DDR path makes a late call during the suspend path after irqs have been disabled to enable the RTC hwmod which calls both unlock and lock, leading to IRQs being reenabled through the local_irq_enable call in omap_hwmod_rtc_lock call. To avoid this change the local_irq_disable/enable to local_irq_save/restore to ensure that from whatever context this is called the proper IRQ configuration is maintained. Signed-off-by: Dave Gerlach <d-gerlach@ti.com> Signed-off-by: Keerthy <j-keerthy@ti.com> Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch/arm/mach-omap2/omap_hwmod_reset.c')
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_reset.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod_reset.c b/arch/arm/mach-omap2/omap_hwmod_reset.c
index b68f9c0aff0b..d5ddba00bb73 100644
--- a/arch/arm/mach-omap2/omap_hwmod_reset.c
+++ b/arch/arm/mach-omap2/omap_hwmod_reset.c
@@ -92,11 +92,13 @@ static void omap_rtc_wait_not_busy(struct omap_hwmod *oh)
92 */ 92 */
93void omap_hwmod_rtc_unlock(struct omap_hwmod *oh) 93void omap_hwmod_rtc_unlock(struct omap_hwmod *oh)
94{ 94{
95 local_irq_disable(); 95 unsigned long flags;
96
97 local_irq_save(flags);
96 omap_rtc_wait_not_busy(oh); 98 omap_rtc_wait_not_busy(oh);
97 omap_hwmod_write(OMAP_RTC_KICK0_VALUE, oh, OMAP_RTC_KICK0_REG); 99 omap_hwmod_write(OMAP_RTC_KICK0_VALUE, oh, OMAP_RTC_KICK0_REG);
98 omap_hwmod_write(OMAP_RTC_KICK1_VALUE, oh, OMAP_RTC_KICK1_REG); 100 omap_hwmod_write(OMAP_RTC_KICK1_VALUE, oh, OMAP_RTC_KICK1_REG);
99 local_irq_enable(); 101 local_irq_restore(flags);
100} 102}
101 103
102/** 104/**
@@ -110,9 +112,11 @@ void omap_hwmod_rtc_unlock(struct omap_hwmod *oh)
110 */ 112 */
111void omap_hwmod_rtc_lock(struct omap_hwmod *oh) 113void omap_hwmod_rtc_lock(struct omap_hwmod *oh)
112{ 114{
113 local_irq_disable(); 115 unsigned long flags;
116
117 local_irq_save(flags);
114 omap_rtc_wait_not_busy(oh); 118 omap_rtc_wait_not_busy(oh);
115 omap_hwmod_write(0x0, oh, OMAP_RTC_KICK0_REG); 119 omap_hwmod_write(0x0, oh, OMAP_RTC_KICK0_REG);
116 omap_hwmod_write(0x0, oh, OMAP_RTC_KICK1_REG); 120 omap_hwmod_write(0x0, oh, OMAP_RTC_KICK1_REG);
117 local_irq_enable(); 121 local_irq_restore(flags);
118} 122}