1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/string.h> 3 #include <linux/kernel.h> 4 #include <linux/of.h> 5 #include <linux/init.h> 6 #include <linux/mod_devicetable.h> 7 #include <linux/slab.h> 8 #include <linux/errno.h> 9 #include <linux/irq.h> 10 #include <linux/of_platform.h> 11 #include <linux/platform_device.h> 12 #include <linux/dma-mapping.h> 13 #include <asm/leon.h> 14 #include <asm/leon_amba.h> 15 16 #include "of_device_common.h" 17 #include "irq.h" 18 19 /* 20 * PCI bus specific translator 21 */ 22 23 static int of_bus_pci_match(struct device_node *np) 24 { 25 if (of_node_is_type(np, "pci") || of_node_is_type(np, "pciex")) { 26 /* Do not do PCI specific frobbing if the 27 * PCI bridge lacks a ranges property. We 28 * want to pass it through up to the next 29 * parent as-is, not with the PCI translate 30 * method which chops off the top address cell. 31 */ 32 if (!of_property_present(np, "ranges")) 33 return 0; 34 35 return 1; 36 } 37 38 return 0; 39 } 40 41 static void of_bus_pci_count_cells(struct device_node *np, 42 int *addrc, int *sizec) 43 { 44 if (addrc) 45 *addrc = 3; 46 if (sizec) 47 *sizec = 2; 48 } 49 50 static int of_bus_pci_map(u32 *addr, const u32 *range, 51 int na, int ns, int pna) 52 { 53 u32 result[OF_MAX_ADDR_CELLS]; 54 int i; 55 56 /* Check address type match */ 57 if ((addr[0] ^ range[0]) & 0x03000000) 58 return -EINVAL; 59 60 if (of_out_of_range(addr + 1, range + 1, range + na + pna, 61 na - 1, ns)) 62 return -EINVAL; 63 64 /* Start with the parent range base. */ 65 memcpy(result, range + na, pna * 4); 66 67 /* Add in the child address offset, skipping high cell. */ 68 for (i = 0; i < na - 1; i++) 69 result[pna - 1 - i] += 70 (addr[na - 1 - i] - 71 range[na - 1 - i]); 72 73 memcpy(addr, result, pna * 4); 74 75 return 0; 76 } 77 78 static unsigned long of_bus_pci_get_flags(const u32 *addr, unsigned long flags) 79 { 80 u32 w = addr[0]; 81 82 /* For PCI, we override whatever child busses may have used. */ 83 flags = 0; 84 switch((w >> 24) & 0x03) { 85 case 0x01: 86 flags |= IORESOURCE_IO; 87 break; 88 89 case 0x02: /* 32 bits */ 90 case 0x03: /* 64 bits */ 91 flags |= IORESOURCE_MEM; 92 break; 93 } 94 if (w & 0x40000000) 95 flags |= IORESOURCE_PREFETCH; 96 return flags; 97 } 98 99 static unsigned long of_bus_sbus_get_flags(const u32 *addr, unsigned long flags) 100 { 101 return IORESOURCE_MEM; 102 } 103 104 /* 105 * AMBAPP bus specific translator 106 */ 107 108 static int of_bus_ambapp_match(struct device_node *np) 109 { 110 return of_node_is_type(np, "ambapp"); 111 } 112 113 static void of_bus_ambapp_count_cells(struct device_node *child, 114 int *addrc, int *sizec) 115 { 116 if (addrc) 117 *addrc = 1; 118 if (sizec) 119 *sizec = 1; 120 } 121 122 static int of_bus_ambapp_map(u32 *addr, const u32 *range, 123 int na, int ns, int pna) 124 { 125 return of_bus_default_map(addr, range, na, ns, pna); 126 } 127 128 static unsigned long of_bus_ambapp_get_flags(const u32 *addr, 129 unsigned long flags) 130 { 131 return IORESOURCE_MEM; 132 } 133 134 /* 135 * Array of bus specific translators 136 */ 137 138 static struct of_bus of_busses[] = { 139 /* PCI */ 140 { 141 .name = "pci", 142 .addr_prop_name = "assigned-addresses", 143 .match = of_bus_pci_match, 144 .count_cells = of_bus_pci_count_cells, 145 .map = of_bus_pci_map, 146 .get_flags = of_bus_pci_get_flags, 147 }, 148 /* SBUS */ 149 { 150 .name = "sbus", 151 .addr_prop_name = "reg", 152 .match = of_bus_sbus_match, 153 .count_cells = of_bus_sbus_count_cells, 154 .map = of_bus_default_map, 155 .get_flags = of_bus_sbus_get_flags, 156 }, 157 /* AMBA */ 158 { 159 .name = "ambapp", 160 .addr_prop_name = "reg", 161 .match = of_bus_ambapp_match, 162 .count_cells = of_bus_ambapp_count_cells, 163 .map = of_bus_ambapp_map, 164 .get_flags = of_bus_ambapp_get_flags, 165 }, 166 /* Default */ 167 { 168 .name = "default", 169 .addr_prop_name = "reg", 170 .match = NULL, 171 .count_cells = of_bus_default_count_cells, 172 .map = of_bus_default_map, 173 .get_flags = of_bus_default_get_flags, 174 }, 175 }; 176 177 static struct of_bus *of_match_bus(struct device_node *np) 178 { 179 int i; 180 181 for (i = 0; i < ARRAY_SIZE(of_busses); i ++) 182 if (!of_busses[i].match || of_busses[i].match(np)) 183 return &of_busses[i]; 184 BUG(); 185 return NULL; 186 } 187 188 static int __init build_one_resource(struct device_node *parent, 189 struct of_bus *bus, 190 struct of_bus *pbus, 191 u32 *addr, 192 int na, int ns, int pna) 193 { 194 const u32 *ranges; 195 unsigned int rlen; 196 int rone; 197 198 ranges = of_get_property(parent, "ranges", &rlen); 199 if (ranges == NULL || rlen == 0) { 200 u32 result[OF_MAX_ADDR_CELLS]; 201 int i; 202 203 memset(result, 0, pna * 4); 204 for (i = 0; i < na; i++) 205 result[pna - 1 - i] = 206 addr[na - 1 - i]; 207 208 memcpy(addr, result, pna * 4); 209 return 0; 210 } 211 212 /* Now walk through the ranges */ 213 rlen /= 4; 214 rone = na + pna + ns; 215 for (; rlen >= rone; rlen -= rone, ranges += rone) { 216 if (!bus->map(addr, ranges, na, ns, pna)) 217 return 0; 218 } 219 220 return 1; 221 } 222 223 static int __init use_1to1_mapping(struct device_node *pp) 224 { 225 /* If we have a ranges property in the parent, use it. */ 226 if (of_property_present(pp, "ranges")) 227 return 0; 228 229 /* Some SBUS devices use intermediate nodes to express 230 * hierarchy within the device itself. These aren't 231 * real bus nodes, and don't have a 'ranges' property. 232 * But, we should still pass the translation work up 233 * to the SBUS itself. 234 */ 235 if (of_node_name_eq(pp, "dma") || 236 of_node_name_eq(pp, "espdma") || 237 of_node_name_eq(pp, "ledma") || 238 of_node_name_eq(pp, "lebuffer")) 239 return 0; 240 241 return 1; 242 } 243 244 static int of_resource_verbose; 245 246 static void __init build_device_resources(struct platform_device *op, 247 struct device *parent) 248 { 249 struct platform_device *p_op; 250 struct of_bus *bus; 251 int na, ns; 252 int index, num_reg; 253 const void *preg; 254 255 if (!parent) 256 return; 257 258 p_op = to_platform_device(parent); 259 bus = of_match_bus(p_op->dev.of_node); 260 bus->count_cells(op->dev.of_node, &na, &ns); 261 262 preg = of_get_property(op->dev.of_node, bus->addr_prop_name, &num_reg); 263 if (!preg || num_reg == 0) 264 return; 265 266 /* Convert to num-cells. */ 267 num_reg /= 4; 268 269 /* Conver to num-entries. */ 270 num_reg /= na + ns; 271 272 op->resource = op->archdata.resource; 273 op->num_resources = num_reg; 274 for (index = 0; index < num_reg; index++) { 275 struct resource *r = &op->resource[index]; 276 u32 addr[OF_MAX_ADDR_CELLS]; 277 const u32 *reg = (preg + (index * ((na + ns) * 4))); 278 struct device_node *dp = op->dev.of_node; 279 struct device_node *pp = p_op->dev.of_node; 280 struct of_bus *pbus, *dbus; 281 u64 size, result = OF_BAD_ADDR; 282 unsigned long flags; 283 int dna, dns; 284 int pna, pns; 285 286 size = of_read_addr(reg + na, ns); 287 288 memcpy(addr, reg, na * 4); 289 290 flags = bus->get_flags(reg, 0); 291 292 if (use_1to1_mapping(pp)) { 293 result = of_read_addr(addr, na); 294 goto build_res; 295 } 296 297 dna = na; 298 dns = ns; 299 dbus = bus; 300 301 while (1) { 302 dp = pp; 303 pp = dp->parent; 304 if (!pp) { 305 result = of_read_addr(addr, dna); 306 break; 307 } 308 309 pbus = of_match_bus(pp); 310 pbus->count_cells(dp, &pna, &pns); 311 312 if (build_one_resource(dp, dbus, pbus, addr, 313 dna, dns, pna)) 314 break; 315 316 flags = pbus->get_flags(addr, flags); 317 318 dna = pna; 319 dns = pns; 320 dbus = pbus; 321 } 322 323 build_res: 324 memset(r, 0, sizeof(*r)); 325 326 if (of_resource_verbose) 327 printk("%pOF reg[%d] -> %llx\n", 328 op->dev.of_node, index, 329 result); 330 331 if (result != OF_BAD_ADDR) { 332 r->start = result & 0xffffffff; 333 r->end = result + size - 1; 334 r->flags = flags | ((result >> 32ULL) & 0xffUL); 335 } 336 r->name = op->dev.of_node->full_name; 337 } 338 } 339 340 static struct platform_device * __init scan_one_device(struct device_node *dp, 341 struct device *parent) 342 { 343 struct platform_device *op = kzalloc(sizeof(*op), GFP_KERNEL); 344 const struct linux_prom_irqs *intr; 345 struct dev_archdata *sd; 346 int len, i; 347 348 if (!op) 349 return NULL; 350 351 sd = &op->dev.archdata; 352 sd->op = op; 353 354 op->dev.of_node = dp; 355 356 intr = of_get_property(dp, "intr", &len); 357 if (intr) { 358 op->archdata.num_irqs = len / sizeof(struct linux_prom_irqs); 359 for (i = 0; i < op->archdata.num_irqs; i++) 360 op->archdata.irqs[i] = 361 sparc_config.build_device_irq(op, intr[i].pri); 362 } else { 363 const unsigned int *irq = 364 of_get_property(dp, "interrupts", &len); 365 366 if (irq) { 367 op->archdata.num_irqs = len / sizeof(unsigned int); 368 for (i = 0; i < op->archdata.num_irqs; i++) 369 op->archdata.irqs[i] = 370 sparc_config.build_device_irq(op, irq[i]); 371 } else { 372 op->archdata.num_irqs = 0; 373 } 374 } 375 376 build_device_resources(op, parent); 377 378 op->dev.parent = parent; 379 op->dev.bus = &platform_bus_type; 380 if (!parent) 381 dev_set_name(&op->dev, "root"); 382 else 383 dev_set_name(&op->dev, "%08x", dp->phandle); 384 385 op->dev.coherent_dma_mask = DMA_BIT_MASK(32); 386 op->dev.dma_mask = &op->dev.coherent_dma_mask; 387 388 if (of_device_register(op)) { 389 printk("%pOF: Could not register of device.\n", dp); 390 kfree(op); 391 op = NULL; 392 } 393 394 return op; 395 } 396 397 static void __init scan_tree(struct device_node *dp, struct device *parent) 398 { 399 while (dp) { 400 struct platform_device *op = scan_one_device(dp, parent); 401 402 if (op) 403 scan_tree(dp->child, &op->dev); 404 405 dp = dp->sibling; 406 } 407 } 408 409 static int __init scan_of_devices(void) 410 { 411 struct device_node *root = of_find_node_by_path("/"); 412 struct platform_device *parent; 413 414 parent = scan_one_device(root, NULL); 415 if (!parent) 416 return 0; 417 418 scan_tree(root->child, &parent->dev); 419 return 0; 420 } 421 postcore_initcall(scan_of_devices); 422 423 static int __init of_debug(char *str) 424 { 425 int val = 0; 426 427 get_option(&str, &val); 428 if (val & 1) 429 of_resource_verbose = 1; 430 return 1; 431 } 432 433 __setup("of_debug=", of_debug); 434
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.