aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/booting-without-of.txt13
-rw-r--r--arch/sh/boards/Kconfig15
-rw-r--r--arch/sh/boards/Makefile2
-rw-r--r--arch/sh/boards/of-generic.c113
-rw-r--r--arch/sh/kernel/head_32.S13
-rw-r--r--arch/sh/kernel/setup.c27
6 files changed, 183 insertions, 0 deletions
diff --git a/Documentation/devicetree/booting-without-of.txt b/Documentation/devicetree/booting-without-of.txt
index 04d34f6a58f3..3f1437fbca6b 100644
--- a/Documentation/devicetree/booting-without-of.txt
+++ b/Documentation/devicetree/booting-without-of.txt
@@ -16,6 +16,7 @@ Table of Contents
16 2) Entry point for arch/powerpc 16 2) Entry point for arch/powerpc
17 3) Entry point for arch/x86 17 3) Entry point for arch/x86
18 4) Entry point for arch/mips/bmips 18 4) Entry point for arch/mips/bmips
19 5) Entry point for arch/sh
19 20
20 II - The DT block format 21 II - The DT block format
21 1) Header 22 1) Header
@@ -316,6 +317,18 @@ it with special cases.
316 This convention is defined for 32-bit systems only, as there are not 317 This convention is defined for 32-bit systems only, as there are not
317 currently any 64-bit BMIPS implementations. 318 currently any 64-bit BMIPS implementations.
318 319
3205) Entry point for arch/sh
321--------------------------
322
323 Device-tree-compatible SH bootloaders are expected to provide the physical
324 address of the device tree blob in r4. Since legacy bootloaders did not
325 guarantee any particular initial register state, kernels built to
326 inter-operate with old bootloaders must either use a builtin DTB or
327 select a legacy board option (something other than CONFIG_SH_DEVICE_TREE)
328 that does not use device tree. Support for the latter is being phased out
329 in favor of device tree.
330
331
319II - The DT block format 332II - The DT block format
320======================== 333========================
321 334
diff --git a/arch/sh/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..71d890932151
--- /dev/null
+++ b/arch/sh/boards/of-generic.c
@@ -0,0 +1,113 @@
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
21static void noop(void)
22{
23}
24
25static int noopi(void)
26{
27 return 0;
28}
29
30static void __init sh_of_mem_reserve(void)
31{
32 early_init_fdt_reserve_self();
33 early_init_fdt_scan_reserved_mem();
34}
35
36static void __init sh_of_time_init(void)
37{
38 pr_info("SH generic board support: scanning for clocksource devices\n");
39 clocksource_probe();
40}
41
42static void __init sh_of_setup(char **cmdline_p)
43{
44 unflatten_device_tree();
45
46 board_time_init = sh_of_time_init;
47
48 sh_mv.mv_name = of_flat_dt_get_machine_name();
49 if (!sh_mv.mv_name)
50 sh_mv.mv_name = "Unknown SH model";
51
52 /* FIXME: register smp ops to use dt to find cpus, use
53 * cpu enable-method, and use irq controller's ipi
54 * functions. */
55}
56
57static int sh_of_irq_demux(int irq)
58{
59 /* FIXME: eventually this should not be used at all;
60 * the interrupt controller should set_handle_irq(). */
61 return irq;
62}
63
64static void __init sh_of_init_irq(void)
65{
66 pr_info("SH generic board support: scanning for interrupt controllers\n");
67 irqchip_init();
68}
69
70static int __init sh_of_clk_init(void)
71{
72#ifdef CONFIG_COMMON_CLK
73 /* Disabled pending move to COMMON_CLK framework. */
74 pr_info("SH generic board support: scanning for clk providers\n");
75 of_clk_init(NULL);
76#endif
77 return 0;
78}
79
80static struct sh_machine_vector __initmv sh_of_generic_mv = {
81 .mv_setup = sh_of_setup,
82 .mv_name = "devicetree", /* replaced by DT root's model */
83 .mv_irq_demux = sh_of_irq_demux,
84 .mv_init_irq = sh_of_init_irq,
85 .mv_clk_init = sh_of_clk_init,
86 .mv_mode_pins = noopi,
87 .mv_mem_init = noop,
88 .mv_mem_reserve = sh_of_mem_reserve,
89};
90
91struct sh_clk_ops;
92
93void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
94{
95}
96
97void __init plat_irq_setup(void)
98{
99}
100
101static int __init sh_of_device_init(void)
102{
103 pr_info("SH generic board support: populating platform devices\n");
104 if (of_have_populated_dt()) {
105 of_iommu_init();
106 of_platform_populate(NULL, of_default_bus_match_table,
107 NULL, NULL);
108 } else {
109 pr_crit("Device tree not populated\n");
110 }
111 return 0;
112}
113arch_initcall_sync(sh_of_device_init);
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/setup.c b/arch/sh/kernel/setup.c
index de19cfa768f2..efb60ce720a7 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();