device.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. /*
  2. * device.c -- common ColdFire SoC device support
  3. *
  4. * (C) Copyright 2011, Greg Ungerer <gerg@uclinux.org>
  5. *
  6. * This file is subject to the terms and conditions of the GNU General Public
  7. * License. See the file COPYING in the main directory of this archive
  8. * for more details.
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/init.h>
  12. #include <linux/io.h>
  13. #include <linux/spi/spi.h>
  14. #include <linux/gpio.h>
  15. #include <asm/traps.h>
  16. #include <asm/coldfire.h>
  17. #include <asm/mcfsim.h>
  18. #include <asm/mcfuart.h>
  19. #include <asm/mcfqspi.h>
  20. /*
  21. * All current ColdFire parts contain from 2, 3 or 4 UARTS.
  22. */
  23. static struct mcf_platform_uart mcf_uart_platform_data[] = {
  24. {
  25. .mapbase = MCFUART_BASE0,
  26. .irq = MCF_IRQ_UART0,
  27. },
  28. {
  29. .mapbase = MCFUART_BASE1,
  30. .irq = MCF_IRQ_UART1,
  31. },
  32. #ifdef MCFUART_BASE2
  33. {
  34. .mapbase = MCFUART_BASE2,
  35. .irq = MCF_IRQ_UART2,
  36. },
  37. #endif
  38. #ifdef MCFUART_BASE3
  39. {
  40. .mapbase = MCFUART_BASE3,
  41. .irq = MCF_IRQ_UART3,
  42. },
  43. #endif
  44. { },
  45. };
  46. static struct platform_device mcf_uart = {
  47. .name = "mcfuart",
  48. .id = 0,
  49. .dev.platform_data = mcf_uart_platform_data,
  50. };
  51. #ifdef CONFIG_FEC
  52. /*
  53. * Some ColdFire cores contain the Fast Ethernet Controller (FEC)
  54. * block. It is Freescale's own hardware block. Some ColdFires
  55. * have 2 of these.
  56. */
  57. static struct resource mcf_fec0_resources[] = {
  58. {
  59. .start = MCFFEC_BASE0,
  60. .end = MCFFEC_BASE0 + MCFFEC_SIZE0 - 1,
  61. .flags = IORESOURCE_MEM,
  62. },
  63. {
  64. .start = MCF_IRQ_FECRX0,
  65. .end = MCF_IRQ_FECRX0,
  66. .flags = IORESOURCE_IRQ,
  67. },
  68. {
  69. .start = MCF_IRQ_FECTX0,
  70. .end = MCF_IRQ_FECTX0,
  71. .flags = IORESOURCE_IRQ,
  72. },
  73. {
  74. .start = MCF_IRQ_FECENTC0,
  75. .end = MCF_IRQ_FECENTC0,
  76. .flags = IORESOURCE_IRQ,
  77. },
  78. };
  79. static struct platform_device mcf_fec0 = {
  80. .name = "fec",
  81. .id = 0,
  82. .num_resources = ARRAY_SIZE(mcf_fec0_resources),
  83. .resource = mcf_fec0_resources,
  84. };
  85. #ifdef MCFFEC_BASE1
  86. static struct resource mcf_fec1_resources[] = {
  87. {
  88. .start = MCFFEC_BASE1,
  89. .end = MCFFEC_BASE1 + MCFFEC_SIZE1 - 1,
  90. .flags = IORESOURCE_MEM,
  91. },
  92. {
  93. .start = MCF_IRQ_FECRX1,
  94. .end = MCF_IRQ_FECRX1,
  95. .flags = IORESOURCE_IRQ,
  96. },
  97. {
  98. .start = MCF_IRQ_FECTX1,
  99. .end = MCF_IRQ_FECTX1,
  100. .flags = IORESOURCE_IRQ,
  101. },
  102. {
  103. .start = MCF_IRQ_FECENTC1,
  104. .end = MCF_IRQ_FECENTC1,
  105. .flags = IORESOURCE_IRQ,
  106. },
  107. };
  108. static struct platform_device mcf_fec1 = {
  109. .name = "fec",
  110. .id = 1,
  111. .num_resources = ARRAY_SIZE(mcf_fec1_resources),
  112. .resource = mcf_fec1_resources,
  113. };
  114. #endif /* MCFFEC_BASE1 */
  115. #endif /* CONFIG_FEC */
  116. #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
  117. /*
  118. * The ColdFire QSPI module is an SPI protocol hardware block used
  119. * on a number of different ColdFire CPUs.
  120. */
  121. static struct resource mcf_qspi_resources[] = {
  122. {
  123. .start = MCFQSPI_BASE,
  124. .end = MCFQSPI_BASE + MCFQSPI_SIZE - 1,
  125. .flags = IORESOURCE_MEM,
  126. },
  127. {
  128. .start = MCF_IRQ_QSPI,
  129. .end = MCF_IRQ_QSPI,
  130. .flags = IORESOURCE_IRQ,
  131. },
  132. };
  133. static int mcf_cs_setup(struct mcfqspi_cs_control *cs_control)
  134. {
  135. int status;
  136. status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
  137. if (status) {
  138. pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
  139. goto fail0;
  140. }
  141. status = gpio_direction_output(MCFQSPI_CS0, 1);
  142. if (status) {
  143. pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
  144. goto fail1;
  145. }
  146. status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
  147. if (status) {
  148. pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
  149. goto fail1;
  150. }
  151. status = gpio_direction_output(MCFQSPI_CS1, 1);
  152. if (status) {
  153. pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
  154. goto fail2;
  155. }
  156. status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
  157. if (status) {
  158. pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
  159. goto fail2;
  160. }
  161. status = gpio_direction_output(MCFQSPI_CS2, 1);
  162. if (status) {
  163. pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
  164. goto fail3;
  165. }
  166. #ifdef MCFQSPI_CS3
  167. status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
  168. if (status) {
  169. pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
  170. goto fail3;
  171. }
  172. status = gpio_direction_output(MCFQSPI_CS3, 1);
  173. if (status) {
  174. pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
  175. gpio_free(MCFQSPI_CS3);
  176. goto fail3;
  177. }
  178. #endif
  179. return 0;
  180. fail3:
  181. gpio_free(MCFQSPI_CS2);
  182. fail2:
  183. gpio_free(MCFQSPI_CS1);
  184. fail1:
  185. gpio_free(MCFQSPI_CS0);
  186. fail0:
  187. return status;
  188. }
  189. static void mcf_cs_teardown(struct mcfqspi_cs_control *cs_control)
  190. {
  191. #ifdef MCFQSPI_CS3
  192. gpio_free(MCFQSPI_CS3);
  193. #endif
  194. gpio_free(MCFQSPI_CS2);
  195. gpio_free(MCFQSPI_CS1);
  196. gpio_free(MCFQSPI_CS0);
  197. }
  198. static void mcf_cs_select(struct mcfqspi_cs_control *cs_control,
  199. u8 chip_select, bool cs_high)
  200. {
  201. switch (chip_select) {
  202. case 0:
  203. gpio_set_value(MCFQSPI_CS0, cs_high);
  204. break;
  205. case 1:
  206. gpio_set_value(MCFQSPI_CS1, cs_high);
  207. break;
  208. case 2:
  209. gpio_set_value(MCFQSPI_CS2, cs_high);
  210. break;
  211. #ifdef MCFQSPI_CS3
  212. case 3:
  213. gpio_set_value(MCFQSPI_CS3, cs_high);
  214. break;
  215. #endif
  216. }
  217. }
  218. static void mcf_cs_deselect(struct mcfqspi_cs_control *cs_control,
  219. u8 chip_select, bool cs_high)
  220. {
  221. switch (chip_select) {
  222. case 0:
  223. gpio_set_value(MCFQSPI_CS0, !cs_high);
  224. break;
  225. case 1:
  226. gpio_set_value(MCFQSPI_CS1, !cs_high);
  227. break;
  228. case 2:
  229. gpio_set_value(MCFQSPI_CS2, !cs_high);
  230. break;
  231. #ifdef MCFQSPI_CS3
  232. case 3:
  233. gpio_set_value(MCFQSPI_CS3, !cs_high);
  234. break;
  235. #endif
  236. }
  237. }
  238. static struct mcfqspi_cs_control mcf_cs_control = {
  239. .setup = mcf_cs_setup,
  240. .teardown = mcf_cs_teardown,
  241. .select = mcf_cs_select,
  242. .deselect = mcf_cs_deselect,
  243. };
  244. static struct mcfqspi_platform_data mcf_qspi_data = {
  245. .bus_num = 0,
  246. .num_chipselect = 4,
  247. .cs_control = &mcf_cs_control,
  248. };
  249. static struct platform_device mcf_qspi = {
  250. .name = "mcfqspi",
  251. .id = 0,
  252. .num_resources = ARRAY_SIZE(mcf_qspi_resources),
  253. .resource = mcf_qspi_resources,
  254. .dev.platform_data = &mcf_qspi_data,
  255. };
  256. #endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
  257. static struct platform_device *mcf_devices[] __initdata = {
  258. &mcf_uart,
  259. #ifdef CONFIG_FEC
  260. &mcf_fec0,
  261. #ifdef MCFFEC_BASE1
  262. &mcf_fec1,
  263. #endif
  264. #endif
  265. #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
  266. &mcf_qspi,
  267. #endif
  268. };
  269. /*
  270. * Some ColdFire UARTs let you set the IRQ line to use.
  271. */
  272. static void __init mcf_uart_set_irq(void)
  273. {
  274. #ifdef MCFUART_UIVR
  275. /* UART0 interrupt setup */
  276. writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
  277. writeb(MCF_IRQ_UART0, MCFUART_BASE0 + MCFUART_UIVR);
  278. mcf_mapirq2imr(MCF_IRQ_UART0, MCFINTC_UART0);
  279. /* UART1 interrupt setup */
  280. writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
  281. writeb(MCF_IRQ_UART1, MCFUART_BASE1 + MCFUART_UIVR);
  282. mcf_mapirq2imr(MCF_IRQ_UART1, MCFINTC_UART1);
  283. #endif
  284. }
  285. static int __init mcf_init_devices(void)
  286. {
  287. mcf_uart_set_irq();
  288. platform_add_devices(mcf_devices, ARRAY_SIZE(mcf_devices));
  289. return 0;
  290. }
  291. arch_initcall(mcf_init_devices);