diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-19 19:09:43 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-19 19:09:43 -0400 |
commit | b31a3bc3dbd2f42b61674d37de7f46022e1f6846 (patch) | |
tree | f497661f34009eff1455df8729ce750fdddad7e5 | |
parent | d5e2d00898bdfed9586472679760fc81a2ca2d02 (diff) | |
parent | b15d53d009558d14c4f394a6d1fa2039c7f45c43 (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.txt | 13 | ||||
-rw-r--r-- | arch/sh/Kconfig | 1 | ||||
-rw-r--r-- | arch/sh/boards/Kconfig | 15 | ||||
-rw-r--r-- | arch/sh/boards/Makefile | 2 | ||||
-rw-r--r-- | arch/sh/boards/of-generic.c | 196 | ||||
-rw-r--r-- | arch/sh/boot/compressed/Makefile | 2 | ||||
-rw-r--r-- | arch/sh/include/asm/Kbuild | 1 | ||||
-rw-r--r-- | arch/sh/include/asm/clkdev.h | 33 | ||||
-rw-r--r-- | arch/sh/include/asm/smp.h | 10 | ||||
-rw-r--r-- | arch/sh/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh2/entry.S | 8 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh2a/entry.S | 8 | ||||
-rw-r--r-- | arch/sh/kernel/entry-common.S | 21 | ||||
-rw-r--r-- | arch/sh/kernel/head_32.S | 13 | ||||
-rw-r--r-- | arch/sh/kernel/localtimer.c | 60 | ||||
-rw-r--r-- | arch/sh/kernel/setup.c | 27 | ||||
-rw-r--r-- | arch/sh/kernel/sh_ksyms_32.c | 3 | ||||
-rw-r--r-- | arch/sh/kernel/smp.c | 24 | ||||
-rw-r--r-- | arch/sh/lib/ashlsi3.S | 35 | ||||
-rw-r--r-- | arch/sh/lib/ashrsi3.S | 33 | ||||
-rw-r--r-- | arch/sh/lib/lshrsi3.S | 34 | ||||
-rw-r--r-- | arch/sh/mm/kmap.c | 2 |
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 | ||
320 | 5) 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 | |||
319 | II - The DT block format | 332 | II - 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 @@ | |||
1 | config SUPERH | 1 | config 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 | |||
6 | config SH_ALPHA_BOARD | 6 | config SH_ALPHA_BOARD |
7 | bool | 7 | bool |
8 | 8 | ||
9 | config 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 | |||
9 | config SH_SOLUTION_ENGINE | 24 | config 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 | |||
15 | obj-$(CONFIG_SH_SH7757LCR) += board-sh7757lcr.o | 15 | obj-$(CONFIG_SH_SH7757LCR) += board-sh7757lcr.o |
16 | obj-$(CONFIG_SH_APSH4A3A) += board-apsh4a3a.o | 16 | obj-$(CONFIG_SH_APSH4A3A) += board-apsh4a3a.o |
17 | obj-$(CONFIG_SH_APSH4AD0A) += board-apsh4ad0a.o | 17 | obj-$(CONFIG_SH_APSH4AD0A) += board-apsh4ad0a.o |
18 | |||
19 | obj-$(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 | |||
23 | static void dummy_smp_setup(void) | ||
24 | { | ||
25 | } | ||
26 | |||
27 | static void dummy_prepare_cpus(unsigned int max_cpus) | ||
28 | { | ||
29 | } | ||
30 | |||
31 | static void dummy_start_cpu(unsigned int cpu, unsigned long entry_point) | ||
32 | { | ||
33 | } | ||
34 | |||
35 | static unsigned int dummy_smp_processor_id(void) | ||
36 | { | ||
37 | return 0; | ||
38 | } | ||
39 | |||
40 | static void dummy_send_ipi(unsigned int cpu, unsigned int message) | ||
41 | { | ||
42 | } | ||
43 | |||
44 | static 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 | |||
55 | extern const struct of_cpu_method __cpu_method_of_table[]; | ||
56 | const struct of_cpu_method __cpu_method_of_table_sentinel | ||
57 | __section(__cpu_method_of_table_end); | ||
58 | |||
59 | static 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 | |||
100 | static void sh_of_smp_probe(void) | ||
101 | { | ||
102 | } | ||
103 | |||
104 | #endif | ||
105 | |||
106 | static void noop(void) | ||
107 | { | ||
108 | } | ||
109 | |||
110 | static int noopi(void) | ||
111 | { | ||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static void __init sh_of_mem_reserve(void) | ||
116 | { | ||
117 | early_init_fdt_reserve_self(); | ||
118 | early_init_fdt_scan_reserved_mem(); | ||
119 | } | ||
120 | |||
121 | static 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 | |||
127 | static 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 | |||
140 | static 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 | |||
147 | static 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 | |||
153 | static 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 | |||
163 | static 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 | |||
174 | struct sh_clk_ops; | ||
175 | |||
176 | void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx) | ||
177 | { | ||
178 | } | ||
179 | |||
180 | void __init plat_irq_setup(void) | ||
181 | { | ||
182 | } | ||
183 | |||
184 | static 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 | } | ||
196 | arch_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)) |
49 | endif | 49 | endif |
50 | 50 | ||
51 | KBUILD_CFLAGS += -I$(lib1funcs-dir) | 51 | KBUILD_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 | ||
2 | generic-y += bitsperlong.h | 2 | generic-y += bitsperlong.h |
3 | generic-y += clkdev.h | ||
3 | generic-y += cputime.h | 4 | generic-y += cputime.h |
4 | generic-y += current.h | 5 | generic-y += current.h |
5 | generic-y += delay.h | 6 | generic-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 | |||
20 | static 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 | ||
72 | struct 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 | |||
46 | obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_callchain.o | 46 | obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_callchain.o |
47 | 47 | ||
48 | obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o | 48 | obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o |
49 | obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o | ||
50 | 49 | ||
51 | ccflags-y := -Werror | 50 | ccflags-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 | ||
179 | trap_entry: | 179 | trap_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 |
184 | 1: | 184 | 1: |
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 | ||
144 | trap_entry: | 144 | trap_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 |
149 | 1: | 149 | 1: |
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) | |||
314 | 10: | 318 | 10: |
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) | |||
339 | 5: .long start_kernel | 349 | 5: .long start_kernel |
340 | 6: .long cpu_init | 350 | 6: .long cpu_init |
341 | 7: .long init_thread_union | 351 | 7: .long init_thread_union |
352 | #if defined(CONFIG_OF) | ||
353 | 8: .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 | |||
28 | static 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 | */ | ||
33 | void 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 | |||
42 | void 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 | |||
58 | void 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 | ||
175 | void calibrate_delay(void) | 178 | void 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 | ||
191 | void __init __add_active_range(unsigned int nid, unsigned long start_pfn, | 195 | void __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 | ||
246 | void __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 | |||
241 | void __init setup_arch(char **cmdline_p) | 268 | void __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); | |||
34 | DECLARE_EXPORT(__lshrsi3); | 34 | DECLARE_EXPORT(__lshrsi3); |
35 | DECLARE_EXPORT(__ashrsi3); | 35 | DECLARE_EXPORT(__ashrsi3); |
36 | DECLARE_EXPORT(__ashlsi3); | 36 | DECLARE_EXPORT(__ashlsi3); |
37 | DECLARE_EXPORT(__lshrsi3_r0); | ||
38 | DECLARE_EXPORT(__ashrsi3_r0); | ||
39 | DECLARE_EXPORT(__ashlsi3_r0); | ||
37 | DECLARE_EXPORT(__ashiftrt_r4_6); | 40 | DECLARE_EXPORT(__ashiftrt_r4_6); |
38 | DECLARE_EXPORT(__ashiftrt_r4_7); | 41 | DECLARE_EXPORT(__ashiftrt_r4_7); |
39 | DECLARE_EXPORT(__ashiftrt_r4_8); | 42 | DECLARE_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 | ||
288 | void smp_timer_broadcast(const struct cpumask *mask) | 286 | #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST |
287 | void 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) | |||
296 | static void ipi_timer(void) | 295 | static 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 | ||
303 | void smp_message_recv(unsigned int msg) | 303 | void 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 | |||
331 | static void flush_tlb_all_ipi(void *info) | 335 | static 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 |
74 | ashlsi3_table: | 91 | ashlsi3_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 |
75 | ashrsi3_table: | 90 | ashrsi3_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 |
74 | lshrsi3_table: | 90 | lshrsi3_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 | } |