Skip to content

Commit

Permalink
ARM: realview/vexpress: consolidate SMP bringup code
Browse files Browse the repository at this point in the history
Realview and Versatile Express share the same SMP bringup code, so
consolidate the two implementations.

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  • Loading branch information
Russell King committed Feb 19, 2011
1 parent cdab142 commit 0462b44
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 234 deletions.
2 changes: 1 addition & 1 deletion arch/arm/mach-realview/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ obj-$(CONFIG_MACH_REALVIEW_PB11MP) += realview_pb11mp.o
obj-$(CONFIG_MACH_REALVIEW_PB1176) += realview_pb1176.o
obj-$(CONFIG_MACH_REALVIEW_PBA8) += realview_pba8.o
obj-$(CONFIG_MACH_REALVIEW_PBX) += realview_pbx.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
obj-$(CONFIG_SMP) += platsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
40 changes: 0 additions & 40 deletions arch/arm/mach-realview/headsmp.S

This file was deleted.

98 changes: 3 additions & 95 deletions arch/arm/mach-realview/platsmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,44 +10,21 @@
*/
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/jiffies.h>
#include <linux/smp.h>
#include <linux/io.h>

#include <asm/cacheflush.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/smp_scu.h>
#include <asm/unified.h>

#include <mach/board-eb.h>
#include <mach/board-pb11mp.h>
#include <mach/board-pbx.h>
#include <asm/smp_scu.h>

#include "core.h"

extern void realview_secondary_startup(void);

/*
* control for which core is the next to come out of the secondary
* boot "holding pen"
*/
volatile int __cpuinitdata pen_release = -1;

/*
* Write pen_release in a way that is guaranteed to be visible to all
* observers, irrespective of whether they're taking part in coherency
* or not. This is necessary for the hotplug code to work reliably.
*/
static void __cpuinit write_pen_release(int val)
{
pen_release = val;
smp_wmb();
__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
}
extern void versatile_secondary_startup(void);

static void __iomem *scu_base_addr(void)
{
Expand All @@ -62,75 +39,6 @@ static void __iomem *scu_base_addr(void)
return (void __iomem *)0;
}

static DEFINE_SPINLOCK(boot_lock);

void __cpuinit platform_secondary_init(unsigned int cpu)
{
/*
* if any interrupts are already enabled for the primary
* core (e.g. timer irq), then they will not have been enabled
* for us: do so
*/
gic_secondary_init(0);

/*
* let the primary processor know we're out of the
* pen, then head off into the C entry point
*/
write_pen_release(-1);

/*
* Synchronise with the boot thread.
*/
spin_lock(&boot_lock);
spin_unlock(&boot_lock);
}

int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
{
unsigned long timeout;

/*
* set synchronisation state between this boot processor
* and the secondary one
*/
spin_lock(&boot_lock);

/*
* The secondary processor is waiting to be released from
* the holding pen - release it, then wait for it to flag
* that it has been released by resetting pen_release.
*
* Note that "pen_release" is the hardware CPU ID, whereas
* "cpu" is Linux's internal ID.
*/
write_pen_release(cpu);

/*
* Send the secondary CPU a soft interrupt, thereby causing
* the boot monitor to read the system wide flags register,
* and branch to the address found there.
*/
smp_cross_call(cpumask_of(cpu), 1);

timeout = jiffies + (1 * HZ);
while (time_before(jiffies, timeout)) {
smp_rmb();
if (pen_release == -1)
break;

udelay(10);
}

/*
* now the secondary core is starting up let it run its
* calibrations, then wait for it to finish
*/
spin_unlock(&boot_lock);

return pen_release != -1 ? -ENOSYS : 0;
}

/*
* Initialise the CPU possible map early - this describes the CPUs
* which may be present or become present in the system.
Expand Down Expand Up @@ -174,6 +82,6 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
* until it receives a soft interrupt, and then the
* secondary CPU branches to this address.
*/
__raw_writel(BSYM(virt_to_phys(realview_secondary_startup)),
__raw_writel(BSYM(virt_to_phys(versatile_secondary_startup)),
__io_address(REALVIEW_SYS_FLAGSSET));
}
2 changes: 1 addition & 1 deletion arch/arm/mach-vexpress/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@

obj-y := v2m.o
obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
obj-$(CONFIG_SMP) += platsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
94 changes: 2 additions & 92 deletions arch/arm/mach-vexpress/platsmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,9 @@
*/
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/jiffies.h>
#include <linux/smp.h>
#include <linux/io.h>

#include <asm/cacheflush.h>
#include <asm/smp_scu.h>
#include <asm/unified.h>

Expand All @@ -26,99 +22,13 @@

#include "core.h"

extern void vexpress_secondary_startup(void);

/*
* control for which core is the next to come out of the secondary
* boot "holding pen"
*/
volatile int __cpuinitdata pen_release = -1;

/*
* Write pen_release in a way that is guaranteed to be visible to all
* observers, irrespective of whether they're taking part in coherency
* or not. This is necessary for the hotplug code to work reliably.
*/
static void __cpuinit write_pen_release(int val)
{
pen_release = val;
smp_wmb();
__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
}
extern void versatile_secondary_startup(void);

static void __iomem *scu_base_addr(void)
{
return MMIO_P2V(A9_MPCORE_SCU);
}

static DEFINE_SPINLOCK(boot_lock);

void __cpuinit platform_secondary_init(unsigned int cpu)
{
/*
* if any interrupts are already enabled for the primary
* core (e.g. timer irq), then they will not have been enabled
* for us: do so
*/
gic_secondary_init(0);

/*
* let the primary processor know we're out of the
* pen, then head off into the C entry point
*/
write_pen_release(-1);

/*
* Synchronise with the boot thread.
*/
spin_lock(&boot_lock);
spin_unlock(&boot_lock);
}

int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
{
unsigned long timeout;

/*
* Set synchronisation state between this boot processor
* and the secondary one
*/
spin_lock(&boot_lock);

/*
* This is really belt and braces; we hold unintended secondary
* CPUs in the holding pen until we're ready for them. However,
* since we haven't sent them a soft interrupt, they shouldn't
* be there.
*/
write_pen_release(cpu);

/*
* Send the secondary CPU a soft interrupt, thereby causing
* the boot monitor to read the system wide flags register,
* and branch to the address found there.
*/
smp_cross_call(cpumask_of(cpu), 1);

timeout = jiffies + (1 * HZ);
while (time_before(jiffies, timeout)) {
smp_rmb();
if (pen_release == -1)
break;

udelay(10);
}

/*
* now the secondary core is starting up let it run its
* calibrations, then wait for it to finish
*/
spin_unlock(&boot_lock);

return pen_release != -1 ? -ENOSYS : 0;
}

/*
* Initialise the CPU possible map early - this describes the CPUs
* which may be present or become present in the system.
Expand Down Expand Up @@ -163,6 +73,6 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
* secondary CPU branches to this address.
*/
writel(~0, MMIO_P2V(V2M_SYS_FLAGSCLR));
writel(BSYM(virt_to_phys(vexpress_secondary_startup)),
writel(BSYM(virt_to_phys(versatile_secondary_startup)),
MMIO_P2V(V2M_SYS_FLAGSSET));
}
2 changes: 1 addition & 1 deletion arch/arm/plat-versatile/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ obj-$(CONFIG_PLAT_VERSATILE_CLCD) += clcd.o
obj-$(CONFIG_PLAT_VERSATILE_FPGA_IRQ) += fpga-irq.o
obj-$(CONFIG_PLAT_VERSATILE_LEDS) += leds.o
obj-$(CONFIG_PLAT_VERSATILE_SCHED_CLOCK) += sched-clock.o

obj-$(CONFIG_SMP) += headsmp.o platsmp.o
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* linux/arch/arm/mach-vexpress/headsmp.S
* linux/arch/arm/plat-versatile/headsmp.S
*
* Copyright (c) 2003 ARM Limited
* All Rights Reserved
Expand All @@ -14,11 +14,11 @@
__INIT

/*
* Versatile Express specific entry point for secondary CPUs. This
* provides a "holding pen" into which all secondary cores are held
* Realview/Versatile Express specific entry point for secondary CPUs.
* This provides a "holding pen" into which all secondary cores are held
* until we're ready for them to initialise.
*/
ENTRY(vexpress_secondary_startup)
ENTRY(versatile_secondary_startup)
mrc p15, 0, r0, c0, c0, 5
and r0, r0, #15
adr r4, 1f
Expand Down
Loading

0 comments on commit 0462b44

Please sign in to comment.