Skip to content

Commit

Permalink
arch: sw_isr: simplification of the macros
Browse files Browse the repository at this point in the history
Simplifies the macros used to create the LUT.
(To be squashed)

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
  • Loading branch information
ycsin committed Sep 28, 2023
1 parent 9d7918d commit 76262c9
Showing 1 changed file with 24 additions and 15 deletions.
39 changes: 24 additions & 15 deletions arch/common/sw_isr_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,37 @@

#ifdef CONFIG_MULTI_LEVEL_INTERRUPTS

/* Get interrupt controllers */
#define _FILTER_INTC(node_id) DT_NODE_HAS_PROP(node_id, interrupt_controller)
/* Get the interrupt controller that has IRQN equals to `irq` */
#define _FILTER_IRQ(node_id, irq) IS_EQ(DT_IRQN(node_id), irq)
/*
* Get the interrupt controller that match both of the filters above,
* resolves to nothing otherwise
* Insert code if the node_id is an interrupt controller
*/
#define _GET_DEV(node_id, irq) \
COND_CODE_1(_FILTER_INTC(node_id), \
(COND_CODE_1(_FILTER_IRQ(node_id, irq), (DEVICE_DT_GET(node_id)), ())), ())
#define _IF_DT_IS_INTC(node_id, code) \
IF_ENABLED(DT_NODE_HAS_PROP(node_id, interrupt_controller), (code))

/*
* Expands to node_id if its IRQN is equal to `irq`, nothing otherwise
* This only works for `irq` between 0 & 255, see `IS_EQ`
*/
#define _IF_DT_INTC_IRQN_EQ(node_id, irq) IF_ENABLED(IS_EQ(DT_IRQN(node_id), irq), (node_id))

/*
* Loop through child of /soc and get root interrupt controllers with `irq` as IRQN,
* Expands to node_id if it's an interrupt controller & its IRQN is `irq`, or nothing otherwise
*/
#define _DT_INTC_GET_IRQN(node_id, irq) _IF_DT_IS_INTC(node_id, _IF_DT_INTC_IRQN_EQ(node_id, irq))

/**
* Loop through child of "/soc" and get root interrupt controllers with `irq` as IRQN,
* this assumes only one device has the IRQN
* @param irq irq number
* @return node_id(s) that has the `irq` number, or empty if none of them has the `irq`
*/
#define INTC_DEVICE_DT_IRQN_GET(irq) DT_FOREACH_CHILD_STATUS_OKAY_VARGS(DT_PATH(soc), _GET_DEV, irq)
#define INTC_DT_IRQN_GET(irq) \
DT_FOREACH_CHILD_STATUS_OKAY_VARGS(DT_PATH(soc), _DT_INTC_GET_IRQN, irq)

/* If can't find any matching interrupt controller, fills with `NULL` */
#define INTC_DEVICE_OR_NULL(d) COND_CODE_0(IS_EMPTY(d), (d), (NULL))
#define INTC_DEVICE_INIT(node_id) .dev = DEVICE_DT_GET_OR_NULL(node_id),

#define INIT_IRQ_PARENT_OFFSET(d, i, o) { \
.dev = INTC_DEVICE_OR_NULL(d), \
INTC_DEVICE_INIT(d) \
.irq = i, \
.offset = o, \
}
Expand All @@ -47,7 +56,7 @@
#ifdef CONFIG_2ND_LEVEL_INTERRUPTS

#define CAT_2ND_LVL_LIST(i, base) \
INIT_IRQ_PARENT_OFFSET(INTC_DEVICE_DT_IRQN_GET(CONFIG_2ND_LVL_INTR_0##i##_OFFSET), \
INIT_IRQ_PARENT_OFFSET(INTC_DT_IRQN_GET(CONFIG_2ND_LVL_INTR_0##i##_OFFSET), \
CONFIG_2ND_LVL_INTR_0##i##_OFFSET, IRQ_INDEX_TO_OFFSET(i, base))
const struct _irq_parent_entry _lvl2_irq_list[CONFIG_NUM_2ND_LEVEL_AGGREGATORS]
= { LISTIFY(CONFIG_NUM_2ND_LEVEL_AGGREGATORS, CAT_2ND_LVL_LIST, (,),
Expand All @@ -58,7 +67,7 @@ const struct _irq_parent_entry _lvl2_irq_list[CONFIG_NUM_2ND_LEVEL_AGGREGATORS]
#ifdef CONFIG_3RD_LEVEL_INTERRUPTS

#define CAT_3RD_LVL_LIST(i, base) \
INIT_IRQ_PARENT_OFFSET(INTC_DEVICE_DT_IRQN_GET(CONFIG_3RD_LVL_INTR_0##i##_OFFSET), \
INIT_IRQ_PARENT_OFFSET(INTC_DT_IRQN_GET(CONFIG_3RD_LVL_INTR_0##i##_OFFSET), \
CONFIG_3RD_LVL_INTR_0##i##_OFFSET, IRQ_INDEX_TO_OFFSET(i, base))
const struct _irq_parent_entry _lvl3_irq_list[CONFIG_NUM_3RD_LEVEL_AGGREGATORS]
= { LISTIFY(CONFIG_NUM_3RD_LEVEL_AGGREGATORS, CAT_3RD_LVL_LIST, (,),
Expand Down

0 comments on commit 76262c9

Please sign in to comment.