[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v3 16/25] arm: irq
From: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> A simple do_IRQ and request_irq implementation for ARM. Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx> Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxx> --- xen/arch/arm/irq.c | 179 +++++++++++++++++++++++++++++++++++++++++++ xen/include/asm-arm/irq.h | 30 +++++++ xen/include/asm-arm/setup.h | 2 + xen/include/xen/irq.h | 13 +++ 4 files changed, 224 insertions(+), 0 deletions(-) create mode 100644 xen/arch/arm/irq.c create mode 100644 xen/include/asm-arm/irq.h diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c new file mode 100644 index 0000000..5663762 --- /dev/null +++ b/xen/arch/arm/irq.c @@ -0,0 +1,179 @@ +/* + * xen/arch/arm/irq.c + * + * ARM Interrupt support + * + * Ian Campbell <ian.campbell@xxxxxxxxxx> + * Copyright (c) 2011 Citrix Systems. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <xen/config.h> +#include <xen/lib.h> +#include <xen/spinlock.h> +#include <xen/irq.h> +#include <xen/init.h> +#include <xen/errno.h> +#include <xen/sched.h> + +#include "gic.h" + +static void enable_none(struct irq_desc *irq) { } +static unsigned int startup_none(struct irq_desc *irq) { return 0; } +static void disable_none(struct irq_desc *irq) { } +static void ack_none(struct irq_desc *irq) +{ + printk("unexpected IRQ trap at irq %02x\n", irq->irq); +} + +#define shutdown_none disable_none +#define end_none enable_none + +hw_irq_controller no_irq_type = { + .typename = "none", + .startup = startup_none, + .shutdown = shutdown_none, + .enable = enable_none, + .disable = disable_none, + .ack = ack_none, + .end = end_none +}; + +int __init arch_init_one_irq_desc(struct irq_desc *desc) +{ + return 0; +} + + +static int __init init_irq_data(void) +{ + int irq; + + for (irq = 0; irq < NR_IRQS; irq++) { + struct irq_desc *desc = irq_to_desc(irq); + init_one_irq_desc(desc); + desc->irq = irq; + desc->action = NULL; + } + return 0; +} + +void __init init_IRQ(void) +{ + BUG_ON(init_irq_data() < 0); +} + +int __init request_irq(unsigned int irq, + void (*handler)(int, void *, struct cpu_user_regs *), + unsigned long irqflags, const char * devname, void *dev_id) +{ + struct irqaction *action; + int retval; + + /* + * Sanity-check: shared interrupts must pass in a real dev-ID, + * otherwise we'll have trouble later trying to figure out + * which interrupt is which (messes up the interrupt freeing + * logic etc). + */ + if (irq >= nr_irqs) + return -EINVAL; + if (!handler) + return -EINVAL; + + action = xmalloc(struct irqaction); + if (!action) + return -ENOMEM; + + action->handler = handler; + action->name = devname; + action->dev_id = dev_id; + action->free_on_release = 1; + + retval = setup_irq(irq, action); + if (retval) + xfree(action); + + return retval; +} + +/* Dispatch an interrupt */ +void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, int is_fiq) +{ + struct irq_desc *desc = irq_to_desc(irq); + struct irqaction *action = desc->action; + + /* TODO: perfc_incr(irqs); */ + + /* TODO: this_cpu(irq_count)++; */ + + irq_enter(); + + spin_lock(&desc->lock); + desc->handler->ack(desc); + + if ( action == NULL ) + { + printk("Unknown %s %#3.3x\n", + is_fiq ? "FIQ" : "IRQ", irq); + goto out; + } + + if ( desc->status & IRQ_GUEST ) + { + struct domain *d = action->dev_id; + + desc->handler->end(desc); + + desc->status |= IRQ_INPROGRESS; + + /* XXX: inject irq into the guest */ + goto out_no_end; + } + + desc->status |= IRQ_PENDING; + + /* + * Since we set PENDING, if another processor is handling a different + * instance of this same irq, the other processor will take care of it. + */ + if ( desc->status & (IRQ_DISABLED | IRQ_INPROGRESS) ) + goto out; + + desc->status |= IRQ_INPROGRESS; + + action = desc->action; + while ( desc->status & IRQ_PENDING ) + { + desc->status &= ~IRQ_PENDING; + spin_unlock_irq(&desc->lock); + action->handler(irq, action->dev_id, regs); + spin_lock_irq(&desc->lock); + } + + desc->status &= ~IRQ_INPROGRESS; + +out: + desc->handler->end(desc); +out_no_end: + spin_unlock(&desc->lock); + irq_exit(); +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/asm-arm/irq.h b/xen/include/asm-arm/irq.h new file mode 100644 index 0000000..8e65a2e --- /dev/null +++ b/xen/include/asm-arm/irq.h @@ -0,0 +1,30 @@ +#ifndef _ASM_HW_IRQ_H +#define _ASM_HW_IRQ_H + +#include <xen/config.h> + +#define NR_VECTORS 256 /* XXX */ + +typedef struct { + DECLARE_BITMAP(_bits,NR_VECTORS); +} vmask_t; + +struct arch_pirq +{ +}; + +struct irq_cfg { +#define arch_irq_desc irq_cfg +}; + +void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, int is_fiq); + +#endif /* _ASM_HW_IRQ_H */ +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/asm-arm/setup.h b/xen/include/asm-arm/setup.h index 1dc3f97..2041f06 100644 --- a/xen/include/asm-arm/setup.h +++ b/xen/include/asm-arm/setup.h @@ -7,6 +7,8 @@ void arch_get_xen_caps(xen_capabilities_info_t *info); int construct_dom0(struct domain *d); +void init_IRQ(void); + #endif /* * Local variables: diff --git a/xen/include/xen/irq.h b/xen/include/xen/irq.h index a2a90e1..5a711cc 100644 --- a/xen/include/xen/irq.h +++ b/xen/include/xen/irq.h @@ -107,6 +107,19 @@ extern irq_desc_t irq_desc[NR_VECTORS]; #define request_irq(irq, handler, irqflags, devname, devid) \ request_irq_vector(irq_to_vector(irq), handler, irqflags, devname, devid) + +#elif defined(__arm__) + +#define NR_IRQS 1024 +#define nr_irqs NR_IRQS +extern irq_desc_t irq_desc[NR_IRQS]; + +extern int setup_irq(unsigned int irq, struct irqaction *); +extern void release_irq(unsigned int irq); +extern int request_irq(unsigned int irq, + void (*handler)(int, void *, struct cpu_user_regs *), + unsigned long irqflags, const char * devname, void *dev_id); + #else extern int setup_irq(unsigned int irq, struct irqaction *); extern void release_irq(unsigned int irq); -- 1.7.2.5 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |