linux-next: manual merge of the arm-soc tree with the arm tree

From: Stephen Rothwell
Date: Mon Oct 24 2011 - 16:40:05 EST


Hi Arnd,

Today's linux-next merge of the arm-soc tree got a conflict in
arch/arm/common/gic.c between commits 292b293ceef2 ("ARM: gic:
consolidate PPI handling") and 28af690a284d ("ARM: gic, local timers: use
the request_percpu_irq() interface") from the arm tree and commits
2071a2a4b8ed ("ARM: gic: add irq_domain support") and e3f14d321b34 ("ARM:
gic: add OF based initialization") from the arm-soc tree.

I hacked it up (almost certainly incorrectly - see below). Someone will
have to provide Linus with a fix for this.
--
Cheers,
Stephen Rothwell sfr@xxxxxxxxxxxxxxxx

diff --cc arch/arm/common/gic.c
index 016c1ae,65cf39d..0000000
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@@ -29,9 -29,10 +29,13 @@@
#include <linux/cpu_pm.h>
#include <linux/cpumask.h>
#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/percpu.h>
+#include <linux/slab.h>
+ #include <linux/of.h>
+ #include <linux/of_address.h>
+ #include <linux/of_irq.h>
+ #include <linux/irqdomain.h>

#include <asm/irq.h>
#include <asm/mach/irq.h>
@@@ -259,14 -259,14 +262,15 @@@ void __init gic_cascade_irq(unsigned in
irq_set_chained_handler(irq, gic_handle_cascade_irq);
}

- static void __init gic_dist_init(struct gic_chip_data *gic,
- unsigned int irq_start)
+ static void __init gic_dist_init(struct gic_chip_data *gic)
{
- unsigned int gic_irqs, irq_limit, i;
+ unsigned int i, irq;
u32 cpumask;
+ unsigned int gic_irqs = gic->gic_irqs;
+ struct irq_domain *domain = &gic->domain;
void __iomem *base = gic->dist_base;
u32 cpu = 0;
+ u32 nrppis = 0, ppi_base = 0;

#ifdef CONFIG_SMP
cpu = cpu_logical_map(smp_processor_id());
@@@ -279,34 -279,6 +283,23 @@@
writel_relaxed(0, base + GIC_DIST_CTRL);

/*
- * Find out how many interrupts are supported.
- * The GIC only supports up to 1020 interrupt sources.
- */
- gic_irqs = readl_relaxed(base + GIC_DIST_CTR) & 0x1f;
- gic_irqs = (gic_irqs + 1) * 32;
- if (gic_irqs > 1020)
- gic_irqs = 1020;
-
- gic->gic_irqs = gic_irqs;
-
- /*
+ * Nobody would be insane enough to use PPIs on a secondary
+ * GIC, right?
+ */
+ if (gic == &gic_data[0]) {
+ nrppis = (32 - irq_start) & 31;
+
+ /* The GIC only supports up to 16 PPIs. */
+ if (nrppis > 16)
+ BUG();
+
+ ppi_base = gic->irq_offset + 32 - nrppis;
+ }
+
+ pr_info("Configuring GIC with %d sources (%d PPIs)\n",
+ gic_irqs, (gic == &gic_data[0]) ? nrppis : 0);
+
+ /*
* Set all global interrupts to be level triggered, active low.
*/
for (i = 32; i < gic_irqs; i += 16)
@@@ -332,29 -304,12 +325,22 @@@
writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32);

/*
- * Limit number of interrupts registered to the platform maximum
- */
- irq_limit = gic->irq_offset + gic_irqs;
- if (WARN_ON(irq_limit > NR_IRQS))
- irq_limit = NR_IRQS;
-
- /*
* Setup the Linux IRQ subsystem.
*/
+ for (i = 0; i < nrppis; i++) {
+ int ppi = i + ppi_base;
+
+ irq_set_percpu_devid(ppi);
+ irq_set_chip_and_handler(ppi, &gic_chip,
+ handle_percpu_devid_irq);
+ irq_set_chip_data(ppi, gic);
+ set_irq_flags(ppi, IRQF_VALID | IRQF_NOAUTOEN);
+ }
+
- for (i = irq_start + nrppis; i < irq_limit; i++) {
- irq_set_chip_and_handler(i, &gic_chip, handle_fasteoi_irq);
- irq_set_chip_data(i, gic);
- set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+ irq_domain_for_each_irq(domain, i, irq) {
+ irq_set_chip_and_handler(irq, &gic_chip, handle_fasteoi_irq);
+ irq_set_chip_data(irq, gic);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}

writel_relaxed(1, base + GIC_DIST_CTRL);

Attachment: pgp00000.pgp
Description: PGP signature