fsl_soc.c 27 KB

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