aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/include/asm/hardware
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2011-11-12 16:09:49 +0000
committerMarc Zyngier <marc.zyngier@arm.com>2011-11-15 18:13:03 +0000
commitdb0d4db22a78d31c59087f7057b8f1612fecc35d (patch)
treee2d84ee2c816d4bef066806863a3937792a08581 /arch/arm/include/asm/hardware
parentcfcfc9eca2bcbd26a8e206baeb005b055dbf8e37 (diff)
ARM: gic: allow GIC to support non-banked setups
The GIC support code is heavily using the fact that hardware implementations are exposing banked registers. Unfortunately, it looks like at least one GIC implementation (EXYNOS) offers both the distributor and the CPU interfaces at different addresses, depending on the CPU. This problem is solved by allowing the distributor and CPU interface addresses to be per-cpu variables for the platforms that require it. The EXYNOS code is updated not to mess with the GIC internals while handling interrupts, and struct gic_chip_data is back to being private. The DT binding for the gic is updated to allow an optional "cpu-offset" value, which is used to compute the various base addresses. Finally, a new config option (GIC_NON_BANKED) is used to control this feature, so the overhead is only present on kernels compiled with support for EXYNOS. Tested on Origen (EXYNOS4) and Panda (OMAP4). Cc: Kukjin Kim <kgene.kim@samsung.com> Cc: Will Deacon <will.deacon@arm.com> Cc: Thomas Abraham <thomas.abraham@linaro.org> Acked-by: Rob Herring <rob.herring@calxeda.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'arch/arm/include/asm/hardware')
-rw-r--r--arch/arm/include/asm/hardware/gic.h24
1 files changed, 8 insertions, 16 deletions
diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
index 3e91f22046f..2721d90625e 100644
--- a/arch/arm/include/asm/hardware/gic.h
+++ b/arch/arm/include/asm/hardware/gic.h
@@ -39,27 +39,19 @@ struct device_node;
extern void __iomem *gic_cpu_base_addr;
extern struct irq_chip gic_arch_extn;
-void gic_init(unsigned int, int, void __iomem *, void __iomem *);
+void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *,
+ u32 offset);
int gic_of_init(struct device_node *node, struct device_node *parent);
void gic_secondary_init(unsigned int);
void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
-struct gic_chip_data {
- void __iomem *dist_base;
- void __iomem *cpu_base;
-#ifdef CONFIG_CPU_PM
- u32 saved_spi_enable[DIV_ROUND_UP(1020, 32)];
- u32 saved_spi_conf[DIV_ROUND_UP(1020, 16)];
- u32 saved_spi_target[DIV_ROUND_UP(1020, 4)];
- u32 __percpu *saved_ppi_enable;
- u32 __percpu *saved_ppi_conf;
-#endif
-#ifdef CONFIG_IRQ_DOMAIN
- struct irq_domain domain;
-#endif
- unsigned int gic_irqs;
-};
+static inline void gic_init(unsigned int nr, int start,
+ void __iomem *dist , void __iomem *cpu)
+{
+ gic_init_bases(nr, start, dist, cpu, 0);
+}
+
#endif
#endif