aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-23 15:15:27 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-23 15:15:27 -0700
commit42cd71bf1e3a081b3150018bbf448cb6c8a844a5 (patch)
tree4a5d2eb0444255e4ad827a76dbd1417dd3876db6 /arch/arm/mach-omap2
parentDocumentation: update GregKH links (diff)
parentMerge branch 'devel-stable' into for-linus (diff)
downloadlinux-dev-42cd71bf1e3a081b3150018bbf448cb6c8a844a5.tar.xz
linux-dev-42cd71bf1e3a081b3150018bbf448cb6c8a844a5.zip
Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm: (137 commits) ARM: bcmring: convert to use sp804 clockevents ARM: bcmring: convert to sp804 clocksource ARM: 6912/1: bcmring: Add clkdev table in init_early clockevents: ARM sp804: obtain sp804 timer rate via clks clockevents: ARM sp804: allow clockevent name to be specified clocksource: ARM sp804: obtain sp804 timer rate via clks clocksource: ARM sp804: allow clocksource name to be specified clocksource: convert OMAP1 to 32-bit down counting clocksource clocksource: convert MXS timrotv2 to 32-bit down counting clocksource clocksource: convert SPEAr platforms 16-bit up counting clocksource clocksource: convert Integrator/AP 16-bit down counting clocksource clocksource: convert W90x900 24-bit down counting clocksource clocksource: convert ARM 32-bit down counting clocksources clocksource: convert ARM 32-bit up counting clocksources clocksource: add common mmio clocksource ARM: update sa1100 to reflect PXA updates ARM: omap1: convert to using readl/writel instead of volatile struct ARM: omap1: delete useless interrupt handler ARM: s5p: consolidate selection of timer register ARM: 6939/1: fix missing 'cpu_relax()' declaration ...
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r--arch/arm/mach-omap2/include/mach/omap4-common.h7
-rw-r--r--arch/arm/mach-omap2/irq.c97
-rw-r--r--arch/arm/mach-omap2/omap-smp.c5
3 files changed, 36 insertions, 73 deletions
diff --git a/arch/arm/mach-omap2/include/mach/omap4-common.h b/arch/arm/mach-omap2/include/mach/omap4-common.h
index de441c05a6a6..e4bd87619734 100644
--- a/arch/arm/mach-omap2/include/mach/omap4-common.h
+++ b/arch/arm/mach-omap2/include/mach/omap4-common.h
@@ -33,4 +33,11 @@ extern void __iomem *gic_dist_base_addr;
extern void __init gic_init_irq(void);
extern void omap_smc1(u32 fn, u32 arg);
+#ifdef CONFIG_SMP
+/* Needed for secondary core boot */
+extern void omap_secondary_startup(void);
+extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask);
+extern void omap_auxcoreboot_addr(u32 cpu_addr);
+extern u32 omap_read_auxcoreboot0(void);
+#endif
#endif
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index 237e4530abf2..3af2b7a1045e 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -73,83 +73,18 @@ static u32 intc_bank_read_reg(struct omap_irq_bank *bank, u16 reg)
return __raw_readl(bank->base_reg + reg);
}
-static int previous_irq;
-
-/*
- * On 34xx we can get occasional spurious interrupts if the ack from
- * an interrupt handler does not get posted before we unmask. Warn about
- * the interrupt handlers that need to flush posted writes.
- */
-static int omap_check_spurious(unsigned int irq)
-{
- u32 sir, spurious;
-
- sir = intc_bank_read_reg(&irq_banks[0], INTC_SIR);
- spurious = sir >> 7;
-
- if (spurious) {
- printk(KERN_WARNING "Spurious irq %i: 0x%08x, please flush "
- "posted write for irq %i\n",
- irq, sir, previous_irq);
- return spurious;
- }
-
- return 0;
-}
-
/* XXX: FIQ and additional INTC support (only MPU at the moment) */
static void omap_ack_irq(struct irq_data *d)
{
intc_bank_write_reg(0x1, &irq_banks[0], INTC_CONTROL);
}
-static void omap_mask_irq(struct irq_data *d)
-{
- unsigned int irq = d->irq;
- int offset = irq & (~(IRQ_BITS_PER_REG - 1));
-
- if (cpu_is_omap34xx() && !cpu_is_ti816x()) {
- int spurious = 0;
-
- /*
- * INT_34XX_GPT12_IRQ is also the spurious irq. Maybe because
- * it is the highest irq number?
- */
- if (irq == INT_34XX_GPT12_IRQ)
- spurious = omap_check_spurious(irq);
-
- if (!spurious)
- previous_irq = irq;
- }
-
- irq &= (IRQ_BITS_PER_REG - 1);
-
- intc_bank_write_reg(1 << irq, &irq_banks[0], INTC_MIR_SET0 + offset);
-}
-
-static void omap_unmask_irq(struct irq_data *d)
-{
- unsigned int irq = d->irq;
- int offset = irq & (~(IRQ_BITS_PER_REG - 1));
-
- irq &= (IRQ_BITS_PER_REG - 1);
-
- intc_bank_write_reg(1 << irq, &irq_banks[0], INTC_MIR_CLEAR0 + offset);
-}
-
static void omap_mask_ack_irq(struct irq_data *d)
{
- omap_mask_irq(d);
+ irq_gc_mask_disable_reg(d);
omap_ack_irq(d);
}
-static struct irq_chip omap_irq_chip = {
- .name = "INTC",
- .irq_ack = omap_mask_ack_irq,
- .irq_mask = omap_mask_irq,
- .irq_unmask = omap_unmask_irq,
-};
-
static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank)
{
unsigned long tmp;
@@ -186,11 +121,31 @@ int omap_irq_pending(void)
return 0;
}
+static __init void
+omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num)
+{
+ struct irq_chip_generic *gc;
+ struct irq_chip_type *ct;
+
+ gc = irq_alloc_generic_chip("INTC", 1, irq_start, base,
+ handle_level_irq);
+ ct = gc->chip_types;
+ ct->chip.irq_ack = omap_mask_ack_irq;
+ ct->chip.irq_mask = irq_gc_mask_disable_reg;
+ ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
+
+ ct->regs.ack = INTC_CONTROL;
+ ct->regs.enable = INTC_MIR_CLEAR0;
+ ct->regs.disable = INTC_MIR_SET0;
+ irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
+ IRQ_NOREQUEST | IRQ_NOPROBE, 0);
+}
+
void __init omap_init_irq(void)
{
unsigned long nr_of_irqs = 0;
unsigned int nr_banks = 0;
- int i;
+ int i, j;
for (i = 0; i < ARRAY_SIZE(irq_banks); i++) {
unsigned long base = 0;
@@ -215,17 +170,15 @@ void __init omap_init_irq(void)
omap_irq_bank_init_one(bank);
+ for (i = 0, j = 0; i < bank->nr_irqs; i += 32, j += 0x20)
+ omap_alloc_gc(bank->base_reg + j, i, 32);
+
nr_of_irqs += bank->nr_irqs;
nr_banks++;
}
printk(KERN_INFO "Total of %ld interrupts on %d active controller%s\n",
nr_of_irqs, nr_banks, nr_banks > 1 ? "s" : "");
-
- for (i = 0; i < nr_of_irqs; i++) {
- irq_set_chip_and_handler(i, &omap_irq_chip, handle_level_irq);
- set_irq_flags(i, IRQF_VALID);
- }
}
#ifdef CONFIG_ARCH_OMAP3
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index b66cfe8bc464..ecfe93c4b585 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -21,6 +21,7 @@
#include <linux/io.h>
#include <asm/cacheflush.h>
+#include <asm/hardware/gic.h>
#include <asm/smp_scu.h>
#include <mach/hardware.h>
#include <mach/omap4-common.h>
@@ -63,7 +64,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
omap_modify_auxcoreboot0(0x200, 0xfffffdff);
flush_cache_all();
smp_wmb();
- smp_cross_call(cpumask_of(cpu), 1);
+ gic_raise_softirq(cpumask_of(cpu), 1);
/*
* Now the secondary core is starting up let it run its
@@ -118,6 +119,8 @@ void __init smp_init_cpus(void)
for (i = 0; i < ncores; i++)
set_cpu_possible(i, true);
+
+ set_smp_cross_call(gic_raise_softirq);
}
void __init platform_smp_prepare_cpus(unsigned int max_cpus)