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 21 static void dummy_smp_setup(void) 22 { 23 } 24 25 static void dummy_prepare_cpus(unsigned int max_cpus) 26 { 27 } 28 29 static void dummy_start_cpu(unsigned int cpu, unsigned long entry_point) 30 { 31 } 32 33 static unsigned int dummy_smp_processor_id(void) 34 { 35 return 0; 36 } 37 38 static void dummy_send_ipi(unsigned int cpu, unsigned int message) 39 { 40 } 41 42 static 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 53 extern const struct of_cpu_method __cpu_method_of_table[]; 54 const struct of_cpu_method __cpu_method_of_table_sentinel 55 __section(__cpu_method_of_table_end); 56 57 static 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 98 static void sh_of_smp_probe(void) 99 { 100 } 101 102 #endif 103 104 static void noop(void) 105 { 106 } 107 108 static int noopi(void) 109 { 110 return 0; 111 } 112 113 static void __init sh_of_mem_reserve(void) 114 { 115 early_init_fdt_reserve_self(); 116 early_init_fdt_scan_reserved_mem(); 117 } 118 119 static void __init sh_of_time_init(void) 120 { 121 pr_info("SH generic board support: scanning for clocksource devices\n"); 122 timer_probe(); 123 } 124 125 static void __init sh_of_setup(char **cmdline_p) 126 { 127 struct device_node *root; 128 129 board_time_init = sh_of_time_init; 130 131 sh_mv.mv_name = "Unknown SH model"; 132 root = of_find_node_by_path("/"); 133 if (root) { 134 of_property_read_string(root, "model", &sh_mv.mv_name); 135 of_node_put(root); 136 } 137 138 sh_of_smp_probe(); 139 } 140 141 static int sh_of_irq_demux(int irq) 142 { 143 /* FIXME: eventually this should not be used at all; 144 * the interrupt controller should set_handle_irq(). */ 145 return irq; 146 } 147 148 static void __init sh_of_init_irq(void) 149 { 150 pr_info("SH generic board support: scanning for interrupt controllers\n"); 151 irqchip_init(); 152 } 153 154 static int __init sh_of_clk_init(void) 155 { 156 #ifdef CONFIG_COMMON_CLK 157 /* Disabled pending move to COMMON_CLK framework. */ 158 pr_info("SH generic board support: scanning for clk providers\n"); 159 of_clk_init(NULL); 160 #endif 161 return 0; 162 } 163 164 static struct sh_machine_vector __initmv sh_of_generic_mv = { 165 .mv_setup = sh_of_setup, 166 .mv_name = "devicetree", /* replaced by DT root's model */ 167 .mv_irq_demux = sh_of_irq_demux, 168 .mv_init_irq = sh_of_init_irq, 169 .mv_clk_init = sh_of_clk_init, 170 .mv_mode_pins = noopi, 171 .mv_mem_init = noop, 172 .mv_mem_reserve = sh_of_mem_reserve, 173 }; 174 175 struct sh_clk_ops; 176 177 void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx) 178 { 179 } 180 181 void __init plat_irq_setup(void) 182 { 183 } 184