From 254056f3b12563c11e6dbcfad2fbfce20a4f3302 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 10 Feb 2011 12:54:10 -0800 Subject: ARM: gic: Use cpu pm notifiers to save gic state When the cpu is powered down in a low power mode, the gic cpu interface may be reset, and when the cpu cluster is powered down, the gic distributor may also be reset. This patch uses CPU_PM_ENTER and CPU_PM_EXIT notifiers to save and restore the gic cpu interface registers, and the CPU_CLUSTER_PM_ENTER and CPU_CLUSTER_PM_EXIT notifiers to save and restore the gic distributor registers. Original-author: Gary King Signed-off-by: Colin Cross Signed-off-by: Santosh Shilimkar Tested-and-Acked-by: Shawn Guo Tested-by: Vishwanath BS --- arch/arm/include/asm/hardware/gic.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch/arm/include/asm/hardware') diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h index 435d3f86c708..c5627057b1c7 100644 --- a/arch/arm/include/asm/hardware/gic.h +++ b/arch/arm/include/asm/hardware/gic.h @@ -46,6 +46,14 @@ struct gic_chip_data { unsigned int irq_offset; 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 + unsigned int gic_irqs; }; #endif -- cgit v1.2.1 From 292b293ceef2eda1f96f0c90b96e954d7bdabd1c Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Wed, 20 Jul 2011 16:24:14 +0100 Subject: ARM: gic: consolidate PPI handling PPI handling is a bit of an odd beast. It uses its own low level handling code and is hardwired to the local timers (hence lacking a registration interface). Instead, switch the low handling to the normal SPI handling code. PPIs are handled by the handle_percpu_devid_irq flow. This also allows the removal of some duplicated code. Cc: Kukjin Kim Cc: David Brown Cc: Bryan Huntsman Cc: Tony Lindgren Cc: Paul Mundt Cc: Magnus Damm Cc: Thomas Gleixner Acked-by: David Brown Tested-by: David Brown Tested-by: Shawn Guo Signed-off-by: Marc Zyngier --- arch/arm/include/asm/hardware/entry-macro-gic.S | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) (limited to 'arch/arm/include/asm/hardware') diff --git a/arch/arm/include/asm/hardware/entry-macro-gic.S b/arch/arm/include/asm/hardware/entry-macro-gic.S index c115b82fe80a..74ebc803904d 100644 --- a/arch/arm/include/asm/hardware/entry-macro-gic.S +++ b/arch/arm/include/asm/hardware/entry-macro-gic.S @@ -22,15 +22,11 @@ * interrupt controller spec. To wit: * * Interrupts 0-15 are IPI - * 16-28 are reserved - * 29-31 are local. We allow 30 to be used for the watchdog. + * 16-31 are local. We allow 30 to be used for the watchdog. * 32-1020 are global * 1021-1022 are reserved * 1023 is "spurious" (no interrupt) * - * For now, we ignore all local interrupts so only return an interrupt if it's - * between 30 and 1020. The test_for_ipi routine below will pick up on IPIs. - * * A simple read from the controller will tell us the number of the highest * priority enabled interrupt. We then just need to check whether it is in the * valid range for an IRQ (30-1020 inclusive). @@ -43,7 +39,7 @@ ldr \tmp, =1021 bic \irqnr, \irqstat, #0x1c00 - cmp \irqnr, #29 + cmp \irqnr, #15 cmpcc \irqnr, \irqnr cmpne \irqnr, \tmp cmpcs \irqnr, \irqnr @@ -62,14 +58,3 @@ strcc \irqstat, [\base, #GIC_CPU_EOI] cmpcs \irqnr, \irqnr .endm - -/* As above, this assumes that irqstat and base are preserved.. */ - - .macro test_for_ltirq, irqnr, irqstat, base, tmp - bic \irqnr, \irqstat, #0x1c00 - mov \tmp, #0 - cmp \irqnr, #29 - moveq \tmp, #1 - streq \irqstat, [\base, #GIC_CPU_EOI] - cmp \tmp, #0 - .endm -- cgit v1.2.1 From 28af690a284dfcb627bd69d0963db1c0f412cb8c Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Fri, 22 Jul 2011 12:52:37 +0100 Subject: ARM: gic, local timers: use the request_percpu_irq() interface This patch remove the hardcoded link between local timers and PPIs, and convert the PPI users (TWD, MCT and MSM timers) to the new *_percpu_irq interface. Also some collateral cleanup (local_timer_ack() is gone, and the interrupt handler is strictly private to each driver). PPIs are now useable for more than just the local timers. Additional testing by David Brown (msm8250 and msm8660) and Shawn Guo (imx6q). Cc: David Brown Cc: Thomas Gleixner Acked-by: David Brown Tested-by: David Brown Tested-by: Shawn Guo Signed-off-by: Marc Zyngier --- arch/arm/include/asm/hardware/gic.h | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/arm/include/asm/hardware') diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h index 435d3f86c708..2dadd50a77d2 100644 --- a/arch/arm/include/asm/hardware/gic.h +++ b/arch/arm/include/asm/hardware/gic.h @@ -40,7 +40,6 @@ void gic_init(unsigned int, unsigned int, void __iomem *, void __iomem *); 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); -void gic_enable_ppi(unsigned int); struct gic_chip_data { unsigned int irq_offset; -- cgit v1.2.1 From 4294f8baaf174c9aa57886e7ed27caf4b02578f6 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 28 Sep 2011 21:25:31 -0500 Subject: ARM: gic: add irq_domain support Convert the gic interrupt controller to use irq domains in preparation for device-tree binding and MULTI_IRQ. This allows for translation between GIC interrupt IDs and Linux irq numbers. The meaning of irq_offset has changed. It now is just the number of skipped GIC interrupt IDs for the controller. It will be 16 for primary GIC and 32 for secondary GICs. Signed-off-by: Rob Herring Cc: Marc Zyngier Reviewed-by: Jamie Iles Tested-by: Thomas Abraham Acked-by: Grant Likely --- arch/arm/include/asm/hardware/gic.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'arch/arm/include/asm/hardware') diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h index 14867e12f205..43a05d90e43b 100644 --- a/arch/arm/include/asm/hardware/gic.h +++ b/arch/arm/include/asm/hardware/gic.h @@ -33,6 +33,9 @@ #define GIC_DIST_SOFTINT 0xf00 #ifndef __ASSEMBLY__ +#include +struct device_node; + extern void __iomem *gic_cpu_base_addr; extern struct irq_chip gic_arch_extn; @@ -42,7 +45,6 @@ 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 { - unsigned int irq_offset; void __iomem *dist_base; void __iomem *cpu_base; #ifdef CONFIG_CPU_PM @@ -51,6 +53,9 @@ struct gic_chip_data { 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; }; -- cgit v1.2.1 From b3f7ed0324091e2cb23fe1b3c10570700f614014 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 28 Sep 2011 21:27:52 -0500 Subject: ARM: gic: add OF based initialization This adds ARM gic interrupt controller initialization using device tree data. The initialization function is intended to be called by of_irq_init function like this: const static struct of_device_id irq_match[] = { { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, }, {} }; static void __init init_irqs(void) { of_irq_init(irq_match); } Signed-off-by: Rob Herring Reviewed-by: Jamie Iles Tested-by: Thomas Abraham Acked-by: Grant Likely --- arch/arm/include/asm/hardware/gic.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/arm/include/asm/hardware') diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h index 43a05d90e43b..0a026b9290f2 100644 --- a/arch/arm/include/asm/hardware/gic.h +++ b/arch/arm/include/asm/hardware/gic.h @@ -40,6 +40,7 @@ extern void __iomem *gic_cpu_base_addr; extern struct irq_chip gic_arch_extn; void gic_init(unsigned int, unsigned int, void __iomem *, void __iomem *); +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); -- cgit v1.2.1 From f37a53cc5d8a8fb199e41386d125d8c2ed9e54ef Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 21 Oct 2011 17:14:27 -0500 Subject: ARM: gic: fix irq_alloc_descs handling for sparse irq Commit "ARM: gic: add irq_domain support" (b49b6ff) breaks SPARSE_IRQ on platforms with GIC. When SPARSE_IRQ is enabled, all NR_IRQS or mach_desc->nr_irqs will be allocated by arch_probe_nr_irqs(). This caused irq_alloc_descs to allocate irq_descs after the pre-allocated space. Make irq_alloc_descs search for an exact irq range and assume it has been pre-allocated on failure. For DT probing dynamic allocation is used. DT enabled platforms should set their nr_irqs to NR_IRQ_LEGACY and have all irq_chips allocate their irq_descs with irq_alloc_descs if SPARSE_IRQ is enabled. gic_init irq_start param is changed to be signed with negative meaning do dynamic Linux irq assigment. Signed-off-by: Rob Herring --- arch/arm/include/asm/hardware/gic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm/include/asm/hardware') diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h index 0a026b9290f2..3e91f22046f5 100644 --- a/arch/arm/include/asm/hardware/gic.h +++ b/arch/arm/include/asm/hardware/gic.h @@ -39,7 +39,7 @@ struct device_node; extern void __iomem *gic_cpu_base_addr; extern struct irq_chip gic_arch_extn; -void gic_init(unsigned int, unsigned int, void __iomem *, void __iomem *); +void gic_init(unsigned int, int, void __iomem *, void __iomem *); 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); -- cgit v1.2.1