platform_get_irq() recieves information about device's irq ( type and irq number ) from device tree node and using this information update irq descriptor in irq_desc[] array.
Introduce dt_irq_xlate and initialize with aplic_irq_xlate() as it is used by dt_device_get_irq() which is called by platform_get_irq(). Co-developed-by: Romain Caritey <romain.cari...@microchip.com> Signed-off-by: Oleksii Kurochko <oleksii.kuroc...@gmail.com> --- xen/arch/riscv/aplic.c | 19 +++++++++++++++ xen/arch/riscv/include/asm/irq.h | 3 +++ xen/arch/riscv/irq.c | 41 ++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/xen/arch/riscv/aplic.c b/xen/arch/riscv/aplic.c index caba8f8993..6dc040af6f 100644 --- a/xen/arch/riscv/aplic.c +++ b/xen/arch/riscv/aplic.c @@ -11,6 +11,7 @@ #include <xen/errno.h> #include <xen/init.h> +#include <xen/irq.h> #include <xen/sections.h> #include <xen/types.h> @@ -21,6 +22,22 @@ static struct intc_info __ro_after_init aplic_info = { .hw_version = INTC_APLIC, }; +static int aplic_irq_xlate(const uint32_t *intspec, unsigned int intsize, + unsigned int *out_hwirq, + unsigned int *out_type) +{ + if ( intsize < 2 ) + return -EINVAL; + + /* Mapping 1:1 */ + *out_hwirq = intspec[0]; + + if ( out_type ) + *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK; + + return 0; +} + static int __init aplic_preinit(struct dt_device_node *node, const void *dat) { if ( aplic_info.node ) @@ -35,6 +52,8 @@ static int __init aplic_preinit(struct dt_device_node *node, const void *dat) aplic_info.node = node; + dt_irq_xlate = aplic_irq_xlate; + return 0; } diff --git a/xen/arch/riscv/include/asm/irq.h b/xen/arch/riscv/include/asm/irq.h index 8f936b7d01..ff1c95e0be 100644 --- a/xen/arch/riscv/include/asm/irq.h +++ b/xen/arch/riscv/include/asm/irq.h @@ -47,6 +47,9 @@ static inline void arch_move_irqs(struct vcpu *v) BUG_ON("unimplemented"); } +struct dt_device_node; +int platform_get_irq(const struct dt_device_node *device, int index); + void init_IRQ(void); #endif /* ASM__RISCV__IRQ_H */ diff --git a/xen/arch/riscv/irq.c b/xen/arch/riscv/irq.c index 99b8f2095e..c332e000c4 100644 --- a/xen/arch/riscv/irq.c +++ b/xen/arch/riscv/irq.c @@ -7,11 +7,52 @@ */ #include <xen/bug.h> +#include <xen/device_tree.h> +#include <xen/errno.h> #include <xen/init.h> #include <xen/irq.h> static irq_desc_t irq_desc[NR_IRQS]; +static bool irq_validate_new_type(unsigned int curr, unsigned int new) +{ + return (curr == IRQ_TYPE_INVALID || curr == new ); +} + +static int irq_set_type(unsigned int irq, unsigned int type) +{ + unsigned long flags; + struct irq_desc *desc = irq_to_desc(irq); + int ret = -EBUSY; + + spin_lock_irqsave(&desc->lock, flags); + + if ( !irq_validate_new_type(desc->arch.type, type) ) + goto err; + + desc->arch.type = type; + + ret = 0; + +err: + spin_unlock_irqrestore(&desc->lock, flags); + + return ret; +} + +int platform_get_irq(const struct dt_device_node *device, int index) +{ + struct dt_irq dt_irq; + + if ( dt_device_get_irq(device, index, &dt_irq) ) + return -1; + + if ( irq_set_type(dt_irq.irq, dt_irq.type) ) + return -1; + + return dt_irq.irq; +} + int arch_init_one_irq_desc(struct irq_desc *desc) { desc->arch.type = IRQ_TYPE_INVALID; -- 2.49.0