1/* 2 * FSL SoC setup code 3 * 4 * Maintained by Kumar Gala (see MAINTAINERS for contact information) 5 * 6 * 2006 (c) MontaVista Software, Inc. 7 * Vitaly Bordug <vbordug@ru.mvista.com> 8 * 9 * This program is free software; you can redistribute it and/or modify it 10 * under the terms of the GNU General Public License as published by the 11 * Free Software Foundation; either version 2 of the License, or (at your 12 * option) any later version. 13 */ 14 15#include <linux/stddef.h> 16#include <linux/kernel.h> 17#include <linux/init.h> 18#include <linux/errno.h> 19#include <linux/major.h> 20#include <linux/delay.h> 21#include <linux/irq.h> 22#include <linux/module.h> 23#include <linux/device.h> 24#include <linux/platform_device.h> 25#include <linux/phy.h> 26#include <linux/fsl_devices.h> 27#include <linux/fs_enet_pd.h> 28#include <linux/fs_uart_pd.h> 29 30#include <asm/system.h> 31#include <asm/atomic.h> 32#include <asm/io.h> 33#include <asm/irq.h> 34#include <asm/time.h> 35#include <asm/prom.h> 36#include <sysdev/fsl_soc.h> 37#include <mm/mmu_decl.h> 38#include <asm/cpm2.h> 39 40extern void init_fcc_ioports(struct fs_platform_info*); 41extern void init_fec_ioports(struct fs_platform_info*); 42extern void init_smc_ioports(struct fs_uart_platform_info*); 43static phys_addr_t immrbase = -1; 44 45phys_addr_t get_immrbase(void) 46{ 47 struct device_node *soc; 48 49 if (immrbase != -1) 50 return immrbase; 51 52 soc = of_find_node_by_type(NULL, "soc"); 53 if (soc) { 54 unsigned int size; 55 const void *prop = of_get_property(soc, "reg", &size); 56 57 if (prop) 58 immrbase = of_translate_address(soc, prop); 59 of_node_put(soc); 60 }; 61 62 return immrbase; 63} 64 65EXPORT_SYMBOL(get_immrbase); 66 67#if defined(CONFIG_CPM2) || defined(CONFIG_8xx) 68 69static u32 brgfreq = -1; 70 71u32 get_brgfreq(void) 72{ 73 struct device_node *node; 74 75 if (brgfreq != -1) 76 return brgfreq; 77 78 node = of_find_node_by_type(NULL, "cpm"); 79 if (node) { 80 unsigned int size; 81 const unsigned int *prop = of_get_property(node, 82 "brg-frequency", &size); 83 84 if (prop) 85 brgfreq = *prop; 86 of_node_put(node); 87 }; 88 89 return brgfreq; 90} 91 92EXPORT_SYMBOL(get_brgfreq); 93 94static u32 fs_baudrate = -1; 95 96u32 get_baudrate(void) 97{ 98 struct device_node *node; 99 100 if (fs_baudrate != -1) 101 return fs_baudrate; 102 103 node = of_find_node_by_type(NULL, "serial"); 104 if (node) { 105 unsigned int size; 106 const unsigned int *prop = of_get_property(node, 107 "current-speed", &size); 108 109 if (prop) 110 fs_baudrate = *prop; 111 of_node_put(node); 112 }; 113 114 return fs_baudrate; 115} 116 117EXPORT_SYMBOL(get_baudrate); 118#endif /* CONFIG_CPM2 */ 119 120static int __init gfar_mdio_of_init(void) 121{ 122 struct device_node *np; 123 unsigned int i; 124 struct platform_device *mdio_dev; 125 struct resource res; 126 int ret; 127 128 for (np = NULL, i = 0; 129 (np = of_find_compatible_node(np, "mdio", "gianfar")) != NULL; 130 i++) { 131 int k; 132 struct device_node *child = NULL; 133 struct gianfar_mdio_data mdio_data; 134 135 memset(&res, 0, sizeof(res)); 136 memset(&mdio_data, 0, sizeof(mdio_data)); 137 138 ret = of_address_to_resource(np, 0, &res); 139 if (ret) 140 goto err; 141 142 mdio_dev = 143 platform_device_register_simple("fsl-gianfar_mdio", 144 res.start, &res, 1); 145 if (IS_ERR(mdio_dev)) { 146 ret = PTR_ERR(mdio_dev); 147 goto err; 148 } 149 150 for (k = 0; k < 32; k++) 151 mdio_data.irq[k] = PHY_POLL; 152 153 while ((child = of_get_next_child(np, child)) != NULL) { 154 int irq = irq_of_parse_and_map(child, 0); 155 if (irq != NO_IRQ) { 156 const u32 *id = of_get_property(child, 157 "reg", NULL); 158 mdio_data.irq[*id] = irq; 159 } 160 } 161 162 ret = 163 platform_device_add_data(mdio_dev, &mdio_data, 164 sizeof(struct gianfar_mdio_data)); 165 if (ret) 166 goto unreg; 167 } 168 169 return 0; 170 171unreg: 172 platform_device_unregister(mdio_dev); 173err: 174 return ret; 175} 176 177arch_initcall(gfar_mdio_of_init); 178 179static const char *gfar_tx_intr = "tx"; 180static const char *gfar_rx_intr = "rx"; 181static const char *gfar_err_intr = "error"; 182 183 184static int __init gfar_of_init(void) 185{ 186 struct device_node *np; 187 unsigned int i; 188 struct platform_device *gfar_dev; 189 struct resource res; 190 int ret; 191 192 for (np = NULL, i = 0; 193 (np = of_find_compatible_node(np, "network", "gianfar")) != NULL; 194 i++) { 195 struct resource r[4]; 196 struct device_node *phy, *mdio; 197 struct gianfar_platform_data gfar_data; 198 const unsigned int *id; 199 const char *model; 200 const void *mac_addr; 201 const phandle *ph; 202 int n_res = 2; 203 204 memset(r, 0, sizeof(r)); 205 memset(&gfar_data, 0, sizeof(gfar_data)); 206 207 ret = of_address_to_resource(np, 0, &r[0]); 208 if (ret) 209 goto err; 210 211 of_irq_to_resource(np, 0, &r[1]); 212 213 model = of_get_property(np, "model", NULL); 214 215 /* If we aren't the FEC we have multiple interrupts */ 216 if (model && strcasecmp(model, "FEC")) { 217 r[1].name = gfar_tx_intr; 218 219 r[2].name = gfar_rx_intr; 220 of_irq_to_resource(np, 1, &r[2]); 221 222 r[3].name = gfar_err_intr; 223 of_irq_to_resource(np, 2, &r[3]); 224 225 n_res += 2; 226 } 227 228 gfar_dev = 229 platform_device_register_simple("fsl-gianfar", i, &r[0], 230 n_res); 231 232 if (IS_ERR(gfar_dev)) { 233 ret = PTR_ERR(gfar_dev); 234 goto err; 235 } 236 237 mac_addr = of_get_mac_address(np); 238 if (mac_addr) 239 memcpy(gfar_data.mac_addr, mac_addr, 6); 240 241 if (model && !strcasecmp(model, "TSEC")) 242 gfar_data.device_flags = 243 FSL_GIANFAR_DEV_HAS_GIGABIT | 244 FSL_GIANFAR_DEV_HAS_COALESCE | 245 FSL_GIANFAR_DEV_HAS_RMON | 246 FSL_GIANFAR_DEV_HAS_MULTI_INTR; 247 if (model && !strcasecmp(model, "eTSEC")) 248 gfar_data.device_flags = 249 FSL_GIANFAR_DEV_HAS_GIGABIT | 250 FSL_GIANFAR_DEV_HAS_COALESCE | 251 FSL_GIANFAR_DEV_HAS_RMON | 252 FSL_GIANFAR_DEV_HAS_MULTI_INTR | 253 FSL_GIANFAR_DEV_HAS_CSUM | 254 FSL_GIANFAR_DEV_HAS_VLAN | 255 FSL_GIANFAR_DEV_HAS_EXTENDED_HASH; 256 257 ph = of_get_property(np, "phy-handle", NULL); 258 phy = of_find_node_by_phandle(*ph); 259 260 if (phy == NULL) { 261 ret = -ENODEV; 262 goto unreg; 263 } 264 265 mdio = of_get_parent(phy); 266 267 id = of_get_property(phy, "reg", NULL); 268 ret = of_address_to_resource(mdio, 0, &res); 269 if (ret) { 270 of_node_put(phy); 271 of_node_put(mdio); 272 goto unreg; 273 } 274 275 gfar_data.phy_id = *id; 276 gfar_data.bus_id = res.start; 277 278 of_node_put(phy); 279 of_node_put(mdio); 280 281 ret = 282 platform_device_add_data(gfar_dev, &gfar_data, 283 sizeof(struct 284 gianfar_platform_data)); 285 if (ret) 286 goto unreg; 287 } 288 289 return 0; 290 291unreg: 292 platform_device_unregister(gfar_dev); 293err: 294 return ret; 295} 296 297arch_initcall(gfar_of_init); 298 299static int __init fsl_i2c_of_init(void) 300{ 301 struct device_node *np; 302 unsigned int i; 303 struct platform_device *i2c_dev; 304 int ret; 305 306 for (np = NULL, i = 0; 307 (np = of_find_compatible_node(np, "i2c", "fsl-i2c")) != NULL; 308 i++) { 309 struct resource r[2]; 310 struct fsl_i2c_platform_data i2c_data; 311 const unsigned char *flags = NULL; 312 313 memset(&r, 0, sizeof(r)); 314 memset(&i2c_data, 0, sizeof(i2c_data)); 315 316 ret = of_address_to_resource(np, 0, &r[0]); 317 if (ret) 318 goto err; 319 320 of_irq_to_resource(np, 0, &r[1]); 321 322 i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2); 323 if (IS_ERR(i2c_dev)) { 324 ret = PTR_ERR(i2c_dev); 325 goto err; 326 } 327 328 i2c_data.device_flags = 0; 329 flags = of_get_property(np, "dfsrr", NULL); 330 if (flags) 331 i2c_data.device_flags |= FSL_I2C_DEV_SEPARATE_DFSRR; 332 333 flags = of_get_property(np, "fsl5200-clocking", NULL); 334 if (flags) 335 i2c_data.device_flags |= FSL_I2C_DEV_CLOCK_5200; 336 337 ret = 338 platform_device_add_data(i2c_dev, &i2c_data, 339 sizeof(struct 340 fsl_i2c_platform_data)); 341 if (ret) 342 goto unreg; 343 } 344 345 return 0; 346 347unreg: 348 platform_device_unregister(i2c_dev); 349err: 350 return ret; 351} 352 353arch_initcall(fsl_i2c_of_init); 354 355#ifdef CONFIG_PPC_83xx 356static int __init mpc83xx_wdt_init(void) 357{ 358 struct resource r; 359 struct device_node *soc, *np; 360 struct platform_device *dev; 361 const unsigned int *freq; 362 int ret; 363 364 np = of_find_compatible_node(NULL, "watchdog", "mpc83xx_wdt"); 365 366 if (!np) { 367 ret = -ENODEV; 368 goto nodev; 369 } 370 371 soc = of_find_node_by_type(NULL, "soc"); 372 373 if (!soc) { 374 ret = -ENODEV; 375 goto nosoc; 376 } 377 378 freq = of_get_property(soc, "bus-frequency", NULL); 379 if (!freq) { 380 ret = -ENODEV; 381 goto err; 382 } 383 384 memset(&r, 0, sizeof(r)); 385 386 ret = of_address_to_resource(np, 0, &r); 387 if (ret) 388 goto err; 389 390 dev = platform_device_register_simple("mpc83xx_wdt", 0, &r, 1); 391 if (IS_ERR(dev)) { 392 ret = PTR_ERR(dev); 393 goto err; 394 } 395 396 ret = platform_device_add_data(dev, freq, sizeof(int)); 397 if (ret) 398 goto unreg; 399 400 of_node_put(soc); 401 of_node_put(np); 402 403 return 0; 404 405unreg: 406 platform_device_unregister(dev); 407err: 408 of_node_put(soc); 409nosoc: 410 of_node_put(np); 411nodev: 412 return ret; 413} 414 415arch_initcall(mpc83xx_wdt_init); 416#endif 417 418static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type) 419{ 420 if (!phy_type) 421 return FSL_USB2_PHY_NONE; 422 if (!strcasecmp(phy_type, "ulpi")) 423 return FSL_USB2_PHY_ULPI; 424 if (!strcasecmp(phy_type, "utmi")) 425 return FSL_USB2_PHY_UTMI; 426 if (!strcasecmp(phy_type, "utmi_wide")) 427 return FSL_USB2_PHY_UTMI_WIDE; 428 if (!strcasecmp(phy_type, "serial")) 429 return FSL_USB2_PHY_SERIAL; 430 431 return FSL_USB2_PHY_NONE; 432} 433 434static int __init fsl_usb_of_init(void) 435{ 436 struct device_node *np; 437 unsigned int i; 438 struct platform_device *usb_dev_mph = NULL, *usb_dev_dr_host = NULL, 439 *usb_dev_dr_client = NULL; 440 int ret; 441 442 for (np = NULL, i = 0; 443 (np = of_find_compatible_node(np, "usb", "fsl-usb2-mph")) != NULL; 444 i++) { 445 struct resource r[2]; 446 struct fsl_usb2_platform_data usb_data; 447 const unsigned char *prop = NULL; 448 449 memset(&r, 0, sizeof(r)); 450 memset(&usb_data, 0, sizeof(usb_data)); 451 452 ret = of_address_to_resource(np, 0, &r[0]); 453 if (ret) 454 goto err; 455 456 of_irq_to_resource(np, 0, &r[1]); 457 458 usb_dev_mph = 459 platform_device_register_simple("fsl-ehci", i, r, 2); 460 if (IS_ERR(usb_dev_mph)) { 461 ret = PTR_ERR(usb_dev_mph); 462 goto err; 463 } 464 465 usb_dev_mph->dev.coherent_dma_mask = 0xffffffffUL; 466 usb_dev_mph->dev.dma_mask = &usb_dev_mph->dev.coherent_dma_mask; 467 468 usb_data.operating_mode = FSL_USB2_MPH_HOST; 469 470 prop = of_get_property(np, "port0", NULL); 471 if (prop) 472 usb_data.port_enables |= FSL_USB2_PORT0_ENABLED; 473 474 prop = of_get_property(np, "port1", NULL); 475 if (prop) 476 usb_data.port_enables |= FSL_USB2_PORT1_ENABLED; 477 478 prop = of_get_property(np, "phy_type", NULL); 479 usb_data.phy_mode = determine_usb_phy(prop); 480 481 ret = 482 platform_device_add_data(usb_dev_mph, &usb_data, 483 sizeof(struct 484 fsl_usb2_platform_data)); 485 if (ret) 486 goto unreg_mph; 487 } 488 489 for (np = NULL; 490 (np = of_find_compatible_node(np, "usb", "fsl-usb2-dr")) != NULL; 491 i++) { 492 struct resource r[2]; 493 struct fsl_usb2_platform_data usb_data; 494 const unsigned char *prop = NULL; 495 496 memset(&r, 0, sizeof(r)); 497 memset(&usb_data, 0, sizeof(usb_data)); 498 499 ret = of_address_to_resource(np, 0, &r[0]); 500 if (ret) 501 goto unreg_mph; 502 503 of_irq_to_resource(np, 0, &r[1]); 504 505 prop = of_get_property(np, "dr_mode", NULL); 506 507 if (!prop || !strcmp(prop, "host")) { 508 usb_data.operating_mode = FSL_USB2_DR_HOST; 509 usb_dev_dr_host = platform_device_register_simple( 510 "fsl-ehci", i, r, 2); 511 if (IS_ERR(usb_dev_dr_host)) { 512 ret = PTR_ERR(usb_dev_dr_host); 513 goto err; 514 } 515 } else if (prop && !strcmp(prop, "peripheral")) { 516 usb_data.operating_mode = FSL_USB2_DR_DEVICE; 517 usb_dev_dr_client = platform_device_register_simple( 518 "fsl-usb2-udc", i, r, 2); 519 if (IS_ERR(usb_dev_dr_client)) { 520 ret = PTR_ERR(usb_dev_dr_client); 521 goto err; 522 } 523 } else if (prop && !strcmp(prop, "otg")) { 524 usb_data.operating_mode = FSL_USB2_DR_OTG; 525 usb_dev_dr_host = platform_device_register_simple( 526 "fsl-ehci", i, r, 2); 527 if (IS_ERR(usb_dev_dr_host)) { 528 ret = PTR_ERR(usb_dev_dr_host); 529 goto err; 530 } 531 usb_dev_dr_client = platform_device_register_simple( 532 "fsl-usb2-udc", i, r, 2); 533 if (IS_ERR(usb_dev_dr_client)) { 534 ret = PTR_ERR(usb_dev_dr_client); 535 goto err; 536 } 537 } else { 538 ret = -EINVAL; 539 goto err; 540 } 541 542 prop = of_get_property(np, "phy_type", NULL); 543 usb_data.phy_mode = determine_usb_phy(prop); 544 545 if (usb_dev_dr_host) { 546 usb_dev_dr_host->dev.coherent_dma_mask = 0xffffffffUL; 547 usb_dev_dr_host->dev.dma_mask = &usb_dev_dr_host-> 548 dev.coherent_dma_mask; 549 if ((ret = platform_device_add_data(usb_dev_dr_host, 550 &usb_data, sizeof(struct 551 fsl_usb2_platform_data)))) 552 goto unreg_dr; 553 } 554 if (usb_dev_dr_client) { 555 usb_dev_dr_client->dev.coherent_dma_mask = 0xffffffffUL; 556 usb_dev_dr_client->dev.dma_mask = &usb_dev_dr_client-> 557 dev.coherent_dma_mask; 558 if ((ret = platform_device_add_data(usb_dev_dr_client, 559 &usb_data, sizeof(struct 560 fsl_usb2_platform_data)))) 561 goto unreg_dr; 562 } 563 } 564 return 0; 565 566unreg_dr: 567 if (usb_dev_dr_host) 568 platform_device_unregister(usb_dev_dr_host); 569 if (usb_dev_dr_client) 570 platform_device_unregister(usb_dev_dr_client); 571unreg_mph: 572 if (usb_dev_mph) 573 platform_device_unregister(usb_dev_mph); 574err: 575 return ret; 576} 577 578arch_initcall(fsl_usb_of_init); 579 580#ifdef CONFIG_CPM2 581 582extern void init_scc_ioports(struct fs_uart_platform_info*); 583 584static const char fcc_regs[] = "fcc_regs"; 585static const char fcc_regs_c[] = "fcc_regs_c"; 586static const char fcc_pram[] = "fcc_pram"; 587static char bus_id[9][BUS_ID_SIZE]; 588 589static int __init fs_enet_of_init(void) 590{ 591 struct device_node *np; 592 unsigned int i; 593 struct platform_device *fs_enet_dev; 594 struct resource res; 595 int ret; 596 597 for (np = NULL, i = 0; 598 (np = of_find_compatible_node(np, "network", "fs_enet")) != NULL; 599 i++) { 600 struct resource r[4]; 601 struct device_node *phy, *mdio; 602 struct fs_platform_info fs_enet_data; 603 const unsigned int *id, *phy_addr, *phy_irq; 604 const void *mac_addr; 605 const phandle *ph; 606 const char *model; 607 608 memset(r, 0, sizeof(r)); 609 memset(&fs_enet_data, 0, sizeof(fs_enet_data)); 610 611 ret = of_address_to_resource(np, 0, &r[0]); 612 if (ret) 613 goto err; 614 r[0].name = fcc_regs; 615 616 ret = of_address_to_resource(np, 1, &r[1]); 617 if (ret) 618 goto err; 619 r[1].name = fcc_pram; 620 621 ret = of_address_to_resource(np, 2, &r[2]); 622 if (ret) 623 goto err; 624 r[2].name = fcc_regs_c; 625 fs_enet_data.fcc_regs_c = r[2].start; 626 627 of_irq_to_resource(np, 0, &r[3]); 628 629 fs_enet_dev = 630 platform_device_register_simple("fsl-cpm-fcc", i, &r[0], 4); 631 632 if (IS_ERR(fs_enet_dev)) { 633 ret = PTR_ERR(fs_enet_dev); 634 goto err; 635 } 636 637 model = of_get_property(np, "model", NULL); 638 if (model == NULL) { 639 ret = -ENODEV; 640 goto unreg; 641 } 642 643 mac_addr = of_get_mac_address(np); 644 if (mac_addr) 645 memcpy(fs_enet_data.macaddr, mac_addr, 6); 646 647 ph = of_get_property(np, "phy-handle", NULL); 648 phy = of_find_node_by_phandle(*ph); 649 650 if (phy == NULL) { 651 ret = -ENODEV; 652 goto unreg; 653 } 654 655 phy_addr = of_get_property(phy, "reg", NULL); 656 fs_enet_data.phy_addr = *phy_addr; 657 658 phy_irq = of_get_property(phy, "interrupts", NULL); 659 660 id = of_get_property(np, "device-id", NULL); 661 fs_enet_data.fs_no = *id; 662 strcpy(fs_enet_data.fs_type, model); 663 664 mdio = of_get_parent(phy); 665 ret = of_address_to_resource(mdio, 0, &res); 666 if (ret) { 667 of_node_put(phy); 668 of_node_put(mdio); 669 goto unreg; 670 } 671 672 fs_enet_data.clk_rx = *((u32 *)of_get_property(np, 673 "rx-clock", NULL)); 674 fs_enet_data.clk_tx = *((u32 *)of_get_property(np, 675 "tx-clock", NULL)); 676 677 if (strstr(model, "FCC")) { 678 int fcc_index = *id - 1; 679 const unsigned char *mdio_bb_prop; 680 681 fs_enet_data.dpram_offset = (u32)cpm_dpram_addr(0); 682 fs_enet_data.rx_ring = 32; 683 fs_enet_data.tx_ring = 32; 684 fs_enet_data.rx_copybreak = 240; 685 fs_enet_data.use_napi = 0; 686 fs_enet_data.napi_weight = 17; 687 fs_enet_data.mem_offset = FCC_MEM_OFFSET(fcc_index); 688 fs_enet_data.cp_page = CPM_CR_FCC_PAGE(fcc_index); 689 fs_enet_data.cp_block = CPM_CR_FCC_SBLOCK(fcc_index); 690 691 snprintf((char*)&bus_id[(*id)], BUS_ID_SIZE, "%x:%02x", 692 (u32)res.start, fs_enet_data.phy_addr); 693 fs_enet_data.bus_id = (char*)&bus_id[(*id)]; 694 fs_enet_data.init_ioports = init_fcc_ioports; 695 696 mdio_bb_prop = of_get_property(phy, "bitbang", NULL); 697 if (mdio_bb_prop) { 698 struct platform_device *fs_enet_mdio_bb_dev; 699 struct fs_mii_bb_platform_info fs_enet_mdio_bb_data; 700 701 fs_enet_mdio_bb_dev = 702 platform_device_register_simple("fsl-bb-mdio", 703 i, NULL, 0); 704 memset(&fs_enet_mdio_bb_data, 0, 705 sizeof(struct fs_mii_bb_platform_info)); 706 fs_enet_mdio_bb_data.mdio_dat.bit = 707 mdio_bb_prop[0]; 708 fs_enet_mdio_bb_data.mdio_dir.bit = 709 mdio_bb_prop[1]; 710 fs_enet_mdio_bb_data.mdc_dat.bit = 711 mdio_bb_prop[2]; 712 fs_enet_mdio_bb_data.mdio_port = 713 mdio_bb_prop[3]; 714 fs_enet_mdio_bb_data.mdc_port = 715 mdio_bb_prop[4]; 716 fs_enet_mdio_bb_data.delay = 717 mdio_bb_prop[5]; 718 719 fs_enet_mdio_bb_data.irq[0] = phy_irq[0]; 720 fs_enet_mdio_bb_data.irq[1] = -1; 721 fs_enet_mdio_bb_data.irq[2] = -1; 722 fs_enet_mdio_bb_data.irq[3] = phy_irq[0]; 723 fs_enet_mdio_bb_data.irq[31] = -1; 724 725 fs_enet_mdio_bb_data.mdio_dat.offset = 726 (u32)&cpm2_immr->im_ioport.iop_pdatc; 727 fs_enet_mdio_bb_data.mdio_dir.offset = 728 (u32)&cpm2_immr->im_ioport.iop_pdirc; 729 fs_enet_mdio_bb_data.mdc_dat.offset = 730 (u32)&cpm2_immr->im_ioport.iop_pdatc; 731 732 ret = platform_device_add_data( 733 fs_enet_mdio_bb_dev, 734 &fs_enet_mdio_bb_data, 735 sizeof(struct fs_mii_bb_platform_info)); 736 if (ret) 737 goto unreg; 738 } 739 740 of_node_put(phy); 741 of_node_put(mdio); 742 743 ret = platform_device_add_data(fs_enet_dev, &fs_enet_data, 744 sizeof(struct 745 fs_platform_info)); 746 if (ret) 747 goto unreg; 748 } 749 } 750 return 0; 751 752unreg: 753 platform_device_unregister(fs_enet_dev); 754err: 755 return ret; 756} 757 758arch_initcall(fs_enet_of_init); 759 760static const char scc_regs[] = "regs"; 761static const char scc_pram[] = "pram"; 762 763static int __init cpm_uart_of_init(void) 764{ 765 struct device_node *np; 766 unsigned int i; 767 struct platform_device *cpm_uart_dev; 768 int ret; 769 770 for (np = NULL, i = 0; 771 (np = of_find_compatible_node(np, "serial", "cpm_uart")) != NULL; 772 i++) { 773 struct resource r[3]; 774 struct fs_uart_platform_info cpm_uart_data; 775 const int *id; 776 const char *model; 777 778 memset(r, 0, sizeof(r)); 779 memset(&cpm_uart_data, 0, sizeof(cpm_uart_data)); 780 781 ret = of_address_to_resource(np, 0, &r[0]); 782 if (ret) 783 goto err; 784 785 r[0].name = scc_regs; 786 787 ret = of_address_to_resource(np, 1, &r[1]); 788 if (ret) 789 goto err; 790 r[1].name = scc_pram; 791 792 of_irq_to_resource(np, 0, &r[2]); 793 794 cpm_uart_dev = 795 platform_device_register_simple("fsl-cpm-scc:uart", i, &r[0], 3); 796 797 if (IS_ERR(cpm_uart_dev)) { 798 ret = PTR_ERR(cpm_uart_dev); 799 goto err; 800 } 801 802 id = of_get_property(np, "device-id", NULL); 803 cpm_uart_data.fs_no = *id; 804 805 model = of_get_property(np, "model", NULL); 806 strcpy(cpm_uart_data.fs_type, model); 807 808 cpm_uart_data.uart_clk = ppc_proc_freq; 809 810 cpm_uart_data.tx_num_fifo = 4; 811 cpm_uart_data.tx_buf_size = 32; 812 cpm_uart_data.rx_num_fifo = 4; 813 cpm_uart_data.rx_buf_size = 32; 814 cpm_uart_data.clk_rx = *((u32 *)of_get_property(np, 815 "rx-clock", NULL)); 816 cpm_uart_data.clk_tx = *((u32 *)of_get_property(np, 817 "tx-clock", NULL)); 818 819 ret = 820 platform_device_add_data(cpm_uart_dev, &cpm_uart_data, 821 sizeof(struct 822 fs_uart_platform_info)); 823 if (ret) 824 goto unreg; 825 } 826 827 return 0; 828 829unreg: 830 platform_device_unregister(cpm_uart_dev); 831err: 832 return ret; 833} 834 835arch_initcall(cpm_uart_of_init); 836#endif /* CONFIG_CPM2 */ 837 838#ifdef CONFIG_8xx 839 840extern void init_scc_ioports(struct fs_platform_info*); 841extern int platform_device_skip(const char *model, int id); 842 843static int __init fs_enet_mdio_of_init(void) 844{ 845 struct device_node *np; 846 unsigned int i; 847 struct platform_device *mdio_dev; 848 struct resource res; 849 int ret; 850 851 for (np = NULL, i = 0; 852 (np = of_find_compatible_node(np, "mdio", "fs_enet")) != NULL; 853 i++) { 854 struct fs_mii_fec_platform_info mdio_data; 855 856 memset(&res, 0, sizeof(res)); 857 memset(&mdio_data, 0, sizeof(mdio_data)); 858 859 ret = of_address_to_resource(np, 0, &res); 860 if (ret) 861 goto err; 862 863 mdio_dev = 864 platform_device_register_simple("fsl-cpm-fec-mdio", 865 res.start, &res, 1); 866 if (IS_ERR(mdio_dev)) { 867 ret = PTR_ERR(mdio_dev); 868 goto err; 869 } 870 871 mdio_data.mii_speed = ((((ppc_proc_freq + 4999999) / 2500000) / 2) & 0x3F) << 1; 872 873 ret = 874 platform_device_add_data(mdio_dev, &mdio_data, 875 sizeof(struct fs_mii_fec_platform_info)); 876 if (ret) 877 goto unreg; 878 } 879 return 0; 880 881unreg: 882 platform_device_unregister(mdio_dev); 883err: 884 return ret; 885} 886 887arch_initcall(fs_enet_mdio_of_init); 888 889static const char *enet_regs = "regs"; 890static const char *enet_pram = "pram"; 891static const char *enet_irq = "interrupt"; 892static char bus_id[9][BUS_ID_SIZE]; 893 894static int __init fs_enet_of_init(void) 895{ 896 struct device_node *np; 897 unsigned int i; 898 struct platform_device *fs_enet_dev = NULL; 899 struct resource res; 900 int ret; 901 902 for (np = NULL, i = 0; 903 (np = of_find_compatible_node(np, "network", "fs_enet")) != NULL; 904 i++) { 905 struct resource r[4]; 906 struct device_node *phy = NULL, *mdio = NULL; 907 struct fs_platform_info fs_enet_data; 908 const unsigned int *id; 909 const unsigned int *phy_addr; 910 const void *mac_addr; 911 const phandle *ph; 912 const char *model; 913 914 memset(r, 0, sizeof(r)); 915 memset(&fs_enet_data, 0, sizeof(fs_enet_data)); 916 917 model = of_get_property(np, "model", NULL); 918 if (model == NULL) { 919 ret = -ENODEV; 920 goto unreg; 921 } 922 923 id = of_get_property(np, "device-id", NULL); 924 fs_enet_data.fs_no = *id; 925 926 if (platform_device_skip(model, *id)) 927 continue; 928 929 ret = of_address_to_resource(np, 0, &r[0]); 930 if (ret) 931 goto err; 932 r[0].name = enet_regs; 933 934 mac_addr = of_get_mac_address(np); 935 if (mac_addr) 936 memcpy(fs_enet_data.macaddr, mac_addr, 6); 937 938 ph = of_get_property(np, "phy-handle", NULL); 939 if (ph != NULL) 940 phy = of_find_node_by_phandle(*ph); 941 942 if (phy != NULL) { 943 phy_addr = of_get_property(phy, "reg", NULL); 944 fs_enet_data.phy_addr = *phy_addr; 945 fs_enet_data.has_phy = 1; 946 947 mdio = of_get_parent(phy); 948 ret = of_address_to_resource(mdio, 0, &res); 949 if (ret) { 950 of_node_put(phy); 951 of_node_put(mdio); 952 goto unreg; 953 } 954 } 955 956 model = of_get_property(np, "model", NULL); 957 strcpy(fs_enet_data.fs_type, model); 958 959 if (strstr(model, "FEC")) { 960 r[1].start = r[1].end = irq_of_parse_and_map(np, 0); 961 r[1].flags = IORESOURCE_IRQ; 962 r[1].name = enet_irq; 963 964 fs_enet_dev = 965 platform_device_register_simple("fsl-cpm-fec", i, &r[0], 2); 966 967 if (IS_ERR(fs_enet_dev)) { 968 ret = PTR_ERR(fs_enet_dev); 969 goto err; 970 } 971 972 fs_enet_data.rx_ring = 128; 973 fs_enet_data.tx_ring = 16; 974 fs_enet_data.rx_copybreak = 240; 975 fs_enet_data.use_napi = 1; 976 fs_enet_data.napi_weight = 17; 977 978 snprintf((char*)&bus_id[i], BUS_ID_SIZE, "%x:%02x", 979 (u32)res.start, fs_enet_data.phy_addr); 980 fs_enet_data.bus_id = (char*)&bus_id[i]; 981 fs_enet_data.init_ioports = init_fec_ioports; 982 } 983 if (strstr(model, "SCC")) { 984 ret = of_address_to_resource(np, 1, &r[1]); 985 if (ret) 986 goto err; 987 r[1].name = enet_pram; 988 989 r[2].start = r[2].end = irq_of_parse_and_map(np, 0); 990 r[2].flags = IORESOURCE_IRQ; 991 r[2].name = enet_irq; 992 993 fs_enet_dev = 994 platform_device_register_simple("fsl-cpm-scc", i, &r[0], 3); 995 996 if (IS_ERR(fs_enet_dev)) { 997 ret = PTR_ERR(fs_enet_dev); 998 goto err; 999 } 1000 1001 fs_enet_data.rx_ring = 64; 1002 fs_enet_data.tx_ring = 8; 1003 fs_enet_data.rx_copybreak = 240; 1004 fs_enet_data.use_napi = 1; 1005 fs_enet_data.napi_weight = 17; 1006 1007 snprintf((char*)&bus_id[i], BUS_ID_SIZE, "%s", "fixed@10:1"); 1008 fs_enet_data.bus_id = (char*)&bus_id[i]; 1009 fs_enet_data.init_ioports = init_scc_ioports; 1010 } 1011 1012 of_node_put(phy); 1013 of_node_put(mdio); 1014 1015 ret = platform_device_add_data(fs_enet_dev, &fs_enet_data, 1016 sizeof(struct 1017 fs_platform_info)); 1018 if (ret) 1019 goto unreg; 1020 } 1021 return 0; 1022 1023unreg: 1024 platform_device_unregister(fs_enet_dev); 1025err: 1026 return ret; 1027} 1028 1029arch_initcall(fs_enet_of_init); 1030 1031 1032static const char *smc_regs = "regs"; 1033static const char *smc_pram = "pram"; 1034 1035static int __init cpm_smc_uart_of_init(void) 1036{ 1037 struct device_node *np; 1038 unsigned int i; 1039 struct platform_device *cpm_uart_dev; 1040 int ret; 1041 1042 for (np = NULL, i = 0; 1043 (np = of_find_compatible_node(np, "serial", "cpm_uart")) != NULL; 1044 i++) { 1045 struct resource r[3]; 1046 struct fs_uart_platform_info cpm_uart_data; 1047 const int *id; 1048 const char *model; 1049 1050 memset(r, 0, sizeof(r)); 1051 memset(&cpm_uart_data, 0, sizeof(cpm_uart_data)); 1052 1053 ret = of_address_to_resource(np, 0, &r[0]); 1054 if (ret) 1055 goto err; 1056 1057 r[0].name = smc_regs; 1058 1059 ret = of_address_to_resource(np, 1, &r[1]); 1060 if (ret) 1061 goto err; 1062 r[1].name = smc_pram; 1063 1064 r[2].start = r[2].end = irq_of_parse_and_map(np, 0); 1065 r[2].flags = IORESOURCE_IRQ; 1066 1067 cpm_uart_dev = 1068 platform_device_register_simple("fsl-cpm-smc:uart", i, &r[0], 3); 1069 1070 if (IS_ERR(cpm_uart_dev)) { 1071 ret = PTR_ERR(cpm_uart_dev); 1072 goto err; 1073 } 1074 1075 model = of_get_property(np, "model", NULL); 1076 strcpy(cpm_uart_data.fs_type, model); 1077 1078 id = of_get_property(np, "device-id", NULL); 1079 cpm_uart_data.fs_no = *id; 1080 cpm_uart_data.uart_clk = ppc_proc_freq; 1081 1082 cpm_uart_data.tx_num_fifo = 4; 1083 cpm_uart_data.tx_buf_size = 32; 1084 cpm_uart_data.rx_num_fifo = 4; 1085 cpm_uart_data.rx_buf_size = 32; 1086 1087 ret = 1088 platform_device_add_data(cpm_uart_dev, &cpm_uart_data, 1089 sizeof(struct 1090 fs_uart_platform_info)); 1091 if (ret) 1092 goto unreg; 1093 } 1094 1095 return 0; 1096 1097unreg: 1098 platform_device_unregister(cpm_uart_dev); 1099err: 1100 return ret; 1101} 1102 1103arch_initcall(cpm_smc_uart_of_init); 1104 1105#endif /* CONFIG_8xx */ 1106