aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMagnus Damm <damm@opensource.se>2010-12-14 02:56:55 -0500
committerPaul Mundt <lethal@linux-sh.org>2010-12-14 04:15:44 -0500
commit1c51ed4fb9f11fa1e0873aa2d5b28f42a85ac299 (patch)
tree258c5de6db68146a86fc27ae1dc2b8fed2dc40e3
parent09dd7ded60019d6a4fd2ae20a08c4ad2bc3ed3e9 (diff)
ARM: mach-shmobile: SMP base support
Add SMP base support for R-Mobile / SH-Mobile processors. This patch contains all base code to support CONFIG_SMP regardless of ARCH_SHMOBILE processor type. Both local timer and CPU hotplug are supported, but no processor specific code is included. At this point only the default behavior is in place, so a single core will always be used even though CONFIG_SMP is enabled on multicore systems. The SMP Kconfig entry for arch/arm/Kconfig is excluded from this patch to simplify merging. Signed-off-by: Magnus Damm <damm@opensource.se> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r--arch/arm/mach-shmobile/Makefile6
-rw-r--r--arch/arm/mach-shmobile/headsmp.S26
-rw-r--r--arch/arm/mach-shmobile/hotplug.c41
-rw-r--r--arch/arm/mach-shmobile/include/mach/common.h1
-rw-r--r--arch/arm/mach-shmobile/include/mach/entry-macro-intc.S6
-rw-r--r--arch/arm/mach-shmobile/include/mach/smp.h16
-rw-r--r--arch/arm/mach-shmobile/localtimer.c25
-rw-r--r--arch/arm/mach-shmobile/platsmp.c73
8 files changed, 194 insertions, 0 deletions
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index f5ad0892984..d4346ddd912 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -11,6 +11,11 @@ obj-$(CONFIG_ARCH_SH7377) += setup-sh7377.o clock-sh7377.o intc-sh7377.o
11obj-$(CONFIG_ARCH_SH7372) += setup-sh7372.o clock-sh7372.o intc-sh7372.o 11obj-$(CONFIG_ARCH_SH7372) += setup-sh7372.o clock-sh7372.o intc-sh7372.o
12obj-$(CONFIG_ARCH_SH73A0) += setup-sh73a0.o clock-sh73a0.o 12obj-$(CONFIG_ARCH_SH73A0) += setup-sh73a0.o clock-sh73a0.o
13 13
14# SMP objects
15smp-y := platsmp.o headsmp.o
16smp-$(CONFIG_HOTPLUG_CPU) += hotplug.o
17smp-$(CONFIG_LOCAL_TIMERS) += localtimer.o
18
14# Pinmux setup 19# Pinmux setup
15pfc-y := 20pfc-y :=
16pfc-$(CONFIG_ARCH_SH7367) += pfc-sh7367.o 21pfc-$(CONFIG_ARCH_SH7367) += pfc-sh7367.o
@@ -26,4 +31,5 @@ obj-$(CONFIG_MACH_AG5EVM) += board-ag5evm.o
26obj-$(CONFIG_MACH_MACKEREL) += board-mackerel.o 31obj-$(CONFIG_MACH_MACKEREL) += board-mackerel.o
27 32
28# Framework support 33# Framework support
34obj-$(CONFIG_SMP) += $(smp-y)
29obj-$(CONFIG_GENERIC_GPIO) += $(pfc-y) 35obj-$(CONFIG_GENERIC_GPIO) += $(pfc-y)
diff --git a/arch/arm/mach-shmobile/headsmp.S b/arch/arm/mach-shmobile/headsmp.S
new file mode 100644
index 00000000000..a5c5af1e6bc
--- /dev/null
+++ b/arch/arm/mach-shmobile/headsmp.S
@@ -0,0 +1,26 @@
1/*
2 * SMP support for R-Mobile / SH-Mobile
3 *
4 * Copyright (C) 2010 Magnus Damm
5 * Copyright (C) 2010 Takashi Yoshii
6 *
7 * Based on vexpress, Copyright (c) 2003 ARM Limited, All Rights Reserved
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13#include <linux/linkage.h>
14#include <linux/init.h>
15
16 __INIT
17
18/*
19 * Reset vector for secondary CPUs.
20 * This will be mapped at address 0 by SBAR register.
21 * We need _long_ jump to the physical address.
22 */
23 .align 12
24ENTRY(shmobile_secondary_vector)
25 ldr pc, 1f
261: .long secondary_startup - CONFIG_PAGE_OFFSET + CONFIG_MEMORY_START
diff --git a/arch/arm/mach-shmobile/hotplug.c b/arch/arm/mach-shmobile/hotplug.c
new file mode 100644
index 00000000000..238a0d97d2d
--- /dev/null
+++ b/arch/arm/mach-shmobile/hotplug.c
@@ -0,0 +1,41 @@
1/*
2 * SMP support for R-Mobile / SH-Mobile
3 *
4 * Copyright (C) 2010 Magnus Damm
5 *
6 * Based on realview, Copyright (C) 2002 ARM Ltd, All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#include <linux/kernel.h>
13#include <linux/errno.h>
14#include <linux/smp.h>
15
16int platform_cpu_kill(unsigned int cpu)
17{
18 return 1;
19}
20
21void platform_cpu_die(unsigned int cpu)
22{
23 while (1) {
24 /*
25 * here's the WFI
26 */
27 asm(".word 0xe320f003\n"
28 :
29 :
30 : "memory", "cc");
31 }
32}
33
34int platform_cpu_disable(unsigned int cpu)
35{
36 /*
37 * we don't allow CPU 0 to be shutdown (it is still too special
38 * e.g. clock tick interrupts)
39 */
40 return cpu == 0 ? -EPERM : 0;
41}
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
index 15932fd2435..32822f7556e 100644
--- a/arch/arm/mach-shmobile/include/mach/common.h
+++ b/arch/arm/mach-shmobile/include/mach/common.h
@@ -3,6 +3,7 @@
3 3
4extern struct sys_timer shmobile_timer; 4extern struct sys_timer shmobile_timer;
5extern void shmobile_setup_console(void); 5extern void shmobile_setup_console(void);
6extern void shmobile_secondary_vector(void);
6struct clk; 7struct clk;
7extern int clk_init(void); 8extern int clk_init(void);
8 9
diff --git a/arch/arm/mach-shmobile/include/mach/entry-macro-intc.S b/arch/arm/mach-shmobile/include/mach/entry-macro-intc.S
index a285d13c741..d06d4ba3251 100644
--- a/arch/arm/mach-shmobile/include/mach/entry-macro-intc.S
+++ b/arch/arm/mach-shmobile/include/mach/entry-macro-intc.S
@@ -17,6 +17,12 @@
17#include <mach/hardware.h> 17#include <mach/hardware.h>
18#include <mach/irqs.h> 18#include <mach/irqs.h>
19 19
20 .macro test_for_ipi, irqnr, irqstat, base, tmp
21 .endm
22
23 .macro test_for_ltirq, irqnr, irqstat, base, tmp
24 .endm
25
20 .macro disable_fiq 26 .macro disable_fiq
21 .endm 27 .endm
22 28
diff --git a/arch/arm/mach-shmobile/include/mach/smp.h b/arch/arm/mach-shmobile/include/mach/smp.h
new file mode 100644
index 00000000000..f4a35ff82c6
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/smp.h
@@ -0,0 +1,16 @@
1#ifndef __MACH_SMP_H
2#define __MACH_SMP_H
3
4#include <asm/hardware/gic.h>
5#include <asm/smp_mpidr.h>
6
7/*
8 * We use IRQ1 as the IPI
9 */
10static inline void smp_cross_call(const struct cpumask *mask)
11{
12#if defined(CONFIG_ARM_GIC)
13 gic_raise_softirq(mask, 1);
14#endif
15}
16#endif
diff --git a/arch/arm/mach-shmobile/localtimer.c b/arch/arm/mach-shmobile/localtimer.c
new file mode 100644
index 00000000000..2111c28b724
--- /dev/null
+++ b/arch/arm/mach-shmobile/localtimer.c
@@ -0,0 +1,25 @@
1/*
2 * SMP support for R-Mobile / SH-Mobile - local timer portion
3 *
4 * Copyright (C) 2010 Magnus Damm
5 *
6 * Based on vexpress, Copyright (C) 2002 ARM Ltd, All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#include <linux/init.h>
13#include <linux/smp.h>
14#include <linux/clockchips.h>
15#include <asm/smp_twd.h>
16#include <asm/localtimer.h>
17
18/*
19 * Setup the local clock events for a CPU.
20 */
21void __cpuinit local_timer_setup(struct clock_event_device *evt)
22{
23 evt->irq = 29;
24 twd_timer_setup(evt);
25}
diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c
new file mode 100644
index 00000000000..b41f5d0650e
--- /dev/null
+++ b/arch/arm/mach-shmobile/platsmp.c
@@ -0,0 +1,73 @@
1/*
2 * SMP support for R-Mobile / SH-Mobile
3 *
4 * Copyright (C) 2010 Magnus Damm
5 *
6 * Based on vexpress, Copyright (C) 2002 ARM Ltd, All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#include <linux/init.h>
13#include <linux/errno.h>
14#include <linux/delay.h>
15#include <linux/device.h>
16#include <linux/smp.h>
17#include <linux/io.h>
18#include <asm/localtimer.h>
19
20static unsigned int __init shmobile_smp_get_core_count(void)
21{
22 return 1;
23}
24
25static void __init shmobile_smp_prepare_cpus(void)
26{
27 /* do nothing for now */
28}
29
30
31void __cpuinit platform_secondary_init(unsigned int cpu)
32{
33 trace_hardirqs_off();
34}
35
36int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
37{
38 return -ENOSYS;
39}
40
41void __init smp_init_cpus(void)
42{
43 unsigned int ncores = shmobile_smp_get_core_count();
44 unsigned int i;
45
46 for (i = 0; i < ncores; i++)
47 set_cpu_possible(i, true);
48}
49
50void __init smp_prepare_cpus(unsigned int max_cpus)
51{
52 unsigned int ncores = shmobile_smp_get_core_count();
53 unsigned int cpu = smp_processor_id();
54 int i;
55
56 smp_store_cpu_info(cpu);
57
58 if (max_cpus > ncores)
59 max_cpus = ncores;
60
61 for (i = 0; i < max_cpus; i++)
62 set_cpu_present(i, true);
63
64 if (max_cpus > 1) {
65 shmobile_smp_prepare_cpus();
66
67 /*
68 * Enable the local timer or broadcast device for the
69 * boot CPU, but only if we have more than one CPU.
70 */
71 percpu_timer_setup();
72 }
73}