diff options
author | Magnus Damm <magnus.damm@gmail.com> | 2008-04-24 08:53:07 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2008-05-08 06:52:07 -0400 |
commit | 4370fe1c06ffa251b63b12a41e2599037a4b7f87 (patch) | |
tree | 9b08db220fafe5c7fa9160fc17a924a5fe1e59dc /arch | |
parent | 720be99006c5830970d5b62633c92b29e4cef137 (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')
-rw-r--r-- | arch/sh/kernel/cpu/irq/intc.c | 9 |
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 | ||
102 | static void modify_8(unsigned long addr, unsigned long h, unsigned long data) | 102 | static 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 | ||
107 | static void modify_16(unsigned long addr, unsigned long h, unsigned long data) | 110 | static 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 | ||
112 | static void modify_32(unsigned long addr, unsigned long h, unsigned long data) | 118 | static 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 | ||
117 | enum { REG_FN_ERR = 0, REG_FN_WRITE_BASE = 1, REG_FN_MODIFY_BASE = 5 }; | 126 | enum { REG_FN_ERR = 0, REG_FN_WRITE_BASE = 1, REG_FN_MODIFY_BASE = 5 }; |