diff options
| -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 | } |
