Skip to content

Commit

Permalink
devicetree.h: rework multilevel interrupt encoding macros
Browse files Browse the repository at this point in the history
Now that we have a very easy way to get the interrupt
controller and the interrupt level of a node, we can
simplify the multilevel interrupt encoding macros.

Signed-off-by: Yong Cong Sin <[email protected]>
  • Loading branch information
ycsin authored and cfriedt committed Jan 23, 2024
1 parent 170c659 commit 734a7db
Showing 1 changed file with 11 additions and 41 deletions.
52 changes: 11 additions & 41 deletions include/zephyr/devicetree.h
Original file line number Diff line number Diff line change
Expand Up @@ -2545,55 +2545,25 @@
* @cond INTERNAL_HIDDEN
*/

/* DT helper macro to get interrupt-parent node */
#define DT_PARENT_INTC_INTERNAL(node_id) DT_PROP(node_id, interrupt_parent)
/* DT helper macro to get the node's interrupt grandparent node */
#define DT_GPARENT_INTC_INTERNAL(node_id) DT_PARENT_INTC_INTERNAL(DT_PARENT_INTC_INTERNAL(node_id))
/* DT helper macro to check if a node is an interrupt controller */
#define DT_IS_INTC_INTERNAL(node_id) DT_NODE_HAS_PROP(node_id, interrupt_controller)
/* DT helper macro to check if the node has a parent interrupt controller */
#define DT_HAS_PARENT_INTC_INTERNAL(node_id) \
/* node has `interrupt-parent`? */ \
IF_ENABLED(DT_NODE_HAS_PROP(node_id, interrupt_parent), \
/* `interrupt-parent` node is an interrupt controller? */ \
(IF_ENABLED(DT_IS_INTC_INTERNAL(DT_PARENT_INTC_INTERNAL(node_id)), \
/* `interrupt-parent` node has interrupt cell(s) ? 1 : 0 */ \
(COND_CODE_0(DT_NUM_IRQS(DT_PARENT_INTC_INTERNAL(node_id)), (0), \
(1))))))
/* DT helper macro to check if the node has a grandparent interrupt controller */
#define DT_HAS_GPARENT_INTC_INTERNAL(node_id) \
IF_ENABLED(DT_HAS_PARENT_INTC_INTERNAL(node_id), \
(DT_HAS_PARENT_INTC_INTERNAL(DT_PARENT_INTC_INTERNAL(node_id))))

/**
* DT helper macro to get the as-seen interrupt number in devicetree,
* or ARM GIC IRQ encoded output from `gen_defines.py`
*/
#define DT_IRQN_BY_IDX_INTERNAL(node_id, idx) DT_IRQ_BY_IDX(node_id, idx, irq)

/* DT helper macro to get the node's parent intc's (only) irq number */
#define DT_PARENT_INTC_IRQN_INTERNAL(node_id) DT_IRQ(DT_PARENT_INTC_INTERNAL(node_id), irq)
/* DT helper macro to get the node's grandparent intc's (only) irq number */
#define DT_GPARENT_INTC_IRQN_INTERNAL(node_id) DT_IRQ(DT_GPARENT_INTC_INTERNAL(node_id), irq)

/* DT helper macro to encode a node's IRQN to level 1 according to the multi-level scheme */
#define DT_IRQN_L1_INTERNAL(node_id, idx) DT_IRQ_BY_IDX(node_id, idx, irq)
/* DT helper macro to encode a node's IRQN to level 2 according to the multi-level scheme */
#define DT_IRQN_L2_INTERNAL(node_id, idx) \
(IRQ_TO_L2(DT_IRQN_BY_IDX_INTERNAL(node_id, idx)) | \
DT_PARENT_INTC_IRQN_INTERNAL(node_id))
(IRQ_TO_L2(DT_IRQN_L1_INTERNAL(node_id, idx)) | DT_IRQ(DT_IRQ_INTC(node_id), irq))
/* DT helper macro to encode a node's IRQN to level 3 according to the multi-level scheme */
#define DT_IRQN_L3_INTERNAL(node_id, idx) \
(IRQ_TO_L3(DT_IRQN_BY_IDX_INTERNAL(node_id, idx)) | \
IRQ_TO_L2(DT_PARENT_INTC_IRQN_INTERNAL(node_id)) | \
DT_GPARENT_INTC_IRQN_INTERNAL(node_id))
(IRQ_TO_L3(DT_IRQN_L1_INTERNAL(node_id, idx)) | \
IRQ_TO_L2(DT_IRQ(DT_IRQ_INTC(node_id), irq)) | \
DT_IRQ(DT_IRQ_INTC(DT_IRQ_INTC(node_id)), irq))
/* DT helper macro for the macros above */
#define DT_IRQN_LVL_INTERNAL(node_id, idx, level) DT_CAT3(DT_IRQN_L, level, _INTERNAL)(node_id, idx)

/**
* DT helper macro to encode a node's interrupt number according to the Zephyr's multi-level scheme
* See doc/kernel/services/interrupts.rst for details
*/
#define DT_MULTI_LEVEL_IRQN_INTERNAL(node_id, idx) \
COND_CODE_1(DT_HAS_GPARENT_INTC_INTERNAL(node_id), (DT_IRQN_L3_INTERNAL(node_id, idx)), \
(COND_CODE_1(DT_HAS_PARENT_INTC_INTERNAL(node_id), \
(DT_IRQN_L2_INTERNAL(node_id, idx)), \
(DT_IRQN_BY_IDX_INTERNAL(node_id, idx)))))
DT_IRQN_LVL_INTERNAL(node_id, idx, DT_IRQ_LEVEL(node_id))

/**
* INTERNAL_HIDDEN @endcond
Expand All @@ -2610,7 +2580,7 @@
#define DT_IRQN_BY_IDX(node_id, idx) \
COND_CODE_1(IS_ENABLED(CONFIG_MULTI_LEVEL_INTERRUPTS), \
(DT_MULTI_LEVEL_IRQN_INTERNAL(node_id, idx)), \
(DT_IRQN_BY_IDX_INTERNAL(node_id, idx)))
(DT_IRQ_BY_IDX(node_id, idx, irq)))

/**
* @brief Get a node's (only) irq number
Expand Down

0 comments on commit 734a7db

Please sign in to comment.