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