aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorMagnus Damm <magnus.damm@gmail.com>2008-04-24 08:53:07 -0400
committerPaul Mundt <lethal@linux-sh.org>2008-05-08 06:52:07 -0400
commit4370fe1c06ffa251b63b12a41e2599037a4b7f87 (patch)
tree9b08db220fafe5c7fa9160fc17a924a5fe1e59dc /arch/sh
parent720be99006c5830970d5b62633c92b29e4cef137 (diff)
sh: intc register modify fix
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>
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/kernel/cpu/irq/intc.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/arch/sh/kernel/cpu/irq/intc.c b/arch/sh/kernel/cpu/irq/intc.c
index e5a4912d665f..da5dae787888 100644
--- a/arch/sh/kernel/cpu/irq/intc.c
+++ b/arch/sh/kernel/cpu/irq/intc.c
@@ -101,17 +101,26 @@ static void write_32(unsigned long addr, unsigned long h, unsigned long data)
101 101
102static void modify_8(unsigned long addr, unsigned long h, unsigned long data) 102static void modify_8(unsigned long addr, unsigned long h, unsigned long data)
103{ 103{
104 unsigned long flags;
105 local_irq_save(flags);
104 ctrl_outb(set_field(ctrl_inb(addr), data, h), addr); 106 ctrl_outb(set_field(ctrl_inb(addr), data, h), addr);
107 local_irq_restore(flags);
105} 108}
106 109
107static void modify_16(unsigned long addr, unsigned long h, unsigned long data) 110static void modify_16(unsigned long addr, unsigned long h, unsigned long data)
108{ 111{
112 unsigned long flags;
113 local_irq_save(flags);
109 ctrl_outw(set_field(ctrl_inw(addr), data, h), addr); 114 ctrl_outw(set_field(ctrl_inw(addr), data, h), addr);
115 local_irq_restore(flags);
110} 116}
111 117
112static void modify_32(unsigned long addr, unsigned long h, unsigned long data) 118static void modify_32(unsigned long addr, unsigned long h, unsigned long data)
113{ 119{
120 unsigned long flags;
121 local_irq_save(flags);
114 ctrl_outl(set_field(ctrl_inl(addr), data, h), addr); 122 ctrl_outl(set_field(ctrl_inl(addr), data, h), addr);
123 local_irq_restore(flags);
115} 124}
116 125
117enum { REG_FN_ERR = 0, REG_FN_WRITE_BASE = 1, REG_FN_MODIFY_BASE = 5 }; 126enum { REG_FN_ERR = 0, REG_FN_WRITE_BASE = 1, REG_FN_MODIFY_BASE = 5 };