Commit c55b2851 authored by Jeffrey Deans's avatar Jeffrey Deans Committed by Ralf Baechle

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: default avatarJeffrey Deans <jeffrey.deans@imgtec.com>
Signed-off-by: default avatarMarkos Chandras <markos.chandras@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/7378/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 1c772b56
...@@ -43,18 +43,17 @@ ...@@ -43,18 +43,17 @@
#ifdef GICISBYTELITTLEENDIAN #ifdef GICISBYTELITTLEENDIAN
#define GICREAD(reg, data) ((data) = (reg), (data) = le32_to_cpu(data)) #define GICREAD(reg, data) ((data) = (reg), (data) = le32_to_cpu(data))
#define GICWRITE(reg, data) ((reg) = cpu_to_le32(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 #else
#define GICREAD(reg, data) ((data) = (reg)) #define GICREAD(reg, data) ((data) = (reg))
#define GICWRITE(reg, data) ((reg) = (data)) #define GICWRITE(reg, data) ((reg) = (data))
#define GICBIS(reg, bits) ((reg) |= (bits))
#endif #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 */ /* GIC Address Space */
...@@ -170,13 +169,15 @@ ...@@ -170,13 +169,15 @@
#define GIC_SH_SET_POLARITY_OFS 0x0100 #define GIC_SH_SET_POLARITY_OFS 0x0100
#define GIC_SET_POLARITY(intr, pol) \ #define GIC_SET_POLARITY(intr, pol) \
GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + \ 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 */ /* Triggering : Reset Value is always 0 */
#define GIC_SH_SET_TRIGGER_OFS 0x0180 #define GIC_SH_SET_TRIGGER_OFS 0x0180
#define GIC_SET_TRIGGER(intr, trig) \ #define GIC_SET_TRIGGER(intr, trig) \
GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_TRIGGER_OFS + \ 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 */ /* Mask manipulation */
#define GIC_SH_SMASK_OFS 0x0380 #define GIC_SH_SMASK_OFS 0x0380
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment