diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-25 12:18:27 +0400 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-25 12:18:27 +0400 | 
| commit | 1bc67188c3843b8e16caaa8624beeb0e2823c1f8 (patch) | |
| tree | 76299c9a161e2f179bf8bbd6c2b6c60191a9c76d /arch/arm/kernel/smp.c | |
| parent | 36b8d186e6cc8e32cb5227f5645a58e1bc0af190 (diff) | |
| parent | bdf4e9482360a3ddc1619efbd5d1c928ede8c3fa (diff) | |
| download | linux-1bc67188c3843b8e16caaa8624beeb0e2823c1f8.tar.xz | |
Merge branch 'for-linus' of http://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-2.6-arm
* 'for-linus' of http://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-2.6-arm: (81 commits)
  ARM: 7133/1: SMP: fix per cpu timer setup before the cpu is marked online
  ARM: 7129/1: Add __arm_ioremap_exec for mapping external memory as MT_MEMORY
  ARM: 7136/1: pl330: Fix a race condition
  ARM: smp: fix clipping of number of CPUs
  ARM: 7137/1: Fix error upon adding LL debug
  ARM: Add a few machine types to mach-types
  ARM: 7130/1: dev_archdata: add private iommu extension
  ARM: 7125/1: Add unwinding annotations for 64bit division functions
  ARM: 7120/1: remove bashism in check for multiple zreladdrs
  ARM: 7118/1: rename temp variable in read*_relaxed()
  ARM: 6217/4: mach-realview: expose PB1176 ROM using physmap and map_rom
  ARM: 7098/1: kdump: copy kernel relocation code at the kexec prepare stage
  ARM: 7062/1: cache: detect PIPT I-cache using CTR
  ARM: platform fixups: remove mdesc argument to fixup function
  ARM: 7017/1: Use generic BUG() handler
  ARM: 7102/1: mach-integrator: update defconfig
  ARM: 7087/2: mach-integrator: get timer frequency from clock
  ARM: 7086/2: mach-integrator: modernize clock event registration
  ARM: 7085/2: mach-integrator: clockevent supports oneshot mode
  ARM: 7084/1: mach-integrator: retire some timer macros
  ...
Diffstat (limited to 'arch/arm/kernel/smp.c')
| -rw-r--r-- | arch/arm/kernel/smp.c | 55 | 
1 files changed, 44 insertions, 11 deletions
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index d88ff0230e82..854ce33715f4 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -16,7 +16,6 @@  #include <linux/cache.h>  #include <linux/profile.h>  #include <linux/errno.h> -#include <linux/ftrace.h>  #include <linux/mm.h>  #include <linux/err.h>  #include <linux/cpu.h> @@ -31,6 +30,8 @@  #include <asm/cacheflush.h>  #include <asm/cpu.h>  #include <asm/cputype.h> +#include <asm/exception.h> +#include <asm/topology.h>  #include <asm/mmu_context.h>  #include <asm/pgtable.h>  #include <asm/pgalloc.h> @@ -39,6 +40,7 @@  #include <asm/tlbflush.h>  #include <asm/ptrace.h>  #include <asm/localtimer.h> +#include <asm/smp_plat.h>  /*   * as from 2.5, kernels no longer have an init_tasks structure @@ -259,6 +261,20 @@ void __ref cpu_die(void)  }  #endif /* CONFIG_HOTPLUG_CPU */ +int __cpu_logical_map[NR_CPUS]; + +void __init smp_setup_processor_id(void) +{ +	int i; +	u32 cpu = is_smp() ? read_cpuid_mpidr() & 0xff : 0; + +	cpu_logical_map(0) = cpu; +	for (i = 1; i < NR_CPUS; ++i) +		cpu_logical_map(i) = i == cpu ? 0 : i; + +	printk(KERN_INFO "Booting Linux on physical CPU %d\n", cpu); +} +  /*   * Called by both boot and secondaries to move global data into   * per-processor storage. @@ -268,6 +284,8 @@ 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; + +	store_cpu_topology(cpuid);  }  /* @@ -301,17 +319,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void)  	 */  	platform_secondary_init(cpu); -	/* -	 * Enable local interrupts. -	 */  	notify_cpu_starting(cpu); -	local_irq_enable(); -	local_fiq_enable(); - -	/* -	 * Setup the percpu timer for this CPU. -	 */ -	percpu_timer_setup();  	calibrate_delay(); @@ -323,10 +331,23 @@ asmlinkage void __cpuinit secondary_start_kernel(void)  	 * before we continue.  	 */  	set_cpu_online(cpu, true); + +	/* +	 * Setup the percpu timer for this CPU. +	 */ +	percpu_timer_setup(); +  	while (!cpu_active(cpu))  		cpu_relax();  	/* +	 * cpu_active bit is set, so it's safe to enalbe interrupts +	 * now. +	 */ +	local_irq_enable(); +	local_fiq_enable(); + +	/*  	 * OK, it's off to the idle thread for us  	 */  	cpu_idle(); @@ -358,6 +379,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus)  {  	unsigned int ncores = num_possible_cpus(); +	init_cpu_topology(); +  	smp_store_cpu_info(smp_processor_id());  	/* @@ -460,6 +483,11 @@ static void ipi_timer(void)  #ifdef CONFIG_LOCAL_TIMERS  asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs)  { +	handle_local_timer(regs); +} + +void handle_local_timer(struct pt_regs *regs) +{  	struct pt_regs *old_regs = set_irq_regs(regs);  	int cpu = smp_processor_id(); @@ -567,6 +595,11 @@ static void ipi_cpu_stop(unsigned int cpu)   */  asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs)  { +	handle_IPI(ipinr, regs); +} + +void handle_IPI(int ipinr, struct pt_regs *regs) +{  	unsigned int cpu = smp_processor_id();  	struct pt_regs *old_regs = set_irq_regs(regs);  | 
