linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 00/12] Consolidating GIC per-cpu interrupts
@ 2011-04-20 19:08 Marc Zyngier
  2011-04-20 19:08 ` [RFC PATCH 01/12] ARM: gic: add per-cpu interrupt multiplexer Marc Zyngier
                   ` (11 more replies)
  0 siblings, 12 replies; 32+ messages in thread
From: Marc Zyngier @ 2011-04-20 19:08 UTC (permalink / raw)
  To: linux-arm-kernel

The current GIC per-cpu interrupt (aka PPIs) suffers from a number of
problems:

- It uses a completely separate scheme to handle the interrupts,
  mostly because the PPI concept doesn't really match the kernel view
  of an interrupt.
- Some low-level code gets duplicated, as usual...
- At least one platform (msm) has started implementing its own
  alternative scheme.

The proposed solution is to let the GIC code expose the PPIs as
something that the kernel can manage. Instead of having a single
interrupt number shared on all cores, make the interrupt number be
different on each CPU.

This enables the use of the normal kernel API (request_irq() and
friends) and the elimination of some low level code.

This patch set is based on 2.6.39-rc4, and depends on Will Deacon's
GIC fasteoi patches. Tested on VExpress, PB-11MP, Pandaboard and
SMDK-S5PV310.

Marc Zyngier (12):
  ARM: gic: add per-cpu interrupt multiplexer
  ARM: smp_twd: add support for remapped PPI interrupts
  ARM: omap4: use remapped PPI interrupts for local timer
  ARM: versatile: use remapped PPI interrupts for local timer
  ARM: shmobile: use remapped PPI interrupts for local timer
  ARM: ux500: use remapped PPI interrupts for local timer
  ARM: tegra: use remapped PPI interrupts for local timer
  ARM: msm: use remapped PPI interrupts for local timer
  ARM: exynos4: use remapped PPI interrupts for local timer
  ARM: gic: remove previous local timer interrupt handling
  ARM: gic: add compute_irqnr macro for exynos4
  ARM: SMP: automatically select ARM_GIC_VPPI

 arch/arm/Kconfig                                  |    1 +
 arch/arm/common/Kconfig                           |    5 +
 arch/arm/common/gic.c                             |  144 ++++++++++++++++++--
 arch/arm/include/asm/entry-macro-multi.S          |    7 -
 arch/arm/include/asm/hardware/entry-macro-gic.S   |   31 ++---
 arch/arm/include/asm/hardware/gic.h               |   12 ++-
 arch/arm/include/asm/localtimer.h                 |    7 +-
 arch/arm/kernel/irq.c                             |    8 +-
 arch/arm/kernel/smp.c                             |    9 +-
 arch/arm/kernel/smp_twd.c                         |   15 ++-
 arch/arm/mach-exynos4/include/mach/entry-macro.S  |   70 +---------
 arch/arm/mach-exynos4/localtimer.c                |    3 +-
 arch/arm/mach-msm/include/mach/entry-macro-qgic.S |   73 +----------
 arch/arm/mach-msm/timer.c                         |   38 +++---
 arch/arm/mach-omap2/include/mach/entry-macro.S    |   14 +--
 arch/arm/mach-omap2/timer-mpu.c                   |    3 +-
 arch/arm/mach-shmobile/entry-intc.S               |    3 -
 arch/arm/mach-shmobile/include/mach/entry-macro.S |    3 -
 arch/arm/mach-shmobile/localtimer.c               |    3 +-
 arch/arm/mach-tegra/localtimer.c                  |    3 +-
 arch/arm/mach-ux500/localtimer.c                  |    3 +-
 arch/arm/plat-versatile/localtimer.c              |    3 +-
 22 files changed, 223 insertions(+), 235 deletions(-)

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [RFC PATCH 01/12] ARM: gic: add per-cpu interrupt multiplexer
  2011-04-20 19:08 [RFC PATCH 00/12] Consolidating GIC per-cpu interrupts Marc Zyngier
@ 2011-04-20 19:08 ` Marc Zyngier
  2011-04-25 20:17   ` Abhijeet Dharmapurikar
  2011-04-26  4:00   ` Stephen Boyd
  2011-04-20 19:08 ` [RFC PATCH 02/12] ARM: smp_twd: add support for remapped PPI interrupts Marc Zyngier
                   ` (10 subsequent siblings)
  11 siblings, 2 replies; 32+ messages in thread
From: Marc Zyngier @ 2011-04-20 19:08 UTC (permalink / raw)
  To: linux-arm-kernel

The kernel doesn't handle very well the concept of per-cpu interrupt
as implemented by the ARM architecture (the same interrupt level is
exposed on each core).

To work around the problem, add another irq_chip to handle PPIs and
remap them so that a single interrupt number is only used on a given
CPU (for example, IRQ 29 and 30 get exposed as IRQ 128 and 129 on
core 0, 130 and 131 on core 1...).

A helper function gic_ppi_to_vppi() is used to convert the PPI number
to the per-processor IRQ.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Will Deacon <will.deacon@arm.com>
---
 arch/arm/common/Kconfig             |    5 ++
 arch/arm/common/gic.c               |  134 +++++++++++++++++++++++++++++++++--
 arch/arm/include/asm/hardware/gic.h |   11 +++
 arch/arm/kernel/irq.c               |    8 ++-
 4 files changed, 152 insertions(+), 6 deletions(-)

diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
index ea5ee4d..020a531 100644
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
@@ -1,6 +1,11 @@
 config ARM_GIC
 	bool
 
+config ARM_GIC_VPPI
+	depends on ARM_GIC
+	select SPARSE_IRQ
+        bool
+
 config ARM_VIC
 	bool
 
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index e9c2ff8..60f8915 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -42,6 +42,11 @@ struct gic_chip_data {
 	unsigned int irq_offset;
 	void __iomem *dist_base;
 	void __iomem *cpu_base;
+#ifdef CONFIG_ARM_GIC_VPPI
+	int	     ppi_base;
+	int	     vppi_base;
+	u16	     nrppis;
+#endif
 };
 
 /*
@@ -262,12 +267,88 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
 	irq_set_chained_handler(irq, gic_handle_cascade_irq);
 }
 
+#ifdef CONFIG_ARM_GIC_VPPI
+unsigned int gic_ppi_to_vppi(unsigned int irq)
+{
+	struct gic_chip_data *chip_data = irq_get_chip_data(irq);
+	unsigned int vppi_irq;
+	unsigned int ppi;
+
+	WARN_ON(!chip_data->vppi_base);
+
+	ppi = irq - chip_data->ppi_base;
+	vppi_irq = ppi + chip_data->nrppis * smp_processor_id();
+	vppi_irq += chip_data->vppi_base;
+
+	return vppi_irq;
+}
+
+static void gic_handle_ppi(unsigned int irq, struct irq_desc *desc)
+{
+	unsigned int vppi_irq;
+
+	vppi_irq = gic_ppi_to_vppi(irq);
+	generic_handle_irq(vppi_irq);
+}
+
+static struct irq_data *gic_vppi_to_ppi(struct irq_data *d)
+{
+	struct gic_chip_data *chip_data = irq_data_get_irq_chip_data(d);
+	unsigned int ppi_irq;
+
+	ppi_irq = d->irq - chip_data->vppi_base - chip_data->nrppis * smp_processor_id();
+	ppi_irq += chip_data->ppi_base;
+
+	return irq_get_irq_data(ppi_irq);
+}
+
+static void gic_ppi_eoi_irq(struct irq_data *d)
+{
+	gic_eoi_irq(gic_vppi_to_ppi(d));
+}
+
+static void gic_ppi_mask_irq(struct irq_data *d)
+{
+	gic_mask_irq(gic_vppi_to_ppi(d));
+}
+
+static void gic_ppi_unmask_irq(struct irq_data *d)
+{
+	gic_unmask_irq(gic_vppi_to_ppi(d));
+}
+
+static int gic_ppi_set_type(struct irq_data *d, unsigned int type)
+{
+	return gic_set_type(gic_vppi_to_ppi(d), type);
+}
+
+static int gic_ppi_set_wake(struct irq_data *d, unsigned int on)
+{
+	return gic_set_wake(gic_vppi_to_ppi(d), on);
+}
+
+static int __init gic_irq_is_ppi(struct gic_chip_data *gic, unsigned int irq)
+{
+	return (irq >= (gic->irq_offset + 16) && irq <= (gic->irq_offset + 31));
+}
+
+static struct irq_chip gic_ppi_chip = {
+	.name			= "GIC-PPI",
+	.irq_eoi		= gic_ppi_eoi_irq,
+	.irq_mask		= gic_ppi_mask_irq,
+	.irq_unmask		= gic_ppi_unmask_irq,
+	.irq_set_type		= gic_ppi_set_type,
+	.irq_set_wake		= gic_ppi_set_wake,
+};
+#endif
+
 static void __init gic_dist_init(struct gic_chip_data *gic,
 	unsigned int irq_start)
 {
-	unsigned int gic_irqs, irq_limit, i;
+	unsigned int gic_irqs, irq_limit, i, nrvppis = 0;
 	void __iomem *base = gic->dist_base;
 	u32 cpumask = 1 << smp_processor_id();
+	u32 dist_ctr, nrcpus;
 
 	cpumask |= cpumask << 8;
 	cpumask |= cpumask << 16;
@@ -278,11 +359,32 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
 	 * Find out how many interrupts are supported.
 	 * The GIC only supports up to 1020 interrupt sources.
 	 */
-	gic_irqs = readl(base + GIC_DIST_CTR) & 0x1f;
-	gic_irqs = (gic_irqs + 1) * 32;
+	dist_ctr = readl(base + GIC_DIST_CTR);
+	gic_irqs = ((dist_ctr & 0x1f) + 1) * 32;
 	if (gic_irqs > 1020)
 		gic_irqs = 1020;
 
+	/* Find out how many CPUs are supported (8 max). */
+	nrcpus = ((dist_ctr >> 5) & 7) + 1;
+
+#ifdef CONFIG_ARM_GIC_VPPI
+	/*
+	 * Nobody would be insane enough to use PPIs on a secondary
+	 * GIC, right?
+	 */
+	if (gic == &gic_data[0]) {
+		gic->nrppis = 16 - (irq_start % 16);
+		gic->ppi_base = gic->irq_offset + 32 - gic->nrppis;
+		nrvppis = gic->nrppis * nrcpus;
+	} else {
+		gic->ppi_base = 0;
+		gic->vppi_base = 0;
+	}
+#endif
+
+	pr_info("Configuring GIC with %d sources (%d additional PPIs)\n",
+		gic_irqs, nrvppis);
+
 	/*
 	 * Set all global interrupts to be level triggered, active low.
 	 */
@@ -312,17 +414,39 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
 	 * Limit number of interrupts registered to the platform maximum
 	 */
 	irq_limit = gic->irq_offset + gic_irqs;
-	if (WARN_ON(irq_limit > NR_IRQS))
+	if (WARN_ON((irq_limit) > NR_IRQS))
 		irq_limit = NR_IRQS;
 
 	/*
 	 * Setup the Linux IRQ subsystem.
 	 */
 	for (i = irq_start; i < irq_limit; i++) {
-		irq_set_chip_and_handler(i, &gic_chip, handle_fasteoi_irq);
+#ifdef CONFIG_ARM_GIC_VPPI
+		if (nrvppis && gic_irq_is_ppi(gic, i))
+			irq_set_chip_and_handler(i, &gic_chip, gic_handle_ppi);
+		else
+#endif
+		{
+			irq_set_chip_and_handler(i, &gic_chip,
+						 handle_fasteoi_irq);
+			set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+		}
+		irq_set_chip_data(i, gic);
+	}
+
+#ifdef CONFIG_ARM_GIC_VPPI
+	if (!nrvppis)
+		goto out;
+	gic->vppi_base = irq_alloc_descs(-1, 0, nrvppis, 0);
+	if (unlikely(WARN_ON(gic->vppi_base < 0)))
+		goto out;
+	for (i = gic->vppi_base; i < (gic->vppi_base + nrvppis); i++) {
+		irq_set_chip_and_handler(i, &gic_ppi_chip, handle_fasteoi_irq);
 		irq_set_chip_data(i, gic);
 		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
 	}
+out:
+#endif
 
 	writel(1, base + GIC_DIST_CTRL);
 }
diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
index 0691f9d..9dbffed 100644
--- a/arch/arm/include/asm/hardware/gic.h
+++ b/arch/arm/include/asm/hardware/gic.h
@@ -33,6 +33,8 @@
 #define GIC_DIST_SOFTINT		0xf00
 
 #ifndef __ASSEMBLY__
+#include <linux/cpumask.h>
+
 extern void __iomem *gic_cpu_base_addr;
 extern struct irq_chip gic_arch_extn;
 
@@ -41,6 +43,15 @@ 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);
+#ifdef CONFIG_ARM_GIC_VPPI
+unsigned int gic_ppi_to_vppi(unsigned int irq);
+#else
+static inline unsigned int gic_ppi_to_vppi(unsigned int irq)
+{
+	return irq;
+}
+#endif
+
 #endif
 
 #endif
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 83bbad0..237959f 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -124,8 +124,14 @@ void __init init_IRQ(void)
 #ifdef CONFIG_SPARSE_IRQ
 int __init arch_probe_nr_irqs(void)
 {
+	int initcnt;
+
 	nr_irqs = machine_desc->nr_irqs ? machine_desc->nr_irqs : NR_IRQS;
-	return nr_irqs;
+	initcnt = nr_irqs;
+#ifdef CONFIG_ARM_GIC_VPPI
+	nr_irqs += 16 * 8;	/* 16 PPIs, 8 CPUs */
+#endif
+	return initcnt;
 }
 #endif
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 02/12] ARM: smp_twd: add support for remapped PPI interrupts
  2011-04-20 19:08 [RFC PATCH 00/12] Consolidating GIC per-cpu interrupts Marc Zyngier
  2011-04-20 19:08 ` [RFC PATCH 01/12] ARM: gic: add per-cpu interrupt multiplexer Marc Zyngier
@ 2011-04-20 19:08 ` Marc Zyngier
  2011-04-25 17:04   ` Stephen Boyd
  2011-04-20 19:08 ` [RFC PATCH 03/12] ARM: omap4: use remapped PPI interrupts for local timer Marc Zyngier
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 32+ messages in thread
From: Marc Zyngier @ 2011-04-20 19:08 UTC (permalink / raw)
  To: linux-arm-kernel

When CONFIG_ARM_GIC_VPPI is enabled, let smp_twd request interrupts
the normal way (ie using request_irq()).

This involves letting PPIs go via the same code path as SPIs and
having normal interrupt handler for the local timer code.

The previous ad-hoc code is still supported when CONFIG_ARM_GIC_VPPI
is not defined.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Will Deacon <will.deacon@arm.com>
---
 arch/arm/include/asm/entry-macro-multi.S        |    2 +-
 arch/arm/include/asm/hardware/entry-macro-gic.S |   19 ++++++++++++-------
 arch/arm/include/asm/localtimer.h               |    6 ++++++
 arch/arm/kernel/smp.c                           |   10 ++++++++++
 arch/arm/kernel/smp_twd.c                       |   16 +++++++++++++++-
 5 files changed, 44 insertions(+), 9 deletions(-)

diff --git a/arch/arm/include/asm/entry-macro-multi.S b/arch/arm/include/asm/entry-macro-multi.S
index ec0bbf7..c599795 100644
--- a/arch/arm/include/asm/entry-macro-multi.S
+++ b/arch/arm/include/asm/entry-macro-multi.S
@@ -24,7 +24,7 @@
 	adrne	lr, BSYM(1b)
 	bne	do_IPI
 
-#ifdef CONFIG_LOCAL_TIMERS
+#if defined(CONFIG_LOCAL_TIMERS) && !defined(CONFIG_ARM_GIC_VPPI)
 	test_for_ltirq r0, r6, r5, lr
 	movne	r0, sp
 	adrne	lr, BSYM(1b)
diff --git a/arch/arm/include/asm/hardware/entry-macro-gic.S b/arch/arm/include/asm/hardware/entry-macro-gic.S
index c115b82..14a3363 100644
--- a/arch/arm/include/asm/hardware/entry-macro-gic.S
+++ b/arch/arm/include/asm/hardware/entry-macro-gic.S
@@ -17,23 +17,26 @@
 	.endm
 #endif
 
+#ifdef CONFIG_ARM_GIC_VPPI
+#define DO_IRQ_BASE	16
+#else
+#define DO_IRQ_BASE	30
+#endif
+
 /*
  * The interrupt numbering scheme is defined in the
  * 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).
+ * valid range for an IRQ (30-1020 inclusive). If CONFIG_ARM_GIC_VPPI is
+ * enabled, local interrupts are handled the same way as global ones.
  */
 
 	.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
@@ -43,7 +46,7 @@
 
 	ldr	\tmp, =1021
 	bic     \irqnr, \irqstat, #0x1c00
-	cmp     \irqnr, #29
+	cmp     \irqnr, #(DO_IRQ_BASE - 1)
 	cmpcc	\irqnr, \irqnr
 	cmpne	\irqnr, \tmp
 	cmpcs	\irqnr, \irqnr
@@ -63,6 +66,7 @@
 	cmpcs	\irqnr, \irqnr
 	.endm
 
+#ifndef CONFIG_ARM_GIC_VPPI
 /* As above, this assumes that irqstat and base are preserved.. */
 
 	.macro test_for_ltirq, irqnr, irqstat, base, tmp
@@ -73,3 +77,4 @@
 	streq	\irqstat, [\base, #GIC_CPU_EOI]
 	cmp	\tmp, #0
 	.endm
+#endif
diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h
index 080d74f..bef44b3 100644
--- a/arch/arm/include/asm/localtimer.h
+++ b/arch/arm/include/asm/localtimer.h
@@ -10,6 +10,8 @@
 #ifndef __ASM_ARM_LOCALTIMER_H
 #define __ASM_ARM_LOCALTIMER_H
 
+#include <linux/interrupt.h>
+
 struct clock_event_device;
 
 /*
@@ -22,6 +24,10 @@ void percpu_timer_setup(void);
  */
 asmlinkage void do_local_timer(struct pt_regs *);
 
+/*
+ * Per-cpu timer IRQ handler
+ */
+irqreturn_t percpu_timer_handler(int irq, void *dev_id);
 
 #ifdef CONFIG_LOCAL_TIMERS
 
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 8fe05ad..64b9d81 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -452,6 +452,16 @@ asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs)
 	set_irq_regs(old_regs);
 }
 
+irqreturn_t percpu_timer_handler(int irq, void *dev_id)
+{
+	if (local_timer_ack()) {
+		ipi_timer();
+		return IRQ_HANDLED;
+	}
+
+	return IRQ_NONE;
+}
+
 void show_local_irqs(struct seq_file *p, int prec)
 {
 	unsigned int cpu;
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index 60636f4..bbb0f4d 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -15,10 +15,11 @@
 #include <linux/smp.h>
 #include <linux/jiffies.h>
 #include <linux/clockchips.h>
-#include <linux/irq.h>
+#include <linux/interrupt.h>
 #include <linux/io.h>
 
 #include <asm/smp_twd.h>
+#include <asm/localtimer.h>
 #include <asm/hardware/gic.h>
 
 /* set up by the platform code */
@@ -124,6 +125,8 @@ static void __cpuinit twd_calibrate_rate(void)
  */
 void __cpuinit twd_timer_setup(struct clock_event_device *clk)
 {
+	int err;
+
 	twd_calibrate_rate();
 
 	clk->name = "local_timer";
@@ -137,8 +140,19 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
 	clk->max_delta_ns = clockevent_delta2ns(0xffffffff, clk);
 	clk->min_delta_ns = clockevent_delta2ns(0xf, clk);
 
+#ifdef CONFIG_ARM_GIC_VPPI
+	err = request_irq(clk->irq, percpu_timer_handler,
+			  IRQF_PERCPU | IRQF_NOBALANCING | IRQF_TIMER,
+			  clk->name, clk);
+	if (err) {
+		pr_err("%s: can't register interrupt %d on cpu %d (%d)\n",
+		       clk->name, clk->irq, smp_processor_id(), err);
+		return;
+	}
+#else
 	/* Make sure our local interrupt controller has this enabled */
 	gic_enable_ppi(clk->irq);
+#endif
 
 	clockevents_register_device(clk);
 }
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 03/12] ARM: omap4: use remapped PPI interrupts for local timer
  2011-04-20 19:08 [RFC PATCH 00/12] Consolidating GIC per-cpu interrupts Marc Zyngier
  2011-04-20 19:08 ` [RFC PATCH 01/12] ARM: gic: add per-cpu interrupt multiplexer Marc Zyngier
  2011-04-20 19:08 ` [RFC PATCH 02/12] ARM: smp_twd: add support for remapped PPI interrupts Marc Zyngier
@ 2011-04-20 19:08 ` Marc Zyngier
  2011-04-29  7:24   ` Santosh Shilimkar
  2011-04-20 19:08 ` [RFC PATCH 04/12] ARM: versatile: " Marc Zyngier
                   ` (8 subsequent siblings)
  11 siblings, 1 reply; 32+ messages in thread
From: Marc Zyngier @ 2011-04-20 19:08 UTC (permalink / raw)
  To: linux-arm-kernel

Use the normal interrupt scheme for the local timers by using
a remapped PPI interrupt.

Tested on a Pandaboard.

Cc: Tony Lindgren <tony@atomide.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/mach-omap2/Kconfig                    |    1 +
 arch/arm/mach-omap2/include/mach/entry-macro.S |   14 +-------------
 arch/arm/mach-omap2/timer-mpu.c                |    3 ++-
 3 files changed, 4 insertions(+), 14 deletions(-)

diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index b997a35..8282921 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -44,6 +44,7 @@ config ARCH_OMAP4
 	depends on ARCH_OMAP2PLUS
 	select CPU_V7
 	select ARM_GIC
+	select ARM_GIC_VPPI
 	select LOCAL_TIMERS if SMP
 	select PL310_ERRATA_588369
 	select PL310_ERRATA_727915
diff --git a/arch/arm/mach-omap2/include/mach/entry-macro.S b/arch/arm/mach-omap2/include/mach/entry-macro.S
index a48690b..22d86ef 100644
--- a/arch/arm/mach-omap2/include/mach/entry-macro.S
+++ b/arch/arm/mach-omap2/include/mach/entry-macro.S
@@ -78,7 +78,7 @@
 4401:		ldr     \irqstat, [\base, #GIC_CPU_INTACK]
 		ldr     \tmp, =1021
 		bic     \irqnr, \irqstat, #0x1c00
-		cmp     \irqnr, #29
+		cmp     \irqnr, #15
 		cmpcc   \irqnr, \irqnr
 		cmpne   \irqnr, \tmp
 		cmpcs   \irqnr, \irqnr
@@ -101,18 +101,6 @@
 		it	cs
 		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
-		itt	eq
-		moveq	\tmp, #1
-		streq	\irqstat, [\base, #GIC_CPU_EOI]
-		cmp	\tmp, #0
-		.endm
 #endif	/* CONFIG_SMP */
 
 #else	/* MULTI_OMAP2 */
diff --git a/arch/arm/mach-omap2/timer-mpu.c b/arch/arm/mach-omap2/timer-mpu.c
index 31c0ac4..1fd5ca5 100644
--- a/arch/arm/mach-omap2/timer-mpu.c
+++ b/arch/arm/mach-omap2/timer-mpu.c
@@ -22,6 +22,7 @@
 #include <asm/irq.h>
 #include <asm/smp_twd.h>
 #include <asm/localtimer.h>
+#include <asm/hardware/gic.h>
 
 /*
  * Setup the local clock events for a CPU.
@@ -32,7 +33,7 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt)
 	if (omap_rev() == OMAP4430_REV_ES1_0)
 		return -ENXIO;
 
-	evt->irq = OMAP44XX_IRQ_LOCALTIMER;
+	evt->irq = gic_ppi_to_vppi(OMAP44XX_IRQ_LOCALTIMER);
 	twd_timer_setup(evt);
 	return 0;
 }
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 04/12] ARM: versatile: use remapped PPI interrupts for local timer
  2011-04-20 19:08 [RFC PATCH 00/12] Consolidating GIC per-cpu interrupts Marc Zyngier
                   ` (2 preceding siblings ...)
  2011-04-20 19:08 ` [RFC PATCH 03/12] ARM: omap4: use remapped PPI interrupts for local timer Marc Zyngier
@ 2011-04-20 19:08 ` Marc Zyngier
  2011-04-20 19:08 ` [RFC PATCH 05/12] ARM: shmobile: " Marc Zyngier
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 32+ messages in thread
From: Marc Zyngier @ 2011-04-20 19:08 UTC (permalink / raw)
  To: linux-arm-kernel

Use the normal interrupt scheme for the local timers by using
a remapped PPI interrupt.

Tested on VExpress and PB-11MP.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/mach-realview/Kconfig       |    2 ++
 arch/arm/mach-vexpress/Kconfig       |    1 +
 arch/arm/plat-versatile/localtimer.c |    3 ++-
 3 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig
index b9a9805..12c7c56 100644
--- a/arch/arm/mach-realview/Kconfig
+++ b/arch/arm/mach-realview/Kconfig
@@ -38,6 +38,7 @@ config MACH_REALVIEW_PB11MP
 	bool "Support RealView(R) Platform Baseboard for ARM11MPCore"
 	select CPU_V6K
 	select ARM_GIC
+	select ARM_GIC_VPPI
 	select HAVE_PATA_PLATFORM
 	select ARCH_HAS_BARRIERS if SMP
 	help
@@ -76,6 +77,7 @@ config MACH_REALVIEW_PBA8
 config MACH_REALVIEW_PBX
 	bool "Support RealView(R) Platform Baseboard Explore"
 	select ARM_GIC
+	select ARM_GIC_VPPI
 	select HAVE_PATA_PLATFORM
 	select ARCH_SPARSEMEM_ENABLE if CPU_V7 && !REALVIEW_HIGH_PHYS_OFFSET
 	select ZONE_DMA if SPARSEMEM
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig
index 9311484..07a53aa 100644
--- a/arch/arm/mach-vexpress/Kconfig
+++ b/arch/arm/mach-vexpress/Kconfig
@@ -5,6 +5,7 @@ config ARCH_VEXPRESS_CA9X4
 	bool "Versatile Express Cortex-A9x4 tile"
 	select CPU_V7
 	select ARM_GIC
+	select ARM_GIC_VPPI
 	select ARM_ERRATA_720789
 	select ARM_ERRATA_751472
 	select ARM_ERRATA_753970
diff --git a/arch/arm/plat-versatile/localtimer.c b/arch/arm/plat-versatile/localtimer.c
index 0fb3961..a76daf4 100644
--- a/arch/arm/plat-versatile/localtimer.c
+++ b/arch/arm/plat-versatile/localtimer.c
@@ -14,6 +14,7 @@
 
 #include <asm/smp_twd.h>
 #include <asm/localtimer.h>
+#include <asm/hardware/gic.h>
 #include <mach/irqs.h>
 
 /*
@@ -21,7 +22,7 @@
  */
 int __cpuinit local_timer_setup(struct clock_event_device *evt)
 {
-	evt->irq = IRQ_LOCALTIMER;
+	evt->irq = gic_ppi_to_vppi(IRQ_LOCALTIMER);
 	twd_timer_setup(evt);
 	return 0;
 }
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 05/12] ARM: shmobile: use remapped PPI interrupts for local timer
  2011-04-20 19:08 [RFC PATCH 00/12] Consolidating GIC per-cpu interrupts Marc Zyngier
                   ` (3 preceding siblings ...)
  2011-04-20 19:08 ` [RFC PATCH 04/12] ARM: versatile: " Marc Zyngier
@ 2011-04-20 19:08 ` Marc Zyngier
  2011-04-20 19:08 ` [RFC PATCH 06/12] ARM: ux500: " Marc Zyngier
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 32+ messages in thread
From: Marc Zyngier @ 2011-04-20 19:08 UTC (permalink / raw)
  To: linux-arm-kernel

Use the normal interrupt scheme for the local timers by using
a remapped PPI interrupt.

Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Magnus Damm <magnus.damm@gmail.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/mach-shmobile/Kconfig                    |    1 +
 arch/arm/mach-shmobile/entry-intc.S               |    3 ---
 arch/arm/mach-shmobile/include/mach/entry-macro.S |    3 ---
 arch/arm/mach-shmobile/localtimer.c               |    3 ++-
 4 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 0c8f6cf..ddcf28c 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -26,6 +26,7 @@ config ARCH_SH73A0
 	select SH_CLK_CPG
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select ARM_GIC
+	select ARM_GIC_VPPI
 
 comment "SH-Mobile Board Type"
 
diff --git a/arch/arm/mach-shmobile/entry-intc.S b/arch/arm/mach-shmobile/entry-intc.S
index cac0a7a..1a1c00c 100644
--- a/arch/arm/mach-shmobile/entry-intc.S
+++ b/arch/arm/mach-shmobile/entry-intc.S
@@ -51,7 +51,4 @@
 	.macro  test_for_ipi, irqnr, irqstat, base, tmp
 	.endm
 
-	.macro  test_for_ltirq, irqnr, irqstat, base, tmp
-	.endm
-
 	arch_irq_handler shmobile_handle_irq_intc
diff --git a/arch/arm/mach-shmobile/include/mach/entry-macro.S b/arch/arm/mach-shmobile/include/mach/entry-macro.S
index d791f10..8d4a416 100644
--- a/arch/arm/mach-shmobile/include/mach/entry-macro.S
+++ b/arch/arm/mach-shmobile/include/mach/entry-macro.S
@@ -27,8 +27,5 @@
 	.macro  test_for_ipi, irqnr, irqstat, base, tmp
 	.endm
 
-	.macro  test_for_ltirq, irqnr, irqstat, base, tmp
-	.endm
-
 	.macro  arch_ret_to_user, tmp1, tmp2
 	.endm
diff --git a/arch/arm/mach-shmobile/localtimer.c b/arch/arm/mach-shmobile/localtimer.c
index ad9ccc9..8a67b1c 100644
--- a/arch/arm/mach-shmobile/localtimer.c
+++ b/arch/arm/mach-shmobile/localtimer.c
@@ -14,13 +14,14 @@
 #include <linux/clockchips.h>
 #include <asm/smp_twd.h>
 #include <asm/localtimer.h>
+#include <asm/hardware/gic.h>
 
 /*
  * Setup the local clock events for a CPU.
  */
 int __cpuinit local_timer_setup(struct clock_event_device *evt)
 {
-	evt->irq = 29;
+	evt->irq = gic_ppi_to_vppi(29);
 	twd_timer_setup(evt);
 	return 0;
 }
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 06/12] ARM: ux500: use remapped PPI interrupts for local timer
  2011-04-20 19:08 [RFC PATCH 00/12] Consolidating GIC per-cpu interrupts Marc Zyngier
                   ` (4 preceding siblings ...)
  2011-04-20 19:08 ` [RFC PATCH 05/12] ARM: shmobile: " Marc Zyngier
@ 2011-04-20 19:08 ` Marc Zyngier
  2011-04-21  8:44   ` Srinidhi KASAGAR
  2011-04-20 19:08 ` [RFC PATCH 07/12] ARM: tegra: " Marc Zyngier
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 32+ messages in thread
From: Marc Zyngier @ 2011-04-20 19:08 UTC (permalink / raw)
  To: linux-arm-kernel

Use the normal interrupt scheme for the local timers by using
a remapped PPI interrupt.

Cc: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
Cc: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/mach-ux500/Kconfig      |    1 +
 arch/arm/mach-ux500/localtimer.c |    3 ++-
 2 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
index 5862601..6f3eb99 100644
--- a/arch/arm/mach-ux500/Kconfig
+++ b/arch/arm/mach-ux500/Kconfig
@@ -4,6 +4,7 @@ config UX500_SOC_COMMON
 	bool
 	default y
 	select ARM_GIC
+	select ARM_GIC_VPPI
 	select HAS_MTU
 	select NOMADIK_GPIO
 	select ARM_ERRATA_753970
diff --git a/arch/arm/mach-ux500/localtimer.c b/arch/arm/mach-ux500/localtimer.c
index 5ba1133..f027cef 100644
--- a/arch/arm/mach-ux500/localtimer.c
+++ b/arch/arm/mach-ux500/localtimer.c
@@ -17,13 +17,14 @@
 #include <asm/irq.h>
 #include <asm/smp_twd.h>
 #include <asm/localtimer.h>
+#include <asm/hardware/gic.h>
 
 /*
  * Setup the local clock events for a CPU.
  */
 int __cpuinit local_timer_setup(struct clock_event_device *evt)
 {
-	evt->irq = IRQ_LOCALTIMER;
+	evt->irq = gic_ppi_to_vppi(IRQ_LOCALTIMER);
 	twd_timer_setup(evt);
 	return 0;
 }
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 07/12] ARM: tegra: use remapped PPI interrupts for local timer
  2011-04-20 19:08 [RFC PATCH 00/12] Consolidating GIC per-cpu interrupts Marc Zyngier
                   ` (5 preceding siblings ...)
  2011-04-20 19:08 ` [RFC PATCH 06/12] ARM: ux500: " Marc Zyngier
@ 2011-04-20 19:08 ` Marc Zyngier
  2011-04-20 19:08 ` [RFC PATCH 08/12] ARM: msm: " Marc Zyngier
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 32+ messages in thread
From: Marc Zyngier @ 2011-04-20 19:08 UTC (permalink / raw)
  To: linux-arm-kernel

Use the normal interrupt scheme for the local timers by using
a remapped PPI interrupt.

Cc: Colin Cross <ccross@android.com>
Cc: Erik Gilling <konkers@android.com>
Cc: Olof Johansson <olof@lixom.net>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/mach-tegra/Kconfig      |    1 +
 arch/arm/mach-tegra/localtimer.c |    3 ++-
 2 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index 3cdeffc..67f478b 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -9,6 +9,7 @@ config ARCH_TEGRA_2x_SOC
 	bool "Tegra 2 family"
 	select CPU_V7
 	select ARM_GIC
+	select ARM_GIC_VPPI
 	select ARCH_REQUIRE_GPIOLIB
 	select USB_ARCH_HAS_EHCI if USB_SUPPORT
 	select USB_ULPI if USB_SUPPORT
diff --git a/arch/arm/mach-tegra/localtimer.c b/arch/arm/mach-tegra/localtimer.c
index e91d681..97cd0a9 100644
--- a/arch/arm/mach-tegra/localtimer.c
+++ b/arch/arm/mach-tegra/localtimer.c
@@ -14,13 +14,14 @@
 #include <asm/irq.h>
 #include <asm/smp_twd.h>
 #include <asm/localtimer.h>
+#include <asm/hardware/gic.h>
 
 /*
  * Setup the local clock events for a CPU.
  */
 int __cpuinit local_timer_setup(struct clock_event_device *evt)
 {
-	evt->irq = IRQ_LOCALTIMER;
+	evt->irq = gic_ppi_to_vppi(IRQ_LOCALTIMER);
 	twd_timer_setup(evt);
 	return 0;
 }
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 08/12] ARM: msm: use remapped PPI interrupts for local timer
  2011-04-20 19:08 [RFC PATCH 00/12] Consolidating GIC per-cpu interrupts Marc Zyngier
                   ` (6 preceding siblings ...)
  2011-04-20 19:08 ` [RFC PATCH 07/12] ARM: tegra: " Marc Zyngier
@ 2011-04-20 19:08 ` Marc Zyngier
  2011-04-26 17:13   ` Stephen Boyd
  2011-04-20 19:08 ` [RFC PATCH 09/12] ARM: exynos4: " Marc Zyngier
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 32+ messages in thread
From: Marc Zyngier @ 2011-04-20 19:08 UTC (permalink / raw)
  To: linux-arm-kernel

Use the normal interrupt scheme for the local timers by using
a remapped PPI interrupt.

MSM already had a very similar scheme, though still mixing both
GIC-specific and generic APIs.

Cc: David Brown <davidb@codeaurora.org>
Cc: Daniel Walker <dwalker@fifo99.com>
Cc: Bryan Huntsman <bryanh@codeaurora.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/mach-msm/Kconfig                         |    2 +
 arch/arm/mach-msm/include/mach/entry-macro-qgic.S |   73 +--------------------
 arch/arm/mach-msm/timer.c                         |   38 ++++++------
 3 files changed, 22 insertions(+), 91 deletions(-)

diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 1516896..1ea7d6f 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -42,6 +42,7 @@ config ARCH_MSM8X60
 				  && !MACH_MSM8X60_FFA)
 	select ARCH_MSM_SCORPIONMP
 	select ARM_GIC
+	select ARM_GIC_VPPI
 	select CPU_V7
 	select MSM_V2_TLMM
 	select MSM_GPIOMUX
@@ -52,6 +53,7 @@ config ARCH_MSM8960
 	select ARCH_MSM_SCORPIONMP
 	select MACH_MSM8960_SIM if (!MACH_MSM8960_RUMI3)
 	select ARM_GIC
+	select ARM_GIC_VPPI
 	select CPU_V7
 	select MSM_V2_TLMM
 	select MSM_GPIOMUX
diff --git a/arch/arm/mach-msm/include/mach/entry-macro-qgic.S b/arch/arm/mach-msm/include/mach/entry-macro-qgic.S
index 1246715..717076f 100644
--- a/arch/arm/mach-msm/include/mach/entry-macro-qgic.S
+++ b/arch/arm/mach-msm/include/mach/entry-macro-qgic.S
@@ -8,81 +8,10 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <mach/hardware.h>
-#include <asm/hardware/gic.h>
+#include <asm/hardware/entry-macro-gic.S>
 
 	.macro	disable_fiq
 	.endm
 
-	.macro  get_irqnr_preamble, base, tmp
-	ldr	\base, =gic_cpu_base_addr
-	ldr	\base, [\base]
-	.endm
-
 	.macro  arch_ret_to_user, tmp1, tmp2
 	.endm
-
-	/*
-	 * The interrupt numbering scheme is defined in the
-	 * interrupt controller spec.  To wit:
-	 *
-	 * Migrated the code from ARM MP port to be more consistent
-	 * with interrupt processing , the following still holds true
-	 * however, all interrupts are treated the same regardless of
-	 * if they are local IPI or PPI
-	 *
-	 * Interrupts 0-15 are IPI
-	 * 16-31 are PPI
-	 *   (16-18 are the timers)
-	 * 32-1020 are global
-	 * 1021-1022 are reserved
-	 * 1023 is "spurious" (no interrupt)
-	 *
-	 * 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 (0-1020 inclusive).
-	 *
-	 * Base ARM code assumes that the local (private) peripheral interrupts
-	 * are not valid, we treat them differently, in that the privates are
-	 * handled like normal shared interrupts with the exception that only
-	 * one processor can register the interrupt and the handler must be
-	 * the same for all processors.
-	 */
-
-	.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-
-	ldr  \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 =srcCPU,
-						   9-0 =int # */
-
-	bic     \irqnr, \irqstat, #0x1c00	@mask src
-	cmp     \irqnr, #15
-	ldr		\tmp, =1021
-	cmpcc	\irqnr, \irqnr
-	cmpne	\irqnr, \tmp
-	cmpcs	\irqnr, \irqnr
-
-	.endm
-
-	/* We assume that irqstat (the raw value of the IRQ acknowledge
-	 * register) is preserved from the macro above.
-	 * If there is an IPI, we immediately signal end of interrupt on the
-	 * controller, since this requires the original irqstat value which
-	 * we won't easily be able to recreate later.
-	 */
-	.macro test_for_ipi, irqnr, irqstat, base, tmp
-    bic \irqnr, \irqstat, #0x1c00
-    cmp \irqnr, #16
-    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, #16
-    moveq   \tmp, #1
-    streq   \irqstat, [\base, #GIC_CPU_EOI]
-    cmp \tmp, #0
-	.endm
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 38b95e9..68eab51 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -23,6 +23,7 @@
 #include <linux/io.h>
 
 #include <asm/mach/time.h>
+#include <asm/hardware/gic.h>
 #include <mach/msm_iomap.h>
 #include <mach/cpu.h>
 
@@ -67,8 +68,8 @@ enum timer_location {
 struct msm_clock {
 	struct clock_event_device   clockevent;
 	struct clocksource          clocksource;
-	struct irqaction            irq;
 	void __iomem                *regbase;
+	unsigned int		    irq;
 	uint32_t                    freq;
 	uint32_t                    shift;
 	void __iomem                *global_counter;
@@ -163,13 +164,7 @@ static struct msm_clock msm_clocks[] = {
 			.mask           = CLOCKSOURCE_MASK(32),
 			.flags          = CLOCK_SOURCE_IS_CONTINUOUS,
 		},
-		.irq = {
-			.name    = "gp_timer",
-			.flags   = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_RISING,
-			.handler = msm_timer_interrupt,
-			.dev_id  = &msm_clocks[0].clockevent,
-			.irq     = INT_GP_TIMER_EXP
-		},
+		.irq = INT_GP_TIMER_EXP,
 		.freq = GPT_HZ,
 	},
 	[MSM_CLOCK_DGT] = {
@@ -188,13 +183,7 @@ static struct msm_clock msm_clocks[] = {
 			.mask           = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT)),
 			.flags          = CLOCK_SOURCE_IS_CONTINUOUS,
 		},
-		.irq = {
-			.name    = "dg_timer",
-			.flags   = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_RISING,
-			.handler = msm_timer_interrupt,
-			.dev_id  = &msm_clocks[1].clockevent,
-			.irq     = INT_DEBUG_TIMER_EXP
-		},
+		.irq = INT_DEBUG_TIMER_EXP,
 		.freq = DGT_HZ >> MSM_DGT_SHIFT,
 		.shift = MSM_DGT_SHIFT,
 	}
@@ -232,6 +221,7 @@ static void __init msm_timer_init(void)
 		struct msm_clock *clock = &msm_clocks[i];
 		struct clock_event_device *ce = &clock->clockevent;
 		struct clocksource *cs = &clock->clocksource;
+		int irq;
 
 		clock->local_counter = clock->regbase + TIMER_COUNT_VAL;
 		clock->global_counter = clock->local_counter + global_offset;
@@ -253,10 +243,13 @@ static void __init msm_timer_init(void)
 			printk(KERN_ERR "msm_timer_init: clocksource_register "
 			       "failed for %s\n", cs->name);
 
-		res = setup_irq(clock->irq.irq, &clock->irq);
+		irq = gic_ppi_to_vppi(clock->irq);
+		res = request_irq(irq, msm_timer_interrupt,
+				  IRQF_TIMER | IRQF_NOBALANCING | IRQF_TRIGGER_RISING,
+				  clock->name, &clock->clockevent);
 		if (res)
-			printk(KERN_ERR "msm_timer_init: setup_irq "
-			       "failed for %s\n", cs->name);
+			pr_err("msm_timer_init: request_irq failed for %s\n",
+			       clock->name);
 
 		clockevents_register_device(ce);
 	}
@@ -292,7 +285,14 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt)
 
 	local_clock_event = evt;
 
-	gic_enable_ppi(clock->irq.irq);
+	res = request_irq(gic_ppi_to_vppi(irq), msm_timer_interrupt,
+			  IRQF_TIMER | IRQF_NOBALANCING | IRQF_TRIGGER_RISING,
+			  clock->name, &clock->clockevent);
+	if (res) {
+		pr_err("local_timer_setup: request_irq failed for %s\n",
+		       clock->name);
+		return err;
+	}
 
 	clockevents_register_device(evt);
 	return 0;
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 09/12] ARM: exynos4: use remapped PPI interrupts for local timer
  2011-04-20 19:08 [RFC PATCH 00/12] Consolidating GIC per-cpu interrupts Marc Zyngier
                   ` (7 preceding siblings ...)
  2011-04-20 19:08 ` [RFC PATCH 08/12] ARM: msm: " Marc Zyngier
@ 2011-04-20 19:08 ` Marc Zyngier
  2011-04-20 19:08 ` [RFC PATCH 10/12] ARM: gic: remove previous local timer interrupt handling Marc Zyngier
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 32+ messages in thread
From: Marc Zyngier @ 2011-04-20 19:08 UTC (permalink / raw)
  To: linux-arm-kernel

Use the normal interrupt scheme for the local timers by using
a remapped PPI interrupt.

Tested on a SMDK-S5PV310 board.

Cc: Ben Dooks <ben-linux@fluff.org>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/mach-exynos4/include/mach/entry-macro.S |   12 +-----------
 arch/arm/mach-exynos4/localtimer.c               |    3 ++-
 arch/arm/plat-s5p/Kconfig                        |    1 +
 3 files changed, 4 insertions(+), 12 deletions(-)

diff --git a/arch/arm/mach-exynos4/include/mach/entry-macro.S b/arch/arm/mach-exynos4/include/mach/entry-macro.S
index d8f38c2..f007168 100644
--- a/arch/arm/mach-exynos4/include/mach/entry-macro.S
+++ b/arch/arm/mach-exynos4/include/mach/entry-macro.S
@@ -50,7 +50,7 @@
 
 		bic     \irqnr, \irqstat, #0x1c00
 
-		cmp     \irqnr, #29
+		cmp     \irqnr, #15
 		cmpcc	\irqnr, \irqnr
 		cmpne	\irqnr, \tmp
 		cmpcs	\irqnr, \irqnr
@@ -72,13 +72,3 @@
 		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
diff --git a/arch/arm/mach-exynos4/localtimer.c b/arch/arm/mach-exynos4/localtimer.c
index 6bf3d0a..315de6f 100644
--- a/arch/arm/mach-exynos4/localtimer.c
+++ b/arch/arm/mach-exynos4/localtimer.c
@@ -14,13 +14,14 @@
 
 #include <asm/irq.h>
 #include <asm/localtimer.h>
+#include <asm/hardware/gic.h>
 
 /*
  * Setup the local clock events for a CPU.
  */
 int __cpuinit local_timer_setup(struct clock_event_device *evt)
 {
-	evt->irq = IRQ_LOCALTIMER;
+	evt->irq = gic_ppi_to_vppi(IRQ_LOCALTIMER);
 	twd_timer_setup(evt);
 	return 0;
 }
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
index 8492297..1ee4a1a 100644
--- a/arch/arm/plat-s5p/Kconfig
+++ b/arch/arm/plat-s5p/Kconfig
@@ -11,6 +11,7 @@ config PLAT_S5P
 	default y
 	select ARM_VIC if !ARCH_EXYNOS4
 	select ARM_GIC if ARCH_EXYNOS4
+	select ARM_GIC_VPPI if ARCH_EXYNOS4
 	select NO_IOPORT
 	select ARCH_REQUIRE_GPIOLIB
 	select S3C_GPIO_TRACK
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 10/12] ARM: gic: remove previous local timer interrupt handling
  2011-04-20 19:08 [RFC PATCH 00/12] Consolidating GIC per-cpu interrupts Marc Zyngier
                   ` (8 preceding siblings ...)
  2011-04-20 19:08 ` [RFC PATCH 09/12] ARM: exynos4: " Marc Zyngier
@ 2011-04-20 19:08 ` Marc Zyngier
  2011-04-20 19:08 ` [RFC PATCH 11/12] ARM: gic: add compute_irqnr macro for exynos4 Marc Zyngier
  2011-04-20 19:08 ` [RFC PATCH 12/12] ARM: SMP: automatically select ARM_GIC_VPPI Marc Zyngier
  11 siblings, 0 replies; 32+ messages in thread
From: Marc Zyngier @ 2011-04-20 19:08 UTC (permalink / raw)
  To: linux-arm-kernel

Now that all users of local timers are using CONFIG_ARM_GIC_VPPI,
the now unused local timer infrastructure can be safely removed.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/common/gic.c                           |   10 ----------
 arch/arm/include/asm/entry-macro-multi.S        |    7 -------
 arch/arm/include/asm/hardware/entry-macro-gic.S |   13 -------------
 arch/arm/include/asm/hardware/gic.h             |    1 -
 arch/arm/include/asm/localtimer.h               |    5 -----
 arch/arm/kernel/smp.c                           |   13 -------------
 arch/arm/kernel/smp_twd.c                       |    5 -----
 7 files changed, 0 insertions(+), 54 deletions(-)

diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 60f8915..9236ce6 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -500,16 +500,6 @@ void __cpuinit gic_secondary_init(unsigned int gic_nr)
 	gic_cpu_init(&gic_data[gic_nr]);
 }
 
-void __cpuinit gic_enable_ppi(unsigned int irq)
-{
-	unsigned long flags;
-
-	local_irq_save(flags);
-	irq_set_status_flags(irq, IRQ_NOPROBE);
-	gic_unmask_irq(irq_get_irq_data(irq));
-	local_irq_restore(flags);
-}
-
 #ifdef CONFIG_SMP
 void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
 {
diff --git a/arch/arm/include/asm/entry-macro-multi.S b/arch/arm/include/asm/entry-macro-multi.S
index c599795..4ef27af 100644
--- a/arch/arm/include/asm/entry-macro-multi.S
+++ b/arch/arm/include/asm/entry-macro-multi.S
@@ -23,13 +23,6 @@
 	movne	r1, sp
 	adrne	lr, BSYM(1b)
 	bne	do_IPI
-
-#if defined(CONFIG_LOCAL_TIMERS) && !defined(CONFIG_ARM_GIC_VPPI)
-	test_for_ltirq r0, r6, r5, lr
-	movne	r0, sp
-	adrne	lr, BSYM(1b)
-	bne	do_local_timer
-#endif
 #endif
 9997:
 	.endm
diff --git a/arch/arm/include/asm/hardware/entry-macro-gic.S b/arch/arm/include/asm/hardware/entry-macro-gic.S
index 14a3363..db83287 100644
--- a/arch/arm/include/asm/hardware/entry-macro-gic.S
+++ b/arch/arm/include/asm/hardware/entry-macro-gic.S
@@ -65,16 +65,3 @@
 	strcc	\irqstat, [\base, #GIC_CPU_EOI]
 	cmpcs	\irqnr, \irqnr
 	.endm
-
-#ifndef CONFIG_ARM_GIC_VPPI
-/* 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
-#endif
diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
index 9dbffed..069d4c0 100644
--- a/arch/arm/include/asm/hardware/gic.h
+++ b/arch/arm/include/asm/hardware/gic.h
@@ -42,7 +42,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);
 #ifdef CONFIG_ARM_GIC_VPPI
 unsigned int gic_ppi_to_vppi(unsigned int irq);
 #else
diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h
index bef44b3..5c8acb4 100644
--- a/arch/arm/include/asm/localtimer.h
+++ b/arch/arm/include/asm/localtimer.h
@@ -20,11 +20,6 @@ struct clock_event_device;
 void percpu_timer_setup(void);
 
 /*
- * Called from assembly, this is the local timer IRQ handler
- */
-asmlinkage void do_local_timer(struct pt_regs *);
-
-/*
  * Per-cpu timer IRQ handler
  */
 irqreturn_t percpu_timer_handler(int irq, void *dev_id);
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 64b9d81..798a357 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -439,19 +439,6 @@ static void ipi_timer(void)
 }
 
 #ifdef CONFIG_LOCAL_TIMERS
-asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs)
-{
-	struct pt_regs *old_regs = set_irq_regs(regs);
-	int cpu = smp_processor_id();
-
-	if (local_timer_ack()) {
-		__inc_irq_stat(cpu, local_timer_irqs);
-		ipi_timer();
-	}
-
-	set_irq_regs(old_regs);
-}
-
 irqreturn_t percpu_timer_handler(int irq, void *dev_id)
 {
 	if (local_timer_ack()) {
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index bbb0f4d..082753c 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -140,7 +140,6 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
 	clk->max_delta_ns = clockevent_delta2ns(0xffffffff, clk);
 	clk->min_delta_ns = clockevent_delta2ns(0xf, clk);
 
-#ifdef CONFIG_ARM_GIC_VPPI
 	err = request_irq(clk->irq, percpu_timer_handler,
 			  IRQF_PERCPU | IRQF_NOBALANCING | IRQF_TIMER,
 			  clk->name, clk);
@@ -149,10 +148,6 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
 		       clk->name, clk->irq, smp_processor_id(), err);
 		return;
 	}
-#else
-	/* Make sure our local interrupt controller has this enabled */
-	gic_enable_ppi(clk->irq);
-#endif
 
 	clockevents_register_device(clk);
 }
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 11/12] ARM: gic: add compute_irqnr macro for exynos4
  2011-04-20 19:08 [RFC PATCH 00/12] Consolidating GIC per-cpu interrupts Marc Zyngier
                   ` (9 preceding siblings ...)
  2011-04-20 19:08 ` [RFC PATCH 10/12] ARM: gic: remove previous local timer interrupt handling Marc Zyngier
@ 2011-04-20 19:08 ` Marc Zyngier
  2011-04-20 19:08 ` [RFC PATCH 12/12] ARM: SMP: automatically select ARM_GIC_VPPI Marc Zyngier
  11 siblings, 0 replies; 32+ messages in thread
From: Marc Zyngier @ 2011-04-20 19:08 UTC (permalink / raw)
  To: linux-arm-kernel

exynos4 has a full copy of entry-macro-gic.S, just for the sake
of an offset added to the IRQ number read from the GIC.

Add a compute_irqnr macro to entry-macro-gic.S so that any platform
can add it's own hook without having to copy the whole file again.

Cc: Ben Dooks <ben-linux@fluff.org>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/include/asm/hardware/entry-macro-gic.S  |    3 +
 arch/arm/mach-exynos4/include/mach/entry-macro.S |   60 ++--------------------
 2 files changed, 8 insertions(+), 55 deletions(-)

diff --git a/arch/arm/include/asm/hardware/entry-macro-gic.S b/arch/arm/include/asm/hardware/entry-macro-gic.S
index db83287..a01dc80 100644
--- a/arch/arm/include/asm/hardware/entry-macro-gic.S
+++ b/arch/arm/include/asm/hardware/entry-macro-gic.S
@@ -50,6 +50,9 @@
 	cmpcc	\irqnr, \irqnr
 	cmpne	\irqnr, \tmp
 	cmpcs	\irqnr, \irqnr
+#ifdef HAVE_GIC_BASE_OFFSET
+	compute_irqnr	\irqnr, \tmp
+#endif
 	.endm
 
 /* We assume that irqstat (the raw value of the IRQ acknowledge
diff --git a/arch/arm/mach-exynos4/include/mach/entry-macro.S b/arch/arm/mach-exynos4/include/mach/entry-macro.S
index f007168..7d87d4e 100644
--- a/arch/arm/mach-exynos4/include/mach/entry-macro.S
+++ b/arch/arm/mach-exynos4/include/mach/entry-macro.S
@@ -9,66 +9,16 @@
  * warranty of any kind, whether express or implied.
 */
 
-#include <mach/hardware.h>
-#include <asm/hardware/gic.h>
+#define HAVE_GIC_BASE_OFFSET	1
+#include <asm/hardware/entry-macro-gic.S>
 
-		.macro	disable_fiq
+		.macro	compute_irqnr, irqnr, tmp
+		addne	\irqnr, #32
 		.endm
 
-		.macro  get_irqnr_preamble, base, tmp
-		ldr	\base, =gic_cpu_base_addr
-		ldr	\base, [\base]
+		.macro	disable_fiq
 		.endm
 
 		.macro  arch_ret_to_user, tmp1, tmp2
 		.endm
 
-		/*
-		 * The interrupt numbering scheme is defined in the
-		 * 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.
-		 * 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).
-		 */
-
-		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-
-		ldr     \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */
-
-		ldr	\tmp, =1021
-
-		bic     \irqnr, \irqstat, #0x1c00
-
-		cmp     \irqnr, #15
-		cmpcc	\irqnr, \irqnr
-		cmpne	\irqnr, \tmp
-		cmpcs	\irqnr, \irqnr
-		addne	\irqnr, \irqnr, #32
-
-		.endm
-
-		/* We assume that irqstat (the raw value of the IRQ acknowledge
-		 * register) is preserved from the macro above.
-		 * If there is an IPI, we immediately signal end of interrupt on the
-		 * controller, since this requires the original irqstat value which
-		 * we won't easily be able to recreate later.
-		 */
-
-		.macro test_for_ipi, irqnr, irqstat, base, tmp
-		bic	\irqnr, \irqstat, #0x1c00
-		cmp	\irqnr, #16
-		strcc	\irqstat, [\base, #GIC_CPU_EOI]
-		cmpcs	\irqnr, \irqnr
-		.endm
-
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 12/12] ARM: SMP: automatically select ARM_GIC_VPPI
  2011-04-20 19:08 [RFC PATCH 00/12] Consolidating GIC per-cpu interrupts Marc Zyngier
                   ` (10 preceding siblings ...)
  2011-04-20 19:08 ` [RFC PATCH 11/12] ARM: gic: add compute_irqnr macro for exynos4 Marc Zyngier
@ 2011-04-20 19:08 ` Marc Zyngier
  11 siblings, 0 replies; 32+ messages in thread
From: Marc Zyngier @ 2011-04-20 19:08 UTC (permalink / raw)
  To: linux-arm-kernel

All SMP platforms are selecting ARM_GIC_VPPI.
Instead, make SMP select ARM_GIC_VPPI and remove select statements
from the platform code.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/Kconfig               |    1 +
 arch/arm/mach-msm/Kconfig      |    2 --
 arch/arm/mach-omap2/Kconfig    |    1 -
 arch/arm/mach-realview/Kconfig |    2 --
 arch/arm/mach-shmobile/Kconfig |    1 -
 arch/arm/mach-tegra/Kconfig    |    1 -
 arch/arm/mach-ux500/Kconfig    |    1 -
 arch/arm/mach-vexpress/Kconfig |    1 -
 arch/arm/plat-s5p/Kconfig      |    1 -
 9 files changed, 1 insertions(+), 10 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 377a7a5..f58303f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1327,6 +1327,7 @@ config SMP
 		 ARCH_EXYNOS4 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \
 		 ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE
 	select USE_GENERIC_SMP_HELPERS
+	select ARM_GIC_VPPI
 	select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP
 	help
 	  This enables support for systems with more than one CPU. If you have
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 1ea7d6f..1516896 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -42,7 +42,6 @@ config ARCH_MSM8X60
 				  && !MACH_MSM8X60_FFA)
 	select ARCH_MSM_SCORPIONMP
 	select ARM_GIC
-	select ARM_GIC_VPPI
 	select CPU_V7
 	select MSM_V2_TLMM
 	select MSM_GPIOMUX
@@ -53,7 +52,6 @@ config ARCH_MSM8960
 	select ARCH_MSM_SCORPIONMP
 	select MACH_MSM8960_SIM if (!MACH_MSM8960_RUMI3)
 	select ARM_GIC
-	select ARM_GIC_VPPI
 	select CPU_V7
 	select MSM_V2_TLMM
 	select MSM_GPIOMUX
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 8282921..b997a35 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -44,7 +44,6 @@ config ARCH_OMAP4
 	depends on ARCH_OMAP2PLUS
 	select CPU_V7
 	select ARM_GIC
-	select ARM_GIC_VPPI
 	select LOCAL_TIMERS if SMP
 	select PL310_ERRATA_588369
 	select PL310_ERRATA_727915
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig
index 12c7c56..b9a9805 100644
--- a/arch/arm/mach-realview/Kconfig
+++ b/arch/arm/mach-realview/Kconfig
@@ -38,7 +38,6 @@ config MACH_REALVIEW_PB11MP
 	bool "Support RealView(R) Platform Baseboard for ARM11MPCore"
 	select CPU_V6K
 	select ARM_GIC
-	select ARM_GIC_VPPI
 	select HAVE_PATA_PLATFORM
 	select ARCH_HAS_BARRIERS if SMP
 	help
@@ -77,7 +76,6 @@ config MACH_REALVIEW_PBA8
 config MACH_REALVIEW_PBX
 	bool "Support RealView(R) Platform Baseboard Explore"
 	select ARM_GIC
-	select ARM_GIC_VPPI
 	select HAVE_PATA_PLATFORM
 	select ARCH_SPARSEMEM_ENABLE if CPU_V7 && !REALVIEW_HIGH_PHYS_OFFSET
 	select ZONE_DMA if SPARSEMEM
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index ddcf28c..0c8f6cf 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -26,7 +26,6 @@ config ARCH_SH73A0
 	select SH_CLK_CPG
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select ARM_GIC
-	select ARM_GIC_VPPI
 
 comment "SH-Mobile Board Type"
 
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index 67f478b..3cdeffc 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -9,7 +9,6 @@ config ARCH_TEGRA_2x_SOC
 	bool "Tegra 2 family"
 	select CPU_V7
 	select ARM_GIC
-	select ARM_GIC_VPPI
 	select ARCH_REQUIRE_GPIOLIB
 	select USB_ARCH_HAS_EHCI if USB_SUPPORT
 	select USB_ULPI if USB_SUPPORT
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
index 6f3eb99..5862601 100644
--- a/arch/arm/mach-ux500/Kconfig
+++ b/arch/arm/mach-ux500/Kconfig
@@ -4,7 +4,6 @@ config UX500_SOC_COMMON
 	bool
 	default y
 	select ARM_GIC
-	select ARM_GIC_VPPI
 	select HAS_MTU
 	select NOMADIK_GPIO
 	select ARM_ERRATA_753970
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig
index 07a53aa..9311484 100644
--- a/arch/arm/mach-vexpress/Kconfig
+++ b/arch/arm/mach-vexpress/Kconfig
@@ -5,7 +5,6 @@ config ARCH_VEXPRESS_CA9X4
 	bool "Versatile Express Cortex-A9x4 tile"
 	select CPU_V7
 	select ARM_GIC
-	select ARM_GIC_VPPI
 	select ARM_ERRATA_720789
 	select ARM_ERRATA_751472
 	select ARM_ERRATA_753970
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
index 1ee4a1a..8492297 100644
--- a/arch/arm/plat-s5p/Kconfig
+++ b/arch/arm/plat-s5p/Kconfig
@@ -11,7 +11,6 @@ config PLAT_S5P
 	default y
 	select ARM_VIC if !ARCH_EXYNOS4
 	select ARM_GIC if ARCH_EXYNOS4
-	select ARM_GIC_VPPI if ARCH_EXYNOS4
 	select NO_IOPORT
 	select ARCH_REQUIRE_GPIOLIB
 	select S3C_GPIO_TRACK
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 06/12] ARM: ux500: use remapped PPI interrupts for local timer
  2011-04-20 19:08 ` [RFC PATCH 06/12] ARM: ux500: " Marc Zyngier
@ 2011-04-21  8:44   ` Srinidhi KASAGAR
  2011-04-21  8:53     ` Marc Zyngier
  0 siblings, 1 reply; 32+ messages in thread
From: Srinidhi KASAGAR @ 2011-04-21  8:44 UTC (permalink / raw)
  To: linux-arm-kernel

> -----Original Message-----
> From: Marc Zyngier [mailto:marc.zyngier at arm.com]
> Sent: Thursday, April 21, 2011 12:38 AM
> To: LAK
> Cc: Srinidhi KASAGAR; Linus WALLEIJ
> Subject: [RFC PATCH 06/12] ARM: ux500: use remapped PPI interrupts for
> local timer
> 
> Use the normal interrupt scheme for the local timers by using
> a remapped PPI interrupt.
> 
> Cc: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
> Cc: Linus Walleij <linus.walleij@stericsson.com>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  arch/arm/mach-ux500/Kconfig      |    1 +
>  arch/arm/mach-ux500/localtimer.c |    3 ++-
>  2 files changed, 3 insertions(+), 1 deletions(-)
> 
> diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
> index 5862601..6f3eb99 100644
> --- a/arch/arm/mach-ux500/Kconfig
> +++ b/arch/arm/mach-ux500/Kconfig
> @@ -4,6 +4,7 @@ config UX500_SOC_COMMON
>  	bool
>  	default y
>  	select ARM_GIC
> +	select ARM_GIC_VPPI

Here you added VPPI and in the other patch 12/12 you remove this
again and make it one time selectable based on CONFIG_SMP.
is that done just for readability purpose?

Otherwise, for mach-ux500:
Acked-by: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>

srinidhi

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [RFC PATCH 06/12] ARM: ux500: use remapped PPI interrupts for local timer
  2011-04-21  8:44   ` Srinidhi KASAGAR
@ 2011-04-21  8:53     ` Marc Zyngier
  0 siblings, 0 replies; 32+ messages in thread
From: Marc Zyngier @ 2011-04-21  8:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 2011-04-21 at 10:44 +0200, Srinidhi KASAGAR wrote:
> > -----Original Message-----
> > From: Marc Zyngier [mailto:marc.zyngier at arm.com]
> > Sent: Thursday, April 21, 2011 12:38 AM
> > To: LAK
> > Cc: Srinidhi KASAGAR; Linus WALLEIJ
> > Subject: [RFC PATCH 06/12] ARM: ux500: use remapped PPI interrupts for
> > local timer
> > 
> > Use the normal interrupt scheme for the local timers by using
> > a remapped PPI interrupt.
> > 
> > Cc: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
> > Cc: Linus Walleij <linus.walleij@stericsson.com>
> > Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> > ---
> >  arch/arm/mach-ux500/Kconfig      |    1 +
> >  arch/arm/mach-ux500/localtimer.c |    3 ++-
> >  2 files changed, 3 insertions(+), 1 deletions(-)
> > 
> > diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
> > index 5862601..6f3eb99 100644
> > --- a/arch/arm/mach-ux500/Kconfig
> > +++ b/arch/arm/mach-ux500/Kconfig
> > @@ -4,6 +4,7 @@ config UX500_SOC_COMMON
> >  	bool
> >  	default y
> >  	select ARM_GIC
> > +	select ARM_GIC_VPPI
> 
> Here you added VPPI and in the other patch 12/12 you remove this
> again and make it one time selectable based on CONFIG_SMP.
> is that done just for readability purpose?

This is in the interest of having a bisectable tree. Because I convert
each platform one at a time, I cannot immediately make CONFIG_SMP select
VPPI (that would break all the not-yet-converted platforms). Once all
platforms are using VPPI, patch #12 does the cleanup for configuration.

> Otherwise, for mach-ux500:
> Acked-by: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>

Thanks,

	M.
-- 
Reality is an implementation detail.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [RFC PATCH 02/12] ARM: smp_twd: add support for remapped PPI interrupts
  2011-04-20 19:08 ` [RFC PATCH 02/12] ARM: smp_twd: add support for remapped PPI interrupts Marc Zyngier
@ 2011-04-25 17:04   ` Stephen Boyd
  2011-04-26  9:05     ` Marc Zyngier
  0 siblings, 1 reply; 32+ messages in thread
From: Stephen Boyd @ 2011-04-25 17:04 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/20/2011 12:08 PM, Marc Zyngier wrote:
> diff --git a/arch/arm/include/asm/entry-macro-multi.S b/arch/arm/include/asm/entry-macro-multi.S
> index ec0bbf7..c599795 100644
> --- a/arch/arm/include/asm/entry-macro-multi.S
> +++ b/arch/arm/include/asm/entry-macro-multi.S
> @@ -24,7 +24,7 @@
>  	adrne	lr, BSYM(1b)
>  	bne	do_IPI
>  
> -#ifdef CONFIG_LOCAL_TIMERS
> +#if defined(CONFIG_LOCAL_TIMERS) && !defined(CONFIG_ARM_GIC_VPPI)
>  	test_for_ltirq r0, r6, r5, lr
>  	movne	r0, sp
>  	adrne	lr, BSYM(1b)
> diff --git a/arch/arm/include/asm/hardware/entry-macro-gic.S b/arch/arm/include/asm/hardware/entry-macro-gic.S
> index c115b82..14a3363 100644
> --- a/arch/arm/include/asm/hardware/entry-macro-gic.S
> +++ b/arch/arm/include/asm/hardware/entry-macro-gic.S
> @@ -17,23 +17,26 @@
>  	.endm
>  #endif
>  
> +#ifdef CONFIG_ARM_GIC_VPPI
> +#define DO_IRQ_BASE	16
> +#else
> +#define DO_IRQ_BASE	30
> +#endif
> +
>  /*
>   * The interrupt numbering scheme is defined in the
>   * 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).
> + * valid range for an IRQ (30-1020 inclusive). If CONFIG_ARM_GIC_VPPI is
> + * enabled, local interrupts are handled the same way as global ones.
>   */
>  
>  	.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
> @@ -43,7 +46,7 @@
>  
>  	ldr	\tmp, =1021
>  	bic     \irqnr, \irqstat, #0x1c00
> -	cmp     \irqnr, #29
> +	cmp     \irqnr, #(DO_IRQ_BASE - 1)
>  	cmpcc	\irqnr, \irqnr
>  	cmpne	\irqnr, \tmp
>  	cmpcs	\irqnr, \irqnr
> @@ -63,6 +66,7 @@
>  	cmpcs	\irqnr, \irqnr
>  	.endm
>  
> +#ifndef CONFIG_ARM_GIC_VPPI
>  /* As above, this assumes that irqstat and base are preserved.. */
>  
>  	.macro test_for_ltirq, irqnr, irqstat, base, tmp
> @@ -73,3 +77,4 @@
>  	streq	\irqstat, [\base, #GIC_CPU_EOI]
>  	cmp	\tmp, #0
>  	.endm
> +#endif

I would expect these bits to be part of the first patch in this series
because they're necessary to actually use the CONFIG_ARM_GIC_VPPI
option. Can you move them to the first patch?

-- 
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [RFC PATCH 01/12] ARM: gic: add per-cpu interrupt multiplexer
  2011-04-20 19:08 ` [RFC PATCH 01/12] ARM: gic: add per-cpu interrupt multiplexer Marc Zyngier
@ 2011-04-25 20:17   ` Abhijeet Dharmapurikar
  2011-04-26  9:08     ` Marc Zyngier
  2011-04-26  4:00   ` Stephen Boyd
  1 sibling, 1 reply; 32+ messages in thread
From: Abhijeet Dharmapurikar @ 2011-04-25 20:17 UTC (permalink / raw)
  To: linux-arm-kernel

Marc Zyngier wrote:
> diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
> index e9c2ff8..60f8915 100644
> --- a/arch/arm/common/gic.c
> +++ b/arch/arm/common/gic.c
> @@ -42,6 +42,11 @@ struct gic_chip_data {
>  	unsigned int irq_offset;
>  	void __iomem *dist_base;
>  	void __iomem *cpu_base;
> +#ifdef CONFIG_ARM_GIC_VPPI
> +	int	     ppi_base;
> +	int	     vppi_base;
> +	u16	     nrppis;
> +#endif
>  };

Can you put some document around this struct? Mention that ppi_base, 
vppi_base and nrppis will be zero for non-primary gic.


>  static void __init gic_dist_init(struct gic_chip_data *gic,
>  	unsigned int irq_start)
>  {
> -	unsigned int gic_irqs, irq_limit, i;
> +	unsigned int gic_irqs, irq_limit, i, nrvppis = 0;
>  	void __iomem *base = gic->dist_base;
>  	u32 cpumask = 1 << smp_processor_id();
> +	u32 dist_ctr, nrcpus;
>  
>  	cpumask |= cpumask << 8;
>  	cpumask |= cpumask << 16;
> @@ -278,11 +359,32 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
>  	 * Find out how many interrupts are supported.
>  	 * The GIC only supports up to 1020 interrupt sources.
>  	 */
> -	gic_irqs = readl(base + GIC_DIST_CTR) & 0x1f;
> -	gic_irqs = (gic_irqs + 1) * 32;
> +	dist_ctr = readl(base + GIC_DIST_CTR);
> +	gic_irqs = ((dist_ctr & 0x1f) + 1) * 32;
>  	if (gic_irqs > 1020)
>  		gic_irqs = 1020;
>  
> +	/* Find out how many CPUs are supported (8 max). */
> +	nrcpus = ((dist_ctr >> 5) & 7) + 1;
> +
> +#ifdef CONFIG_ARM_GIC_VPPI
> +	/*
> +	 * Nobody would be insane enough to use PPIs on a secondary
> +	 * GIC, right?
> +	 */
> +	if (gic == &gic_data[0]) {
> +		gic->nrppis = 16 - (irq_start % 16);
> +		gic->ppi_base = gic->irq_offset + 32 - gic->nrppis;
> +		nrvppis = gic->nrppis * nrcpus;
> +	} else {
> +		gic->ppi_base = 0;
> +		gic->vppi_base = 0;
> +	}
> +#endif
> +
> +	pr_info("Configuring GIC with %d sources (%d additional PPIs)\n",
> +		gic_irqs, nrvppis);
> +
>  	/*
>  	 * Set all global interrupts to be level triggered, active low.
>  	 */
> @@ -312,17 +414,39 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
>  	 * Limit number of interrupts registered to the platform maximum
>  	 */
>  	irq_limit = gic->irq_offset + gic_irqs;
> -	if (WARN_ON(irq_limit > NR_IRQS))
> +	if (WARN_ON((irq_limit) > NR_IRQS))
>  		irq_limit = NR_IRQS;
>  
>  	/*
>  	 * Setup the Linux IRQ subsystem.
>  	 */
>  	for (i = irq_start; i < irq_limit; i++) {
> -		irq_set_chip_and_handler(i, &gic_chip, handle_fasteoi_irq);
> +#ifdef CONFIG_ARM_GIC_VPPI
> +		if (nrvppis && gic_irq_is_ppi(gic, i))
> +			irq_set_chip_and_handler(i, &gic_chip, gic_handle_ppi);
> +		else
> +#endif
> +		{
> +			irq_set_chip_and_handler(i, &gic_chip,
> +						 handle_fasteoi_irq);
> +			set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
> +		}
> +		irq_set_chip_data(i, gic);
> +	}
> +
> +#ifdef CONFIG_ARM_GIC_VPPI
> +	if (!nrvppis)
> +		goto out;
> +	gic->vppi_base = irq_alloc_descs(-1, 0, nrvppis, 0);
> +	if (unlikely(WARN_ON(gic->vppi_base < 0)))
> +		goto out;
> +	for (i = gic->vppi_base; i < (gic->vppi_base + nrvppis); i++) {
> +		irq_set_chip_and_handler(i, &gic_ppi_chip, handle_fasteoi_irq);

Can we do with handle_percpu_irq instead of handle_fasteoi_irq?

--
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm 
Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [RFC PATCH 01/12] ARM: gic: add per-cpu interrupt multiplexer
  2011-04-20 19:08 ` [RFC PATCH 01/12] ARM: gic: add per-cpu interrupt multiplexer Marc Zyngier
  2011-04-25 20:17   ` Abhijeet Dharmapurikar
@ 2011-04-26  4:00   ` Stephen Boyd
  2011-04-26  9:12     ` Marc Zyngier
  1 sibling, 1 reply; 32+ messages in thread
From: Stephen Boyd @ 2011-04-26  4:00 UTC (permalink / raw)
  To: linux-arm-kernel

Just minor comments. I'm not a GIC or IRQ expert (yet).

On 4/20/2011 12:08 PM, Marc Zyngier wrote:
> @@ -312,17 +414,39 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
>  	 * Limit number of interrupts registered to the platform maximum
>  	 */
>  	irq_limit = gic->irq_offset + gic_irqs;
> -	if (WARN_ON(irq_limit > NR_IRQS))
> +	if (WARN_ON((irq_limit) > NR_IRQS))

() are RFC leftovers?

>  		irq_limit = NR_IRQS;
>  
>  	/*
>  	 * Setup the Linux IRQ subsystem.
>  	 */
>  	for (i = irq_start; i < irq_limit; i++) {
> -		irq_set_chip_and_handler(i, &gic_chip, handle_fasteoi_irq);
> +#ifdef CONFIG_ARM_GIC_VPPI
> +		if (nrvppis && gic_irq_is_ppi(gic, i))
> +			irq_set_chip_and_handler(i, &gic_chip, gic_handle_ppi);
> +		else
> +#endif
> +		{
> +			irq_set_chip_and_handler(i, &gic_chip,
> +						 handle_fasteoi_irq);
> +			set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
> +		}
> +		irq_set_chip_data(i, gic);
> +	}
> +
> +#ifdef CONFIG_ARM_GIC_VPPI
> +	if (!nrvppis)
> +		goto out;
> +	gic->vppi_base = irq_alloc_descs(-1, 0, nrvppis, 0);
> +	if (unlikely(WARN_ON(gic->vppi_base < 0)))

WARN_ON should already have an unlikely in it.

-- 
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [RFC PATCH 02/12] ARM: smp_twd: add support for remapped PPI interrupts
  2011-04-25 17:04   ` Stephen Boyd
@ 2011-04-26  9:05     ` Marc Zyngier
  2011-04-26 16:21       ` Stephen Boyd
  0 siblings, 1 reply; 32+ messages in thread
From: Marc Zyngier @ 2011-04-26  9:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 25 Apr 2011 10:04:17 -0700
Stephen Boyd <sboyd@codeaurora.org> wrote:

Hi Stephen,

> On 4/20/2011 12:08 PM, Marc Zyngier wrote:
> > diff --git a/arch/arm/include/asm/entry-macro-multi.S b/arch/arm/include/asm/entry-macro-multi.S
> > index ec0bbf7..c599795 100644
> > --- a/arch/arm/include/asm/entry-macro-multi.S
> > +++ b/arch/arm/include/asm/entry-macro-multi.S
> > @@ -24,7 +24,7 @@
> >  	adrne	lr, BSYM(1b)
> >  	bne	do_IPI
> >  
> > -#ifdef CONFIG_LOCAL_TIMERS
> > +#if defined(CONFIG_LOCAL_TIMERS) && !defined(CONFIG_ARM_GIC_VPPI)
> >  	test_for_ltirq r0, r6, r5, lr
> >  	movne	r0, sp
> >  	adrne	lr, BSYM(1b)
> > diff --git a/arch/arm/include/asm/hardware/entry-macro-gic.S b/arch/arm/include/asm/hardware/entry-macro-gic.S
> > index c115b82..14a3363 100644
> > --- a/arch/arm/include/asm/hardware/entry-macro-gic.S
> > +++ b/arch/arm/include/asm/hardware/entry-macro-gic.S
> > @@ -17,23 +17,26 @@
> >  	.endm
> >  #endif
> >  
> > +#ifdef CONFIG_ARM_GIC_VPPI
> > +#define DO_IRQ_BASE	16
> > +#else
> > +#define DO_IRQ_BASE	30
> > +#endif
> > +
> >  /*
> >   * The interrupt numbering scheme is defined in the
> >   * 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).
> > + * valid range for an IRQ (30-1020 inclusive). If CONFIG_ARM_GIC_VPPI is
> > + * enabled, local interrupts are handled the same way as global ones.
> >   */
> >  
> >  	.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
> > @@ -43,7 +46,7 @@
> >  
> >  	ldr	\tmp, =1021
> >  	bic     \irqnr, \irqstat, #0x1c00
> > -	cmp     \irqnr, #29
> > +	cmp     \irqnr, #(DO_IRQ_BASE - 1)
> >  	cmpcc	\irqnr, \irqnr
> >  	cmpne	\irqnr, \tmp
> >  	cmpcs	\irqnr, \irqnr
> > @@ -63,6 +66,7 @@
> >  	cmpcs	\irqnr, \irqnr
> >  	.endm
> >  
> > +#ifndef CONFIG_ARM_GIC_VPPI
> >  /* As above, this assumes that irqstat and base are preserved.. */
> >  
> >  	.macro test_for_ltirq, irqnr, irqstat, base, tmp
> > @@ -73,3 +77,4 @@
> >  	streq	\irqstat, [\base, #GIC_CPU_EOI]
> >  	cmp	\tmp, #0
> >  	.endm
> > +#endif
> 
> I would expect these bits to be part of the first patch in this series
> because they're necessary to actually use the CONFIG_ARM_GIC_VPPI
> option. Can you move them to the first patch?

I'd tend to agree with you, though local timer being the only user of
PPIs, it doesn't matter that much... ;-)

I'll move these changes to the first patch on the next iteration of the
patch set.

Thanks,

	M.
-- 
I'm the slime oozin' out from your TV set...

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [RFC PATCH 01/12] ARM: gic: add per-cpu interrupt multiplexer
  2011-04-25 20:17   ` Abhijeet Dharmapurikar
@ 2011-04-26  9:08     ` Marc Zyngier
  0 siblings, 0 replies; 32+ messages in thread
From: Marc Zyngier @ 2011-04-26  9:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 25 Apr 2011 13:17:01 -0700
Abhijeet Dharmapurikar <adharmap@codeaurora.org> wrote:

> Marc Zyngier wrote:
> > diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
> > index e9c2ff8..60f8915 100644
> > --- a/arch/arm/common/gic.c
> > +++ b/arch/arm/common/gic.c
> > @@ -42,6 +42,11 @@ struct gic_chip_data {
> >  	unsigned int irq_offset;
> >  	void __iomem *dist_base;
> >  	void __iomem *cpu_base;
> > +#ifdef CONFIG_ARM_GIC_VPPI
> > +	int	     ppi_base;
> > +	int	     vppi_base;
> > +	u16	     nrppis;
> > +#endif
> >  };
> 
> Can you put some document around this struct? Mention that ppi_base, 
> vppi_base and nrppis will be zero for non-primary gic.

Sure.

> >  static void __init gic_dist_init(struct gic_chip_data *gic,
> >  	unsigned int irq_start)
> >  {
> > -	unsigned int gic_irqs, irq_limit, i;
> > +	unsigned int gic_irqs, irq_limit, i, nrvppis = 0;
> >  	void __iomem *base = gic->dist_base;
> >  	u32 cpumask = 1 << smp_processor_id();
> > +	u32 dist_ctr, nrcpus;
> >  
> >  	cpumask |= cpumask << 8;
> >  	cpumask |= cpumask << 16;
> > @@ -278,11 +359,32 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
> >  	 * Find out how many interrupts are supported.
> >  	 * The GIC only supports up to 1020 interrupt sources.
> >  	 */
> > -	gic_irqs = readl(base + GIC_DIST_CTR) & 0x1f;
> > -	gic_irqs = (gic_irqs + 1) * 32;
> > +	dist_ctr = readl(base + GIC_DIST_CTR);
> > +	gic_irqs = ((dist_ctr & 0x1f) + 1) * 32;
> >  	if (gic_irqs > 1020)
> >  		gic_irqs = 1020;
> >  
> > +	/* Find out how many CPUs are supported (8 max). */
> > +	nrcpus = ((dist_ctr >> 5) & 7) + 1;
> > +
> > +#ifdef CONFIG_ARM_GIC_VPPI
> > +	/*
> > +	 * Nobody would be insane enough to use PPIs on a secondary
> > +	 * GIC, right?
> > +	 */
> > +	if (gic == &gic_data[0]) {
> > +		gic->nrppis = 16 - (irq_start % 16);
> > +		gic->ppi_base = gic->irq_offset + 32 - gic->nrppis;
> > +		nrvppis = gic->nrppis * nrcpus;
> > +	} else {
> > +		gic->ppi_base = 0;
> > +		gic->vppi_base = 0;
> > +	}
> > +#endif
> > +
> > +	pr_info("Configuring GIC with %d sources (%d additional PPIs)\n",
> > +		gic_irqs, nrvppis);
> > +
> >  	/*
> >  	 * Set all global interrupts to be level triggered, active low.
> >  	 */
> > @@ -312,17 +414,39 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
> >  	 * Limit number of interrupts registered to the platform maximum
> >  	 */
> >  	irq_limit = gic->irq_offset + gic_irqs;
> > -	if (WARN_ON(irq_limit > NR_IRQS))
> > +	if (WARN_ON((irq_limit) > NR_IRQS))
> >  		irq_limit = NR_IRQS;
> >  
> >  	/*
> >  	 * Setup the Linux IRQ subsystem.
> >  	 */
> >  	for (i = irq_start; i < irq_limit; i++) {
> > -		irq_set_chip_and_handler(i, &gic_chip, handle_fasteoi_irq);
> > +#ifdef CONFIG_ARM_GIC_VPPI
> > +		if (nrvppis && gic_irq_is_ppi(gic, i))
> > +			irq_set_chip_and_handler(i, &gic_chip, gic_handle_ppi);
> > +		else
> > +#endif
> > +		{
> > +			irq_set_chip_and_handler(i, &gic_chip,
> > +						 handle_fasteoi_irq);
> > +			set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
> > +		}
> > +		irq_set_chip_data(i, gic);
> > +	}
> > +
> > +#ifdef CONFIG_ARM_GIC_VPPI
> > +	if (!nrvppis)
> > +		goto out;
> > +	gic->vppi_base = irq_alloc_descs(-1, 0, nrvppis, 0);
> > +	if (unlikely(WARN_ON(gic->vppi_base < 0)))
> > +		goto out;
> > +	for (i = gic->vppi_base; i < (gic->vppi_base + nrvppis); i++) {
> > +		irq_set_chip_and_handler(i, &gic_ppi_chip, handle_fasteoi_irq);
> 
> Can we do with handle_percpu_irq instead of handle_fasteoi_irq?

Ah, very good point. Should work just fine. Thanks for the suggestion!

	M.
-- 
I'm the slime oozin' out from your TV set...

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [RFC PATCH 01/12] ARM: gic: add per-cpu interrupt multiplexer
  2011-04-26  4:00   ` Stephen Boyd
@ 2011-04-26  9:12     ` Marc Zyngier
  0 siblings, 0 replies; 32+ messages in thread
From: Marc Zyngier @ 2011-04-26  9:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 25 Apr 2011 21:00:33 -0700
Stephen Boyd <sboyd@codeaurora.org> wrote:

> Just minor comments. I'm not a GIC or IRQ expert (yet).
> 
> On 4/20/2011 12:08 PM, Marc Zyngier wrote:
> > @@ -312,17 +414,39 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
> >  	 * Limit number of interrupts registered to the platform maximum
> >  	 */
> >  	irq_limit = gic->irq_offset + gic_irqs;
> > -	if (WARN_ON(irq_limit > NR_IRQS))
> > +	if (WARN_ON((irq_limit) > NR_IRQS))
> 
> () are RFC leftovers?

Just a fossil dating back from an early version of the patch. Will fix.

> >  		irq_limit = NR_IRQS;
> >  
> >  	/*
> >  	 * Setup the Linux IRQ subsystem.
> >  	 */
> >  	for (i = irq_start; i < irq_limit; i++) {
> > -		irq_set_chip_and_handler(i, &gic_chip, handle_fasteoi_irq);
> > +#ifdef CONFIG_ARM_GIC_VPPI
> > +		if (nrvppis && gic_irq_is_ppi(gic, i))
> > +			irq_set_chip_and_handler(i, &gic_chip, gic_handle_ppi);
> > +		else
> > +#endif
> > +		{
> > +			irq_set_chip_and_handler(i, &gic_chip,
> > +						 handle_fasteoi_irq);
> > +			set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
> > +		}
> > +		irq_set_chip_data(i, gic);
> > +	}
> > +
> > +#ifdef CONFIG_ARM_GIC_VPPI
> > +	if (!nrvppis)
> > +		goto out;
> > +	gic->vppi_base = irq_alloc_descs(-1, 0, nrvppis, 0);
> > +	if (unlikely(WARN_ON(gic->vppi_base < 0)))
> 
> WARN_ON should already have an unlikely in it.

Good point. Will fix as well.

Thanks for reviewing,

	M.
-- 
I'm the slime oozin' out from your TV set...

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [RFC PATCH 02/12] ARM: smp_twd: add support for remapped PPI interrupts
  2011-04-26  9:05     ` Marc Zyngier
@ 2011-04-26 16:21       ` Stephen Boyd
  2011-04-26 16:53         ` Marc Zyngier
  0 siblings, 1 reply; 32+ messages in thread
From: Stephen Boyd @ 2011-04-26 16:21 UTC (permalink / raw)
  To: linux-arm-kernel

On 04/26/2011 02:05 AM, Marc Zyngier wrote:
> I'd tend to agree with you, though local timer being the only user of
> PPIs, it doesn't matter that much... ;-)
>
>
>
> I'll move these changes to the first patch on the next iteration of the
> patch set.
>

Thanks. It mattered to me when I only pulled down the first patch and
the MSM patch and tested it out and was confused why the timer tick
wasn't happening. MSM doesn't have the ARM twd.

-- 
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [RFC PATCH 02/12] ARM: smp_twd: add support for remapped PPI interrupts
  2011-04-26 16:21       ` Stephen Boyd
@ 2011-04-26 16:53         ` Marc Zyngier
  0 siblings, 0 replies; 32+ messages in thread
From: Marc Zyngier @ 2011-04-26 16:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 26 Apr 2011 09:21:59 -0700
Stephen Boyd <sboyd@codeaurora.org> wrote:

> On 04/26/2011 02:05 AM, Marc Zyngier wrote:
> > I'll move these changes to the first patch on the next iteration of the
> > patch set.
> >
> 
> Thanks. It mattered to me when I only pulled down the first patch and
> the MSM patch and tested it out and was confused why the timer tick
> wasn't happening. MSM doesn't have the ARM twd.

D'oh! Of course, this is a good reason to move this code to the first
patch.

Thanks,

	M.
-- 
I'm the slime oozin' out from your TV set...

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [RFC PATCH 08/12] ARM: msm: use remapped PPI interrupts for local timer
  2011-04-20 19:08 ` [RFC PATCH 08/12] ARM: msm: " Marc Zyngier
@ 2011-04-26 17:13   ` Stephen Boyd
  2011-05-03 16:15     ` Marc Zyngier
  2011-05-03 19:04     ` Russell King - ARM Linux
  0 siblings, 2 replies; 32+ messages in thread
From: Stephen Boyd @ 2011-04-26 17:13 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/20/2011 12:08 PM, Marc Zyngier wrote:
> diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
> index 38b95e9..68eab51 100644
> --- a/arch/arm/mach-msm/timer.c
> +++ b/arch/arm/mach-msm/timer.c
> @@ -23,6 +23,7 @@
>  #include <linux/io.h>
>  
>  #include <asm/mach/time.h>
> +#include <asm/hardware/gic.h>
>  #include <mach/msm_iomap.h>
>  #include <mach/cpu.h>
>  
> @@ -67,8 +68,8 @@ enum timer_location {
>  struct msm_clock {
>  	struct clock_event_device   clockevent;
>  	struct clocksource          clocksource;
> -	struct irqaction            irq;
>  	void __iomem                *regbase;
> +	unsigned int		    irq;

I don't know why this moved down below regbase, but ok.

> @@ -292,7 +285,14 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt)
>  
>  	local_clock_event = evt;

I think we can get rid of this variable now. We should be able to pass
evt to request_irq() and use that in the interrupt handler. See far below.

This patch doesn't compile for me though. I applied the below fixup:

8<---------------

diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 68eab51..38e51cc 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -246,10 +246,10 @@ static void __init msm_timer_init(void)
                irq = gic_ppi_to_vppi(clock->irq);
                res = request_irq(irq, msm_timer_interrupt,
                                  IRQF_TIMER | IRQF_NOBALANCING | IRQF_TRIGGER_RISING,
-                                 clock->name, &clock->clockevent);
+                                 ce->name, ce);
                if (res)
                        pr_err("msm_timer_init: request_irq failed for %s\n",
-                              clock->name);
+                              ce->name);
 
                clockevents_register_device(ce);
        }
@@ -258,6 +258,7 @@ static void __init msm_timer_init(void)
 #ifdef CONFIG_SMP
 int __cpuinit local_timer_setup(struct clock_event_device *evt)
 {
+       int res;
        struct msm_clock *clock = &msm_clocks[MSM_GLOBAL_TIMER];
 
        /* Use existing clock_event for cpu 0 */
@@ -271,7 +272,7 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt)
                writel(0, clock->regbase + TIMER_CLEAR);
                writel(~0, clock->regbase + TIMER_MATCH_VAL);
        }
-       evt->irq = clock->irq.irq;
+       evt->irq = gic_ppi_to_vppi(clock->irq);
        evt->name = "local_timer";
        evt->features = CLOCK_EVT_FEAT_ONESHOT;
        evt->rating = clock->clockevent.rating;
@@ -285,13 +286,13 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt)
 
        local_clock_event = evt;
 
-       res = request_irq(gic_ppi_to_vppi(irq), msm_timer_interrupt,
+       res = request_irq(evt->irq, msm_timer_interrupt,
                          IRQF_TIMER | IRQF_NOBALANCING | IRQF_TRIGGER_RISING,
-                         clock->name, &clock->clockevent);
+                         clock->clockevent.name, &clock->clockevent);
        if (res) {
                pr_err("local_timer_setup: request_irq failed for %s\n",
-                      clock->name);
-               return err;


----

And then I figured that we shouldn't be overriding the irq handler for
the PPIs anymore in msm code so I applied this patch (not sure about
handle_percpu_irq though, see Abhijeet's response):

8<--------------

diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 35ed594..f66e1f0 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -42,8 +42,6 @@ static struct platform_device *devices[] __initdata = {
 
 static void __init msm8x60_init_irq(void)
 {
-       unsigned int i;
-
        gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE,
                 (void *)MSM_QGIC_CPU_BASE);
 
@@ -55,15 +53,6 @@ static void __init msm8x60_init_irq(void)
         */
        if (!machine_is_msm8x60_sim())
                writel(0x0000FFFF, MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET);
-
-       /* FIXME: Not installing AVS_SVICINT and AVS_SVICINTSWDONE yet
-        * as they are configured as level, which does not play nice with
-        * handle_percpu_irq.
-        */
-       for (i = GIC_PPI_START; i < GIC_SPI_START; i++) {
-               if (i != AVS_SVICINT && i != AVS_SVICINTSWDONE)
-                       irq_set_handler(i, handle_percpu_irq);
-       }
 }
 

---

And then well I thought maybe we could apply this patch on top to
actually pass the clockevent to msm_timer_interrupt() instead of
statically limiting ourselves to one local clockevent (and only two cores):

8<------------

diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 38e51cc..009faea 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -84,13 +84,10 @@ enum {
 
 
 static struct msm_clock msm_clocks[];
-static struct clock_event_device *local_clock_event;
 
 static irqreturn_t msm_timer_interrupt(int irq, void *dev_id)
 {
        struct clock_event_device *evt = dev_id;
-       if (smp_processor_id() != 0)
-               evt = local_clock_event;
        if (evt->event_handler == NULL)
                return IRQ_HANDLED;
        evt->event_handler(evt);
@@ -267,11 +264,9 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt)
 
        writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL);
 
-       if (!local_clock_event) {
-               writel(0, clock->regbase  + TIMER_ENABLE);
-               writel(0, clock->regbase + TIMER_CLEAR);
-               writel(~0, clock->regbase + TIMER_MATCH_VAL);
-       }
+       writel(0, clock->regbase  + TIMER_ENABLE);
+       writel(0, clock->regbase + TIMER_CLEAR);
+       writel(~0, clock->regbase + TIMER_MATCH_VAL);
        evt->irq = gic_ppi_to_vppi(clock->irq);
        evt->name = "local_timer";
        evt->features = CLOCK_EVT_FEAT_ONESHOT;
@@ -284,11 +279,9 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt)
                clockevent_delta2ns(0xf0000000 >> clock->shift, evt);
        evt->min_delta_ns = clockevent_delta2ns(4, evt);
 
-       local_clock_event = evt;
-
        res = request_irq(evt->irq, msm_timer_interrupt,
                          IRQF_TIMER | IRQF_NOBALANCING | IRQF_TRIGGER_RISING,
-                         clock->clockevent.name, &clock->clockevent);
+                         clock->clockevent.name, evt);
        if (res) {
                pr_err("local_timer_setup: request_irq failed for %s\n",
                       clock->clockevent.name);


---

So after all that it looks like it sort of works (at least it boots and
sits at a console). I actually wanted to do something like this a few
days ago and by coincidence you've done it. Telepathy? Perhaps.

I found one issue. I don't quite understand it, but we call
local_timer_setup() on each cpu hotplug add event, and thus the
request_irq() call is going to fail the second time you hotplug add a
cpu. Simplest fix I see is to have a flag so we don't do boot stuff more
than once (similar to our check for !local_clock_event which I
mistakenly dropped up there for the wrong reason!).

Why do we need to call local_timer_setup() on each CPU up though? It
would be nice to be able to just add local timers for all possible CPUs
at boot time and then have the clockevents core take care of enabling
and disabling the events as appropriate without ARM code forcing the
events to be UNUSED and then re-adding the events back on CPU up. I'm
probably missing something really obvious here.

-- 
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 03/12] ARM: omap4: use remapped PPI interrupts for local timer
  2011-04-20 19:08 ` [RFC PATCH 03/12] ARM: omap4: use remapped PPI interrupts for local timer Marc Zyngier
@ 2011-04-29  7:24   ` Santosh Shilimkar
  2011-05-03 16:18     ` Marc Zyngier
  0 siblings, 1 reply; 32+ messages in thread
From: Santosh Shilimkar @ 2011-04-29  7:24 UTC (permalink / raw)
  To: linux-arm-kernel

Marc,

On 4/21/2011 12:38 AM, Marc Zyngier wrote:
> Use the normal interrupt scheme for the local timers by using
> a remapped PPI interrupt.
>
> Tested on a Pandaboard.
>
> Cc: Tony Lindgren<tony@atomide.com>
> Cc: Santosh Shilimkar<santosh.shilimkar@ti.com>
> Signed-off-by: Marc Zyngier<marc.zyngier@arm.com>
> ---

Have reviewed and tested your series along with
OMAP changes. It boots fine on OMAP4430 SDP.

# cat /proc/interrupts
            CPU0       CPU1
.
410:       3678          0   GIC-PPI  local_timer
413:          0       1042   GIC-PPI  local_timer
.
LOC:          0          0  Local timer interrupts
.

Though above output would be bit miss leading, this
series removes the duplicate code from platforms and
consolidate it at one place.

FWIW, you can add my

Reviewedd-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Tested-by: Santosh Shilimkar <santosh.shilimkar@ti.com>

Regards
Santosh

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [RFC PATCH 08/12] ARM: msm: use remapped PPI interrupts for local timer
  2011-04-26 17:13   ` Stephen Boyd
@ 2011-05-03 16:15     ` Marc Zyngier
  2011-05-03 17:38       ` Stephen Boyd
  2011-05-03 19:04     ` Russell King - ARM Linux
  1 sibling, 1 reply; 32+ messages in thread
From: Marc Zyngier @ 2011-05-03 16:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 2011-04-26 at 10:13 -0700, Stephen Boyd wrote:

Hi Stephen,

> On 4/20/2011 12:08 PM, Marc Zyngier wrote:
> > diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
> > index 38b95e9..68eab51 100644
> > --- a/arch/arm/mach-msm/timer.c
> > +++ b/arch/arm/mach-msm/timer.c
> > @@ -23,6 +23,7 @@
> >  #include <linux/io.h>
> >  
> >  #include <asm/mach/time.h>
> > +#include <asm/hardware/gic.h>
> >  #include <mach/msm_iomap.h>
> >  #include <mach/cpu.h>
> >  
> > @@ -67,8 +68,8 @@ enum timer_location {
> >  struct msm_clock {
> >  	struct clock_event_device   clockevent;
> >  	struct clocksource          clocksource;
> > -	struct irqaction            irq;
> >  	void __iomem                *regbase;
> > +	unsigned int		    irq;
> 
> I don't know why this moved down below regbase, but ok.
> 
> > @@ -292,7 +285,14 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt)
> >  
> >  	local_clock_event = evt;
> 
> I think we can get rid of this variable now. We should be able to pass
> evt to request_irq() and use that in the interrupt handler. See far below.
> 
> This patch doesn't compile for me though. I applied the below fixup:
> 
> 8<---------------
> 
> diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
> index 68eab51..38e51cc 100644
> --- a/arch/arm/mach-msm/timer.c
> +++ b/arch/arm/mach-msm/timer.c
> @@ -246,10 +246,10 @@ static void __init msm_timer_init(void)
>                 irq = gic_ppi_to_vppi(clock->irq);
>                 res = request_irq(irq, msm_timer_interrupt,
>                                   IRQF_TIMER | IRQF_NOBALANCING | IRQF_TRIGGER_RISING,
> -                                 clock->name, &clock->clockevent);
> +                                 ce->name, ce);
>                 if (res)
>                         pr_err("msm_timer_init: request_irq failed for %s\n",
> -                              clock->name);
> +                              ce->name);
>  
>                 clockevents_register_device(ce);
>         }
> @@ -258,6 +258,7 @@ static void __init msm_timer_init(void)
>  #ifdef CONFIG_SMP
>  int __cpuinit local_timer_setup(struct clock_event_device *evt)
>  {
> +       int res;
>         struct msm_clock *clock = &msm_clocks[MSM_GLOBAL_TIMER];
>  
>         /* Use existing clock_event for cpu 0 */
> @@ -271,7 +272,7 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt)
>                 writel(0, clock->regbase + TIMER_CLEAR);
>                 writel(~0, clock->regbase + TIMER_MATCH_VAL);
>         }
> -       evt->irq = clock->irq.irq;
> +       evt->irq = gic_ppi_to_vppi(clock->irq);
>         evt->name = "local_timer";
>         evt->features = CLOCK_EVT_FEAT_ONESHOT;
>         evt->rating = clock->clockevent.rating;
> @@ -285,13 +286,13 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt)
>  
>         local_clock_event = evt;
>  
> -       res = request_irq(gic_ppi_to_vppi(irq), msm_timer_interrupt,
> +       res = request_irq(evt->irq, msm_timer_interrupt,
>                           IRQF_TIMER | IRQF_NOBALANCING | IRQF_TRIGGER_RISING,
> -                         clock->name, &clock->clockevent);
> +                         clock->clockevent.name, &clock->clockevent);
>         if (res) {
>                 pr_err("local_timer_setup: request_irq failed for %s\n",
> -                      clock->name);
> -               return err;
> 
> 
> ----
> 
> And then I figured that we shouldn't be overriding the irq handler for
> the PPIs anymore in msm code so I applied this patch (not sure about
> handle_percpu_irq though, see Abhijeet's response):
> 
> 8<--------------
> 
> diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
> index 35ed594..f66e1f0 100644
> --- a/arch/arm/mach-msm/board-msm8x60.c
> +++ b/arch/arm/mach-msm/board-msm8x60.c
> @@ -42,8 +42,6 @@ static struct platform_device *devices[] __initdata = {
>  
>  static void __init msm8x60_init_irq(void)
>  {
> -       unsigned int i;
> -
>         gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE,
>                  (void *)MSM_QGIC_CPU_BASE);
>  
> @@ -55,15 +53,6 @@ static void __init msm8x60_init_irq(void)
>          */
>         if (!machine_is_msm8x60_sim())
>                 writel(0x0000FFFF, MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET);
> -
> -       /* FIXME: Not installing AVS_SVICINT and AVS_SVICINTSWDONE yet
> -        * as they are configured as level, which does not play nice with
> -        * handle_percpu_irq.
> -        */
> -       for (i = GIC_PPI_START; i < GIC_SPI_START; i++) {
> -               if (i != AVS_SVICINT && i != AVS_SVICINTSWDONE)
> -                       irq_set_handler(i, handle_percpu_irq);
> -       }
>  }
>  
> 
> ---
> 
> And then well I thought maybe we could apply this patch on top to
> actually pass the clockevent to msm_timer_interrupt() instead of
> statically limiting ourselves to one local clockevent (and only two cores):
> 
> 8<------------
> 
> diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
> index 38e51cc..009faea 100644
> --- a/arch/arm/mach-msm/timer.c
> +++ b/arch/arm/mach-msm/timer.c
> @@ -84,13 +84,10 @@ enum {
>  
> 
>  static struct msm_clock msm_clocks[];
> -static struct clock_event_device *local_clock_event;
>  
>  static irqreturn_t msm_timer_interrupt(int irq, void *dev_id)
>  {
>         struct clock_event_device *evt = dev_id;
> -       if (smp_processor_id() != 0)
> -               evt = local_clock_event;
>         if (evt->event_handler == NULL)
>                 return IRQ_HANDLED;
>         evt->event_handler(evt);
> @@ -267,11 +264,9 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt)
>  
>         writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL);
>  
> -       if (!local_clock_event) {
> -               writel(0, clock->regbase  + TIMER_ENABLE);
> -               writel(0, clock->regbase + TIMER_CLEAR);
> -               writel(~0, clock->regbase + TIMER_MATCH_VAL);
> -       }
> +       writel(0, clock->regbase  + TIMER_ENABLE);
> +       writel(0, clock->regbase + TIMER_CLEAR);
> +       writel(~0, clock->regbase + TIMER_MATCH_VAL);
>         evt->irq = gic_ppi_to_vppi(clock->irq);
>         evt->name = "local_timer";
>         evt->features = CLOCK_EVT_FEAT_ONESHOT;
> @@ -284,11 +279,9 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt)
>                 clockevent_delta2ns(0xf0000000 >> clock->shift, evt);
>         evt->min_delta_ns = clockevent_delta2ns(4, evt);
>  
> -       local_clock_event = evt;
> -
>         res = request_irq(evt->irq, msm_timer_interrupt,
>                           IRQF_TIMER | IRQF_NOBALANCING | IRQF_TRIGGER_RISING,
> -                         clock->clockevent.name, &clock->clockevent);
> +                         clock->clockevent.name, evt);
>         if (res) {
>                 pr_err("local_timer_setup: request_irq failed for %s\n",
>                        clock->clockevent.name);
> 
> 
> ---
> 
> So after all that it looks like it sort of works (at least it boots and
> sits at a console). I actually wanted to do something like this a few
> days ago and by coincidence you've done it. Telepathy? Perhaps.

Thanks for having a look at all of this. I think the lack of an MSM
platform shows here... Can I fold your patches into mine?

I think that this kind of cleanup crossed the mind of anyone having to
deal with local timers on more than one platform. I just got fed up
quicker... ;-)

> I found one issue. I don't quite understand it, but we call
> local_timer_setup() on each cpu hotplug add event, and thus the
> request_irq() call is going to fail the second time you hotplug add a
> cpu. Simplest fix I see is to have a flag so we don't do boot stuff more
> than once (similar to our check for !local_clock_event which I
> mistakenly dropped up there for the wrong reason!).
> 
> Why do we need to call local_timer_setup() on each CPU up though? It
> would be nice to be able to just add local timers for all possible CPUs
> at boot time and then have the clockevents core take care of enabling
> and disabling the events as appropriate without ARM code forcing the
> events to be UNUSED and then re-adding the events back on CPU up. I'm
> probably missing something really obvious here.
> 

This need to be investigated indeed. I'm seeing a nice crash on my OMAP4
while bringing a CPU back up, and I suspect it might be the same root
cause.

	M.
-- 
Reality is an implementation detail.
-- 
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium.  Thank you.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [RFC PATCH 03/12] ARM: omap4: use remapped PPI interrupts for local timer
  2011-04-29  7:24   ` Santosh Shilimkar
@ 2011-05-03 16:18     ` Marc Zyngier
  0 siblings, 0 replies; 32+ messages in thread
From: Marc Zyngier @ 2011-05-03 16:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 2011-04-29 at 12:54 +0530, Santosh Shilimkar wrote:

Hi Santosh,

> On 4/21/2011 12:38 AM, Marc Zyngier wrote:
> > Use the normal interrupt scheme for the local timers by using
> > a remapped PPI interrupt.
> >
> > Tested on a Pandaboard.
> >
> > Cc: Tony Lindgren<tony@atomide.com>
> > Cc: Santosh Shilimkar<santosh.shilimkar@ti.com>
> > Signed-off-by: Marc Zyngier<marc.zyngier@arm.com>
> > ---
> 
> Have reviewed and tested your series along with
> OMAP changes. It boots fine on OMAP4430 SDP.
> 
> # cat /proc/interrupts
>             CPU0       CPU1
> .
> 410:       3678          0   GIC-PPI  local_timer
> 413:          0       1042   GIC-PPI  local_timer
> .
> LOC:          0          0  Local timer interrupts
> .
> 
> Though above output would be bit miss leading, this
> series removes the duplicate code from platforms and
> consolidate it at one place.

The LOC line is gone in the next iteration of the patch serie.

> FWIW, you can add my
> 
> Reviewedd-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Tested-by: Santosh Shilimkar <santosh.shilimkar@ti.com>

Thanks for testing.

	M.
-- 
Reality is an implementation detail.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [RFC PATCH 08/12] ARM: msm: use remapped PPI interrupts for local timer
  2011-05-03 16:15     ` Marc Zyngier
@ 2011-05-03 17:38       ` Stephen Boyd
  0 siblings, 0 replies; 32+ messages in thread
From: Stephen Boyd @ 2011-05-03 17:38 UTC (permalink / raw)
  To: linux-arm-kernel

On 05/03/2011 09:15 AM, Marc Zyngier wrote:
>
> Thanks for having a look at all of this. I think the lack of an MSM
> platform shows here... Can I fold your patches into mine?

Sure, just leave out this hunk:

-       if (!local_clock_event) {
-               writel(0, clock->regbase  + TIMER_ENABLE);
-               writel(0, clock->regbase + TIMER_CLEAR);
-               writel(~0, clock->regbase + TIMER_MATCH_VAL);
-       }


and add a bool or something to make sure these lines don't get executed
more than once. Hopefully you get the idea.

-- 
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [RFC PATCH 08/12] ARM: msm: use remapped PPI interrupts for local timer
  2011-04-26 17:13   ` Stephen Boyd
  2011-05-03 16:15     ` Marc Zyngier
@ 2011-05-03 19:04     ` Russell King - ARM Linux
  2011-05-04  5:47       ` Stephen Boyd
  1 sibling, 1 reply; 32+ messages in thread
From: Russell King - ARM Linux @ 2011-05-03 19:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Apr 26, 2011 at 10:13:52AM -0700, Stephen Boyd wrote:
> Why do we need to call local_timer_setup() on each CPU up though? It
> would be nice to be able to just add local timers for all possible CPUs
> at boot time and then have the clockevents core take care of enabling
> and disabling the events as appropriate without ARM code forcing the
> events to be UNUSED and then re-adding the events back on CPU up. I'm
> probably missing something really obvious here.

Firstly, because you can't access the local timer registers from non-
local CPUs.  Secondly, when you offline a CPU, generic code unregisters
the local timer, so whenever you online a CPU you have to add its local
timer clockevent back again.

Thirdly, you may have a system where the local timer gets powered down
when a CPU is offlined, and so it would need reinitialization when you
online it again.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [RFC PATCH 08/12] ARM: msm: use remapped PPI interrupts for local timer
  2011-05-03 19:04     ` Russell King - ARM Linux
@ 2011-05-04  5:47       ` Stephen Boyd
  2011-05-04 18:45         ` Jeff Ohlstein
  0 siblings, 1 reply; 32+ messages in thread
From: Stephen Boyd @ 2011-05-04  5:47 UTC (permalink / raw)
  To: linux-arm-kernel

On 5/3/2011 12:04 PM, Russell King - ARM Linux wrote:
> On Tue, Apr 26, 2011 at 10:13:52AM -0700, Stephen Boyd wrote:
>> Why do we need to call local_timer_setup() on each CPU up though? It
>> would be nice to be able to just add local timers for all possible CPUs
>> at boot time and then have the clockevents core take care of enabling
>> and disabling the events as appropriate without ARM code forcing the
>> events to be UNUSED and then re-adding the events back on CPU up. I'm
>> probably missing something really obvious here.
> Firstly, because you can't access the local timer registers from non-
> local CPUs.  Secondly, when you offline a CPU, generic code unregisters
> the local timer, so whenever you online a CPU you have to add its local
> timer clockevent back again.
>
> Thirdly, you may have a system where the local timer gets powered down
> when a CPU is offlined, and so it would need reinitialization when you
> online it again.

Ok that all sounds fine and good. Thanks.

I took a peek at the APB timer on x86 and I see that apbt_setup_irq()
does an

        if (system_state == SYSTEM_BOOTING) {
                if (request_irq(adev->irq, apbt_interrupt_handler,

which is probably exactly what we want to do to handle the crash I'm
talking about. They also do a memcpy() of the clockevent and what looks
like a disable_irq() on CPU_DEAD which might all be good ideas.

-- 
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [RFC PATCH 08/12] ARM: msm: use remapped PPI interrupts for local timer
  2011-05-04  5:47       ` Stephen Boyd
@ 2011-05-04 18:45         ` Jeff Ohlstein
  2011-05-05  1:17           ` Stephen Boyd
  0 siblings, 1 reply; 32+ messages in thread
From: Jeff Ohlstein @ 2011-05-04 18:45 UTC (permalink / raw)
  To: linux-arm-kernel

Stephen Boyd wrote:
> 
> I took a peek at the APB timer on x86 and I see that apbt_setup_irq()
> does an
> 
>         if (system_state == SYSTEM_BOOTING) {
>                 if (request_irq(adev->irq, apbt_interrupt_handler,
> 
> which is probably exactly what we want to do to handle the crash I'm
> talking about.
> 

This won't work right with the maxcpus commandline option set to
something lower than the number of cpus present on the system. This
option controls how many cpus the system tries to bring up during boot,
while still allowing one to hotplug the rest of them later. If you do
hotplug them later, system_state will no longer be SYSTEM_BOOTING, and
this code won't do what it needs to do.

-- 
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [RFC PATCH 08/12] ARM: msm: use remapped PPI interrupts for local timer
  2011-05-04 18:45         ` Jeff Ohlstein
@ 2011-05-05  1:17           ` Stephen Boyd
  0 siblings, 0 replies; 32+ messages in thread
From: Stephen Boyd @ 2011-05-05  1:17 UTC (permalink / raw)
  To: linux-arm-kernel

On 05/04/2011 11:45 AM, Jeff Ohlstein wrote:
> This won't work right with the maxcpus commandline option set to
> something lower than the number of cpus present on the system. This
> option controls how many cpus the system tries to bring up during boot,
> while still allowing one to hotplug the rest of them later. If you do
> hotplug them later, system_state will no longer be SYSTEM_BOOTING, and
> this code won't do what it needs to do.
>

Hmm the documentation isn't very clear there. I see in
Documentation/cpu-hotplug.txt that maxcpus=n means:

             Restrict boot time cpus to n. Say if you have 4 cpus, using
             maxcpus=2 will only boot 2. You can choose to bring the
             other cpus later online, read FAQ's for more info.

and then Documentation/kernel-parameters.txt says:

             [SMP] Maximum number of processors that an SMP kernel
             should make use of.  maxcpus=n : n >= 0 limits the
             kernel to using 'n' processors.  n=0 is a special case,
             it is equivalent to "nosmp", which also disables
             the IO APIC.

which doesn't agree. That should be reconciled.

^ permalink raw reply	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2011-05-05  1:17 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-04-20 19:08 [RFC PATCH 00/12] Consolidating GIC per-cpu interrupts Marc Zyngier
2011-04-20 19:08 ` [RFC PATCH 01/12] ARM: gic: add per-cpu interrupt multiplexer Marc Zyngier
2011-04-25 20:17   ` Abhijeet Dharmapurikar
2011-04-26  9:08     ` Marc Zyngier
2011-04-26  4:00   ` Stephen Boyd
2011-04-26  9:12     ` Marc Zyngier
2011-04-20 19:08 ` [RFC PATCH 02/12] ARM: smp_twd: add support for remapped PPI interrupts Marc Zyngier
2011-04-25 17:04   ` Stephen Boyd
2011-04-26  9:05     ` Marc Zyngier
2011-04-26 16:21       ` Stephen Boyd
2011-04-26 16:53         ` Marc Zyngier
2011-04-20 19:08 ` [RFC PATCH 03/12] ARM: omap4: use remapped PPI interrupts for local timer Marc Zyngier
2011-04-29  7:24   ` Santosh Shilimkar
2011-05-03 16:18     ` Marc Zyngier
2011-04-20 19:08 ` [RFC PATCH 04/12] ARM: versatile: " Marc Zyngier
2011-04-20 19:08 ` [RFC PATCH 05/12] ARM: shmobile: " Marc Zyngier
2011-04-20 19:08 ` [RFC PATCH 06/12] ARM: ux500: " Marc Zyngier
2011-04-21  8:44   ` Srinidhi KASAGAR
2011-04-21  8:53     ` Marc Zyngier
2011-04-20 19:08 ` [RFC PATCH 07/12] ARM: tegra: " Marc Zyngier
2011-04-20 19:08 ` [RFC PATCH 08/12] ARM: msm: " Marc Zyngier
2011-04-26 17:13   ` Stephen Boyd
2011-05-03 16:15     ` Marc Zyngier
2011-05-03 17:38       ` Stephen Boyd
2011-05-03 19:04     ` Russell King - ARM Linux
2011-05-04  5:47       ` Stephen Boyd
2011-05-04 18:45         ` Jeff Ohlstein
2011-05-05  1:17           ` Stephen Boyd
2011-04-20 19:08 ` [RFC PATCH 09/12] ARM: exynos4: " Marc Zyngier
2011-04-20 19:08 ` [RFC PATCH 10/12] ARM: gic: remove previous local timer interrupt handling Marc Zyngier
2011-04-20 19:08 ` [RFC PATCH 11/12] ARM: gic: add compute_irqnr macro for exynos4 Marc Zyngier
2011-04-20 19:08 ` [RFC PATCH 12/12] ARM: SMP: automatically select ARM_GIC_VPPI Marc Zyngier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).