diff options
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r-- | arch/arm/kernel/debug.S | 87 | ||||
-rw-r--r-- | arch/arm/kernel/head.S | 4 | ||||
-rw-r--r-- | arch/arm/kernel/setup.c | 4 | ||||
-rw-r--r-- | arch/arm/kernel/smp.c | 72 |
4 files changed, 77 insertions, 90 deletions
diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S index c45522c3678..66f711b2e0e 100644 --- a/arch/arm/kernel/debug.S +++ b/arch/arm/kernel/debug.S @@ -20,90 +20,9 @@ * references to these in a production kernel! */ -#if defined(CONFIG_DEBUG_ICEDCC) - @@ debug using ARM EmbeddedICE DCC channel - - .macro addruart, rp, rv, tmp - .endm - -#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7) - - .macro senduart, rd, rx - mcr p14, 0, \rd, c0, c5, 0 - .endm - - .macro busyuart, rd, rx -1001: - mrc p14, 0, \rx, c0, c1, 0 - tst \rx, #0x20000000 - beq 1001b - .endm - - .macro waituart, rd, rx - mov \rd, #0x2000000 -1001: - subs \rd, \rd, #1 - bmi 1002f - mrc p14, 0, \rx, c0, c1, 0 - tst \rx, #0x20000000 - bne 1001b -1002: - .endm - -#elif defined(CONFIG_CPU_XSCALE) - - .macro senduart, rd, rx - mcr p14, 0, \rd, c8, c0, 0 - .endm - - .macro busyuart, rd, rx -1001: - mrc p14, 0, \rx, c14, c0, 0 - tst \rx, #0x10000000 - beq 1001b - .endm - - .macro waituart, rd, rx - mov \rd, #0x10000000 -1001: - subs \rd, \rd, #1 - bmi 1002f - mrc p14, 0, \rx, c14, c0, 0 - tst \rx, #0x10000000 - bne 1001b -1002: - .endm - -#else - - .macro senduart, rd, rx - mcr p14, 0, \rd, c1, c0, 0 - .endm - - .macro busyuart, rd, rx -1001: - mrc p14, 0, \rx, c0, c0, 0 - tst \rx, #2 - beq 1001b - - .endm - - .macro waituart, rd, rx - mov \rd, #0x2000000 -1001: - subs \rd, \rd, #1 - bmi 1002f - mrc p14, 0, \rx, c0, c0, 0 - tst \rx, #2 - bne 1001b -1002: - .endm - -#endif /* CONFIG_CPU_V6 */ - -#elif !defined(CONFIG_DEBUG_SEMIHOSTING) -#include <mach/debug-macro.S> -#endif /* CONFIG_DEBUG_ICEDCC */ +#if !defined(CONFIG_DEBUG_SEMIHOSTING) +#include CONFIG_DEBUG_LL_INCLUDE +#endif #ifdef CONFIG_MMU .macro addruart_current, rx, tmp1, tmp2 diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 3db960e20cb..9874d074119 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -23,8 +23,8 @@ #include <asm/thread_info.h> #include <asm/pgtable.h> -#ifdef CONFIG_DEBUG_LL -#include <mach/debug-macro.S> +#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_SEMIHOSTING) +#include CONFIG_DEBUG_LL_INCLUDE #endif /* diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index a81dcecc734..725f9f2a954 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -977,8 +977,10 @@ void __init setup_arch(char **cmdline_p) unflatten_device_tree(); #ifdef CONFIG_SMP - if (is_smp()) + if (is_smp()) { + smp_set_ops(mdesc->smp); smp_init_cpus(); + } #endif reserve_crashkernel(); diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index ebd8ad274d7..aa4ffe6e5ec 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -19,7 +19,6 @@ #include <linux/mm.h> #include <linux/err.h> #include <linux/cpu.h> -#include <linux/smp.h> #include <linux/seq_file.h> #include <linux/irq.h> #include <linux/percpu.h> @@ -27,6 +26,7 @@ #include <linux/completion.h> #include <linux/atomic.h> +#include <asm/smp.h> #include <asm/cacheflush.h> #include <asm/cpu.h> #include <asm/cputype.h> @@ -42,6 +42,7 @@ #include <asm/ptrace.h> #include <asm/localtimer.h> #include <asm/smp_plat.h> +#include <asm/mach/arch.h> /* * as from 2.5, kernels no longer have an init_tasks structure @@ -50,6 +51,12 @@ */ struct secondary_data secondary_data; +/* + * control for which core is the next to come out of the secondary + * boot "holding pen" + */ +volatile int __cpuinitdata pen_release = -1; + enum ipi_msg_type { IPI_TIMER = 2, IPI_RESCHEDULE, @@ -60,6 +67,14 @@ enum ipi_msg_type { static DECLARE_COMPLETION(cpu_running); +static struct smp_operations smp_ops; + +void __init smp_set_ops(struct smp_operations *ops) +{ + if (ops) + smp_ops = *ops; +}; + int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle) { int ret; @@ -100,13 +115,64 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle) return ret; } +/* platform specific SMP operations */ +void __init smp_init_cpus(void) +{ + if (smp_ops.smp_init_cpus) + smp_ops.smp_init_cpus(); +} + +static void __init platform_smp_prepare_cpus(unsigned int max_cpus) +{ + if (smp_ops.smp_prepare_cpus) + smp_ops.smp_prepare_cpus(max_cpus); +} + +static void __cpuinit platform_secondary_init(unsigned int cpu) +{ + if (smp_ops.smp_secondary_init) + smp_ops.smp_secondary_init(cpu); +} + +int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + if (smp_ops.smp_boot_secondary) + return smp_ops.smp_boot_secondary(cpu, idle); + return -ENOSYS; +} + #ifdef CONFIG_HOTPLUG_CPU static void percpu_timer_stop(void); +static int platform_cpu_kill(unsigned int cpu) +{ + if (smp_ops.cpu_kill) + return smp_ops.cpu_kill(cpu); + return 1; +} + +static void platform_cpu_die(unsigned int cpu) +{ + if (smp_ops.cpu_die) + smp_ops.cpu_die(cpu); +} + +static int platform_cpu_disable(unsigned int cpu) +{ + if (smp_ops.cpu_disable) + return smp_ops.cpu_disable(cpu); + + /* + * By default, allow disabling all CPUs except the first one, + * since this is special on a lot of platforms, e.g. because + * of clock tick interrupts. + */ + return cpu == 0 ? -EPERM : 0; +} /* * __cpu_disable runs on the processor to be shutdown. */ -int __cpu_disable(void) +int __cpuinit __cpu_disable(void) { unsigned int cpu = smp_processor_id(); int ret; @@ -149,7 +215,7 @@ static DECLARE_COMPLETION(cpu_died); * called on the thread which is asking for a CPU to be shutdown - * waits until shutdown has completed, or it is timed out. */ -void __cpu_die(unsigned int cpu) +void __cpuinit __cpu_die(unsigned int cpu) { if (!wait_for_completion_timeout(&cpu_died, msecs_to_jiffies(5000))) { pr_err("CPU%u: cpu didn't die\n", cpu); |