summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordayu@datangmobile.cn <dayu@datangmobile.cn>2009-02-18 13:47:42 +0800
committerKumar Gala <galak@kernel.crashing.org>2009-03-09 09:25:35 -0500
commit30c404699dd650f213d480d263c775915a0e1297 (patch)
tree915be54e8939a83259ab272f47d74b152ce35b0b
parent1ab082d7cbd0f34e39a5396cc6340c00bc5d66ef (diff)
powerpc/83xx: Fix the interrupt loss problem on ipic
The interrupt pending register is write 1 clear. If there are more than one external interrupts pending at the same time, acking the first interrupt by reading pending register then OR the corresponding bit and write back to pending register will also clear other interrupt pending bits. That will cause loss of interrupt. Signed-off-by: Da Yu <dayu@datangmobile.cn> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
-rw-r--r--arch/powerpc/sysdev/ipic.c6
1 files changed, 2 insertions, 4 deletions
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index 9a89cd3e80a2..a86d3ce01ead 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -568,8 +568,7 @@ static void ipic_ack_irq(unsigned int virq)
spin_lock_irqsave(&ipic_lock, flags);
- temp = ipic_read(ipic->regs, ipic_info[src].ack);
- temp |= (1 << (31 - ipic_info[src].bit));
+ temp = 1 << (31 - ipic_info[src].bit);
ipic_write(ipic->regs, ipic_info[src].ack, temp);
/* mb() can't guarantee that ack is finished. But it does finish
@@ -592,8 +591,7 @@ static void ipic_mask_irq_and_ack(unsigned int virq)
temp &= ~(1 << (31 - ipic_info[src].bit));
ipic_write(ipic->regs, ipic_info[src].mask, temp);
- temp = ipic_read(ipic->regs, ipic_info[src].ack);
- temp |= (1 << (31 - ipic_info[src].bit));
+ temp = 1 << (31 - ipic_info[src].bit);
ipic_write(ipic->regs, ipic_info[src].ack, temp);
/* mb() can't guarantee that ack is finished. But it does finish