irq: multilevel: add API to increment a multilevel IRQ

Unlike a normal IRQ, a multilevel IRQ can't be incremented by
simply `irq++`, as that would always increment the L1 of a IRQ,
regardless of its level. A function that understands the level
for which the IRQ operates in is required.

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
Signed-off-by: Yong Cong Sin <yongcong.sin@gmail.com>
This commit is contained in:
Yong Cong Sin 2024-09-24 15:21:42 +08:00 committed by Alberto Escolar
commit 8bfdff3cb1
3 changed files with 62 additions and 0 deletions

View file

@ -40,5 +40,31 @@
interrupt-parent = <&test_l2_irq>;
interrupt-names = "test";
};
test_l1_irq_inc: interrupt-controller@bbbbdccc {
compatible = "vnd,intc";
reg = <0xbbbbdccc 0x10>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <12 0>; /* +1 */
interrupt-parent = <&test_cpu_intc>;
};
test_l2_irq_inc: interrupt-controller@bbbbdcdc {
compatible = "vnd,intc";
reg = <0xbbbbdcdc 0x10>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <14 0>; /* +2 */
interrupt-parent = <&test_l1_irq>;
};
test_l3_irq_inc: interrupt-holder-inc {
compatible = "vnd,interrupt-holder";
status = "okay";
interrupts = <16 3>; /* +3 */
interrupt-parent = <&test_l2_irq>;
interrupt-names = "test";
};
};
};

View file

@ -71,6 +71,17 @@ ZTEST(interrupt_feature, test_multi_level_api)
zassert_equal(irq_get_intc_irq(irqn_l3), irqn_l2);
zassert_equal(irq_get_intc_irq(irqn_l2), irqn_l1);
zassert_equal(irq_get_intc_irq(irqn_l1), irqn_l1);
const uint32_t irqn_l3_inc = DT_IRQN(DT_NODELABEL(test_l3_irq_inc));
const uint32_t irqn_l2_inc = DT_IRQN(DT_NODELABEL(test_l2_irq_inc));
const uint32_t irqn_l1_inc = DT_IRQN(DT_NODELABEL(test_l1_irq_inc));
/**
* - irq_increment()
*/
zassert_equal(irq_increment(irqn_l1, 1), irqn_l1_inc);
zassert_equal(irq_increment(irqn_l2, 2), irqn_l2_inc);
zassert_equal(irq_increment(irqn_l3, 3), irqn_l3_inc);
}
ZTEST_SUITE(gen_isr_table_multilevel, NULL, NULL, NULL, NULL, NULL);