diff options
author | merge <null@invalid> | 2008-12-09 21:10:29 +0000 |
---|---|---|
committer | Andy Green <agreen@pads.home.warmcat.com> | 2008-12-09 21:10:29 +0000 |
commit | 4cb6aa6461979dc4bdc468ab6bf948e9a7055368 (patch) | |
tree | 5b41ba4c907baa6341f0a45cd08c62d815707620 /arch/arm/plat-s3c24xx/irq.c | |
parent | c59a8bdc7ca4b5470ebc43dfc31ed1d3d23a7c6f (diff) |
MERGE-via-pending-tracking-hist-fix-s3c_irq_demux_extint8-to-h
pending-tracking-hist top was fix-s3c_irq_demux_extint8-to-h / e3a894b0f1fae0caa2224a5d1b3c409fcac9f5cc ... parent commitmessage:
From: Balaji Rao <balajirrao@openmoko.org>
Fix s3c_irq_demux_extint8 to handle masked but pending IRQs
Hi,
It was observed that even after the move to level irq on pcf50633, the
problem of 'the phone doesn't resume if POWER is pressed during
transition to standby' remains.
The original problem was due to a lost edge.
The present problem - When POWER is pressed during the transition,
handle_level_irq runs which looks at the IRQ_DISABLED flag set by
pcf50633_suspend and masks the irq on chip. Now when the cpu wakes up
(level keeps hitting us), s3c_irq_demux_extint8 runs, which tries to
handle all pending irqs. But before it does so, it applies the mask
and hence not all pending irqs were acked and hence, our pmu's irq
(level) caused an irq flood..
This patch clears those interrupts which are masked, but pending. Fixes
the problem for me. Mildly tested.
Signed-off-by: Balaji Rao <balajirrao@openmoko.org>
Diffstat (limited to 'arch/arm/plat-s3c24xx/irq.c')
-rw-r--r-- | arch/arm/plat-s3c24xx/irq.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c index d696bbd1c9e..e236ec70fa0 100644 --- a/arch/arm/plat-s3c24xx/irq.c +++ b/arch/arm/plat-s3c24xx/irq.c @@ -497,6 +497,20 @@ s3c_irq_demux_extint8(unsigned int irq, generic_handle_irq(irq); } + /* ACK those interrupts which are masked, but pending */ + eintpnd = __raw_readl(S3C24XX_EINTPEND); + eintmsk = __raw_readl(S3C24XX_EINTMASK); + + eintpnd &= eintmsk; + eintpnd &= ~0xff; /* ignore lower irqs */ + + while (eintpnd) { + irq = __ffs(eintpnd); + eintpnd &= ~(1 << irq); + + irq += (IRQ_EINT4 - 4); + s3c_irqext_ack(irq); + } } static void |