sh: intc register modify fix
authorMagnus Damm <magnus.damm@gmail.com>
Thu, 24 Apr 2008 12:53:07 +0000 (21:53 +0900)
committerPaul Mundt <lethal@linux-sh.org>
Thu, 8 May 2008 10:52:07 +0000 (19:52 +0900)
Make sure register modifications stay atomic. Fixes processors with
shared priority register masking. Dual bitmap masking is unaffected.

Signed-off-by: Magnus Damm <damm@igel.co.jp>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
arch/sh/kernel/cpu/irq/intc.c

index e5a4912..da5dae7 100644 (file)
@@ -101,17 +101,26 @@ static void write_32(unsigned long addr, unsigned long h, unsigned long data)
 
 static void modify_8(unsigned long addr, unsigned long h, unsigned long data)
 {
+       unsigned long flags;
+       local_irq_save(flags);
        ctrl_outb(set_field(ctrl_inb(addr), data, h), addr);
+       local_irq_restore(flags);
 }
 
 static void modify_16(unsigned long addr, unsigned long h, unsigned long data)
 {
+       unsigned long flags;
+       local_irq_save(flags);
        ctrl_outw(set_field(ctrl_inw(addr), data, h), addr);
+       local_irq_restore(flags);
 }
 
 static void modify_32(unsigned long addr, unsigned long h, unsigned long data)
 {
+       unsigned long flags;
+       local_irq_save(flags);
        ctrl_outl(set_field(ctrl_inl(addr), data, h), addr);
+       local_irq_restore(flags);
 }
 
 enum { REG_FN_ERR = 0, REG_FN_WRITE_BASE = 1, REG_FN_MODIFY_BASE = 5 };