···1414 *1515 * o There is one CPU Interface per CPU, which sends interrupts sent1616 * by the Distributor, and interrupts generated locally, to the1717- * associated CPU.1717+ * associated CPU. The base address of the CPU interface is usually1818+ * aliased so that the same address points to different chips depending1919+ * on the CPU it is accessed from.1820 *1921 * Note that IRQs 0-31 are special - they are local to each CPU.2022 * As such, the enable set/clear, pending set/clear and active bit···3331#include <asm/mach/irq.h>3432#include <asm/hardware/gic.h>35333636-static void __iomem *gic_dist_base;3737-static void __iomem *gic_cpu_base;3834static DEFINE_SPINLOCK(irq_controller_lock);3535+3636+struct gic_chip_data {3737+ unsigned int irq_offset;3838+ void __iomem *dist_base;3939+ void __iomem *cpu_base;4040+};4141+4242+#ifndef MAX_GIC_NR4343+#define MAX_GIC_NR 14444+#endif4545+4646+static struct gic_chip_data gic_data[MAX_GIC_NR];4747+4848+static inline void __iomem *gic_dist_base(unsigned int irq)4949+{5050+ struct gic_chip_data *gic_data = get_irq_chip_data(irq);5151+ return gic_data->dist_base;5252+}5353+5454+static inline void __iomem *gic_cpu_base(unsigned int irq)5555+{5656+ struct gic_chip_data *gic_data = get_irq_chip_data(irq);5757+ return gic_data->cpu_base;5858+}5959+6060+static inline unsigned int gic_irq(unsigned int irq)6161+{6262+ struct gic_chip_data *gic_data = get_irq_chip_data(irq);6363+ return irq - gic_data->irq_offset;6464+}39654066/*4167 * Routines to acknowledge, disable and enable interrupts···8555 u32 mask = 1 << (irq % 32);86568757 spin_lock(&irq_controller_lock);8888- writel(mask, gic_dist_base + GIC_DIST_ENABLE_CLEAR + (irq / 32) * 4);8989- writel(irq, gic_cpu_base + GIC_CPU_EOI);5858+ writel(mask, gic_dist_base(irq) + GIC_DIST_ENABLE_CLEAR + (gic_irq(irq) / 32) * 4);5959+ writel(gic_irq(irq), gic_cpu_base(irq) + GIC_CPU_EOI);9060 spin_unlock(&irq_controller_lock);9161}9262···9565 u32 mask = 1 << (irq % 32);96669767 spin_lock(&irq_controller_lock);9898- writel(mask, gic_dist_base + GIC_DIST_ENABLE_CLEAR + (irq / 32) * 4);6868+ writel(mask, gic_dist_base(irq) + GIC_DIST_ENABLE_CLEAR + (gic_irq(irq) / 32) * 4);9969 spin_unlock(&irq_controller_lock);10070}10171···10474 u32 mask = 1 << (irq % 32);1057510676 spin_lock(&irq_controller_lock);107107- writel(mask, gic_dist_base + GIC_DIST_ENABLE_SET + (irq / 32) * 4);7777+ writel(mask, gic_dist_base(irq) + GIC_DIST_ENABLE_SET + (gic_irq(irq) / 32) * 4);10878 spin_unlock(&irq_controller_lock);10979}1108011181#ifdef CONFIG_SMP11282static void gic_set_cpu(unsigned int irq, cpumask_t mask_val)11383{114114- void __iomem *reg = gic_dist_base + GIC_DIST_TARGET + (irq & ~3);8484+ void __iomem *reg = gic_dist_base(irq) + GIC_DIST_TARGET + (gic_irq(irq) & ~3);11585 unsigned int shift = (irq % 4) * 8;11686 unsigned int cpu = first_cpu(mask_val);11787 u32 val;···12595}12696#endif127979898+static void fastcall gic_handle_cascade_irq(unsigned int irq,9999+ struct irq_desc *desc)100100+{101101+ struct gic_chip_data *chip_data = get_irq_data(irq);102102+ struct irq_chip *chip = get_irq_chip(irq);103103+ unsigned int cascade_irq;104104+ unsigned long status;105105+106106+ /* primary controller ack'ing */107107+ chip->ack(irq);108108+109109+ spin_lock(&irq_controller_lock);110110+ status = readl(chip_data->cpu_base + GIC_CPU_INTACK);111111+ spin_unlock(&irq_controller_lock);112112+113113+ cascade_irq = (status & 0x3ff);114114+ if (cascade_irq > 1020)115115+ goto out;116116+ if (cascade_irq < 32 || cascade_irq >= NR_IRQS) {117117+ do_bad_IRQ(cascade_irq, desc);118118+ goto out;119119+ }120120+121121+ cascade_irq += chip_data->irq_offset;122122+ generic_handle_irq(cascade_irq);123123+124124+ out:125125+ /* primary controller unmasking */126126+ chip->unmask(irq);127127+}128128+128129static struct irq_chip gic_chip = {129130 .name = "GIC",130131 .ack = gic_ack_irq,···166105#endif167106};168107169169-void __init gic_dist_init(void __iomem *base)108108+void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)109109+{110110+ if (gic_nr >= MAX_GIC_NR)111111+ BUG();112112+ if (set_irq_data(irq, &gic_data[gic_nr]) != 0)113113+ BUG();114114+ set_irq_chained_handler(irq, gic_handle_cascade_irq);115115+}116116+117117+void __init gic_dist_init(unsigned int gic_nr, void __iomem *base,118118+ unsigned int irq_start)170119{171120 unsigned int max_irq, i;172121 u32 cpumask = 1 << smp_processor_id();173122123123+ if (gic_nr >= MAX_GIC_NR)124124+ BUG();125125+174126 cpumask |= cpumask << 8;175127 cpumask |= cpumask << 16;176128177177- gic_dist_base = base;129129+ gic_data[gic_nr].dist_base = base;130130+ gic_data[gic_nr].irq_offset = (irq_start - 1) & ~31;178131179132 writel(0, base + GIC_DIST_CTRL);180133···233158 /*234159 * Setup the Linux IRQ subsystem.235160 */236236- for (i = 29; i < max_irq; i++) {161161+ for (i = irq_start; i < gic_data[gic_nr].irq_offset + max_irq; i++) {237162 set_irq_chip(i, &gic_chip);163163+ set_irq_chip_data(i, &gic_data[gic_nr]);238164 set_irq_handler(i, handle_level_irq);239165 set_irq_flags(i, IRQF_VALID | IRQF_PROBE);240166 }···243167 writel(1, base + GIC_DIST_CTRL);244168}245169246246-void __cpuinit gic_cpu_init(void __iomem *base)170170+void __cpuinit gic_cpu_init(unsigned int gic_nr, void __iomem *base)247171{248248- gic_cpu_base = base;172172+ if (gic_nr >= MAX_GIC_NR)173173+ BUG();174174+175175+ gic_data[gic_nr].cpu_base = base;176176+249177 writel(0xf0, base + GIC_CPU_PRIMASK);250178 writel(1, base + GIC_CPU_CTRL);251179}···259179{260180 unsigned long map = *cpus_addr(cpumask);261181262262- writel(map << 16 | irq, gic_dist_base + GIC_DIST_SOFTINT);182182+ /* this always happens on GIC0 */183183+ writel(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT);263184}264185#endif
+10
arch/arm/mach-realview/Kconfig
···1616 kernel built with this option enabled is not compatible with1717 other tiles.18181919+config REALVIEW_MPCORE_REVB2020+ bool "Support MPcore RevB tile"2121+ depends on REALVIEW_MPCORE2222+ default n2323+ help2424+ Enable support for the MPCore RevB tile on the Realview platform.2525+ Since there are device address differences, a2626+ kernel built with this option enabled is not compatible with2727+ other tiles.2828+1929endmenu
+1-1
arch/arm/mach-realview/platsmp.c
···5252 * core (e.g. timer irq), then they will not have been enabled5353 * for us: do so5454 */5555- gic_cpu_init(__io_address(REALVIEW_GIC_CPU_BASE));5555+ gic_cpu_init(0, __io_address(REALVIEW_GIC_CPU_BASE));56565757 /*5858 * let the primary processor know we're out of the