1 /* 2 * FSL SoC setup code 3 * 4 * Maintained by Kumar Gala (see MAINTAINERS for contact information) 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the 8 * Free Software Foundation; either version 2 of the License, or (at your 9 * option) any later version. 10 */ 11 12 #include <linux/config.h> 13 #include <linux/stddef.h> 14 #include <linux/kernel.h> 15 #include <linux/init.h> 16 #include <linux/errno.h> 17 #include <linux/major.h> 18 #include <linux/delay.h> 19 #include <linux/irq.h> 20 #include <linux/module.h> 21 #include <linux/device.h> 22 #include <linux/platform_device.h> 23 #include <linux/fsl_devices.h> 24 25 #include <asm/system.h> 26 #include <asm/atomic.h> 27 #include <asm/io.h> 28 #include <asm/irq.h> 29 #include <asm/prom.h> 30 #include <sysdev/fsl_soc.h> 31 #include <mm/mmu_decl.h> 32 33 static phys_addr_t immrbase = -1; 34 35 phys_addr_t get_immrbase(void) 36 { 37 struct device_node *soc; 38 39 if (immrbase != -1) 40 return immrbase; 41 42 soc = of_find_node_by_type(NULL, "soc"); 43 if (soc) { 44 unsigned int size; 45 void *prop = get_property(soc, "reg", &size); 46 immrbase = of_translate_address(soc, prop); 47 of_node_put(soc); 48 }; 49 50 return immrbase; 51 } 52 53 EXPORT_SYMBOL(get_immrbase); 54 55 static int __init gfar_mdio_of_init(void) 56 { 57 struct device_node *np; 58 unsigned int i; 59 struct platform_device *mdio_dev; 60 struct resource res; 61 int ret; 62 63 for (np = NULL, i = 0; 64 (np = of_find_compatible_node(np, "mdio", "gianfar")) != NULL; 65 i++) { 66 int k; 67 struct device_node *child = NULL; 68 struct gianfar_mdio_data mdio_data; 69 70 memset(&res, 0, sizeof(res)); 71 memset(&mdio_data, 0, sizeof(mdio_data)); 72 73 ret = of_address_to_resource(np, 0, &res); 74 if (ret) 75 goto err; 76 77 mdio_dev = 78 platform_device_register_simple("fsl-gianfar_mdio", 79 res.start, &res, 1); 80 if (IS_ERR(mdio_dev)) { 81 ret = PTR_ERR(mdio_dev); 82 goto err; 83 } 84 85 for (k = 0; k < 32; k++) 86 mdio_data.irq[k] = -1; 87 88 while ((child = of_get_next_child(np, child)) != NULL) { 89 if (child->n_intrs) { 90 u32 *id = 91 (u32 *) get_property(child, "reg", NULL); 92 mdio_data.irq[*id] = child->intrs[0].line; 93 } 94 } 95 96 ret = 97 platform_device_add_data(mdio_dev, &mdio_data, 98 sizeof(struct gianfar_mdio_data)); 99 if (ret) 100 goto unreg; 101 } 102 103 return 0; 104 105 unreg: 106 platform_device_unregister(mdio_dev); 107 err: 108 return ret; 109 } 110 111 arch_initcall(gfar_mdio_of_init); 112 113 static const char *gfar_tx_intr = "tx"; 114 static const char *gfar_rx_intr = "rx"; 115 static const char *gfar_err_intr = "error"; 116 117 static int __init gfar_of_init(void) 118 { 119 struct device_node *np; 120 unsigned int i; 121 struct platform_device *gfar_dev; 122 struct resource res; 123 int ret; 124 125 for (np = NULL, i = 0; 126 (np = of_find_compatible_node(np, "network", "gianfar")) != NULL; 127 i++) { 128 struct resource r[4]; 129 struct device_node *phy, *mdio; 130 struct gianfar_platform_data gfar_data; 131 unsigned int *id; 132 char *model; 133 void *mac_addr; 134 phandle *ph; 135 136 memset(r, 0, sizeof(r)); 137 memset(&gfar_data, 0, sizeof(gfar_data)); 138 139 ret = of_address_to_resource(np, 0, &r[0]); 140 if (ret) 141 goto err; 142 143 r[1].start = np->intrs[0].line; 144 r[1].end = np->intrs[0].line; 145 r[1].flags = IORESOURCE_IRQ; 146 147 model = get_property(np, "model", NULL); 148 149 /* If we aren't the FEC we have multiple interrupts */ 150 if (model && strcasecmp(model, "FEC")) { 151 r[1].name = gfar_tx_intr; 152 153 r[2].name = gfar_rx_intr; 154 r[2].start = np->intrs[1].line; 155 r[2].end = np->intrs[1].line; 156 r[2].flags = IORESOURCE_IRQ; 157 158 r[3].name = gfar_err_intr; 159 r[3].start = np->intrs[2].line; 160 r[3].end = np->intrs[2].line; 161 r[3].flags = IORESOURCE_IRQ; 162 } 163 164 gfar_dev = 165 platform_device_register_simple("fsl-gianfar", i, &r[0], 166 np->n_intrs + 1); 167 168 if (IS_ERR(gfar_dev)) { 169 ret = PTR_ERR(gfar_dev); 170 goto err; 171 } 172 173 mac_addr = get_property(np, "address", NULL); 174 memcpy(gfar_data.mac_addr, mac_addr, 6); 175 176 if (model && !strcasecmp(model, "TSEC")) 177 gfar_data.device_flags = 178 FSL_GIANFAR_DEV_HAS_GIGABIT | 179 FSL_GIANFAR_DEV_HAS_COALESCE | 180 FSL_GIANFAR_DEV_HAS_RMON | 181 FSL_GIANFAR_DEV_HAS_MULTI_INTR; 182 if (model && !strcasecmp(model, "eTSEC")) 183 gfar_data.device_flags = 184 FSL_GIANFAR_DEV_HAS_GIGABIT | 185 FSL_GIANFAR_DEV_HAS_COALESCE | 186 FSL_GIANFAR_DEV_HAS_RMON | 187 FSL_GIANFAR_DEV_HAS_MULTI_INTR | 188 FSL_GIANFAR_DEV_HAS_CSUM | 189 FSL_GIANFAR_DEV_HAS_VLAN | 190 FSL_GIANFAR_DEV_HAS_EXTENDED_HASH; 191 192 ph = (phandle *) get_property(np, "phy-handle", NULL); 193 phy = of_find_node_by_phandle(*ph); 194 195 if (phy == NULL) { 196 ret = -ENODEV; 197 goto unreg; 198 } 199 200 mdio = of_get_parent(phy); 201 202 id = (u32 *) get_property(phy, "reg", NULL); 203 ret = of_address_to_resource(mdio, 0, &res); 204 if (ret) { 205 of_node_put(phy); 206 of_node_put(mdio); 207 goto unreg; 208 } 209 210 gfar_data.phy_id = *id; 211 gfar_data.bus_id = res.start; 212 213 of_node_put(phy); 214 of_node_put(mdio); 215 216 ret = 217 platform_device_add_data(gfar_dev, &gfar_data, 218 sizeof(struct 219 gianfar_platform_data)); 220 if (ret) 221 goto unreg; 222 } 223 224 return 0; 225 226 unreg: 227 platform_device_unregister(gfar_dev); 228 err: 229 return ret; 230 } 231 232 arch_initcall(gfar_of_init); 233 234 static int __init fsl_i2c_of_init(void) 235 { 236 struct device_node *np; 237 unsigned int i; 238 struct platform_device *i2c_dev; 239 int ret; 240 241 for (np = NULL, i = 0; 242 (np = of_find_compatible_node(np, "i2c", "fsl-i2c")) != NULL; 243 i++) { 244 struct resource r[2]; 245 struct fsl_i2c_platform_data i2c_data; 246 unsigned char *flags = NULL; 247 248 memset(&r, 0, sizeof(r)); 249 memset(&i2c_data, 0, sizeof(i2c_data)); 250 251 ret = of_address_to_resource(np, 0, &r[0]); 252 if (ret) 253 goto err; 254 255 r[1].start = np->intrs[0].line; 256 r[1].end = np->intrs[0].line; 257 r[1].flags = IORESOURCE_IRQ; 258 259 i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2); 260 if (IS_ERR(i2c_dev)) { 261 ret = PTR_ERR(i2c_dev); 262 goto err; 263 } 264 265 i2c_data.device_flags = 0; 266 flags = get_property(np, "dfsrr", NULL); 267 if (flags) 268 i2c_data.device_flags |= FSL_I2C_DEV_SEPARATE_DFSRR; 269 270 flags = get_property(np, "fsl5200-clocking", NULL); 271 if (flags) 272 i2c_data.device_flags |= FSL_I2C_DEV_CLOCK_5200; 273 274 ret = 275 platform_device_add_data(i2c_dev, &i2c_data, 276 sizeof(struct 277 fsl_i2c_platform_data)); 278 if (ret) 279 goto unreg; 280 } 281 282 return 0; 283 284 unreg: 285 platform_device_unregister(i2c_dev); 286 err: 287 return ret; 288 } 289 290 arch_initcall(fsl_i2c_of_init); 291 292 #ifdef CONFIG_PPC_83xx 293 static int __init mpc83xx_wdt_init(void) 294 { 295 struct resource r; 296 struct device_node *soc, *np; 297 struct platform_device *dev; 298 unsigned int *freq; 299 int ret; 300 301 np = of_find_compatible_node(NULL, "watchdog", "mpc83xx_wdt"); 302 303 if (!np) { 304 ret = -ENODEV; 305 goto nodev; 306 } 307 308 soc = of_find_node_by_type(NULL, "soc"); 309 310 if (!soc) { 311 ret = -ENODEV; 312 goto nosoc; 313 } 314 315 freq = (unsigned int *)get_property(soc, "bus-frequency", NULL); 316 if (!freq) { 317 ret = -ENODEV; 318 goto err; 319 } 320 321 memset(&r, 0, sizeof(r)); 322 323 ret = of_address_to_resource(np, 0, &r); 324 if (ret) 325 goto err; 326 327 dev = platform_device_register_simple("mpc83xx_wdt", 0, &r, 1); 328 if (IS_ERR(dev)) { 329 ret = PTR_ERR(dev); 330 goto err; 331 } 332 333 ret = platform_device_add_data(dev, freq, sizeof(int)); 334 if (ret) 335 goto unreg; 336 337 of_node_put(soc); 338 of_node_put(np); 339 340 return 0; 341 342 unreg: 343 platform_device_unregister(dev); 344 err: 345 of_node_put(soc); 346 nosoc: 347 of_node_put(np); 348 nodev: 349 return ret; 350 } 351 352 arch_initcall(mpc83xx_wdt_init); 353 #endif 354 355 static enum fsl_usb2_phy_modes determine_usb_phy(char * phy_type) 356 { 357 if (!phy_type) 358 return FSL_USB2_PHY_NONE; 359 if (!strcasecmp(phy_type, "ulpi")) 360 return FSL_USB2_PHY_ULPI; 361 if (!strcasecmp(phy_type, "utmi")) 362 return FSL_USB2_PHY_UTMI; 363 if (!strcasecmp(phy_type, "utmi_wide")) 364 return FSL_USB2_PHY_UTMI_WIDE; 365 if (!strcasecmp(phy_type, "serial")) 366 return FSL_USB2_PHY_SERIAL; 367 368 return FSL_USB2_PHY_NONE; 369 } 370 371 static int __init fsl_usb_of_init(void) 372 { 373 struct device_node *np; 374 unsigned int i; 375 struct platform_device *usb_dev; 376 int ret; 377 378 for (np = NULL, i = 0; 379 (np = of_find_compatible_node(np, "usb", "fsl-usb2-mph")) != NULL; 380 i++) { 381 struct resource r[2]; 382 struct fsl_usb2_platform_data usb_data; 383 unsigned char *prop = NULL; 384 385 memset(&r, 0, sizeof(r)); 386 memset(&usb_data, 0, sizeof(usb_data)); 387 388 ret = of_address_to_resource(np, 0, &r[0]); 389 if (ret) 390 goto err; 391 392 r[1].start = np->intrs[0].line; 393 r[1].end = np->intrs[0].line; 394 r[1].flags = IORESOURCE_IRQ; 395 396 usb_dev = 397 platform_device_register_simple("fsl-usb2-mph", i, r, 2); 398 if (IS_ERR(usb_dev)) { 399 ret = PTR_ERR(usb_dev); 400 goto err; 401 } 402 403 usb_dev->dev.coherent_dma_mask = 0xffffffffUL; 404 usb_dev->dev.dma_mask = &usb_dev->dev.coherent_dma_mask; 405 406 usb_data.operating_mode = FSL_USB2_MPH_HOST; 407 408 prop = get_property(np, "port0", NULL); 409 if (prop) 410 usb_data.port_enables |= FSL_USB2_PORT0_ENABLED; 411 412 prop = get_property(np, "port1", NULL); 413 if (prop) 414 usb_data.port_enables |= FSL_USB2_PORT1_ENABLED; 415 416 prop = get_property(np, "phy_type", NULL); 417 usb_data.phy_mode = determine_usb_phy(prop); 418 419 ret = 420 platform_device_add_data(usb_dev, &usb_data, 421 sizeof(struct 422 fsl_usb2_platform_data)); 423 if (ret) 424 goto unreg; 425 } 426 427 return 0; 428 429 unreg: 430 platform_device_unregister(usb_dev); 431 err: 432 return ret; 433 } 434 435 arch_initcall(fsl_usb_of_init); 436 437 static int __init fsl_usb_dr_of_init(void) 438 { 439 struct device_node *np; 440 unsigned int i; 441 struct platform_device *usb_dev; 442 int ret; 443 444 for (np = NULL, i = 0; 445 (np = of_find_compatible_node(np, "usb", "fsl-usb2-dr")) != NULL; 446 i++) { 447 struct resource r[2]; 448 struct fsl_usb2_platform_data usb_data; 449 unsigned char *prop = NULL; 450 451 memset(&r, 0, sizeof(r)); 452 memset(&usb_data, 0, sizeof(usb_data)); 453 454 ret = of_address_to_resource(np, 0, &r[0]); 455 if (ret) 456 goto err; 457 458 r[1].start = np->intrs[0].line; 459 r[1].end = np->intrs[0].line; 460 r[1].flags = IORESOURCE_IRQ; 461 462 usb_dev = 463 platform_device_register_simple("fsl-usb2-dr", i, r, 2); 464 if (IS_ERR(usb_dev)) { 465 ret = PTR_ERR(usb_dev); 466 goto err; 467 } 468 469 usb_dev->dev.coherent_dma_mask = 0xffffffffUL; 470 usb_dev->dev.dma_mask = &usb_dev->dev.coherent_dma_mask; 471 472 usb_data.operating_mode = FSL_USB2_DR_HOST; 473 474 prop = get_property(np, "phy_type", NULL); 475 usb_data.phy_mode = determine_usb_phy(prop); 476 477 ret = 478 platform_device_add_data(usb_dev, &usb_data, 479 sizeof(struct 480 fsl_usb2_platform_data)); 481 if (ret) 482 goto unreg; 483 } 484 485 return 0; 486 487 unreg: 488 platform_device_unregister(usb_dev); 489 err: 490 return ret; 491 } 492 493 arch_initcall(fsl_usb_dr_of_init); 494