devices.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. /*
  2. * Author: MontaVista Software, Inc.
  3. * <source@mvista.com>
  4. *
  5. * Based on the OMAP devices.c
  6. *
  7. * 2005 (c) MontaVista Software, Inc. This file is licensed under the
  8. * terms of the GNU General Public License version 2. This program is
  9. * licensed "as is" without any warranty of any kind, whether express
  10. * or implied.
  11. *
  12. * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
  13. * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
  14. *
  15. * This program is free software; you can redistribute it and/or
  16. * modify it under the terms of the GNU General Public License
  17. * as published by the Free Software Foundation; either version 2
  18. * of the License, or (at your option) any later version.
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program; if not, write to the Free Software
  26. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  27. * MA 02110-1301, USA.
  28. */
  29. #include <linux/module.h>
  30. #include <linux/kernel.h>
  31. #include <linux/init.h>
  32. #include <linux/platform_device.h>
  33. #include <linux/gpio.h>
  34. #include <linux/dma-mapping.h>
  35. #include <mach/irqs.h>
  36. #include <mach/hardware.h>
  37. #include <mach/common.h>
  38. #include <mach/mmc.h>
  39. #include "devices.h"
  40. /*
  41. * SPI master controller
  42. *
  43. * - i.MX1: 2 channel (slighly different register setting)
  44. * - i.MX21: 2 channel
  45. * - i.MX27: 3 channel
  46. */
  47. static struct resource mxc_spi_resources0[] = {
  48. {
  49. .start = CSPI1_BASE_ADDR,
  50. .end = CSPI1_BASE_ADDR + SZ_4K - 1,
  51. .flags = IORESOURCE_MEM,
  52. }, {
  53. .start = MXC_INT_CSPI1,
  54. .end = MXC_INT_CSPI1,
  55. .flags = IORESOURCE_IRQ,
  56. },
  57. };
  58. static struct resource mxc_spi_resources1[] = {
  59. {
  60. .start = CSPI2_BASE_ADDR,
  61. .end = CSPI2_BASE_ADDR + SZ_4K - 1,
  62. .flags = IORESOURCE_MEM,
  63. }, {
  64. .start = MXC_INT_CSPI2,
  65. .end = MXC_INT_CSPI2,
  66. .flags = IORESOURCE_IRQ,
  67. },
  68. };
  69. #ifdef CONFIG_MACH_MX27
  70. static struct resource mxc_spi_resources2[] = {
  71. {
  72. .start = CSPI3_BASE_ADDR,
  73. .end = CSPI3_BASE_ADDR + SZ_4K - 1,
  74. .flags = IORESOURCE_MEM,
  75. }, {
  76. .start = MXC_INT_CSPI3,
  77. .end = MXC_INT_CSPI3,
  78. .flags = IORESOURCE_IRQ,
  79. },
  80. };
  81. #endif
  82. struct platform_device mxc_spi_device0 = {
  83. .name = "spi_imx",
  84. .id = 0,
  85. .num_resources = ARRAY_SIZE(mxc_spi_resources0),
  86. .resource = mxc_spi_resources0,
  87. };
  88. struct platform_device mxc_spi_device1 = {
  89. .name = "spi_imx",
  90. .id = 1,
  91. .num_resources = ARRAY_SIZE(mxc_spi_resources1),
  92. .resource = mxc_spi_resources1,
  93. };
  94. #ifdef CONFIG_MACH_MX27
  95. struct platform_device mxc_spi_device2 = {
  96. .name = "spi_imx",
  97. .id = 2,
  98. .num_resources = ARRAY_SIZE(mxc_spi_resources2),
  99. .resource = mxc_spi_resources2,
  100. };
  101. #endif
  102. /*
  103. * General Purpose Timer
  104. * - i.MX21: 3 timers
  105. * - i.MX27: 6 timers
  106. */
  107. /* We use gpt0 as system timer, so do not add a device for this one */
  108. static struct resource timer1_resources[] = {
  109. {
  110. .start = GPT2_BASE_ADDR,
  111. .end = GPT2_BASE_ADDR + 0x17,
  112. .flags = IORESOURCE_MEM,
  113. }, {
  114. .start = MXC_INT_GPT2,
  115. .end = MXC_INT_GPT2,
  116. .flags = IORESOURCE_IRQ,
  117. }
  118. };
  119. struct platform_device mxc_gpt1 = {
  120. .name = "imx_gpt",
  121. .id = 1,
  122. .num_resources = ARRAY_SIZE(timer1_resources),
  123. .resource = timer1_resources,
  124. };
  125. static struct resource timer2_resources[] = {
  126. {
  127. .start = GPT3_BASE_ADDR,
  128. .end = GPT3_BASE_ADDR + 0x17,
  129. .flags = IORESOURCE_MEM,
  130. }, {
  131. .start = MXC_INT_GPT3,
  132. .end = MXC_INT_GPT3,
  133. .flags = IORESOURCE_IRQ,
  134. }
  135. };
  136. struct platform_device mxc_gpt2 = {
  137. .name = "imx_gpt",
  138. .id = 2,
  139. .num_resources = ARRAY_SIZE(timer2_resources),
  140. .resource = timer2_resources,
  141. };
  142. #ifdef CONFIG_MACH_MX27
  143. static struct resource timer3_resources[] = {
  144. {
  145. .start = GPT4_BASE_ADDR,
  146. .end = GPT4_BASE_ADDR + 0x17,
  147. .flags = IORESOURCE_MEM,
  148. }, {
  149. .start = MXC_INT_GPT4,
  150. .end = MXC_INT_GPT4,
  151. .flags = IORESOURCE_IRQ,
  152. }
  153. };
  154. struct platform_device mxc_gpt3 = {
  155. .name = "imx_gpt",
  156. .id = 3,
  157. .num_resources = ARRAY_SIZE(timer3_resources),
  158. .resource = timer3_resources,
  159. };
  160. static struct resource timer4_resources[] = {
  161. {
  162. .start = GPT5_BASE_ADDR,
  163. .end = GPT5_BASE_ADDR + 0x17,
  164. .flags = IORESOURCE_MEM,
  165. }, {
  166. .start = MXC_INT_GPT5,
  167. .end = MXC_INT_GPT5,
  168. .flags = IORESOURCE_IRQ,
  169. }
  170. };
  171. struct platform_device mxc_gpt4 = {
  172. .name = "imx_gpt",
  173. .id = 4,
  174. .num_resources = ARRAY_SIZE(timer4_resources),
  175. .resource = timer4_resources,
  176. };
  177. static struct resource timer5_resources[] = {
  178. {
  179. .start = GPT6_BASE_ADDR,
  180. .end = GPT6_BASE_ADDR + 0x17,
  181. .flags = IORESOURCE_MEM,
  182. }, {
  183. .start = MXC_INT_GPT6,
  184. .end = MXC_INT_GPT6,
  185. .flags = IORESOURCE_IRQ,
  186. }
  187. };
  188. struct platform_device mxc_gpt5 = {
  189. .name = "imx_gpt",
  190. .id = 5,
  191. .num_resources = ARRAY_SIZE(timer5_resources),
  192. .resource = timer5_resources,
  193. };
  194. #endif
  195. /*
  196. * Watchdog:
  197. * - i.MX1
  198. * - i.MX21
  199. * - i.MX27
  200. */
  201. static struct resource mxc_wdt_resources[] = {
  202. {
  203. .start = WDOG_BASE_ADDR,
  204. .end = WDOG_BASE_ADDR + 0x30,
  205. .flags = IORESOURCE_MEM,
  206. },
  207. };
  208. struct platform_device mxc_wdt = {
  209. .name = "mxc_wdt",
  210. .id = 0,
  211. .num_resources = ARRAY_SIZE(mxc_wdt_resources),
  212. .resource = mxc_wdt_resources,
  213. };
  214. static struct resource mxc_w1_master_resources[] = {
  215. {
  216. .start = OWIRE_BASE_ADDR,
  217. .end = OWIRE_BASE_ADDR + SZ_4K - 1,
  218. .flags = IORESOURCE_MEM,
  219. },
  220. };
  221. struct platform_device mxc_w1_master_device = {
  222. .name = "mxc_w1",
  223. .id = 0,
  224. .num_resources = ARRAY_SIZE(mxc_w1_master_resources),
  225. .resource = mxc_w1_master_resources,
  226. };
  227. static struct resource mxc_nand_resources[] = {
  228. {
  229. .start = NFC_BASE_ADDR,
  230. .end = NFC_BASE_ADDR + 0xfff,
  231. .flags = IORESOURCE_MEM,
  232. }, {
  233. .start = MXC_INT_NANDFC,
  234. .end = MXC_INT_NANDFC,
  235. .flags = IORESOURCE_IRQ,
  236. },
  237. };
  238. struct platform_device mxc_nand_device = {
  239. .name = "mxc_nand",
  240. .id = 0,
  241. .num_resources = ARRAY_SIZE(mxc_nand_resources),
  242. .resource = mxc_nand_resources,
  243. };
  244. /*
  245. * lcdc:
  246. * - i.MX1: the basic controller
  247. * - i.MX21: to be checked
  248. * - i.MX27: like i.MX1, with slightly variations
  249. */
  250. static struct resource mxc_fb[] = {
  251. {
  252. .start = LCDC_BASE_ADDR,
  253. .end = LCDC_BASE_ADDR + 0xFFF,
  254. .flags = IORESOURCE_MEM,
  255. }, {
  256. .start = MXC_INT_LCDC,
  257. .end = MXC_INT_LCDC,
  258. .flags = IORESOURCE_IRQ,
  259. }
  260. };
  261. /* mxc lcd driver */
  262. struct platform_device mxc_fb_device = {
  263. .name = "imx-fb",
  264. .id = 0,
  265. .num_resources = ARRAY_SIZE(mxc_fb),
  266. .resource = mxc_fb,
  267. .dev = {
  268. .coherent_dma_mask = DMA_BIT_MASK(32),
  269. },
  270. };
  271. #ifdef CONFIG_MACH_MX27
  272. static struct resource mxc_fec_resources[] = {
  273. {
  274. .start = FEC_BASE_ADDR,
  275. .end = FEC_BASE_ADDR + 0xfff,
  276. .flags = IORESOURCE_MEM,
  277. }, {
  278. .start = MXC_INT_FEC,
  279. .end = MXC_INT_FEC,
  280. .flags = IORESOURCE_IRQ,
  281. },
  282. };
  283. struct platform_device mxc_fec_device = {
  284. .name = "fec",
  285. .id = 0,
  286. .num_resources = ARRAY_SIZE(mxc_fec_resources),
  287. .resource = mxc_fec_resources,
  288. };
  289. #endif
  290. static struct resource mxc_i2c_1_resources[] = {
  291. {
  292. .start = I2C_BASE_ADDR,
  293. .end = I2C_BASE_ADDR + 0x0fff,
  294. .flags = IORESOURCE_MEM,
  295. }, {
  296. .start = MXC_INT_I2C,
  297. .end = MXC_INT_I2C,
  298. .flags = IORESOURCE_IRQ,
  299. }
  300. };
  301. struct platform_device mxc_i2c_device0 = {
  302. .name = "imx-i2c",
  303. .id = 0,
  304. .num_resources = ARRAY_SIZE(mxc_i2c_1_resources),
  305. .resource = mxc_i2c_1_resources,
  306. };
  307. #ifdef CONFIG_MACH_MX27
  308. static struct resource mxc_i2c_2_resources[] = {
  309. {
  310. .start = I2C2_BASE_ADDR,
  311. .end = I2C2_BASE_ADDR + 0x0fff,
  312. .flags = IORESOURCE_MEM,
  313. }, {
  314. .start = MXC_INT_I2C2,
  315. .end = MXC_INT_I2C2,
  316. .flags = IORESOURCE_IRQ,
  317. }
  318. };
  319. struct platform_device mxc_i2c_device1 = {
  320. .name = "imx-i2c",
  321. .id = 1,
  322. .num_resources = ARRAY_SIZE(mxc_i2c_2_resources),
  323. .resource = mxc_i2c_2_resources,
  324. };
  325. #endif
  326. static struct resource mxc_pwm_resources[] = {
  327. {
  328. .start = PWM_BASE_ADDR,
  329. .end = PWM_BASE_ADDR + 0x0fff,
  330. .flags = IORESOURCE_MEM,
  331. }, {
  332. .start = MXC_INT_PWM,
  333. .end = MXC_INT_PWM,
  334. .flags = IORESOURCE_IRQ,
  335. }
  336. };
  337. struct platform_device mxc_pwm_device = {
  338. .name = "mxc_pwm",
  339. .id = 0,
  340. .num_resources = ARRAY_SIZE(mxc_pwm_resources),
  341. .resource = mxc_pwm_resources,
  342. };
  343. /*
  344. * Resource definition for the MXC SDHC
  345. */
  346. static struct resource mxc_sdhc1_resources[] = {
  347. {
  348. .start = SDHC1_BASE_ADDR,
  349. .end = SDHC1_BASE_ADDR + SZ_4K - 1,
  350. .flags = IORESOURCE_MEM,
  351. }, {
  352. .start = MXC_INT_SDHC1,
  353. .end = MXC_INT_SDHC1,
  354. .flags = IORESOURCE_IRQ,
  355. }, {
  356. .start = DMA_REQ_SDHC1,
  357. .end = DMA_REQ_SDHC1,
  358. .flags = IORESOURCE_DMA,
  359. },
  360. };
  361. static u64 mxc_sdhc1_dmamask = DMA_BIT_MASK(32);
  362. struct platform_device mxc_sdhc_device0 = {
  363. .name = "mxc-mmc",
  364. .id = 0,
  365. .dev = {
  366. .dma_mask = &mxc_sdhc1_dmamask,
  367. .coherent_dma_mask = DMA_BIT_MASK(32),
  368. },
  369. .num_resources = ARRAY_SIZE(mxc_sdhc1_resources),
  370. .resource = mxc_sdhc1_resources,
  371. };
  372. static struct resource mxc_sdhc2_resources[] = {
  373. {
  374. .start = SDHC2_BASE_ADDR,
  375. .end = SDHC2_BASE_ADDR + SZ_4K - 1,
  376. .flags = IORESOURCE_MEM,
  377. }, {
  378. .start = MXC_INT_SDHC2,
  379. .end = MXC_INT_SDHC2,
  380. .flags = IORESOURCE_IRQ,
  381. }, {
  382. .start = DMA_REQ_SDHC2,
  383. .end = DMA_REQ_SDHC2,
  384. .flags = IORESOURCE_DMA,
  385. },
  386. };
  387. static u64 mxc_sdhc2_dmamask = DMA_BIT_MASK(32);
  388. struct platform_device mxc_sdhc_device1 = {
  389. .name = "mxc-mmc",
  390. .id = 1,
  391. .dev = {
  392. .dma_mask = &mxc_sdhc2_dmamask,
  393. .coherent_dma_mask = DMA_BIT_MASK(32),
  394. },
  395. .num_resources = ARRAY_SIZE(mxc_sdhc2_resources),
  396. .resource = mxc_sdhc2_resources,
  397. };
  398. #ifdef CONFIG_MACH_MX27
  399. static struct resource otg_resources[] = {
  400. {
  401. .start = OTG_BASE_ADDR,
  402. .end = OTG_BASE_ADDR + 0x1ff,
  403. .flags = IORESOURCE_MEM,
  404. }, {
  405. .start = MXC_INT_USB3,
  406. .end = MXC_INT_USB3,
  407. .flags = IORESOURCE_IRQ,
  408. },
  409. };
  410. static u64 otg_dmamask = DMA_BIT_MASK(32);
  411. /* OTG gadget device */
  412. struct platform_device mxc_otg_udc_device = {
  413. .name = "fsl-usb2-udc",
  414. .id = -1,
  415. .dev = {
  416. .dma_mask = &otg_dmamask,
  417. .coherent_dma_mask = DMA_BIT_MASK(32),
  418. },
  419. .resource = otg_resources,
  420. .num_resources = ARRAY_SIZE(otg_resources),
  421. };
  422. /* OTG host */
  423. struct platform_device mxc_otg_host = {
  424. .name = "mxc-ehci",
  425. .id = 0,
  426. .dev = {
  427. .coherent_dma_mask = DMA_BIT_MASK(32),
  428. .dma_mask = &otg_dmamask,
  429. },
  430. .resource = otg_resources,
  431. .num_resources = ARRAY_SIZE(otg_resources),
  432. };
  433. /* USB host 1 */
  434. static u64 usbh1_dmamask = DMA_BIT_MASK(32);
  435. static struct resource mxc_usbh1_resources[] = {
  436. {
  437. .start = OTG_BASE_ADDR + 0x200,
  438. .end = OTG_BASE_ADDR + 0x3ff,
  439. .flags = IORESOURCE_MEM,
  440. }, {
  441. .start = MXC_INT_USB1,
  442. .end = MXC_INT_USB1,
  443. .flags = IORESOURCE_IRQ,
  444. },
  445. };
  446. struct platform_device mxc_usbh1 = {
  447. .name = "mxc-ehci",
  448. .id = 1,
  449. .dev = {
  450. .coherent_dma_mask = DMA_BIT_MASK(32),
  451. .dma_mask = &usbh1_dmamask,
  452. },
  453. .resource = mxc_usbh1_resources,
  454. .num_resources = ARRAY_SIZE(mxc_usbh1_resources),
  455. };
  456. /* USB host 2 */
  457. static u64 usbh2_dmamask = DMA_BIT_MASK(32);
  458. static struct resource mxc_usbh2_resources[] = {
  459. {
  460. .start = OTG_BASE_ADDR + 0x400,
  461. .end = OTG_BASE_ADDR + 0x5ff,
  462. .flags = IORESOURCE_MEM,
  463. }, {
  464. .start = MXC_INT_USB2,
  465. .end = MXC_INT_USB2,
  466. .flags = IORESOURCE_IRQ,
  467. },
  468. };
  469. struct platform_device mxc_usbh2 = {
  470. .name = "mxc-ehci",
  471. .id = 2,
  472. .dev = {
  473. .coherent_dma_mask = DMA_BIT_MASK(32),
  474. .dma_mask = &usbh2_dmamask,
  475. },
  476. .resource = mxc_usbh2_resources,
  477. .num_resources = ARRAY_SIZE(mxc_usbh2_resources),
  478. };
  479. #endif
  480. static struct resource imx_ssi_resources0[] = {
  481. {
  482. .start = SSI1_BASE_ADDR,
  483. .end = SSI1_BASE_ADDR + 0x6F,
  484. .flags = IORESOURCE_MEM,
  485. }, {
  486. .start = MXC_INT_SSI1,
  487. .end = MXC_INT_SSI1,
  488. .flags = IORESOURCE_IRQ,
  489. }, {
  490. .name = "tx0",
  491. .start = DMA_REQ_SSI1_TX0,
  492. .end = DMA_REQ_SSI1_TX0,
  493. .flags = IORESOURCE_DMA,
  494. }, {
  495. .name = "rx0",
  496. .start = DMA_REQ_SSI1_RX0,
  497. .end = DMA_REQ_SSI1_RX0,
  498. .flags = IORESOURCE_DMA,
  499. }, {
  500. .name = "tx1",
  501. .start = DMA_REQ_SSI1_TX1,
  502. .end = DMA_REQ_SSI1_TX1,
  503. .flags = IORESOURCE_DMA,
  504. }, {
  505. .name = "rx1",
  506. .start = DMA_REQ_SSI1_RX1,
  507. .end = DMA_REQ_SSI1_RX1,
  508. .flags = IORESOURCE_DMA,
  509. },
  510. };
  511. static struct resource imx_ssi_resources1[] = {
  512. {
  513. .start = SSI2_BASE_ADDR,
  514. .end = SSI2_BASE_ADDR + 0x6F,
  515. .flags = IORESOURCE_MEM,
  516. }, {
  517. .start = MXC_INT_SSI2,
  518. .end = MXC_INT_SSI2,
  519. .flags = IORESOURCE_IRQ,
  520. }, {
  521. .name = "tx0",
  522. .start = DMA_REQ_SSI2_TX0,
  523. .end = DMA_REQ_SSI2_TX0,
  524. .flags = IORESOURCE_DMA,
  525. }, {
  526. .name = "rx0",
  527. .start = DMA_REQ_SSI2_RX0,
  528. .end = DMA_REQ_SSI2_RX0,
  529. .flags = IORESOURCE_DMA,
  530. }, {
  531. .name = "tx1",
  532. .start = DMA_REQ_SSI2_TX1,
  533. .end = DMA_REQ_SSI2_TX1,
  534. .flags = IORESOURCE_DMA,
  535. }, {
  536. .name = "rx1",
  537. .start = DMA_REQ_SSI2_RX1,
  538. .end = DMA_REQ_SSI2_RX1,
  539. .flags = IORESOURCE_DMA,
  540. },
  541. };
  542. struct platform_device imx_ssi_device0 = {
  543. .name = "imx-ssi",
  544. .id = 0,
  545. .num_resources = ARRAY_SIZE(imx_ssi_resources0),
  546. .resource = imx_ssi_resources0,
  547. };
  548. struct platform_device imx_ssi_device1 = {
  549. .name = "imx-ssi",
  550. .id = 1,
  551. .num_resources = ARRAY_SIZE(imx_ssi_resources1),
  552. .resource = imx_ssi_resources1,
  553. };
  554. /* GPIO port description */
  555. static struct mxc_gpio_port imx_gpio_ports[] = {
  556. {
  557. .chip.label = "gpio-0",
  558. .irq = MXC_INT_GPIO,
  559. .base = IO_ADDRESS(GPIO_BASE_ADDR),
  560. .virtual_irq_start = MXC_GPIO_IRQ_START,
  561. }, {
  562. .chip.label = "gpio-1",
  563. .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x100),
  564. .virtual_irq_start = MXC_GPIO_IRQ_START + 32,
  565. }, {
  566. .chip.label = "gpio-2",
  567. .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x200),
  568. .virtual_irq_start = MXC_GPIO_IRQ_START + 64,
  569. }, {
  570. .chip.label = "gpio-3",
  571. .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x300),
  572. .virtual_irq_start = MXC_GPIO_IRQ_START + 96,
  573. }, {
  574. .chip.label = "gpio-4",
  575. .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x400),
  576. .virtual_irq_start = MXC_GPIO_IRQ_START + 128,
  577. }, {
  578. .chip.label = "gpio-5",
  579. .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x500),
  580. .virtual_irq_start = MXC_GPIO_IRQ_START + 160,
  581. }
  582. };
  583. int __init mxc_register_gpios(void)
  584. {
  585. return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports));
  586. }