diff options
Diffstat (limited to 'dev')
-rw-r--r-- | dev/interrupt/arm_gic/arm_gic.c | 8 | ||||
-rw-r--r-- | dev/interrupt/arm_gic/gic_v3.c | 9 | ||||
-rw-r--r-- | dev/interrupt/arm_gic/gic_v3.h | 1 |
3 files changed, 15 insertions, 3 deletions
diff --git a/dev/interrupt/arm_gic/arm_gic.c b/dev/interrupt/arm_gic/arm_gic.c index c237cecd..a23d00c7 100644 --- a/dev/interrupt/arm_gic/arm_gic.c +++ b/dev/interrupt/arm_gic/arm_gic.c @@ -194,8 +194,14 @@ static void gic_set_enable(uint vector, bool enable) #endif if (enable) GICDREG_WRITE(0, GICD_ISENABLER(reg), mask); - else + else { GICDREG_WRITE(0, GICD_ICENABLER(reg), mask); + +#if GIC_VERSION > 2 + /* for GIC V3, make sure write is complete */ + arm_gicv3_wait_for_write_complete(); +#endif + } } static void arm_gic_init_percpu(uint level) diff --git a/dev/interrupt/arm_gic/gic_v3.c b/dev/interrupt/arm_gic/gic_v3.c index d5e3c668..cc1005d1 100644 --- a/dev/interrupt/arm_gic/gic_v3.c +++ b/dev/interrupt/arm_gic/gic_v3.c @@ -108,13 +108,18 @@ static void gicv3_gicr_init(void) { /* GICD_CTRL Register write pending bit */ #define GICD_CTLR_RWP (0x1U << 31) +void arm_gicv3_wait_for_write_complete(void) { + /* wait until write complete */ + while (GICDREG_READ(0, GICD_CTLR) & GICD_CTLR_RWP) { + } +} + static void gicv3_gicd_ctrl_write(uint32_t val) { /* write CTRL register */ GICDREG_WRITE(0, GICD_CTLR, val); /* wait until write complete */ - while (GICDREG_READ(0, GICD_CTLR) & GICD_CTLR_RWP) { - } + arm_gicv3_wait_for_write_complete(); } static void gicv3_gicd_setup_irq_group(uint32_t vector, uint32_t grp) { diff --git a/dev/interrupt/arm_gic/gic_v3.h b/dev/interrupt/arm_gic/gic_v3.h index 6c3b74f6..0a327f7f 100644 --- a/dev/interrupt/arm_gic/gic_v3.h +++ b/dev/interrupt/arm_gic/gic_v3.h @@ -29,3 +29,4 @@ void arm_gicv3_configure_irq_locked(unsigned int cpu, unsigned int vector); void arm_gicv3_suspend_cpu(unsigned int cpu); void arm_gicv3_resume_cpu_locked(unsigned int cpu, bool gicd); uint64_t arm_gicv3_sgir_val(u_int irq, size_t cpu_num); +void arm_gicv3_wait_for_write_complete(void); |