Commit 05c74a6c authored by Russell King's avatar Russell King

ARM: SMP: consolidate the common parts of smp_prepare_cpus()

There is a certain amount of smp_prepare_cpus() which doesn't belong
in the platform support code - that is, code which is invariant to the
SMP implementation.  Move this code into arch/arm/kernel/smp.c, and
add a platform_ prefix to the original function.
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent aec66ba1
...@@ -45,10 +45,6 @@ asmlinkage void do_IPI(int ipinr, struct pt_regs *regs); ...@@ -45,10 +45,6 @@ asmlinkage void do_IPI(int ipinr, struct pt_regs *regs);
*/ */
extern void smp_init_cpus(void); extern void smp_init_cpus(void);
/*
* Move global data into per-processor storage.
*/
extern void smp_store_cpu_info(unsigned int cpuid);
/* /*
* Raise an IPI cross call on CPUs in callmap. * Raise an IPI cross call on CPUs in callmap.
...@@ -72,6 +68,11 @@ asmlinkage void secondary_start_kernel(void); ...@@ -72,6 +68,11 @@ asmlinkage void secondary_start_kernel(void);
*/ */
extern void platform_secondary_init(unsigned int cpu); extern void platform_secondary_init(unsigned int cpu);
/*
* Initialize cpu_possible map, and enable coherency
*/
extern void platform_smp_prepare_cpus(unsigned int);
/* /*
* Initial data for bringing up a secondary CPU. * Initial data for bringing up a secondary CPU.
*/ */
......
...@@ -281,6 +281,17 @@ void __ref cpu_die(void) ...@@ -281,6 +281,17 @@ void __ref cpu_die(void)
} }
#endif /* CONFIG_HOTPLUG_CPU */ #endif /* CONFIG_HOTPLUG_CPU */
/*
* Called by both boot and secondaries to move global data into
* per-processor storage.
*/
static void __cpuinit smp_store_cpu_info(unsigned int cpuid)
{
struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid);
cpu_info->loops_per_jiffy = loops_per_jiffy;
}
/* /*
* This is the secondary CPU boot entry. We're using this CPUs * This is the secondary CPU boot entry. We're using this CPUs
* idle thread stack, but a set of temporary page tables. * idle thread stack, but a set of temporary page tables.
...@@ -339,17 +350,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void) ...@@ -339,17 +350,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
cpu_idle(); cpu_idle();
} }
/*
* Called by both boot and secondaries to move global data into
* per-processor storage.
*/
void __cpuinit smp_store_cpu_info(unsigned int cpuid)
{
struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid);
cpu_info->loops_per_jiffy = loops_per_jiffy;
}
void __init smp_cpus_done(unsigned int max_cpus) void __init smp_cpus_done(unsigned int max_cpus)
{ {
int cpu; int cpu;
...@@ -372,6 +372,33 @@ void __init smp_prepare_boot_cpu(void) ...@@ -372,6 +372,33 @@ void __init smp_prepare_boot_cpu(void)
per_cpu(cpu_data, cpu).idle = current; per_cpu(cpu_data, cpu).idle = current;
} }
void __init smp_prepare_cpus(unsigned int max_cpus)
{
unsigned int ncores = num_possible_cpus();
smp_store_cpu_info(smp_processor_id());
/*
* are we trying to boot more cores than exist?
*/
if (max_cpus > ncores)
max_cpus = ncores;
if (max_cpus > 1) {
/*
* Enable the local timer or broadcast device for the
* boot CPU, but only if we have more than one CPU.
*/
percpu_timer_setup();
/*
* Initialise the SCU if there are more than one CPU
* and let them know where to start.
*/
platform_smp_prepare_cpus(max_cpus);
}
}
void arch_send_call_function_ipi_mask(const struct cpumask *mask) void arch_send_call_function_ipi_mask(const struct cpumask *mask)
{ {
smp_cross_call(mask, IPI_CALL_FUNC); smp_cross_call(mask, IPI_CALL_FUNC);
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include <linux/io.h> #include <linux/io.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/localtimer.h>
#include <asm/smp_scu.h> #include <asm/smp_scu.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/omap4-common.h> #include <mach/omap4-common.h>
...@@ -123,20 +122,10 @@ void __init smp_init_cpus(void) ...@@ -123,20 +122,10 @@ void __init smp_init_cpus(void)
set_cpu_possible(i, true); set_cpu_possible(i, true);
} }
void __init smp_prepare_cpus(unsigned int max_cpus) void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{ {
unsigned int ncores = num_possible_cpus();
unsigned int cpu = smp_processor_id();
int i; int i;
smp_store_cpu_info(cpu);
/*
* are we trying to boot more cores than exist?
*/
if (max_cpus > ncores)
max_cpus = ncores;
/* /*
* Initialise the present map, which describes the set of CPUs * Initialise the present map, which describes the set of CPUs
* actually populated at the present time. * actually populated at the present time.
...@@ -144,18 +133,10 @@ void __init smp_prepare_cpus(unsigned int max_cpus) ...@@ -144,18 +133,10 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
for (i = 0; i < max_cpus; i++) for (i = 0; i < max_cpus; i++)
set_cpu_present(i, true); set_cpu_present(i, true);
if (max_cpus > 1) { /*
/* * Initialise the SCU and wake up the secondary core using
* Enable the local timer or broadcast device for the * wakeup_secondary().
* boot CPU, but only if we have more than one CPU. */
*/ scu_enable(scu_base);
percpu_timer_setup(); wakeup_secondary();
/*
* Initialise the SCU and wake up the secondary core using
* wakeup_secondary().
*/
scu_enable(scu_base);
wakeup_secondary();
}
} }
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/localtimer.h>
#include <asm/unified.h> #include <asm/unified.h>
#include <mach/board-eb.h> #include <mach/board-eb.h>
...@@ -147,20 +146,10 @@ void __init smp_init_cpus(void) ...@@ -147,20 +146,10 @@ void __init smp_init_cpus(void)
set_cpu_possible(i, true); set_cpu_possible(i, true);
} }
void __init smp_prepare_cpus(unsigned int max_cpus) void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{ {
unsigned int ncores = num_possible_cpus();
unsigned int cpu = smp_processor_id();
int i; int i;
smp_store_cpu_info(cpu);
/*
* are we trying to boot more cores than exist?
*/
if (max_cpus > ncores)
max_cpus = ncores;
/* /*
* Initialise the present map, which describes the set of CPUs * Initialise the present map, which describes the set of CPUs
* actually populated at the present time. * actually populated at the present time.
...@@ -168,22 +157,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus) ...@@ -168,22 +157,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
for (i = 0; i < max_cpus; i++) for (i = 0; i < max_cpus; i++)
set_cpu_present(i, true); set_cpu_present(i, true);
if (max_cpus > 1) { scu_enable(scu_base_addr());
/*
* Enable the local timer or broadcast device for the /*
* boot CPU, but only if we have more than one CPU. * Write the address of secondary startup into the
*/ * system-wide flags register. The BootMonitor waits
percpu_timer_setup(); * until it receives a soft interrupt, and then the
* secondary CPU branches to this address.
scu_enable(scu_base_addr()); */
__raw_writel(BSYM(virt_to_phys(realview_secondary_startup)),
/* __io_address(REALVIEW_SYS_FLAGSSET));
* Write the address of secondary startup into the
* system-wide flags register. The BootMonitor waits
* until it receives a soft interrupt, and then the
* secondary CPU branches to this address.
*/
__raw_writel(BSYM(virt_to_phys(realview_secondary_startup)),
__io_address(REALVIEW_SYS_FLAGSSET));
}
} }
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include <linux/io.h> #include <linux/io.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/localtimer.h>
#include <asm/smp_scu.h> #include <asm/smp_scu.h>
#include <asm/unified.h> #include <asm/unified.h>
...@@ -142,18 +141,10 @@ void __init smp_init_cpus(void) ...@@ -142,18 +141,10 @@ void __init smp_init_cpus(void)
set_cpu_possible(i, true); set_cpu_possible(i, true);
} }
void __init smp_prepare_cpus(unsigned int max_cpus) void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{ {
unsigned int ncores = num_possible_cpus();
unsigned int cpu = smp_processor_id();
int i; int i;
smp_store_cpu_info(cpu);
/* are we trying to boot more cores than exist? */
if (max_cpus > ncores)
max_cpus = ncores;
/* /*
* Initialise the present map, which describes the set of CPUs * Initialise the present map, which describes the set of CPUs
* actually populated at the present time. * actually populated at the present time.
...@@ -161,25 +152,13 @@ void __init smp_prepare_cpus(unsigned int max_cpus) ...@@ -161,25 +152,13 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
for (i = 0; i < max_cpus; i++) for (i = 0; i < max_cpus; i++)
set_cpu_present(i, true); set_cpu_present(i, true);
scu_enable(scu_base_addr());
/* /*
* Initialise the SCU if there are more than one CPU and let * Write the address of secondary startup into the
* them know where to start. * system-wide flags register. The boot monitor waits
* until it receives a soft interrupt, and then the
* secondary CPU branches to this address.
*/ */
if (max_cpus > 1) {
/*
* Enable the local timer or broadcast device for the
* boot CPU, but only if we have more than one CPU.
*/
percpu_timer_setup();
scu_enable(scu_base_addr());
/*
* Write the address of secondary startup into the
* system-wide flags register. The boot monitor waits
* until it receives a soft interrupt, and then the
* secondary CPU branches to this address.
*/
__raw_writel(BSYM(virt_to_phys(s5pv310_secondary_startup)), S5P_VA_SYSRAM); __raw_writel(BSYM(virt_to_phys(s5pv310_secondary_startup)), S5P_VA_SYSRAM);
}
} }
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/localtimer.h>
#include <asm/smp_scu.h> #include <asm/smp_scu.h>
#include <mach/iomap.h> #include <mach/iomap.h>
...@@ -127,20 +126,10 @@ void __init smp_init_cpus(void) ...@@ -127,20 +126,10 @@ void __init smp_init_cpus(void)
cpu_set(i, cpu_possible_map); cpu_set(i, cpu_possible_map);
} }
void __init smp_prepare_cpus(unsigned int max_cpus) void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{ {
unsigned int ncores = scu_get_core_count(scu_base);
unsigned int cpu = smp_processor_id();
int i; int i;
smp_store_cpu_info(cpu);
/*
* are we trying to boot more cores than exist?
*/
if (max_cpus > ncores)
max_cpus = ncores;
/* /*
* Initialise the present map, which describes the set of CPUs * Initialise the present map, which describes the set of CPUs
* actually populated at the present time. * actually populated at the present time.
...@@ -148,8 +137,5 @@ void __init smp_prepare_cpus(unsigned int max_cpus) ...@@ -148,8 +137,5 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
for (i = 0; i < max_cpus; i++) for (i = 0; i < max_cpus; i++)
set_cpu_present(i, true); set_cpu_present(i, true);
if (max_cpus > 1) { scu_enable(scu_base);
percpu_timer_setup();
scu_enable(scu_base);
}
} }
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include <linux/io.h> #include <linux/io.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/localtimer.h>
#include <asm/smp_scu.h> #include <asm/smp_scu.h>
#include <mach/hardware.h> #include <mach/hardware.h>
...@@ -138,20 +137,10 @@ void __init smp_init_cpus(void) ...@@ -138,20 +137,10 @@ void __init smp_init_cpus(void)
set_cpu_possible(i, true); set_cpu_possible(i, true);
} }
void __init smp_prepare_cpus(unsigned int max_cpus) void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{ {
unsigned int ncores = num_possible_cpus();
unsigned int cpu = smp_processor_id();
int i; int i;
smp_store_cpu_info(cpu);
/*
* are we trying to boot more cores than exist?
*/
if (max_cpus > ncores)
max_cpus = ncores;
/* /*
* Initialise the present map, which describes the set of CPUs * Initialise the present map, which describes the set of CPUs
* actually populated at the present time. * actually populated at the present time.
...@@ -159,13 +148,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) ...@@ -159,13 +148,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
for (i = 0; i < max_cpus; i++) for (i = 0; i < max_cpus; i++)
set_cpu_present(i, true); set_cpu_present(i, true);
if (max_cpus > 1) { scu_enable(__io_address(UX500_SCU_BASE));
/* wakeup_secondary();
* Enable the local timer or broadcast device for the
* boot CPU, but only if we have more than one CPU.
*/
percpu_timer_setup();
scu_enable(__io_address(UX500_SCU_BASE));
wakeup_secondary();
}
} }
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include <linux/io.h> #include <linux/io.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/localtimer.h>
#include <asm/smp_scu.h> #include <asm/smp_scu.h>
#include <asm/unified.h> #include <asm/unified.h>
...@@ -136,20 +135,10 @@ void __init smp_init_cpus(void) ...@@ -136,20 +135,10 @@ void __init smp_init_cpus(void)
set_cpu_possible(i, true); set_cpu_possible(i, true);
} }
void __init smp_prepare_cpus(unsigned int max_cpus) void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{ {
unsigned int ncores = num_possible_cpus();
unsigned int cpu = smp_processor_id();
int i; int i;
smp_store_cpu_info(cpu);
/*
* are we trying to boot more cores than exist?
*/
if (max_cpus > ncores)
max_cpus = ncores;
/* /*
* Initialise the present map, which describes the set of CPUs * Initialise the present map, which describes the set of CPUs
* actually populated at the present time. * actually populated at the present time.
...@@ -157,27 +146,15 @@ void __init smp_prepare_cpus(unsigned int max_cpus) ...@@ -157,27 +146,15 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
for (i = 0; i < max_cpus; i++) for (i = 0; i < max_cpus; i++)
set_cpu_present(i, true); set_cpu_present(i, true);
scu_enable(scu_base_addr());
/* /*
* Initialise the SCU if there are more than one CPU and let * Write the address of secondary startup into the
* them know where to start. * system-wide flags register. The boot monitor waits
* until it receives a soft interrupt, and then the
* secondary CPU branches to this address.
*/ */
if (max_cpus > 1) { writel(~0, MMIO_P2V(V2M_SYS_FLAGSCLR));
/* writel(BSYM(virt_to_phys(vexpress_secondary_startup)),
* Enable the local timer or broadcast device for the MMIO_P2V(V2M_SYS_FLAGSSET));
* boot CPU, but only if we have more than one CPU.
*/
percpu_timer_setup();
scu_enable(scu_base_addr());
/*
* Write the address of secondary startup into the
* system-wide flags register. The boot monitor waits
* until it receives a soft interrupt, and then the
* secondary CPU branches to this address.
*/
writel(~0, MMIO_P2V(V2M_SYS_FLAGSCLR));
writel(BSYM(virt_to_phys(vexpress_secondary_startup)),
MMIO_P2V(V2M_SYS_FLAGSSET));
}
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment