aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-03-19 19:09:43 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-03-19 19:09:43 -0400
commitb31a3bc3dbd2f42b61674d37de7f46022e1f6846 (patch)
treef497661f34009eff1455df8729ce750fdddad7e5
parentd5e2d00898bdfed9586472679760fc81a2ca2d02 (diff)
parentb15d53d009558d14c4f394a6d1fa2039c7f45c43 (diff)
Merge tag 'tag-sh-for-4.6' of git://git.libc.org/linux-sh
Pull arch/sh updates from Rich Felker: "This includes minor cleanups, a fix for a crash that likely affects all sh models with MMU, and introduction of a framework for boards described by device tree, which sets the stage for future J2 support" * tag 'tag-sh-for-4.6' of git://git.libc.org/linux-sh: sched/preempt, sh: kmap_coherent relies on disabled preemption sh: add SMP method selection to device tree pseudo-board sh: add device tree support and generic board using device tree sh: remove arch-specific localtimer and use generic one sh: make MMU-specific SMP code conditional on CONFIG_MMU sh: provide unified syscall trap compatible with all SH models sh: New gcc support sh: Disable trace for kernel uncompressing. sh: Use generic clkdev.h header
-rw-r--r--Documentation/devicetree/booting-without-of.txt13
-rw-r--r--arch/sh/Kconfig1
-rw-r--r--arch/sh/boards/Kconfig15
-rw-r--r--arch/sh/boards/Makefile2
-rw-r--r--arch/sh/boards/of-generic.c196
-rw-r--r--arch/sh/boot/compressed/Makefile2
-rw-r--r--arch/sh/include/asm/Kbuild1
-rw-r--r--arch/sh/include/asm/clkdev.h33
-rw-r--r--arch/sh/include/asm/smp.h10
-rw-r--r--arch/sh/kernel/Makefile1
-rw-r--r--arch/sh/kernel/cpu/sh2/entry.S8
-rw-r--r--arch/sh/kernel/cpu/sh2a/entry.S8
-rw-r--r--arch/sh/kernel/entry-common.S21
-rw-r--r--arch/sh/kernel/head_32.S13
-rw-r--r--arch/sh/kernel/localtimer.c60
-rw-r--r--arch/sh/kernel/setup.c27
-rw-r--r--arch/sh/kernel/sh_ksyms_32.c3
-rw-r--r--arch/sh/kernel/smp.c24
-rw-r--r--arch/sh/lib/ashlsi3.S35
-rw-r--r--arch/sh/lib/ashrsi3.S33
-rw-r--r--arch/sh/lib/lshrsi3.S34
-rw-r--r--arch/sh/mm/kmap.c2
22 files changed, 397 insertions, 145 deletions
diff --git a/Documentation/devicetree/booting-without-of.txt b/Documentation/devicetree/booting-without-of.txt
index 04d34f6a58f3..3f1437fbca6b 100644
--- a/Documentation/devicetree/booting-without-of.txt
+++ b/Documentation/devicetree/booting-without-of.txt
@@ -16,6 +16,7 @@ Table of Contents
16 2) Entry point for arch/powerpc 16 2) Entry point for arch/powerpc
17 3) Entry point for arch/x86 17 3) Entry point for arch/x86
18 4) Entry point for arch/mips/bmips 18 4) Entry point for arch/mips/bmips
19 5) Entry point for arch/sh
19 20
20 II - The DT block format 21 II - The DT block format
21 1) Header 22 1) Header
@@ -316,6 +317,18 @@ it with special cases.
316 This convention is defined for 32-bit systems only, as there are not 317 This convention is defined for 32-bit systems only, as there are not
317 currently any 64-bit BMIPS implementations. 318 currently any 64-bit BMIPS implementations.
318 319
3205) Entry point for arch/sh
321--------------------------
322
323 Device-tree-compatible SH bootloaders are expected to provide the physical
324 address of the device tree blob in r4. Since legacy bootloaders did not
325 guarantee any particular initial register state, kernels built to
326 inter-operate with old bootloaders must either use a builtin DTB or
327 select a legacy board option (something other than CONFIG_SH_DEVICE_TREE)
328 that does not use device tree. Support for the latter is being phased out
329 in favor of device tree.
330
331
319II - The DT block format 332II - The DT block format
320======================== 333========================
321 334
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 17a4f1593d65..7ed20fc3fc81 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -1,5 +1,6 @@
1config SUPERH 1config SUPERH
2 def_bool y 2 def_bool y
3 select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
3 select ARCH_MIGHT_HAVE_PC_PARPORT 4 select ARCH_MIGHT_HAVE_PC_PARPORT
4 select HAVE_PATA_PLATFORM 5 select HAVE_PATA_PLATFORM
5 select CLKDEV_LOOKUP 6 select CLKDEV_LOOKUP
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
index 89963d13f930..5e52d5362292 100644
--- a/arch/sh/boards/Kconfig
+++ b/arch/sh/boards/Kconfig
@@ -6,6 +6,21 @@ config SOLUTION_ENGINE
6config SH_ALPHA_BOARD 6config SH_ALPHA_BOARD
7 bool 7 bool
8 8
9config SH_DEVICE_TREE
10 bool "Board Described by Device Tree"
11 select OF
12 select OF_EARLY_FLATTREE
13 select CLKSRC_OF
14 select GENERIC_CALIBRATE_DELAY
15 help
16 Select Board Described by Device Tree to build a kernel that
17 does not hard-code any board-specific knowledge but instead uses
18 a device tree blob provided by the boot-loader. You must enable
19 drivers for any hardware you want to use separately. At this
20 time, only boards based on the open-hardware J-Core processors
21 have sufficient driver coverage to use this option; do not
22 select it if you are using original SuperH hardware.
23
9config SH_SOLUTION_ENGINE 24config SH_SOLUTION_ENGINE
10 bool "SolutionEngine" 25 bool "SolutionEngine"
11 select SOLUTION_ENGINE 26 select SOLUTION_ENGINE
diff --git a/arch/sh/boards/Makefile b/arch/sh/boards/Makefile
index 975a0f64ff20..cea300362035 100644
--- a/arch/sh/boards/Makefile
+++ b/arch/sh/boards/Makefile
@@ -15,3 +15,5 @@ obj-$(CONFIG_SH_TITAN) += board-titan.o
15obj-$(CONFIG_SH_SH7757LCR) += board-sh7757lcr.o 15obj-$(CONFIG_SH_SH7757LCR) += board-sh7757lcr.o
16obj-$(CONFIG_SH_APSH4A3A) += board-apsh4a3a.o 16obj-$(CONFIG_SH_APSH4A3A) += board-apsh4a3a.o
17obj-$(CONFIG_SH_APSH4AD0A) += board-apsh4ad0a.o 17obj-$(CONFIG_SH_APSH4AD0A) += board-apsh4ad0a.o
18
19obj-$(CONFIG_SH_DEVICE_TREE) += of-generic.o
diff --git a/arch/sh/boards/of-generic.c b/arch/sh/boards/of-generic.c
new file mode 100644
index 000000000000..bf3a166a5407
--- /dev/null
+++ b/arch/sh/boards/of-generic.c
@@ -0,0 +1,196 @@
1/*
2 * SH generic board support, using device tree
3 *
4 * Copyright (C) 2015-2016 Smart Energy Instruments, Inc.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10
11#include <linux/of.h>
12#include <linux/of_platform.h>
13#include <linux/of_fdt.h>
14#include <linux/of_iommu.h>
15#include <linux/clocksource.h>
16#include <linux/irqchip.h>
17#include <linux/clk-provider.h>
18#include <asm/machvec.h>
19#include <asm/rtc.h>
20
21#ifdef CONFIG_SMP
22
23static void dummy_smp_setup(void)
24{
25}
26
27static void dummy_prepare_cpus(unsigned int max_cpus)
28{
29}
30
31static void dummy_start_cpu(unsigned int cpu, unsigned long entry_point)
32{
33}
34
35static unsigned int dummy_smp_processor_id(void)
36{
37 return 0;
38}
39
40static void dummy_send_ipi(unsigned int cpu, unsigned int message)
41{
42}
43
44static struct plat_smp_ops dummy_smp_ops = {
45 .smp_setup = dummy_smp_setup,
46 .prepare_cpus = dummy_prepare_cpus,
47 .start_cpu = dummy_start_cpu,
48 .smp_processor_id = dummy_smp_processor_id,
49 .send_ipi = dummy_send_ipi,
50 .cpu_die = native_cpu_die,
51 .cpu_disable = native_cpu_disable,
52 .play_dead = native_play_dead,
53};
54
55extern const struct of_cpu_method __cpu_method_of_table[];
56const struct of_cpu_method __cpu_method_of_table_sentinel
57 __section(__cpu_method_of_table_end);
58
59static void sh_of_smp_probe(void)
60{
61 struct device_node *np = 0;
62 const char *method = 0;
63 const struct of_cpu_method *m = __cpu_method_of_table;
64
65 pr_info("SH generic board support: scanning for cpus\n");
66
67 init_cpu_possible(cpumask_of(0));
68
69 while ((np = of_find_node_by_type(np, "cpu"))) {
70 const __be32 *cell = of_get_property(np, "reg", NULL);
71 u64 id = -1;
72 if (cell) id = of_read_number(cell, of_n_addr_cells(np));
73 if (id < NR_CPUS) {
74 if (!method)
75 of_property_read_string(np, "enable-method", &method);
76 set_cpu_possible(id, true);
77 set_cpu_present(id, true);
78 __cpu_number_map[id] = id;
79 __cpu_logical_map[id] = id;
80 }
81 }
82 if (!method) {
83 np = of_find_node_by_name(NULL, "cpus");
84 of_property_read_string(np, "enable-method", &method);
85 }
86
87 pr_info("CPU enable method: %s\n", method);
88 if (method)
89 for (; m->method; m++)
90 if (!strcmp(m->method, method)) {
91 register_smp_ops(m->ops);
92 return;
93 }
94
95 register_smp_ops(&dummy_smp_ops);
96}
97
98#else
99
100static void sh_of_smp_probe(void)
101{
102}
103
104#endif
105
106static void noop(void)
107{
108}
109
110static int noopi(void)
111{
112 return 0;
113}
114
115static void __init sh_of_mem_reserve(void)
116{
117 early_init_fdt_reserve_self();
118 early_init_fdt_scan_reserved_mem();
119}
120
121static void __init sh_of_time_init(void)
122{
123 pr_info("SH generic board support: scanning for clocksource devices\n");
124 clocksource_probe();
125}
126
127static void __init sh_of_setup(char **cmdline_p)
128{
129 unflatten_device_tree();
130
131 board_time_init = sh_of_time_init;
132
133 sh_mv.mv_name = of_flat_dt_get_machine_name();
134 if (!sh_mv.mv_name)
135 sh_mv.mv_name = "Unknown SH model";
136
137 sh_of_smp_probe();
138}
139
140static int sh_of_irq_demux(int irq)
141{
142 /* FIXME: eventually this should not be used at all;
143 * the interrupt controller should set_handle_irq(). */
144 return irq;
145}
146
147static void __init sh_of_init_irq(void)
148{
149 pr_info("SH generic board support: scanning for interrupt controllers\n");
150 irqchip_init();
151}
152
153static int __init sh_of_clk_init(void)
154{
155#ifdef CONFIG_COMMON_CLK
156 /* Disabled pending move to COMMON_CLK framework. */
157 pr_info("SH generic board support: scanning for clk providers\n");
158 of_clk_init(NULL);
159#endif
160 return 0;
161}
162
163static struct sh_machine_vector __initmv sh_of_generic_mv = {
164 .mv_setup = sh_of_setup,
165 .mv_name = "devicetree", /* replaced by DT root's model */
166 .mv_irq_demux = sh_of_irq_demux,
167 .mv_init_irq = sh_of_init_irq,
168 .mv_clk_init = sh_of_clk_init,
169 .mv_mode_pins = noopi,
170 .mv_mem_init = noop,
171 .mv_mem_reserve = sh_of_mem_reserve,
172};
173
174struct sh_clk_ops;
175
176void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
177{
178}
179
180void __init plat_irq_setup(void)
181{
182}
183
184static int __init sh_of_device_init(void)
185{
186 pr_info("SH generic board support: populating platform devices\n");
187 if (of_have_populated_dt()) {
188 of_iommu_init();
189 of_platform_populate(NULL, of_default_bus_match_table,
190 NULL, NULL);
191 } else {
192 pr_crit("Device tree not populated\n");
193 }
194 return 0;
195}
196arch_initcall_sync(sh_of_device_init);
diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile
index 23bc849d9c64..6df826ee7316 100644
--- a/arch/sh/boot/compressed/Makefile
+++ b/arch/sh/boot/compressed/Makefile
@@ -48,7 +48,7 @@ ifeq ($(BITS),64)
48 lib1funcs-dir := $(addsuffix $(BITS), $(lib1funcs-dir)) 48 lib1funcs-dir := $(addsuffix $(BITS), $(lib1funcs-dir))
49endif 49endif
50 50
51KBUILD_CFLAGS += -I$(lib1funcs-dir) 51KBUILD_CFLAGS += -I$(lib1funcs-dir) -DDISABLE_BRANCH_PROFILING
52 52
53$(addprefix $(obj)/,$(lib1funcs-y)): $(obj)/%: $(lib1funcs-dir)/% FORCE 53$(addprefix $(obj)/,$(lib1funcs-y)): $(obj)/%: $(lib1funcs-dir)/% FORCE
54 $(call cmd,shipped) 54 $(call cmd,shipped)
diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild
index aac452b26aa8..a319745a7b63 100644
--- a/arch/sh/include/asm/Kbuild
+++ b/arch/sh/include/asm/Kbuild
@@ -1,5 +1,6 @@
1 1
2generic-y += bitsperlong.h 2generic-y += bitsperlong.h
3generic-y += clkdev.h
3generic-y += cputime.h 4generic-y += cputime.h
4generic-y += current.h 5generic-y += current.h
5generic-y += delay.h 6generic-y += delay.h
diff --git a/arch/sh/include/asm/clkdev.h b/arch/sh/include/asm/clkdev.h
deleted file mode 100644
index c41901465fb0..000000000000
--- a/arch/sh/include/asm/clkdev.h
+++ /dev/null
@@ -1,33 +0,0 @@
1/*
2 * Copyright (C) 2010 Paul Mundt <lethal@linux-sh.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Helper for the clk API to assist looking up a struct clk.
9 */
10
11#ifndef __CLKDEV__H_
12#define __CLKDEV__H_
13
14#include <linux/bootmem.h>
15#include <linux/mm.h>
16#include <linux/slab.h>
17
18#include <asm/clock.h>
19
20static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
21{
22 if (!slab_is_available())
23 return alloc_bootmem_low_pages(size);
24 else
25 return kzalloc(size, GFP_KERNEL);
26}
27
28#ifndef CONFIG_COMMON_CLK
29#define __clk_put(clk)
30#define __clk_get(clk) ({ 1; })
31#endif
32
33#endif /* __CLKDEV_H__ */
diff --git a/arch/sh/include/asm/smp.h b/arch/sh/include/asm/smp.h
index 78b0d0f4b24b..1baf0ba96242 100644
--- a/arch/sh/include/asm/smp.h
+++ b/arch/sh/include/asm/smp.h
@@ -69,6 +69,16 @@ static inline int hard_smp_processor_id(void)
69 return mp_ops->smp_processor_id(); 69 return mp_ops->smp_processor_id();
70} 70}
71 71
72struct of_cpu_method {
73 const char *method;
74 struct plat_smp_ops *ops;
75};
76
77#define CPU_METHOD_OF_DECLARE(name, _method, _ops) \
78 static const struct of_cpu_method __cpu_method_of_table_##name \
79 __used __section(__cpu_method_of_table) \
80 = { .method = _method, .ops = _ops }
81
72#else 82#else
73 83
74#define hard_smp_processor_id() (0) 84#define hard_smp_processor_id() (0)
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index 2ccf36c824c6..09040fd07d2e 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -46,6 +46,5 @@ obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o
46obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_callchain.o 46obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_callchain.o
47 47
48obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o 48obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
49obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o
50 49
51ccflags-y := -Werror 50ccflags-y := -Werror
diff --git a/arch/sh/kernel/cpu/sh2/entry.S b/arch/sh/kernel/cpu/sh2/entry.S
index c8a4331d9b8d..a1505956ef28 100644
--- a/arch/sh/kernel/cpu/sh2/entry.S
+++ b/arch/sh/kernel/cpu/sh2/entry.S
@@ -144,9 +144,9 @@ ENTRY(exception_handler)
144 mov #64,r8 144 mov #64,r8
145 cmp/hs r8,r9 145 cmp/hs r8,r9
146 bt interrupt_entry ! vec >= 64 is interrupt 146 bt interrupt_entry ! vec >= 64 is interrupt
147 mov #32,r8 147 mov #31,r8
148 cmp/hs r8,r9 148 cmp/hs r8,r9
149 bt trap_entry ! 64 > vec >= 32 is trap 149 bt trap_entry ! 64 > vec >= 31 is trap
150 150
151 mov.l 4f,r8 151 mov.l 4f,r8
152 mov r9,r4 152 mov r9,r4
@@ -178,9 +178,9 @@ interrupt_entry:
178 178
179trap_entry: 179trap_entry:
180 mov #0x30,r8 180 mov #0x30,r8
181 cmp/ge r8,r9 ! vector 0x20-0x2f is systemcall 181 cmp/ge r8,r9 ! vector 0x1f-0x2f is systemcall
182 bt 1f 182 bt 1f
183 add #-0x10,r9 ! convert SH2 to SH3/4 ABI 183 mov #0x1f,r9 ! convert to unified SH2/3/4 trap number
1841: 1841:
185 shll2 r9 ! TRA 185 shll2 r9 ! TRA
186 bra system_call ! jump common systemcall entry 186 bra system_call ! jump common systemcall entry
diff --git a/arch/sh/kernel/cpu/sh2a/entry.S b/arch/sh/kernel/cpu/sh2a/entry.S
index 222742ddc0d6..da77a8ef4696 100644
--- a/arch/sh/kernel/cpu/sh2a/entry.S
+++ b/arch/sh/kernel/cpu/sh2a/entry.S
@@ -109,9 +109,9 @@ ENTRY(exception_handler)
109 mov #64,r8 109 mov #64,r8
110 cmp/hs r8,r9 110 cmp/hs r8,r9
111 bt interrupt_entry ! vec >= 64 is interrupt 111 bt interrupt_entry ! vec >= 64 is interrupt
112 mov #32,r8 112 mov #31,r8
113 cmp/hs r8,r9 113 cmp/hs r8,r9
114 bt trap_entry ! 64 > vec >= 32 is trap 114 bt trap_entry ! 64 > vec >= 31 is trap
115 115
116 mov.l 4f,r8 116 mov.l 4f,r8
117 mov r9,r4 117 mov r9,r4
@@ -143,9 +143,9 @@ interrupt_entry:
143 143
144trap_entry: 144trap_entry:
145 mov #0x30,r8 145 mov #0x30,r8
146 cmp/ge r8,r9 ! vector 0x20-0x2f is systemcall 146 cmp/ge r8,r9 ! vector 0x1f-0x2f is systemcall
147 bt 1f 147 bt 1f
148 add #-0x10,r9 ! convert SH2 to SH3/4 ABI 148 mov #0x1f,r9 ! convert to unified SH2/3/4 trap number
1491: 1491:
150 shll2 r9 ! TRA 150 shll2 r9 ! TRA
151 bra system_call ! jump common systemcall entry 151 bra system_call ! jump common systemcall entry
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index 13047a4facd2..c001f782c5f1 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -268,20 +268,29 @@ debug_trap:
268 * Syscall #: R3 268 * Syscall #: R3
269 * Arguments #0 to #3: R4--R7 269 * Arguments #0 to #3: R4--R7
270 * Arguments #4 to #6: R0, R1, R2 270 * Arguments #4 to #6: R0, R1, R2
271 * TRA: (number of arguments + ABI revision) x 4 271 * TRA: See following table.
272 * 272 *
273 * This code also handles delegating other traps to the BIOS/gdb stub
274 * according to:
275 *
276 * Trap number
277 * (TRA>>2) Purpose 273 * (TRA>>2) Purpose
278 * -------- ------- 274 * -------- -------
279 * 0x00-0x0f original SH-3/4 syscall ABI (not in general use). 275 * 0x00-0x0f original SH-3/4 syscall ABI (not in general use).
280 * 0x10-0x1f general SH-3/4 syscall ABI. 276 * 0x10-0x1f general SH-3/4 syscall ABI.
281 * 0x20-0x2f syscall ABI for SH-2 parts. 277 * 0x1f unified SH-2/3/4 syscall ABI (preferred).
278 * 0x20-0x2f original SH-2 syscall ABI.
282 * 0x30-0x3f debug traps used by the kernel. 279 * 0x30-0x3f debug traps used by the kernel.
283 * 0x40-0xff Not supported by all parts, so left unhandled. 280 * 0x40-0xff Not supported by all parts, so left unhandled.
284 * 281 *
282 * For making system calls, any trap number in the range for the
283 * given cpu model may be used, but the unified trap number 0x1f is
284 * preferred for compatibility with all models.
285 *
286 * The low bits of the trap number were once documented as matching
287 * the number of arguments, but they were never actually used as such
288 * by the kernel. SH-2 originally used its own separate trap range
289 * because several hardware exceptions fell in the range used for the
290 * SH-3/4 syscall ABI.
291 *
292 * This code also handles delegating other traps to the BIOS/gdb stub.
293 *
285 * Note: When we're first called, the TRA value must be shifted 294 * Note: When we're first called, the TRA value must be shifted
286 * right 2 bits in order to get the value that was used as the "trapa" 295 * right 2 bits in order to get the value that was used as the "trapa"
287 * argument. 296 * argument.
diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S
index 7db248936b60..974bc152cc84 100644
--- a/arch/sh/kernel/head_32.S
+++ b/arch/sh/kernel/head_32.S
@@ -66,6 +66,10 @@ ENTRY(_stext)
66 mov #0, r0 66 mov #0, r0
67 ldc r0, r6_bank 67 ldc r0, r6_bank
68#endif 68#endif
69
70#ifdef CONFIG_OF
71 mov r4, r12 ! Store device tree blob pointer in r12
72#endif
69 73
70 /* 74 /*
71 * Prefetch if possible to reduce cache miss penalty. 75 * Prefetch if possible to reduce cache miss penalty.
@@ -314,6 +318,12 @@ ENTRY(_stext)
31410: 31810:
315#endif 319#endif
316 320
321#ifdef CONFIG_OF
322 mov.l 8f, r0 ! Make flat device tree available early.
323 jsr @r0
324 mov r12, r4
325#endif
326
317 ! Additional CPU initialization 327 ! Additional CPU initialization
318 mov.l 6f, r0 328 mov.l 6f, r0
319 jsr @r0 329 jsr @r0
@@ -339,6 +349,9 @@ ENTRY(stack_start)
3395: .long start_kernel 3495: .long start_kernel
3406: .long cpu_init 3506: .long cpu_init
3417: .long init_thread_union 3517: .long init_thread_union
352#if defined(CONFIG_OF)
3538: .long sh_fdt_init
354#endif
342 355
343#ifdef CONFIG_PMB 356#ifdef CONFIG_PMB
344.LPMB_ADDR: .long PMB_ADDR 357.LPMB_ADDR: .long PMB_ADDR
diff --git a/arch/sh/kernel/localtimer.c b/arch/sh/kernel/localtimer.c
deleted file mode 100644
index cbb7d4636ec0..000000000000
--- a/arch/sh/kernel/localtimer.c
+++ /dev/null
@@ -1,60 +0,0 @@
1/*
2 * Dummy local timer
3 *
4 * Copyright (C) 2008 Paul Mundt
5 *
6 * cloned from:
7 *
8 * linux/arch/arm/mach-realview/localtimer.c
9 *
10 * Copyright (C) 2002 ARM Ltd.
11 * All Rights Reserved
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 */
17#include <linux/init.h>
18#include <linux/kernel.h>
19#include <linux/delay.h>
20#include <linux/device.h>
21#include <linux/smp.h>
22#include <linux/jiffies.h>
23#include <linux/percpu.h>
24#include <linux/clockchips.h>
25#include <linux/hardirq.h>
26#include <linux/irq.h>
27
28static DEFINE_PER_CPU(struct clock_event_device, local_clockevent);
29
30/*
31 * Used on SMP for either the local timer or SMP_MSG_TIMER
32 */
33void local_timer_interrupt(void)
34{
35 struct clock_event_device *clk = this_cpu_ptr(&local_clockevent);
36
37 irq_enter();
38 clk->event_handler(clk);
39 irq_exit();
40}
41
42void local_timer_setup(unsigned int cpu)
43{
44 struct clock_event_device *clk = &per_cpu(local_clockevent, cpu);
45
46 clk->name = "dummy_timer";
47 clk->features = CLOCK_EVT_FEAT_ONESHOT |
48 CLOCK_EVT_FEAT_PERIODIC |
49 CLOCK_EVT_FEAT_DUMMY;
50 clk->rating = 400;
51 clk->mult = 1;
52 clk->broadcast = smp_timer_broadcast;
53 clk->cpumask = cpumask_of(cpu);
54
55 clockevents_register_device(clk);
56}
57
58void local_timer_stop(unsigned int cpu)
59{
60}
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 3f1c18b28e8a..5d34605b58b5 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -29,6 +29,8 @@
29#include <linux/delay.h> 29#include <linux/delay.h>
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <linux/memblock.h> 31#include <linux/memblock.h>
32#include <linux/of.h>
33#include <linux/of_fdt.h>
32#include <asm/uaccess.h> 34#include <asm/uaccess.h>
33#include <asm/io.h> 35#include <asm/io.h>
34#include <asm/page.h> 36#include <asm/page.h>
@@ -172,6 +174,7 @@ disable:
172#endif 174#endif
173} 175}
174 176
177#ifndef CONFIG_GENERIC_CALIBRATE_DELAY
175void calibrate_delay(void) 178void calibrate_delay(void)
176{ 179{
177 struct clk *clk = clk_get(NULL, "cpu_clk"); 180 struct clk *clk = clk_get(NULL, "cpu_clk");
@@ -187,6 +190,7 @@ void calibrate_delay(void)
187 (loops_per_jiffy/(5000/HZ)) % 100, 190 (loops_per_jiffy/(5000/HZ)) % 100,
188 loops_per_jiffy); 191 loops_per_jiffy);
189} 192}
193#endif
190 194
191void __init __add_active_range(unsigned int nid, unsigned long start_pfn, 195void __init __add_active_range(unsigned int nid, unsigned long start_pfn,
192 unsigned long end_pfn) 196 unsigned long end_pfn)
@@ -238,6 +242,29 @@ void __init __weak plat_early_device_setup(void)
238{ 242{
239} 243}
240 244
245#ifdef CONFIG_OF
246void __ref sh_fdt_init(phys_addr_t dt_phys)
247{
248 static int done = 0;
249 void *dt_virt;
250
251 /* Avoid calling an __init function on secondary cpus. */
252 if (done) return;
253
254 dt_virt = phys_to_virt(dt_phys);
255
256 if (!dt_virt || !early_init_dt_scan(dt_virt)) {
257 pr_crit("Error: invalid device tree blob"
258 " at physical address %p\n", (void *)dt_phys);
259
260 while (true)
261 cpu_relax();
262 }
263
264 done = 1;
265}
266#endif
267
241void __init setup_arch(char **cmdline_p) 268void __init setup_arch(char **cmdline_p)
242{ 269{
243 enable_mmu(); 270 enable_mmu();
diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c
index d77f2f6c7ff0..0b30b9dfc87f 100644
--- a/arch/sh/kernel/sh_ksyms_32.c
+++ b/arch/sh/kernel/sh_ksyms_32.c
@@ -34,6 +34,9 @@ DECLARE_EXPORT(__sdivsi3);
34DECLARE_EXPORT(__lshrsi3); 34DECLARE_EXPORT(__lshrsi3);
35DECLARE_EXPORT(__ashrsi3); 35DECLARE_EXPORT(__ashrsi3);
36DECLARE_EXPORT(__ashlsi3); 36DECLARE_EXPORT(__ashlsi3);
37DECLARE_EXPORT(__lshrsi3_r0);
38DECLARE_EXPORT(__ashrsi3_r0);
39DECLARE_EXPORT(__ashlsi3_r0);
37DECLARE_EXPORT(__ashiftrt_r4_6); 40DECLARE_EXPORT(__ashiftrt_r4_6);
38DECLARE_EXPORT(__ashiftrt_r4_7); 41DECLARE_EXPORT(__ashiftrt_r4_7);
39DECLARE_EXPORT(__ashiftrt_r4_8); 42DECLARE_EXPORT(__ashiftrt_r4_8);
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index 13f633add29a..38e7860845db 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -22,6 +22,7 @@
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23#include <linux/sched.h> 23#include <linux/sched.h>
24#include <linux/atomic.h> 24#include <linux/atomic.h>
25#include <linux/clockchips.h>
25#include <asm/processor.h> 26#include <asm/processor.h>
26#include <asm/mmu_context.h> 27#include <asm/mmu_context.h>
27#include <asm/smp.h> 28#include <asm/smp.h>
@@ -141,16 +142,13 @@ int __cpu_disable(void)
141 migrate_irqs(); 142 migrate_irqs();
142 143
143 /* 144 /*
144 * Stop the local timer for this CPU.
145 */
146 local_timer_stop(cpu);
147
148 /*
149 * Flush user cache and TLB mappings, and then remove this CPU 145 * Flush user cache and TLB mappings, and then remove this CPU
150 * from the vm mask set of all processes. 146 * from the vm mask set of all processes.
151 */ 147 */
152 flush_cache_all(); 148 flush_cache_all();
149#ifdef CONFIG_MMU
153 local_flush_tlb_all(); 150 local_flush_tlb_all();
151#endif
154 152
155 clear_tasks_mm_cpumask(cpu); 153 clear_tasks_mm_cpumask(cpu);
156 154
@@ -183,8 +181,10 @@ asmlinkage void start_secondary(void)
183 atomic_inc(&mm->mm_count); 181 atomic_inc(&mm->mm_count);
184 atomic_inc(&mm->mm_users); 182 atomic_inc(&mm->mm_users);
185 current->active_mm = mm; 183 current->active_mm = mm;
184#ifdef CONFIG_MMU
186 enter_lazy_tlb(mm, current); 185 enter_lazy_tlb(mm, current);
187 local_flush_tlb_all(); 186 local_flush_tlb_all();
187#endif
188 188
189 per_cpu_trap_init(); 189 per_cpu_trap_init();
190 190
@@ -194,8 +194,6 @@ asmlinkage void start_secondary(void)
194 194
195 local_irq_enable(); 195 local_irq_enable();
196 196
197 /* Enable local timers */
198 local_timer_setup(cpu);
199 calibrate_delay(); 197 calibrate_delay();
200 198
201 smp_store_cpu_info(cpu); 199 smp_store_cpu_info(cpu);
@@ -285,7 +283,8 @@ void arch_send_call_function_single_ipi(int cpu)
285 mp_ops->send_ipi(cpu, SMP_MSG_FUNCTION_SINGLE); 283 mp_ops->send_ipi(cpu, SMP_MSG_FUNCTION_SINGLE);
286} 284}
287 285
288void smp_timer_broadcast(const struct cpumask *mask) 286#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
287void tick_broadcast(const struct cpumask *mask)
289{ 288{
290 int cpu; 289 int cpu;
291 290
@@ -296,9 +295,10 @@ void smp_timer_broadcast(const struct cpumask *mask)
296static void ipi_timer(void) 295static void ipi_timer(void)
297{ 296{
298 irq_enter(); 297 irq_enter();
299 local_timer_interrupt(); 298 tick_receive_broadcast();
300 irq_exit(); 299 irq_exit();
301} 300}
301#endif
302 302
303void smp_message_recv(unsigned int msg) 303void smp_message_recv(unsigned int msg)
304{ 304{
@@ -312,9 +312,11 @@ void smp_message_recv(unsigned int msg)
312 case SMP_MSG_FUNCTION_SINGLE: 312 case SMP_MSG_FUNCTION_SINGLE:
313 generic_smp_call_function_single_interrupt(); 313 generic_smp_call_function_single_interrupt();
314 break; 314 break;
315#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
315 case SMP_MSG_TIMER: 316 case SMP_MSG_TIMER:
316 ipi_timer(); 317 ipi_timer();
317 break; 318 break;
319#endif
318 default: 320 default:
319 printk(KERN_WARNING "SMP %d: %s(): unknown IPI %d\n", 321 printk(KERN_WARNING "SMP %d: %s(): unknown IPI %d\n",
320 smp_processor_id(), __func__, msg); 322 smp_processor_id(), __func__, msg);
@@ -328,6 +330,8 @@ int setup_profiling_timer(unsigned int multiplier)
328 return 0; 330 return 0;
329} 331}
330 332
333#ifdef CONFIG_MMU
334
331static void flush_tlb_all_ipi(void *info) 335static void flush_tlb_all_ipi(void *info)
332{ 336{
333 local_flush_tlb_all(); 337 local_flush_tlb_all();
@@ -467,3 +471,5 @@ void flush_tlb_one(unsigned long asid, unsigned long vaddr)
467 smp_call_function(flush_tlb_one_ipi, (void *)&fd, 1); 471 smp_call_function(flush_tlb_one_ipi, (void *)&fd, 1);
468 local_flush_tlb_one(asid, vaddr); 472 local_flush_tlb_one(asid, vaddr);
469} 473}
474
475#endif
diff --git a/arch/sh/lib/ashlsi3.S b/arch/sh/lib/ashlsi3.S
index bd47e9b403a5..70a6434945ab 100644
--- a/arch/sh/lib/ashlsi3.S
+++ b/arch/sh/lib/ashlsi3.S
@@ -54,21 +54,38 @@ Boston, MA 02110-1301, USA. */
54! 54!
55! (none) 55! (none)
56! 56!
57! __ashlsi3_r0
58!
59! Entry:
60!
61! r4: Value to shift
62! r0: Shifts
63!
64! Exit:
65!
66! r0: Result
67!
68! Destroys:
69!
70! (none)
71
72
57 .global __ashlsi3 73 .global __ashlsi3
74 .global __ashlsi3_r0
58 75
59 .align 2 76 .align 2
60__ashlsi3: 77__ashlsi3:
61 mov #31,r0 78 mov r5,r0
62 and r0,r5 79 .align 2
80__ashlsi3_r0:
81 and #31,r0
82 mov.l r4,@-r15
83 mov r0,r4
63 mova ashlsi3_table,r0 84 mova ashlsi3_table,r0
64 mov.b @(r0,r5),r5 85 mov.b @(r0,r4),r4
65#ifdef __sh1__ 86 add r4,r0
66 add r5,r0
67 jmp @r0 87 jmp @r0
68#else 88 mov.l @r15+,r0
69 braf r5
70#endif
71 mov r4,r0
72 89
73 .align 2 90 .align 2
74ashlsi3_table: 91ashlsi3_table:
diff --git a/arch/sh/lib/ashrsi3.S b/arch/sh/lib/ashrsi3.S
index 6f3cf46b77c2..602599d80209 100644
--- a/arch/sh/lib/ashrsi3.S
+++ b/arch/sh/lib/ashrsi3.S
@@ -54,22 +54,37 @@ Boston, MA 02110-1301, USA. */
54! 54!
55! (none) 55! (none)
56! 56!
57! __ashrsi3_r0
58!
59! Entry:
60!
61! r4: Value to shift
62! r0: Shifts
63!
64! Exit:
65!
66! r0: Result
67!
68! Destroys:
69!
70! (none)
57 71
58 .global __ashrsi3 72 .global __ashrsi3
73 .global __ashrsi3_r0
59 74
60 .align 2 75 .align 2
61__ashrsi3: 76__ashrsi3:
62 mov #31,r0 77 mov r5,r0
63 and r0,r5 78 .align 2
79__ashrsi3_r0:
80 and #31,r0
81 mov.l r4,@-r15
82 mov r0,r4
64 mova ashrsi3_table,r0 83 mova ashrsi3_table,r0
65 mov.b @(r0,r5),r5 84 mov.b @(r0,r4),r4
66#ifdef __sh1__ 85 add r4,r0
67 add r5,r0
68 jmp @r0 86 jmp @r0
69#else 87 mov.l @r15+,r0
70 braf r5
71#endif
72 mov r4,r0
73 88
74 .align 2 89 .align 2
75ashrsi3_table: 90ashrsi3_table:
diff --git a/arch/sh/lib/lshrsi3.S b/arch/sh/lib/lshrsi3.S
index 1e7aaa557130..f2a6959f526d 100644
--- a/arch/sh/lib/lshrsi3.S
+++ b/arch/sh/lib/lshrsi3.S
@@ -54,21 +54,37 @@ Boston, MA 02110-1301, USA. */
54! 54!
55! (none) 55! (none)
56! 56!
57! __lshrsi3_r0
58!
59! Entry:
60!
61! r0: Value to shift
62! r5: Shifts
63!
64! Exit:
65!
66! r0: Result
67!
68! Destroys:
69!
70! (none)
71!
57 .global __lshrsi3 72 .global __lshrsi3
73 .global __lshrsi3_r0
58 74
59 .align 2 75 .align 2
60__lshrsi3: 76__lshrsi3:
61 mov #31,r0 77 mov r5,r0
62 and r0,r5 78 .align 2
79__lshrsi3_r0:
80 and #31,r0
81 mov.l r4,@-r15
82 mov r0,r4
63 mova lshrsi3_table,r0 83 mova lshrsi3_table,r0
64 mov.b @(r0,r5),r5 84 mov.b @(r0,r4),r4
65#ifdef __sh1__ 85 add r4,r0
66 add r5,r0
67 jmp @r0 86 jmp @r0
68#else 87 mov.l @r15+,r0
69 braf r5
70#endif
71 mov r4,r0
72 88
73 .align 2 89 .align 2
74lshrsi3_table: 90lshrsi3_table:
diff --git a/arch/sh/mm/kmap.c b/arch/sh/mm/kmap.c
index ec29e14ec5a8..bf25d7c79a2d 100644
--- a/arch/sh/mm/kmap.c
+++ b/arch/sh/mm/kmap.c
@@ -36,6 +36,7 @@ void *kmap_coherent(struct page *page, unsigned long addr)
36 36
37 BUG_ON(!test_bit(PG_dcache_clean, &page->flags)); 37 BUG_ON(!test_bit(PG_dcache_clean, &page->flags));
38 38
39 preempt_disable();
39 pagefault_disable(); 40 pagefault_disable();
40 41
41 idx = FIX_CMAP_END - 42 idx = FIX_CMAP_END -
@@ -64,4 +65,5 @@ void kunmap_coherent(void *kvaddr)
64 } 65 }
65 66
66 pagefault_enable(); 67 pagefault_enable();
68 preempt_enable();
67} 69}