From fb02196b30d3b17348b2011dfa20ca377f49920e Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 14 Feb 2025 11:19:00 +0100 Subject: [PATCH] core: interrupt: itr_chip may not require configure handler The configure handler in struct itr_ops is not required for interrupt providers which consumers only use the DT to get and configure their interrupts (with interrupt_dt_get_by_*() and interrupt_create_handler()). Therefore change itr_chip_is_valid() to not enforce its support but add back that constraint for the interrupt main controller. Add an itr_chip_dt_only_init() helper function for interrupt controllers which consumers only use the DT to configure their interrupt, that is such controllers do not need a configure handler. itr_chip_is_valid() is not called outside interrupt.c where it is used in itr_chip_init() and itr_chip_dt_only_init() so make it a local function. Signed-off-by: Etienne Carriere Reviewed-by: Jens Wiklander --- core/include/kernel/interrupt.h | 26 +++++++++----------- core/kernel/interrupt.c | 43 ++++++++++++++++++++++++++++++--- 2 files changed, 52 insertions(+), 17 deletions(-) diff --git a/core/include/kernel/interrupt.h b/core/include/kernel/interrupt.h index a56168dce9e..e49c96e6f38 100644 --- a/core/include/kernel/interrupt.h +++ b/core/include/kernel/interrupt.h @@ -59,9 +59,15 @@ struct itr_chip { * @raise_sgi Raise a SGI or NULL if not applicable to that controller * @set_affinity Set interrupt/cpu affinity or NULL if not applicable * - * Handlers @enable, @disable, @mask, @unmask and @configure are mandated. - * Handlers @mask and @unmask have unpaged memory constraints. - * See itr_chip_is_valid(). + * Handlers @enable, @disable, @mask and @unmask are mandated. Handlers + * @mask and @unmask have unpaged memory constraints. These requirements are + * verified by itr_chip_init() and itr_chip_dt_only_init(). + * + * Handler @configure is needed for interrupt providers which do not rely on + * DT for consumers interrupt configuration, that is interrupt consumers using + * interrupt_configure() or friends (interrupt_add_handler(), + * interrupt_add_configure_handler(), interrupt_add_handler_with_chip(), + * etc...). */ struct itr_ops { void (*configure)(struct itr_chip *chip, size_t it, uint32_t type, @@ -124,18 +130,10 @@ struct itr_handler { }) /* - * Return true only if interrupt chip provides required handlers - * @chip: Interrupt controller reference + * Initialise an interrupt controller handle to be used only with the DT + * @chip Interrupt controller */ -static inline bool itr_chip_is_valid(struct itr_chip *chip) -{ - return chip && is_unpaged(chip) && chip->ops && - is_unpaged((void *)chip->ops) && - chip->ops->mask && is_unpaged(chip->ops->mask) && - chip->ops->unmask && is_unpaged(chip->ops->unmask) && - chip->ops->enable && chip->ops->disable && - chip->ops->configure; -} +TEE_Result itr_chip_dt_only_init(struct itr_chip *chip); /* * Initialise an interrupt controller handle diff --git a/core/kernel/interrupt.c b/core/kernel/interrupt.c index 7c700953f3f..929e8fda9d2 100644 --- a/core/kernel/interrupt.c +++ b/core/kernel/interrupt.c @@ -22,12 +22,40 @@ static struct itr_chip *itr_main_chip __nex_bss; +static bool itr_chip_is_valid(struct itr_chip *chip) +{ + return chip && is_unpaged(chip) && chip->ops && + is_unpaged((void *)chip->ops) && + chip->ops->mask && is_unpaged(chip->ops->mask) && + chip->ops->unmask && is_unpaged(chip->ops->unmask) && + chip->ops->enable && chip->ops->disable; +} + +static void __itr_chip_init(struct itr_chip *chip) +{ + SLIST_INIT(&chip->handlers); +} + TEE_Result itr_chip_init(struct itr_chip *chip) +{ + /* + * Interrupt chips not using only the DT to configure + * consumers interrupts require configure handler. + */ + if (!itr_chip_is_valid(chip) || !chip->ops->configure) + return TEE_ERROR_BAD_PARAMETERS; + + __itr_chip_init(chip); + + return TEE_SUCCESS; +} + +TEE_Result itr_chip_dt_only_init(struct itr_chip *chip) { if (!itr_chip_is_valid(chip)) return TEE_ERROR_BAD_PARAMETERS; - SLIST_INIT(&chip->handlers); + __itr_chip_init(chip); return TEE_SUCCESS; } @@ -105,6 +133,11 @@ void interrupt_call_handlers(struct itr_chip *chip, size_t itr_num) TEE_Result interrupt_configure(struct itr_chip *chip, size_t itr_num, uint32_t type, uint32_t prio) { + if (!chip->ops->configure) { + EMSG("No configure handler in itr_chip %s", chip->name); + return TEE_ERROR_NOT_IMPLEMENTED; + } + chip->ops->configure(chip, itr_num, type, prio); return TEE_SUCCESS; @@ -114,6 +147,7 @@ static TEE_Result add_configure_handler(struct itr_handler *hdl, uint32_t type, uint32_t prio, bool configure) { + TEE_Result res = TEE_ERROR_GENERIC; struct itr_handler *h = NULL; assert(hdl && hdl->chip->ops && is_unpaged(hdl) && @@ -129,8 +163,11 @@ static TEE_Result add_configure_handler(struct itr_handler *hdl, } } - if (configure) - interrupt_configure(hdl->chip, hdl->it, type, prio); + if (configure) { + res = interrupt_configure(hdl->chip, hdl->it, type, prio); + if (res) + return res; + } SLIST_INSERT_HEAD(&hdl->chip->handlers, hdl, link);