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; 60 const char *method = NULL; 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 for_each_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 of_node_put(np); 84 } 85 86 pr_info("CPU enable method: %s\n", method); 87 if (method) 88 for (; m->method; m++) 89 if (!strcmp(m->method, method)) { 90 register_smp_ops(m->ops); 91 return; 92 } 93 94 register_smp_ops(&dummy_smp_ops); 95 } 96 97 #else 98 99 static void sh_of_smp_probe(void) 100 { 101 } 102 103 #endif 104 105 static void noop(void) 106 { 107 } 108 109 static int noopi(void) 110 { 111 return 0; 112 } 113 114 static void __init sh_of_mem_reserve(void) 115 { 116 early_init_fdt_reserve_self(); 117 early_init_fdt_scan_reserved_mem(); 118 } 119 120 static void __init sh_of_time_init(void) 121 { 122 pr_info("SH generic board support: scanning for clocksource devices\n"); 123 timer_probe(); 124 } 125 126 static void __init sh_of_setup(char **cmdline_p) 127 { 128 struct device_node *root; 129 130 board_time_init = sh_of_time_init; 131 132 sh_mv.mv_name = "Unknown SH model"; 133 root = of_find_node_by_path("/"); 134 if (root) { 135 of_property_read_string(root, "model", &sh_mv.mv_name); 136 of_node_put(root); 137 } 138 139 sh_of_smp_probe(); 140 } 141 142 static int sh_of_irq_demux(int irq) 143 { 144 /* FIXME: eventually this should not be used at all; 145 * the interrupt controller should set_handle_irq(). */ 146 return irq; 147 } 148 149 static void __init sh_of_init_irq(void) 150 { 151 pr_info("SH generic board support: scanning for interrupt controllers\n"); 152 irqchip_init(); 153 } 154 155 static int __init sh_of_clk_init(void) 156 { 157 #ifdef CONFIG_COMMON_CLK 158 /* Disabled pending move to COMMON_CLK framework. */ 159 pr_info("SH generic board support: scanning for clk providers\n"); 160 of_clk_init(NULL); 161 #endif 162 return 0; 163 } 164 165 static struct sh_machine_vector __initmv sh_of_generic_mv = { 166 .mv_setup = sh_of_setup, 167 .mv_name = "devicetree", /* replaced by DT root's model */ 168 .mv_irq_demux = sh_of_irq_demux, 169 .mv_init_irq = sh_of_init_irq, 170 .mv_clk_init = sh_of_clk_init, 171 .mv_mode_pins = noopi, 172 .mv_mem_init = noop, 173 .mv_mem_reserve = sh_of_mem_reserve, 174 }; 175 176 struct sh_clk_ops; 177 178 void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx) 179 { 180 } 181 182 void __init plat_irq_setup(void) 183 { 184 } 185