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>
This commit is contained in:
Родитель
1c772b5664
Коммит
c55b2851f9
|
@ -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 @@
|
||||||
#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
|
||||||
|
|
Загрузка…
Ссылка в новой задаче