summaryrefslogtreecommitdiff
path: root/arch/mips
diff options
context:
space:
mode:
authorJeffrey Deans <jeffrey.deans@imgtec.com>2014-07-17 12:20:59 +0400
committerRalf Baechle <ralf@linux-mips.org>2014-08-02 02:06:41 +0400
commitc55b2851f901215fbfa46e4ea9cc04761c776815 (patch)
treea743802f48557f7915c727abf59a451e083732a0 /arch/mips
parent1c772b5664d9efa8d8d25b69b4ea8ae8996d6153 (diff)
downloadlinux-c55b2851f901215fbfa46e4ea9cc04761c776815.tar.xz
MIPS: GIC: Fix GICBIS macro
The GICBIS macro could update the GIC registers incorrectly, depending on the data value passed in: * Bits were only OR'd into the register data, so register fields could not be cleared. * Bits were OR'd into the register data without masking the data to the correct field width, corrupting adjacent bits. Signed-off-by: Jeffrey Deans <jeffrey.deans@imgtec.com> Signed-off-by: Markos Chandras <markos.chandras@imgtec.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/7378/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/include/asm/gic.h21
1 files changed, 11 insertions, 10 deletions
diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h
index 8b30befd99d6..3f20b2111d56 100644
--- a/arch/mips/include/asm/gic.h
+++ b/arch/mips/include/asm/gic.h
@@ -43,18 +43,17 @@
#ifdef GICISBYTELITTLEENDIAN
#define GICREAD(reg, data) ((data) = (reg), (data) = le32_to_cpu(data))
#define GICWRITE(reg, data) ((reg) = cpu_to_le32(data))
-#define GICBIS(reg, bits) \
- ({unsigned int data; \
- GICREAD(reg, data); \
- data |= bits; \
- GICWRITE(reg, data); \
- })
-
#else
#define GICREAD(reg, data) ((data) = (reg))
#define GICWRITE(reg, data) ((reg) = (data))
-#define GICBIS(reg, bits) ((reg) |= (bits))
#endif
+#define GICBIS(reg, mask, bits) \
+ do { u32 data; \
+ GICREAD((reg), data); \
+ data &= ~(mask); \
+ data |= ((bits) & (mask)); \
+ GICWRITE((reg), data); \
+ } while (0)
/* GIC Address Space */
@@ -170,13 +169,15 @@
#define GIC_SH_SET_POLARITY_OFS 0x0100
#define GIC_SET_POLARITY(intr, pol) \
GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + \
- GIC_INTR_OFS(intr)), (pol) << GIC_INTR_BIT(intr))
+ GIC_INTR_OFS(intr)), (1 << GIC_INTR_BIT(intr)), \
+ (pol) << GIC_INTR_BIT(intr))
/* Triggering : Reset Value is always 0 */
#define GIC_SH_SET_TRIGGER_OFS 0x0180
#define GIC_SET_TRIGGER(intr, trig) \
GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_TRIGGER_OFS + \
- GIC_INTR_OFS(intr)), (trig) << GIC_INTR_BIT(intr))
+ GIC_INTR_OFS(intr)), (1 << GIC_INTR_BIT(intr)), \
+ (trig) << GIC_INTR_BIT(intr))
/* Mask manipulation */
#define GIC_SH_SMASK_OFS 0x0380