Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions core/drivers/atmel_saic.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ struct saic_data {
uint32_t external[SAMA5D2_AIC_MAX_IRQS32];
};

static struct saic_data saic = {0};
static struct saic_data saic;

static void saic_register_pm(void);

Expand All @@ -47,7 +47,7 @@ void interrupt_main_handler(void)
{
uint32_t irqnr = saic_read_reg(AT91_AIC_IVR);

itr_handle(irqnr);
interrupt_call_handlers(&saic.chip, irqnr);
saic_write_reg(AT91_AIC_EOICR, 0);
}

Expand Down Expand Up @@ -192,9 +192,11 @@ static int saic_dt_get_irq(const uint32_t *properties, int len,
return it;
}

struct itr_chip saic_chip = {
.ops = &saic_ops,
.dt_get_irq = &saic_dt_get_irq,
static struct saic_data saic = {
.chip = {
.ops = &saic_ops,
.dt_get_irq = &saic_dt_get_irq,
},
};

static void saic_clear_aicredir(void)
Expand Down Expand Up @@ -297,7 +299,7 @@ TEE_Result atmel_saic_setup(void)
saic_init_external(fdt, node);
saic_init_hw();

interrupt_main_init(&saic_chip);
interrupt_main_init(&saic.chip);
saic_register_pm();

return TEE_SUCCESS;
Expand Down
2 changes: 1 addition & 1 deletion core/drivers/gic.c
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ static void __maybe_unused gic_native_itr_handler(void)
id = iar & GICC_IAR_IT_ID_MASK;

if (id <= gd->max_it)
itr_handle(id);
interrupt_call_handlers(&gd->chip, id);
else
DMSG("ignoring interrupt %" PRIu32, id);

Expand Down
3 changes: 2 additions & 1 deletion core/drivers/hfic.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ void interrupt_main_handler(void)
return;
}

itr_handle(id);
interrupt_call_handlers(&hfic_data.chip, id);

res = thread_hvc(HF_INTERRUPT_DEACTIVATE, id, id, 0);
assert(!res);
}
2 changes: 1 addition & 1 deletion core/drivers/plic.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ void plic_it_handle(void)
uint32_t id = plic_claim_interrupt(pd);

if (id <= pd->max_it)
itr_handle(id);
interrupt_call_handlers(&pd->chip, id);
else
DMSG("ignoring interrupt %" PRIu32, id);

Expand Down
105 changes: 94 additions & 11 deletions core/include/kernel/interrupt.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,6 @@ TEE_Result itr_chip_init(struct itr_chip *chip);
*/
void interrupt_main_init(struct itr_chip *data);

/*
* Call handlers registered for that interrupt in core interrupt controller
* @it Interrupt line number
*/
void itr_handle(size_t it);

/* Retrieve main interrupt controller reference */
struct itr_chip *interrupt_get_main_chip(void);

Expand Down Expand Up @@ -264,6 +258,70 @@ static inline void interrupt_disable(struct itr_chip *chip, size_t itr_num)
chip->ops->disable(chip, itr_num);
}

/*
* interrupt_can_raise_pi() - Return whether controller embeds raise_pi
* @chip Interrupt controller
*/
static inline bool interrupt_can_raise_pi(struct itr_chip *chip)
{
return chip->ops->raise_pi;
}

/*
* interrupt_can_raise_sgi() - Return whether controller embeds raise_sgi
* @chip Interrupt controller
*/
static inline bool interrupt_can_raise_sgi(struct itr_chip *chip)
{
return chip->ops->raise_sgi;
}

/*
* interrupt_can_set_affinity() - Return whether controller embeds set_affinity
* @chip Interrupt controller
*/
static inline bool interrupt_can_set_affinity(struct itr_chip *chip)
{
return chip->ops->set_affinity;
}

/*
* interrupt_raise_pi() - Raise a peripheral interrupt of a controller
* @chip Interrupt controller
* @itr_num Interrupt number to raise
*/
static inline void interrupt_raise_pi(struct itr_chip *chip, size_t itr_num)
{
assert(interrupt_can_raise_pi(chip));
chip->ops->raise_pi(chip, itr_num);
}

/*
* interrupt_raise_sgi() - Raise a software generiated interrupt of a controller
* @chip Interrupt controller
* @itr_num Interrupt number to raise
* @cpu_mask Mask of the CPUs targeted by the interrupt
*/
static inline void interrupt_raise_sgi(struct itr_chip *chip, size_t itr_num,
uint8_t cpu_mask)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not strictly related to this PR, but... I notice that cpu_mask is an uint8_t, does it mean the API can only support at most 8 cores? Or perhaps a "CPU" is not a core? (the comment near itr_raise_sgi() mentions a "cpu interface").

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I mimicked the existing GIC function API. As for a generic purpose interrupt controller framework, I don't think "raise SGI" or "raise PPI" really make sense but I propose to postpone this to later, once there's a need.

{
assert(interrupt_can_raise_sgi(chip));
chip->ops->raise_sgi(chip, itr_num, cpu_mask);
}

/*
* interrupt_set_affinity() - Set CPU affinity for a controller interrupt
* @chip Interrupt controller
* @itr_num Interrupt number to raise
* @cpu_mask Mask of the CPUs targeted by the interrupt
*/
static inline void interrupt_set_affinity(struct itr_chip *chip, size_t itr_num,
uint8_t cpu_mask)
{
assert(interrupt_can_set_affinity(chip));
chip->ops->set_affinity(chip, itr_num, cpu_mask);
}

/*
* interrupt_configure() - Configure an interrupt in an interrupt controller
* @chip Interrupt controller
Expand Down Expand Up @@ -321,6 +379,24 @@ static inline TEE_Result interrupt_add_handler_with_chip(struct itr_chip *chip,
*/
void interrupt_remove_handler(struct itr_handler *hdl);

/*
* interrupt_alloc_add_conf_handler() - Allocate, configure, register a handler
* @chip Interrupt controller
* @itr_num Interrupt number
* @handler Interrupt handler to register
* @flags Bitmask flag ITRF_*
* @data Private data reference passed to @handler
* @type Interrupt trigger type (IRQ_TYPE_* defines) or IRQ_TYPE_NONE
* @prio Interrupt priority or 0
* @out_hdl NULL or output pointer to allocated struct itr_handler
*/
TEE_Result interrupt_alloc_add_conf_handler(struct itr_chip *chip,
size_t it_num,
itr_handler_t handler,
uint32_t flags, void *data,
uint32_t type, uint32_t prio,
struct itr_handler **out_hdl);

/*
* interrupt_alloc_add_handler() - Allocate and register an interrupt handler
* @chip Interrupt controller
Expand All @@ -330,16 +406,23 @@ void interrupt_remove_handler(struct itr_handler *hdl);
* @data Private data reference passed to @handler
* @out_hdl NULL or output pointer to allocated struct itr_handler
*/
TEE_Result interrupt_alloc_add_handler(struct itr_chip *chip, size_t it_num,
itr_handler_t handler, uint32_t flags,
void *data,
struct itr_handler **out_hdl);
static inline TEE_Result interrupt_alloc_add_handler(struct itr_chip *chip,
size_t it_num,
itr_handler_t handler,
uint32_t flags,
void *data,
struct itr_handler **hdl)
{
return interrupt_alloc_add_conf_handler(chip, it_num, handler, flags,
data, IRQ_TYPE_NONE, 0, hdl);
}

/*
* interrupt_remove_free_handler() - Remove/free a registered interrupt handler
* @hdl Interrupt handler to remove and free
*
* This function is the counterpart of interrupt_alloc_add_handler().
* This function is the counterpart of interrupt_alloc_add_handler()
* and interrupt_alloc_add_conf_handler().
* This function may panic on non-NULL invalid @hdl reference.
*/
void interrupt_remove_free_handler(struct itr_handler *hdl);
Expand Down
16 changes: 7 additions & 9 deletions core/kernel/interrupt.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,6 @@ int dt_get_irq_type_prio(const void *fdt, int node, uint32_t *type,
}
#endif

void itr_handle(size_t it)
{
interrupt_call_handlers(itr_main_chip, it);
}

struct itr_handler *itr_alloc_add_type_prio(size_t it, itr_handler_t handler,
uint32_t flags, void *data,
uint32_t type, uint32_t prio)
Expand Down Expand Up @@ -232,9 +227,12 @@ void interrupt_remove_handler(struct itr_handler *hdl)
SLIST_REMOVE(&hdl->chip->handlers, hdl, itr_handler, link);
}

TEE_Result interrupt_alloc_add_handler(struct itr_chip *chip, size_t itr_num,
itr_handler_t handler, uint32_t flags,
void *data, struct itr_handler **out_hdl)
TEE_Result interrupt_alloc_add_conf_handler(struct itr_chip *chip,
size_t itr_num,
itr_handler_t handler,
uint32_t flags, void *data,
uint32_t type, uint32_t prio,
struct itr_handler **out_hdl)
{
TEE_Result res = TEE_ERROR_GENERIC;
struct itr_handler *hdl = NULL;
Expand All @@ -245,7 +243,7 @@ TEE_Result interrupt_alloc_add_handler(struct itr_chip *chip, size_t itr_num,

*hdl = ITR_HANDLER(chip, itr_num, flags, handler, data);

res = interrupt_add_handler(hdl);
res = interrupt_add_configure_handler(hdl, type, prio);
if (res) {
free(hdl);
return res;
Expand Down