aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh')
-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
21 files changed, 384 insertions, 145 deletions
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}