irq: multilevel: add APIs with level
as argument
Add APIs that accept an additional `level` argument, and use that to call the respective functions. In some cases this can reduce code complexity, especially when the level isn't known at build time. Signed-off-by: Yong Cong Sin <ycsin@meta.com>
This commit is contained in:
parent
8f9ebb652f
commit
dcaf217336
2 changed files with 77 additions and 0 deletions
|
@ -12,6 +12,7 @@
|
||||||
#define ZEPHYR_INCLUDE_IRQ_MULTILEVEL_H_
|
#define ZEPHYR_INCLUDE_IRQ_MULTILEVEL_H_
|
||||||
|
|
||||||
#ifndef _ASMLANGUAGE
|
#ifndef _ASMLANGUAGE
|
||||||
|
#include <zephyr/sys/__assert.h>
|
||||||
#include <zephyr/sys/util_macro.h>
|
#include <zephyr/sys/util_macro.h>
|
||||||
#include <zephyr/types.h>
|
#include <zephyr/types.h>
|
||||||
|
|
||||||
|
@ -166,6 +167,76 @@ static inline unsigned int irq_parent_level_3(unsigned int irq)
|
||||||
BIT_MASK(CONFIG_2ND_LEVEL_INTERRUPT_BITS);
|
BIT_MASK(CONFIG_2ND_LEVEL_INTERRUPT_BITS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return the interrupt number for a given level
|
||||||
|
*
|
||||||
|
* @param irq IRQ number in its zephyr format
|
||||||
|
* @param level IRQ level
|
||||||
|
*
|
||||||
|
* @return IRQ number in the level
|
||||||
|
*/
|
||||||
|
static inline unsigned int irq_from_level(unsigned int irq, unsigned int level)
|
||||||
|
{
|
||||||
|
if (level == 1) {
|
||||||
|
return irq;
|
||||||
|
} else if (level == 2) {
|
||||||
|
return irq_from_level_2(irq);
|
||||||
|
} else if (level == 3) {
|
||||||
|
return irq_from_level_3(irq);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* level is higher than 3 */
|
||||||
|
__ASSERT_NO_MSG(false);
|
||||||
|
return irq;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Converts irq from level 1 to to a given level
|
||||||
|
*
|
||||||
|
* @param irq IRQ number in its zephyr format
|
||||||
|
* @param level IRQ level
|
||||||
|
*
|
||||||
|
* @return Converted IRQ number in the level
|
||||||
|
*/
|
||||||
|
static inline unsigned int irq_to_level(unsigned int irq, unsigned int level)
|
||||||
|
{
|
||||||
|
if (level == 1) {
|
||||||
|
return irq;
|
||||||
|
} else if (level == 2) {
|
||||||
|
return irq_to_level_2(irq);
|
||||||
|
} else if (level == 3) {
|
||||||
|
return irq_to_level_3(irq);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* level is higher than 3 */
|
||||||
|
__ASSERT_NO_MSG(false);
|
||||||
|
return irq;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the parent IRQ of the given level raw IRQ number
|
||||||
|
*
|
||||||
|
* @param irq IRQ number in its zephyr format
|
||||||
|
* @param level IRQ level
|
||||||
|
*
|
||||||
|
* @return IRQ parent of the given level
|
||||||
|
*/
|
||||||
|
static inline unsigned int irq_parent_level(unsigned int irq, unsigned int level)
|
||||||
|
{
|
||||||
|
if (level == 1) {
|
||||||
|
/* doesn't really make sense, but return anyway */
|
||||||
|
return irq;
|
||||||
|
} else if (level == 2) {
|
||||||
|
return irq_parent_level_2(irq);
|
||||||
|
} else if (level == 3) {
|
||||||
|
return irq_parent_level_3(irq);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* level is higher than 3 */
|
||||||
|
__ASSERT_NO_MSG(false);
|
||||||
|
return irq;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the parent interrupt controller IRQ of the given IRQ number
|
* @brief Returns the parent interrupt controller IRQ of the given IRQ number
|
||||||
*
|
*
|
||||||
|
|
|
@ -415,14 +415,20 @@ static void test_multi_level_bit_masks_fn(uint32_t irq1, uint32_t irq2, uint32_t
|
||||||
|
|
||||||
if (has_l2) {
|
if (has_l2) {
|
||||||
zassert_equal(hwirq2, irq_from_level_2(irqn));
|
zassert_equal(hwirq2, irq_from_level_2(irqn));
|
||||||
|
zassert_equal(hwirq2, irq_from_level(irqn, 2));
|
||||||
zassert_equal((hwirq2 + 1) << l2_shift, irq_to_level_2(hwirq2));
|
zassert_equal((hwirq2 + 1) << l2_shift, irq_to_level_2(hwirq2));
|
||||||
|
zassert_equal((hwirq2 + 1) << l2_shift, irq_to_level(hwirq2, 2));
|
||||||
zassert_equal(hwirq1, irq_parent_level_2(irqn));
|
zassert_equal(hwirq1, irq_parent_level_2(irqn));
|
||||||
|
zassert_equal(hwirq1, irq_parent_level(irqn, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_l3) {
|
if (has_l3) {
|
||||||
zassert_equal(hwirq3, irq_from_level_3(irqn));
|
zassert_equal(hwirq3, irq_from_level_3(irqn));
|
||||||
|
zassert_equal(hwirq3, irq_from_level(irqn, 3));
|
||||||
zassert_equal((hwirq3 + 1) << l3_shift, irq_to_level_3(hwirq3));
|
zassert_equal((hwirq3 + 1) << l3_shift, irq_to_level_3(hwirq3));
|
||||||
|
zassert_equal((hwirq3 + 1) << l3_shift, irq_to_level(hwirq3, 3));
|
||||||
zassert_equal(hwirq2 + 1, irq_parent_level_3(irqn));
|
zassert_equal(hwirq2 + 1, irq_parent_level_3(irqn));
|
||||||
|
zassert_equal(hwirq2 + 1, irq_parent_level(irqn, 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_l3) {
|
if (has_l3) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue