X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Farm%2Fcommon%2Fgic.c;h=09b9d1b6844c05315dc50af6e0ea0ffacdfad725;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=c02dc8116a18ef5facc08dbf61655c0144cfdaec;hpb=76828883507a47dae78837ab5dec5a5b4513c667;p=linux-2.6.git diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index c02dc8116..09b9d1b68 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c @@ -33,6 +33,7 @@ static void __iomem *gic_dist_base; static void __iomem *gic_cpu_base; +static DEFINE_SPINLOCK(irq_controller_lock); /* * Routines to acknowledge, disable and enable interrupts @@ -52,41 +53,55 @@ static void __iomem *gic_cpu_base; static void gic_ack_irq(unsigned int irq) { u32 mask = 1 << (irq % 32); + + spin_lock(&irq_controller_lock); writel(mask, gic_dist_base + GIC_DIST_ENABLE_CLEAR + (irq / 32) * 4); writel(irq, gic_cpu_base + GIC_CPU_EOI); + spin_unlock(&irq_controller_lock); } static void gic_mask_irq(unsigned int irq) { u32 mask = 1 << (irq % 32); + + spin_lock(&irq_controller_lock); writel(mask, gic_dist_base + GIC_DIST_ENABLE_CLEAR + (irq / 32) * 4); + spin_unlock(&irq_controller_lock); } static void gic_unmask_irq(unsigned int irq) { u32 mask = 1 << (irq % 32); + + spin_lock(&irq_controller_lock); writel(mask, gic_dist_base + GIC_DIST_ENABLE_SET + (irq / 32) * 4); + spin_unlock(&irq_controller_lock); } #ifdef CONFIG_SMP -static void gic_set_cpu(struct irqdesc *desc, unsigned int irq, unsigned int cpu) +static void gic_set_cpu(unsigned int irq, cpumask_t mask_val) { void __iomem *reg = gic_dist_base + GIC_DIST_TARGET + (irq & ~3); unsigned int shift = (irq % 4) * 8; + unsigned int cpu = first_cpu(mask_val); u32 val; + spin_lock(&irq_controller_lock); + irq_desc[irq].cpu = cpu; val = readl(reg) & ~(0xff << shift); val |= 1 << (cpu + shift); writel(val, reg); + spin_unlock(&irq_controller_lock); } #endif -static struct irqchip gic_chip = { +static struct irq_chip gic_chip = { + .name = "GIC", .ack = gic_ack_irq, .mask = gic_mask_irq, .unmask = gic_unmask_irq, #ifdef CONFIG_SMP - .set_cpu = gic_set_cpu, + .set_affinity = gic_set_cpu, #endif }; @@ -145,7 +160,7 @@ void __init gic_dist_init(void __iomem *base) */ for (i = 29; i < max_irq; i++) { set_irq_chip(i, &gic_chip); - set_irq_handler(i, do_level_IRQ); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); }