diff options
author | Jeenu Viswambharan <jeenu.viswambharan@arm.com> | 2017-09-22 08:32:09 +0100 |
---|---|---|
committer | Jeenu Viswambharan <jeenu.viswambharan@arm.com> | 2017-10-16 16:50:01 +0100 |
commit | 979225f4eed00d631bb57ebd09068edd91b8df7b (patch) | |
tree | 19077c174e283c3fc8f9d6ddc2230e14554d3a70 /drivers/arm/gic/v3 | |
parent | cbd3f3706d4217ee3669deeb52b158e84eb97f56 (diff) |
GIC: Add APIs to enable and disable interrupt
API documentation updated.
Change-Id: Ice7511f8df5356851001d2f7dc2a46cfe318f9ba
Co-authored-by: Yousuf A <yousuf.sait@arm.com>
Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
Diffstat (limited to 'drivers/arm/gic/v3')
-rw-r--r-- | drivers/arm/gic/v3/gicv3_helpers.c | 11 | ||||
-rw-r--r-- | drivers/arm/gic/v3/gicv3_main.c | 64 | ||||
-rw-r--r-- | drivers/arm/gic/v3/gicv3_private.h | 1 |
3 files changed, 76 insertions, 0 deletions
diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c index 81d50ad4..ee874f92 100644 --- a/drivers/arm/gic/v3/gicv3_helpers.c +++ b/drivers/arm/gic/v3/gicv3_helpers.c @@ -173,6 +173,17 @@ void gicr_set_isenabler0(uintptr_t base, unsigned int id) /* * Accessor to set the bit corresponding to interrupt ID in GIC Re-distributor + * ICENABLER0. + */ +void gicr_set_icenabler0(uintptr_t base, unsigned int id) +{ + unsigned bit_num = id & ((1 << ICENABLER_SHIFT) - 1); + + gicr_write_icenabler0(base, (1 << bit_num)); +} + +/* + * Accessor to set the bit corresponding to interrupt ID in GIC Re-distributor * ISACTIVER0. */ unsigned int gicr_get_isactiver0(uintptr_t base, unsigned int id) diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c index 08cf0957..b3231993 100644 --- a/drivers/arm/gic/v3/gicv3_main.c +++ b/drivers/arm/gic/v3/gicv3_main.c @@ -805,3 +805,67 @@ unsigned int gicv3_get_interrupt_active(unsigned int id, unsigned int proc_num) return value; } + +/******************************************************************************* + * This function enables the interrupt identified by id. The proc_num + * is used if the interrupt is SGI or PPI, and programs the corresponding + * Redistributor interface. + ******************************************************************************/ +void gicv3_enable_interrupt(unsigned int id, unsigned int proc_num) +{ + assert(gicv3_driver_data); + assert(gicv3_driver_data->gicd_base); + assert(proc_num < gicv3_driver_data->rdistif_num); + assert(gicv3_driver_data->rdistif_base_addrs); + assert(id <= MAX_SPI_ID); + + /* + * Ensure that any shared variable updates depending on out of band + * interrupt trigger are observed before enabling interrupt. + */ + dsbishst(); + if (id < MIN_SPI_ID) { + /* For SGIs and PPIs */ + gicr_set_isenabler0( + gicv3_driver_data->rdistif_base_addrs[proc_num], + id); + } else { + gicd_set_isenabler(gicv3_driver_data->gicd_base, id); + } +} + +/******************************************************************************* + * This function disables the interrupt identified by id. The proc_num + * is used if the interrupt is SGI or PPI, and programs the corresponding + * Redistributor interface. + ******************************************************************************/ +void gicv3_disable_interrupt(unsigned int id, unsigned int proc_num) +{ + assert(gicv3_driver_data); + assert(gicv3_driver_data->gicd_base); + assert(proc_num < gicv3_driver_data->rdistif_num); + assert(gicv3_driver_data->rdistif_base_addrs); + assert(id <= MAX_SPI_ID); + + /* + * Disable interrupt, and ensure that any shared variable updates + * depending on out of band interrupt trigger are observed afterwards. + */ + if (id < MIN_SPI_ID) { + /* For SGIs and PPIs */ + gicr_set_icenabler0( + gicv3_driver_data->rdistif_base_addrs[proc_num], + id); + + /* Write to clear enable requires waiting for pending writes */ + gicr_wait_for_pending_write( + gicv3_driver_data->rdistif_base_addrs[proc_num]); + } else { + gicd_set_icenabler(gicv3_driver_data->gicd_base, id); + + /* Write to clear enable requires waiting for pending writes */ + gicd_wait_for_pending_write(gicv3_driver_data->gicd_base); + } + + dsbishst(); +} diff --git a/drivers/arm/gic/v3/gicv3_private.h b/drivers/arm/gic/v3/gicv3_private.h index bb8ad9ae..19fce2e7 100644 --- a/drivers/arm/gic/v3/gicv3_private.h +++ b/drivers/arm/gic/v3/gicv3_private.h @@ -71,6 +71,7 @@ unsigned int gicr_get_isactiver0(uintptr_t base, unsigned int id); void gicd_set_igrpmodr(uintptr_t base, unsigned int id); void gicr_set_igrpmodr0(uintptr_t base, unsigned int id); void gicr_set_isenabler0(uintptr_t base, unsigned int id); +void gicr_set_icenabler0(uintptr_t base, unsigned int id); void gicr_set_igroupr0(uintptr_t base, unsigned int id); void gicd_clr_igrpmodr(uintptr_t base, unsigned int id); void gicr_clr_igrpmodr0(uintptr_t base, unsigned int id); |