Skip to content

Commit

Permalink
core: interrupt: itr_chip may not require configure handler
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Jens Wiklander <[email protected]>
  • Loading branch information
etienne-lms committed Feb 14, 2025
1 parent f2ea7ca commit fb02196
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 17 deletions.
26 changes: 12 additions & 14 deletions core/include/kernel/interrupt.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down
43 changes: 40 additions & 3 deletions core/kernel/interrupt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand All @@ -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) &&
Expand All @@ -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);

Expand Down

0 comments on commit fb02196

Please sign in to comment.