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 | |
11 | #include <linux/kernel.h> |
12 | #include <linux/init.h> |
13 | #include <linux/io.h> |
14 | #include <linux/spi/spi.h> |
15 | #include <linux/gpio.h> |
16 | #include <linux/fec.h> |
17 | #include <linux/dmaengine.h> |
18 | #include <asm/traps.h> |
19 | #include <asm/coldfire.h> |
20 | #include <asm/mcfsim.h> |
21 | #include <asm/mcfuart.h> |
22 | #include <asm/mcfqspi.h> |
23 | #include <linux/platform_data/edma.h> |
24 | #include <linux/platform_data/dma-mcf-edma.h> |
25 | #include <linux/platform_data/mmc-esdhc-mcf.h> |
26 | |
27 | /* |
28 | * All current ColdFire parts contain from 2, 3, 4 or 10 UARTS. |
29 | */ |
30 | static struct mcf_platform_uart mcf_uart_platform_data[] = { |
31 | { |
32 | .mapbase = MCFUART_BASE0, |
33 | .irq = MCF_IRQ_UART0, |
34 | }, |
35 | { |
36 | .mapbase = MCFUART_BASE1, |
37 | .irq = MCF_IRQ_UART1, |
38 | }, |
39 | #ifdef MCFUART_BASE2 |
40 | { |
41 | .mapbase = MCFUART_BASE2, |
42 | .irq = MCF_IRQ_UART2, |
43 | }, |
44 | #endif |
45 | #ifdef MCFUART_BASE3 |
46 | { |
47 | .mapbase = MCFUART_BASE3, |
48 | .irq = MCF_IRQ_UART3, |
49 | }, |
50 | #endif |
51 | #ifdef MCFUART_BASE4 |
52 | { |
53 | .mapbase = MCFUART_BASE4, |
54 | .irq = MCF_IRQ_UART4, |
55 | }, |
56 | #endif |
57 | #ifdef MCFUART_BASE5 |
58 | { |
59 | .mapbase = MCFUART_BASE5, |
60 | .irq = MCF_IRQ_UART5, |
61 | }, |
62 | #endif |
63 | #ifdef MCFUART_BASE6 |
64 | { |
65 | .mapbase = MCFUART_BASE6, |
66 | .irq = MCF_IRQ_UART6, |
67 | }, |
68 | #endif |
69 | #ifdef MCFUART_BASE7 |
70 | { |
71 | .mapbase = MCFUART_BASE7, |
72 | .irq = MCF_IRQ_UART7, |
73 | }, |
74 | #endif |
75 | #ifdef MCFUART_BASE8 |
76 | { |
77 | .mapbase = MCFUART_BASE8, |
78 | .irq = MCF_IRQ_UART8, |
79 | }, |
80 | #endif |
81 | #ifdef MCFUART_BASE9 |
82 | { |
83 | .mapbase = MCFUART_BASE9, |
84 | .irq = MCF_IRQ_UART9, |
85 | }, |
86 | #endif |
87 | { }, |
88 | }; |
89 | |
90 | static struct platform_device mcf_uart = { |
91 | .name = "mcfuart" , |
92 | .id = 0, |
93 | .dev.platform_data = mcf_uart_platform_data, |
94 | }; |
95 | |
96 | #if IS_ENABLED(CONFIG_FEC) |
97 | |
98 | #ifdef CONFIG_M5441x |
99 | #define FEC_NAME "enet-fec" |
100 | static struct fec_platform_data fec_pdata = { |
101 | .phy = PHY_INTERFACE_MODE_RMII, |
102 | }; |
103 | #define FEC_PDATA (&fec_pdata) |
104 | #else |
105 | #define FEC_NAME "fec" |
106 | #define FEC_PDATA NULL |
107 | #endif |
108 | |
109 | /* |
110 | * Some ColdFire cores contain the Fast Ethernet Controller (FEC) |
111 | * block. It is Freescale's own hardware block. Some ColdFires |
112 | * have 2 of these. |
113 | */ |
114 | static struct resource mcf_fec0_resources[] = { |
115 | { |
116 | .start = MCFFEC_BASE0, |
117 | .end = MCFFEC_BASE0 + MCFFEC_SIZE0 - 1, |
118 | .flags = IORESOURCE_MEM, |
119 | }, |
120 | { |
121 | .start = MCF_IRQ_FECRX0, |
122 | .end = MCF_IRQ_FECRX0, |
123 | .flags = IORESOURCE_IRQ, |
124 | }, |
125 | { |
126 | .start = MCF_IRQ_FECTX0, |
127 | .end = MCF_IRQ_FECTX0, |
128 | .flags = IORESOURCE_IRQ, |
129 | }, |
130 | { |
131 | .start = MCF_IRQ_FECENTC0, |
132 | .end = MCF_IRQ_FECENTC0, |
133 | .flags = IORESOURCE_IRQ, |
134 | }, |
135 | }; |
136 | |
137 | static struct platform_device mcf_fec0 = { |
138 | .name = FEC_NAME, |
139 | .id = 0, |
140 | .num_resources = ARRAY_SIZE(mcf_fec0_resources), |
141 | .resource = mcf_fec0_resources, |
142 | .dev = { |
143 | .dma_mask = &mcf_fec0.dev.coherent_dma_mask, |
144 | .coherent_dma_mask = DMA_BIT_MASK(32), |
145 | .platform_data = FEC_PDATA, |
146 | } |
147 | }; |
148 | |
149 | #ifdef MCFFEC_BASE1 |
150 | static struct resource mcf_fec1_resources[] = { |
151 | { |
152 | .start = MCFFEC_BASE1, |
153 | .end = MCFFEC_BASE1 + MCFFEC_SIZE1 - 1, |
154 | .flags = IORESOURCE_MEM, |
155 | }, |
156 | { |
157 | .start = MCF_IRQ_FECRX1, |
158 | .end = MCF_IRQ_FECRX1, |
159 | .flags = IORESOURCE_IRQ, |
160 | }, |
161 | { |
162 | .start = MCF_IRQ_FECTX1, |
163 | .end = MCF_IRQ_FECTX1, |
164 | .flags = IORESOURCE_IRQ, |
165 | }, |
166 | { |
167 | .start = MCF_IRQ_FECENTC1, |
168 | .end = MCF_IRQ_FECENTC1, |
169 | .flags = IORESOURCE_IRQ, |
170 | }, |
171 | }; |
172 | |
173 | static struct platform_device mcf_fec1 = { |
174 | .name = FEC_NAME, |
175 | .id = 1, |
176 | .num_resources = ARRAY_SIZE(mcf_fec1_resources), |
177 | .resource = mcf_fec1_resources, |
178 | .dev = { |
179 | .dma_mask = &mcf_fec1.dev.coherent_dma_mask, |
180 | .coherent_dma_mask = DMA_BIT_MASK(32), |
181 | .platform_data = FEC_PDATA, |
182 | } |
183 | }; |
184 | #endif /* MCFFEC_BASE1 */ |
185 | #endif /* CONFIG_FEC */ |
186 | |
187 | #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) |
188 | /* |
189 | * The ColdFire QSPI module is an SPI protocol hardware block used |
190 | * on a number of different ColdFire CPUs. |
191 | */ |
192 | static struct resource mcf_qspi_resources[] = { |
193 | { |
194 | .start = MCFQSPI_BASE, |
195 | .end = MCFQSPI_BASE + MCFQSPI_SIZE - 1, |
196 | .flags = IORESOURCE_MEM, |
197 | }, |
198 | { |
199 | .start = MCF_IRQ_QSPI, |
200 | .end = MCF_IRQ_QSPI, |
201 | .flags = IORESOURCE_IRQ, |
202 | }, |
203 | }; |
204 | |
205 | static int mcf_cs_setup(struct mcfqspi_cs_control *cs_control) |
206 | { |
207 | int status; |
208 | |
209 | status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0" ); |
210 | if (status) { |
211 | pr_debug("gpio_request for MCFQSPI_CS0 failed\n" ); |
212 | goto fail0; |
213 | } |
214 | status = gpio_direction_output(MCFQSPI_CS0, 1); |
215 | if (status) { |
216 | pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n" ); |
217 | goto fail1; |
218 | } |
219 | |
220 | status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1" ); |
221 | if (status) { |
222 | pr_debug("gpio_request for MCFQSPI_CS1 failed\n" ); |
223 | goto fail1; |
224 | } |
225 | status = gpio_direction_output(MCFQSPI_CS1, 1); |
226 | if (status) { |
227 | pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n" ); |
228 | goto fail2; |
229 | } |
230 | |
231 | status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2" ); |
232 | if (status) { |
233 | pr_debug("gpio_request for MCFQSPI_CS2 failed\n" ); |
234 | goto fail2; |
235 | } |
236 | status = gpio_direction_output(MCFQSPI_CS2, 1); |
237 | if (status) { |
238 | pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n" ); |
239 | goto fail3; |
240 | } |
241 | |
242 | #ifdef MCFQSPI_CS3 |
243 | status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3" ); |
244 | if (status) { |
245 | pr_debug("gpio_request for MCFQSPI_CS3 failed\n" ); |
246 | goto fail3; |
247 | } |
248 | status = gpio_direction_output(MCFQSPI_CS3, 1); |
249 | if (status) { |
250 | pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n" ); |
251 | gpio_free(MCFQSPI_CS3); |
252 | goto fail3; |
253 | } |
254 | #endif |
255 | |
256 | return 0; |
257 | |
258 | fail3: |
259 | gpio_free(MCFQSPI_CS2); |
260 | fail2: |
261 | gpio_free(MCFQSPI_CS1); |
262 | fail1: |
263 | gpio_free(MCFQSPI_CS0); |
264 | fail0: |
265 | return status; |
266 | } |
267 | |
268 | static void mcf_cs_teardown(struct mcfqspi_cs_control *cs_control) |
269 | { |
270 | #ifdef MCFQSPI_CS3 |
271 | gpio_free(MCFQSPI_CS3); |
272 | #endif |
273 | gpio_free(MCFQSPI_CS2); |
274 | gpio_free(MCFQSPI_CS1); |
275 | gpio_free(MCFQSPI_CS0); |
276 | } |
277 | |
278 | static void mcf_cs_select(struct mcfqspi_cs_control *cs_control, |
279 | u8 chip_select, bool cs_high) |
280 | { |
281 | switch (chip_select) { |
282 | case 0: |
283 | gpio_set_value(MCFQSPI_CS0, cs_high); |
284 | break; |
285 | case 1: |
286 | gpio_set_value(MCFQSPI_CS1, cs_high); |
287 | break; |
288 | case 2: |
289 | gpio_set_value(MCFQSPI_CS2, cs_high); |
290 | break; |
291 | #ifdef MCFQSPI_CS3 |
292 | case 3: |
293 | gpio_set_value(MCFQSPI_CS3, cs_high); |
294 | break; |
295 | #endif |
296 | } |
297 | } |
298 | |
299 | static void mcf_cs_deselect(struct mcfqspi_cs_control *cs_control, |
300 | u8 chip_select, bool cs_high) |
301 | { |
302 | switch (chip_select) { |
303 | case 0: |
304 | gpio_set_value(MCFQSPI_CS0, !cs_high); |
305 | break; |
306 | case 1: |
307 | gpio_set_value(MCFQSPI_CS1, !cs_high); |
308 | break; |
309 | case 2: |
310 | gpio_set_value(MCFQSPI_CS2, !cs_high); |
311 | break; |
312 | #ifdef MCFQSPI_CS3 |
313 | case 3: |
314 | gpio_set_value(MCFQSPI_CS3, !cs_high); |
315 | break; |
316 | #endif |
317 | } |
318 | } |
319 | |
320 | static struct mcfqspi_cs_control mcf_cs_control = { |
321 | .setup = mcf_cs_setup, |
322 | .teardown = mcf_cs_teardown, |
323 | .select = mcf_cs_select, |
324 | .deselect = mcf_cs_deselect, |
325 | }; |
326 | |
327 | static struct mcfqspi_platform_data mcf_qspi_data = { |
328 | .bus_num = 0, |
329 | .num_chipselect = 4, |
330 | .cs_control = &mcf_cs_control, |
331 | }; |
332 | |
333 | static struct platform_device mcf_qspi = { |
334 | .name = "mcfqspi" , |
335 | .id = 0, |
336 | .num_resources = ARRAY_SIZE(mcf_qspi_resources), |
337 | .resource = mcf_qspi_resources, |
338 | .dev.platform_data = &mcf_qspi_data, |
339 | }; |
340 | #endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */ |
341 | |
342 | #if IS_ENABLED(CONFIG_I2C_IMX) |
343 | static struct resource mcf_i2c0_resources[] = { |
344 | { |
345 | .start = MCFI2C_BASE0, |
346 | .end = MCFI2C_BASE0 + MCFI2C_SIZE0 - 1, |
347 | .flags = IORESOURCE_MEM, |
348 | }, |
349 | { |
350 | .start = MCF_IRQ_I2C0, |
351 | .end = MCF_IRQ_I2C0, |
352 | .flags = IORESOURCE_IRQ, |
353 | }, |
354 | }; |
355 | |
356 | static struct platform_device mcf_i2c0 = { |
357 | .name = "imx1-i2c" , |
358 | .id = 0, |
359 | .num_resources = ARRAY_SIZE(mcf_i2c0_resources), |
360 | .resource = mcf_i2c0_resources, |
361 | }; |
362 | #ifdef MCFI2C_BASE1 |
363 | |
364 | static struct resource mcf_i2c1_resources[] = { |
365 | { |
366 | .start = MCFI2C_BASE1, |
367 | .end = MCFI2C_BASE1 + MCFI2C_SIZE1 - 1, |
368 | .flags = IORESOURCE_MEM, |
369 | }, |
370 | { |
371 | .start = MCF_IRQ_I2C1, |
372 | .end = MCF_IRQ_I2C1, |
373 | .flags = IORESOURCE_IRQ, |
374 | }, |
375 | }; |
376 | |
377 | static struct platform_device mcf_i2c1 = { |
378 | .name = "imx1-i2c" , |
379 | .id = 1, |
380 | .num_resources = ARRAY_SIZE(mcf_i2c1_resources), |
381 | .resource = mcf_i2c1_resources, |
382 | }; |
383 | |
384 | #endif /* MCFI2C_BASE1 */ |
385 | |
386 | #ifdef MCFI2C_BASE2 |
387 | |
388 | static struct resource mcf_i2c2_resources[] = { |
389 | { |
390 | .start = MCFI2C_BASE2, |
391 | .end = MCFI2C_BASE2 + MCFI2C_SIZE2 - 1, |
392 | .flags = IORESOURCE_MEM, |
393 | }, |
394 | { |
395 | .start = MCF_IRQ_I2C2, |
396 | .end = MCF_IRQ_I2C2, |
397 | .flags = IORESOURCE_IRQ, |
398 | }, |
399 | }; |
400 | |
401 | static struct platform_device mcf_i2c2 = { |
402 | .name = "imx1-i2c" , |
403 | .id = 2, |
404 | .num_resources = ARRAY_SIZE(mcf_i2c2_resources), |
405 | .resource = mcf_i2c2_resources, |
406 | }; |
407 | |
408 | #endif /* MCFI2C_BASE2 */ |
409 | |
410 | #ifdef MCFI2C_BASE3 |
411 | |
412 | static struct resource mcf_i2c3_resources[] = { |
413 | { |
414 | .start = MCFI2C_BASE3, |
415 | .end = MCFI2C_BASE3 + MCFI2C_SIZE3 - 1, |
416 | .flags = IORESOURCE_MEM, |
417 | }, |
418 | { |
419 | .start = MCF_IRQ_I2C3, |
420 | .end = MCF_IRQ_I2C3, |
421 | .flags = IORESOURCE_IRQ, |
422 | }, |
423 | }; |
424 | |
425 | static struct platform_device mcf_i2c3 = { |
426 | .name = "imx1-i2c" , |
427 | .id = 3, |
428 | .num_resources = ARRAY_SIZE(mcf_i2c3_resources), |
429 | .resource = mcf_i2c3_resources, |
430 | }; |
431 | |
432 | #endif /* MCFI2C_BASE3 */ |
433 | |
434 | #ifdef MCFI2C_BASE4 |
435 | |
436 | static struct resource mcf_i2c4_resources[] = { |
437 | { |
438 | .start = MCFI2C_BASE4, |
439 | .end = MCFI2C_BASE4 + MCFI2C_SIZE4 - 1, |
440 | .flags = IORESOURCE_MEM, |
441 | }, |
442 | { |
443 | .start = MCF_IRQ_I2C4, |
444 | .end = MCF_IRQ_I2C4, |
445 | .flags = IORESOURCE_IRQ, |
446 | }, |
447 | }; |
448 | |
449 | static struct platform_device mcf_i2c4 = { |
450 | .name = "imx1-i2c" , |
451 | .id = 4, |
452 | .num_resources = ARRAY_SIZE(mcf_i2c4_resources), |
453 | .resource = mcf_i2c4_resources, |
454 | }; |
455 | |
456 | #endif /* MCFI2C_BASE4 */ |
457 | |
458 | #ifdef MCFI2C_BASE5 |
459 | |
460 | static struct resource mcf_i2c5_resources[] = { |
461 | { |
462 | .start = MCFI2C_BASE5, |
463 | .end = MCFI2C_BASE5 + MCFI2C_SIZE5 - 1, |
464 | .flags = IORESOURCE_MEM, |
465 | }, |
466 | { |
467 | .start = MCF_IRQ_I2C5, |
468 | .end = MCF_IRQ_I2C5, |
469 | .flags = IORESOURCE_IRQ, |
470 | }, |
471 | }; |
472 | |
473 | static struct platform_device mcf_i2c5 = { |
474 | .name = "imx1-i2c" , |
475 | .id = 5, |
476 | .num_resources = ARRAY_SIZE(mcf_i2c5_resources), |
477 | .resource = mcf_i2c5_resources, |
478 | }; |
479 | |
480 | #endif /* MCFI2C_BASE5 */ |
481 | #endif /* IS_ENABLED(CONFIG_I2C_IMX) */ |
482 | |
483 | #ifdef MCFEDMA_BASE |
484 | |
485 | static const struct dma_slave_map mcf_edma_map[] = { |
486 | { "dreq0" , "rx-tx" , MCF_EDMA_FILTER_PARAM(0) }, |
487 | { "dreq1" , "rx-tx" , MCF_EDMA_FILTER_PARAM(1) }, |
488 | { "uart.0" , "rx" , MCF_EDMA_FILTER_PARAM(2) }, |
489 | { "uart.0" , "tx" , MCF_EDMA_FILTER_PARAM(3) }, |
490 | { "uart.1" , "rx" , MCF_EDMA_FILTER_PARAM(4) }, |
491 | { "uart.1" , "tx" , MCF_EDMA_FILTER_PARAM(5) }, |
492 | { "uart.2" , "rx" , MCF_EDMA_FILTER_PARAM(6) }, |
493 | { "uart.2" , "tx" , MCF_EDMA_FILTER_PARAM(7) }, |
494 | { "timer0" , "rx-tx" , MCF_EDMA_FILTER_PARAM(8) }, |
495 | { "timer1" , "rx-tx" , MCF_EDMA_FILTER_PARAM(9) }, |
496 | { "timer2" , "rx-tx" , MCF_EDMA_FILTER_PARAM(10) }, |
497 | { "timer3" , "rx-tx" , MCF_EDMA_FILTER_PARAM(11) }, |
498 | { "fsl-dspi.0" , "rx" , MCF_EDMA_FILTER_PARAM(12) }, |
499 | { "fsl-dspi.0" , "tx" , MCF_EDMA_FILTER_PARAM(13) }, |
500 | { "fsl-dspi.1" , "rx" , MCF_EDMA_FILTER_PARAM(14) }, |
501 | { "fsl-dspi.1" , "tx" , MCF_EDMA_FILTER_PARAM(15) }, |
502 | }; |
503 | |
504 | static struct mcf_edma_platform_data mcf_edma_data = { |
505 | .dma_channels = 64, |
506 | .slave_map = mcf_edma_map, |
507 | .slavecnt = ARRAY_SIZE(mcf_edma_map), |
508 | }; |
509 | |
510 | static struct resource mcf_edma_resources[] = { |
511 | { |
512 | .start = MCFEDMA_BASE, |
513 | .end = MCFEDMA_BASE + MCFEDMA_SIZE - 1, |
514 | .flags = IORESOURCE_MEM, |
515 | }, |
516 | { |
517 | .start = MCFEDMA_IRQ_INTR0, |
518 | .end = MCFEDMA_IRQ_INTR0 + 15, |
519 | .flags = IORESOURCE_IRQ, |
520 | .name = "edma-tx-00-15" , |
521 | }, |
522 | { |
523 | .start = MCFEDMA_IRQ_INTR16, |
524 | .end = MCFEDMA_IRQ_INTR16 + 39, |
525 | .flags = IORESOURCE_IRQ, |
526 | .name = "edma-tx-16-55" , |
527 | }, |
528 | { |
529 | .start = MCFEDMA_IRQ_INTR56, |
530 | .end = MCFEDMA_IRQ_INTR56, |
531 | .flags = IORESOURCE_IRQ, |
532 | .name = "edma-tx-56-63" , |
533 | }, |
534 | { |
535 | .start = MCFEDMA_IRQ_ERR, |
536 | .end = MCFEDMA_IRQ_ERR, |
537 | .flags = IORESOURCE_IRQ, |
538 | .name = "edma-err" , |
539 | }, |
540 | }; |
541 | |
542 | static u64 mcf_edma_dmamask = DMA_BIT_MASK(32); |
543 | |
544 | static struct platform_device mcf_edma = { |
545 | .name = "mcf-edma" , |
546 | .id = 0, |
547 | .num_resources = ARRAY_SIZE(mcf_edma_resources), |
548 | .resource = mcf_edma_resources, |
549 | .dev = { |
550 | .dma_mask = &mcf_edma_dmamask, |
551 | .coherent_dma_mask = DMA_BIT_MASK(32), |
552 | .platform_data = &mcf_edma_data, |
553 | } |
554 | }; |
555 | #endif /* MCFEDMA_BASE */ |
556 | |
557 | #ifdef MCFSDHC_BASE |
558 | static struct mcf_esdhc_platform_data mcf_esdhc_data = { |
559 | .max_bus_width = 4, |
560 | .cd_type = ESDHC_CD_NONE, |
561 | }; |
562 | |
563 | static struct resource mcf_esdhc_resources[] = { |
564 | { |
565 | .start = MCFSDHC_BASE, |
566 | .end = MCFSDHC_BASE + MCFSDHC_SIZE - 1, |
567 | .flags = IORESOURCE_MEM, |
568 | }, { |
569 | .start = MCF_IRQ_SDHC, |
570 | .end = MCF_IRQ_SDHC, |
571 | .flags = IORESOURCE_IRQ, |
572 | }, |
573 | }; |
574 | |
575 | static struct platform_device mcf_esdhc = { |
576 | .name = "sdhci-esdhc-mcf" , |
577 | .id = 0, |
578 | .num_resources = ARRAY_SIZE(mcf_esdhc_resources), |
579 | .resource = mcf_esdhc_resources, |
580 | .dev.platform_data = &mcf_esdhc_data, |
581 | }; |
582 | #endif /* MCFSDHC_BASE */ |
583 | |
584 | #ifdef MCFFLEXCAN_SIZE |
585 | |
586 | #include <linux/can/platform/flexcan.h> |
587 | |
588 | static struct flexcan_platform_data mcf5441x_flexcan_info = { |
589 | .clk_src = 1, |
590 | .clock_frequency = 120000000, |
591 | }; |
592 | |
593 | static struct resource mcf5441x_flexcan0_resource[] = { |
594 | { |
595 | .start = MCFFLEXCAN_BASE0, |
596 | .end = MCFFLEXCAN_BASE0 + MCFFLEXCAN_SIZE, |
597 | .flags = IORESOURCE_MEM, |
598 | }, |
599 | { |
600 | .start = MCF_IRQ_IFL0, |
601 | .end = MCF_IRQ_IFL0, |
602 | .flags = IORESOURCE_IRQ, |
603 | }, |
604 | { |
605 | .start = MCF_IRQ_BOFF0, |
606 | .end = MCF_IRQ_BOFF0, |
607 | .flags = IORESOURCE_IRQ, |
608 | }, |
609 | { |
610 | .start = MCF_IRQ_ERR0, |
611 | .end = MCF_IRQ_ERR0, |
612 | .flags = IORESOURCE_IRQ, |
613 | }, |
614 | }; |
615 | |
616 | static struct platform_device mcf_flexcan0 = { |
617 | .name = "flexcan-mcf5441x" , |
618 | .id = 0, |
619 | .num_resources = ARRAY_SIZE(mcf5441x_flexcan0_resource), |
620 | .resource = mcf5441x_flexcan0_resource, |
621 | .dev.platform_data = &mcf5441x_flexcan_info, |
622 | }; |
623 | #endif /* MCFFLEXCAN_SIZE */ |
624 | |
625 | static struct platform_device *mcf_devices[] __initdata = { |
626 | &mcf_uart, |
627 | #if IS_ENABLED(CONFIG_FEC) |
628 | &mcf_fec0, |
629 | #ifdef MCFFEC_BASE1 |
630 | &mcf_fec1, |
631 | #endif |
632 | #endif |
633 | #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) |
634 | &mcf_qspi, |
635 | #endif |
636 | #if IS_ENABLED(CONFIG_I2C_IMX) |
637 | &mcf_i2c0, |
638 | #ifdef MCFI2C_BASE1 |
639 | &mcf_i2c1, |
640 | #endif |
641 | #ifdef MCFI2C_BASE2 |
642 | &mcf_i2c2, |
643 | #endif |
644 | #ifdef MCFI2C_BASE3 |
645 | &mcf_i2c3, |
646 | #endif |
647 | #ifdef MCFI2C_BASE4 |
648 | &mcf_i2c4, |
649 | #endif |
650 | #ifdef MCFI2C_BASE5 |
651 | &mcf_i2c5, |
652 | #endif |
653 | #endif |
654 | #ifdef MCFEDMA_BASE |
655 | &mcf_edma, |
656 | #endif |
657 | #ifdef MCFSDHC_BASE |
658 | &mcf_esdhc, |
659 | #endif |
660 | #ifdef MCFFLEXCAN_SIZE |
661 | &mcf_flexcan0, |
662 | #endif |
663 | }; |
664 | |
665 | /* |
666 | * Some ColdFire UARTs let you set the IRQ line to use. |
667 | */ |
668 | static void __init mcf_uart_set_irq(void) |
669 | { |
670 | #ifdef MCFUART_UIVR |
671 | /* UART0 interrupt setup */ |
672 | writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCFSIM_UART1ICR); |
673 | writeb(MCF_IRQ_UART0, MCFUART_BASE0 + MCFUART_UIVR); |
674 | mcf_mapirq2imr(MCF_IRQ_UART0, MCFINTC_UART0); |
675 | |
676 | /* UART1 interrupt setup */ |
677 | writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCFSIM_UART2ICR); |
678 | writeb(MCF_IRQ_UART1, MCFUART_BASE1 + MCFUART_UIVR); |
679 | mcf_mapirq2imr(MCF_IRQ_UART1, MCFINTC_UART1); |
680 | #endif |
681 | } |
682 | |
683 | static int __init mcf_init_devices(void) |
684 | { |
685 | mcf_uart_set_irq(); |
686 | platform_add_devices(mcf_devices, ARRAY_SIZE(mcf_devices)); |
687 | return 0; |
688 | } |
689 | |
690 | arch_initcall(mcf_init_devices); |
691 | |