From 43b3e1898206a1e385c9cb06f6040ea83a58b638 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Mon, 4 Apr 2011 09:32:46 +0100 Subject: ARM: 6860/1: OMAP4: Move the privately used SMP boot functions to OMAP specific header. Header files in arch/arm/*/include/mach included from arch/arm/include/asm/*.h are there to provide necessary definitions for either the rest of the kernel or the ARM specific parts. They shouldn't be polluted with *any* platform private stuff which is not absolutely necessary to satisfy the rest of the kernel. Hence move the OMAP specific SMP boot functions to different header instead of keeping them in 'plat/smp.h' which gets included indirectly by linux/smp.h The patch is outcome of the discussion in below thread: http://www.spinics.net/lists/arm-kernel/msg120363.html Cc: Tony Lindgren Signed-off-by: Santosh Shilimkar Signed-off-by: Russell King --- arch/arm/mach-omap2/include/mach/omap4-common.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch/arm/mach-omap2') 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 -- cgit v1.2.2 From 667a11facee70c0bd15cf07946fba71236490e07 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 16 May 2011 02:07:38 -0700 Subject: arm: omap2/3: Use generic irq chip Use generic irq chip for omap2 & 3. Note that this patch also leaves out the spurious IRQ warning for omap3. This warning should no longer be needed as the interrupt handlers for various devices have implemented the necessayr read-back of the posted write. Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/irq.c | 97 ++++++++++++----------------------------------- 1 file changed, 25 insertions(+), 72 deletions(-) (limited to 'arch/arm/mach-omap2') 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 -- cgit v1.2.2 From 0f7b332f9777819a39a3b325690379a7efef89d1 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 3 Apr 2011 13:01:30 +0100 Subject: ARM: consolidate SMP cross call implementation Rather than having each platform class provide a mach/smp.h header for smp_cross_call(), arrange for them to register the function with the core ARM SMP code instead. Signed-off-by: Russell King --- arch/arm/mach-omap2/omap-smp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-omap2') 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 #include +#include #include #include #include @@ -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) -- cgit v1.2.2