linux/arch/sh/boards/of-generic.c
<<
>>
Prefs
   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_fdt.h>
  13#include <linux/clocksource.h>
  14#include <linux/irqchip.h>
  15#include <linux/clk-provider.h>
  16#include <asm/machvec.h>
  17#include <asm/rtc.h>
  18
  19#ifdef CONFIG_SMP
  20
  21static void dummy_smp_setup(void)
  22{
  23}
  24
  25static void dummy_prepare_cpus(unsigned int max_cpus)
  26{
  27}
  28
  29static void dummy_start_cpu(unsigned int cpu, unsigned long entry_point)
  30{
  31}
  32
  33static unsigned int dummy_smp_processor_id(void)
  34{
  35        return 0;
  36}
  37
  38static void dummy_send_ipi(unsigned int cpu, unsigned int message)
  39{
  40}
  41
  42static struct plat_smp_ops dummy_smp_ops = {
  43        .smp_setup              = dummy_smp_setup,
  44        .prepare_cpus           = dummy_prepare_cpus,
  45        .start_cpu              = dummy_start_cpu,
  46        .smp_processor_id       = dummy_smp_processor_id,
  47        .send_ipi               = dummy_send_ipi,
  48        .cpu_die                = native_cpu_die,
  49        .cpu_disable            = native_cpu_disable,
  50        .play_dead              = native_play_dead,
  51};
  52
  53extern const struct of_cpu_method __cpu_method_of_table[];
  54const struct of_cpu_method __cpu_method_of_table_sentinel
  55        __section(__cpu_method_of_table_end);
  56
  57static void sh_of_smp_probe(void)
  58{
  59        struct device_node *np = 0;
  60        const char *method = 0;
  61        const struct of_cpu_method *m = __cpu_method_of_table;
  62
  63        pr_info("SH generic board support: scanning for cpus\n");
  64
  65        init_cpu_possible(cpumask_of(0));
  66
  67        while ((np = of_find_node_by_type(np, "cpu"))) {
  68                const __be32 *cell = of_get_property(np, "reg", NULL);
  69                u64 id = -1;
  70                if (cell) id = of_read_number(cell, of_n_addr_cells(np));
  71                if (id < NR_CPUS) {
  72                        if (!method)
  73                                of_property_read_string(np, "enable-method", &method);
  74                        set_cpu_possible(id, true);
  75                        set_cpu_present(id, true);
  76                        __cpu_number_map[id] = id;
  77                        __cpu_logical_map[id] = id;
  78                }
  79        }
  80        if (!method) {
  81                np = of_find_node_by_name(NULL, "cpus");
  82                of_property_read_string(np, "enable-method", &method);
  83        }
  84
  85        pr_info("CPU enable method: %s\n", method);
  86        if (method)
  87                for (; m->method; m++)
  88                        if (!strcmp(m->method, method)) {
  89                                register_smp_ops(m->ops);
  90                                return;
  91                        }
  92
  93        register_smp_ops(&dummy_smp_ops);
  94}
  95
  96#else
  97
  98static void sh_of_smp_probe(void)
  99{
 100}
 101
 102#endif
 103
 104static void noop(void)
 105{
 106}
 107
 108static int noopi(void)
 109{
 110        return 0;
 111}
 112
 113static void __init sh_of_mem_reserve(void)
 114{
 115        early_init_fdt_reserve_self();
 116        early_init_fdt_scan_reserved_mem();
 117}
 118
 119static void __init sh_of_time_init(void)
 120{
 121        pr_info("SH generic board support: scanning for clocksource devices\n");
 122        clocksource_probe();
 123}
 124
 125static void __init sh_of_setup(char **cmdline_p)
 126{
 127        struct device_node *root;
 128
 129#ifdef CONFIG_USE_BUILTIN_DTB
 130        unflatten_and_copy_device_tree();
 131#else
 132        unflatten_device_tree();
 133#endif
 134
 135        board_time_init = sh_of_time_init;
 136
 137        sh_mv.mv_name = "Unknown SH model";
 138        root = of_find_node_by_path("/");
 139        if (root) {
 140                of_property_read_string(root, "model", &sh_mv.mv_name);
 141                of_node_put(root);
 142        }
 143
 144        sh_of_smp_probe();
 145}
 146
 147static int sh_of_irq_demux(int irq)
 148{
 149        /* FIXME: eventually this should not be used at all;
 150         * the interrupt controller should set_handle_irq(). */
 151        return irq;
 152}
 153
 154static void __init sh_of_init_irq(void)
 155{
 156        pr_info("SH generic board support: scanning for interrupt controllers\n");
 157        irqchip_init();
 158}
 159
 160static int __init sh_of_clk_init(void)
 161{
 162#ifdef CONFIG_COMMON_CLK
 163        /* Disabled pending move to COMMON_CLK framework. */
 164        pr_info("SH generic board support: scanning for clk providers\n");
 165        of_clk_init(NULL);
 166#endif
 167        return 0;
 168}
 169
 170static struct sh_machine_vector __initmv sh_of_generic_mv = {
 171        .mv_setup       = sh_of_setup,
 172        .mv_name        = "devicetree", /* replaced by DT root's model */
 173        .mv_irq_demux   = sh_of_irq_demux,
 174        .mv_init_irq    = sh_of_init_irq,
 175        .mv_clk_init    = sh_of_clk_init,
 176        .mv_mode_pins   = noopi,
 177        .mv_mem_init    = noop,
 178        .mv_mem_reserve = sh_of_mem_reserve,
 179};
 180
 181struct sh_clk_ops;
 182
 183void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
 184{
 185}
 186
 187void __init plat_irq_setup(void)
 188{
 189}
 190