OSDN Git Service

sh: Basic Device Tree support
authorYoshinori Sato <ysato@users.sourceforge.jp>
Tue, 23 Jun 2015 04:03:43 +0000 (13:03 +0900)
committerYoshinori Sato <ysato@users.sourceforge.jp>
Tue, 23 Jun 2015 04:03:43 +0000 (13:03 +0900)
Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
arch/sh/Kconfig.cpu
arch/sh/Makefile
arch/sh/kernel/head_32.S
arch/sh/kernel/setup.c
drivers/sh/intc/irqdomain.c

index 05b518e..0062dad 100644 (file)
@@ -105,4 +105,8 @@ config CPU_HAS_DSP
 config CPU_HAS_FPU
        bool
 
+config SH_BUILTIN_DTB
+       string "Builtin DTB"
+       default ""
+
 endmenu
index bf5b3f5..17bb2e5 100644 (file)
@@ -162,6 +162,11 @@ machdir-y  += mach-common
 # Companion chips
 core-$(CONFIG_HD6446X_SERIES)  += arch/sh/cchips/hd6446x/
 
+# device tree
+ifneq '$(CONFIG_SH_BUILTIN_DTB)' '""'
+core-y += arch/sh/boot/dts/
+endif
+
 #
 # CPU header paths
 #
@@ -208,6 +213,14 @@ BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.xz uImage.lzo \
               romImage
 PHONY += $(BOOT_TARGETS)
 
+%.dtb %.dtb.S %.dtb.o: | scripts
+       $(Q)$(MAKE) $(build)=arch/sh/boot/dts arch/sh/boot/dts/$@
+
+PHONY += dtbs
+
+dtbs: scripts
+       $(Q)$(MAKE) $(build)=arch/sh/boot/dts
+
 all: $(KBUILD_IMAGE)
 
 $(BOOT_TARGETS): vmlinux
index 7db2489..347e2f7 100644 (file)
@@ -321,6 +321,11 @@ ENTRY(_stext)
 
        SYNCO()                 ! Wait for pending instructions..
        
+#if defined(CONFIG_OF)
+       mov.l   8f, r0
+       jsr     @r0
+        nop
+#endif
        !                       Start kernel
        mov.l   5f, r0
        jmp     @r0
@@ -339,6 +344,9 @@ ENTRY(stack_start)
 5:     .long   start_kernel
 6:     .long   cpu_init
 7:     .long   init_thread_union
+#if defined(CONFIG_OF)
+8:     .long   sh_fdt_init
+#endif
 
 #ifdef CONFIG_PMB
 .LPMB_ADDR:            .long   PMB_ADDR
index de19cfa..c3b5628 100644 (file)
@@ -29,6 +29,8 @@
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/memblock.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/page.h>
@@ -100,6 +102,7 @@ unsigned long memory_limit = 0;
 static struct resource mem_resources[MAX_NUMNODES];
 
 int l1i_cache_shape, l1d_cache_shape, l2_cache_shape;
+extern char __dtb_start[];
 
 static int __init early_parse_mem(char *p)
 {
@@ -174,13 +177,21 @@ disable:
 
 void calibrate_delay(void)
 {
+#if !defined(CONFIG_OF)
        struct clk *clk = clk_get(NULL, "cpu_clk");
 
        if (IS_ERR(clk))
                panic("Need a sane CPU clock definition!");
 
        loops_per_jiffy = (clk_get_rate(clk) >> 1) / HZ;
+#else
+       struct device_node *cpu;
+       int freq;
 
+       cpu = of_find_compatible_node(NULL, NULL, "renesas,superh");
+       of_property_read_s32(cpu, "clock-frequency", &freq);
+       loops_per_jiffy = freq / HZ / 2;
+#endif
        printk(KERN_INFO "Calibrating delay loop (skipped)... "
                         "%lu.%02lu BogoMIPS PRESET (lpj=%lu)\n",
                         loops_per_jiffy/(500000/HZ),
@@ -240,6 +251,9 @@ void __init __weak plat_early_device_setup(void)
 
 void __init setup_arch(char **cmdline_p)
 {
+#if defined(CONFIG_OF)
+       unflatten_and_copy_device_tree();
+#endif
        enable_mmu();
 
        ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
@@ -322,3 +336,11 @@ int test_mode_pin(int pin)
 {
        return sh_mv.mv_mode_pins() & pin;
 }
+
+#if defined(CONFIG_OF)
+void __init sh_fdt_init(void)
+{
+       early_init_dt_scan(__dtb_start);
+       memblock_allow_resize();
+}
+#endif
index 3968f1c..65cbd70 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/irqdomain.h>
 #include <linux/sh_intc.h>
 #include <linux/export.h>
+#include <linux/of_irq.h>
 #include "internals.h"
 
 /**
@@ -45,13 +46,21 @@ void __init intc_irq_domain_init(struct intc_desc_int *d,
                                 struct intc_hw_desc *hw)
 {
        unsigned int irq_base, irq_end;
-
+#if defined(CONFIG_OF)
+       struct device_node *intc = NULL;
+#define INTC intc
+#else
+#define INTC NULL
+#endif
        /*
         * Quick linear revmap check
         */
        irq_base = evt2irq(hw->vectors[0].vect);
        irq_end = evt2irq(hw->vectors[hw->nr_vectors - 1].vect);
 
+#if defined(CONFIG_OF)
+       intc = of_find_compatible_node(NULL, NULL, "renesas,sh-intc");
+#endif
        /*
         * Linear domains have a hard-wired assertion that IRQs start at
         * 0 in order to make some performance optimizations. Lamely
@@ -59,10 +68,10 @@ void __init intc_irq_domain_init(struct intc_desc_int *d,
         * tree penalty for linear cases with non-zero hwirq bases.
         */
        if (irq_base == 0 && irq_end == (irq_base + hw->nr_vectors - 1))
-               d->domain = irq_domain_add_linear(NULL, hw->nr_vectors,
+               d->domain = irq_domain_add_linear(INTC, hw->nr_vectors,
                                                  &intc_evt_ops, NULL);
        else
-               d->domain = irq_domain_add_tree(NULL, &intc_evt_ops, NULL);
+               d->domain = irq_domain_add_tree(INTC, &intc_evt_ops, NULL);
 
        BUG_ON(!d->domain);
 }