GNU Linux-libre 4.9.309-gnu1
[releases.git] / arch / m68k / coldfire / device.c
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 <asm/traps.h>
18 #include <asm/coldfire.h>
19 #include <asm/mcfsim.h>
20 #include <asm/mcfuart.h>
21 #include <asm/mcfqspi.h>
22
23 /*
24  *      All current ColdFire parts contain from 2, 3, 4 or 10 UARTS.
25  */
26 static struct mcf_platform_uart mcf_uart_platform_data[] = {
27         {
28                 .mapbase        = MCFUART_BASE0,
29                 .irq            = MCF_IRQ_UART0,
30         },
31         {
32                 .mapbase        = MCFUART_BASE1,
33                 .irq            = MCF_IRQ_UART1,
34         },
35 #ifdef MCFUART_BASE2
36         {
37                 .mapbase        = MCFUART_BASE2,
38                 .irq            = MCF_IRQ_UART2,
39         },
40 #endif
41 #ifdef MCFUART_BASE3
42         {
43                 .mapbase        = MCFUART_BASE3,
44                 .irq            = MCF_IRQ_UART3,
45         },
46 #endif
47 #ifdef MCFUART_BASE4
48         {
49                 .mapbase        = MCFUART_BASE4,
50                 .irq            = MCF_IRQ_UART4,
51         },
52 #endif
53 #ifdef MCFUART_BASE5
54         {
55                 .mapbase        = MCFUART_BASE5,
56                 .irq            = MCF_IRQ_UART5,
57         },
58 #endif
59 #ifdef MCFUART_BASE6
60         {
61                 .mapbase        = MCFUART_BASE6,
62                 .irq            = MCF_IRQ_UART6,
63         },
64 #endif
65 #ifdef MCFUART_BASE7
66         {
67                 .mapbase        = MCFUART_BASE7,
68                 .irq            = MCF_IRQ_UART7,
69         },
70 #endif
71 #ifdef MCFUART_BASE8
72         {
73                 .mapbase        = MCFUART_BASE8,
74                 .irq            = MCF_IRQ_UART8,
75         },
76 #endif
77 #ifdef MCFUART_BASE9
78         {
79                 .mapbase        = MCFUART_BASE9,
80                 .irq            = MCF_IRQ_UART9,
81         },
82 #endif
83         { },
84 };
85
86 static struct platform_device mcf_uart = {
87         .name                   = "mcfuart",
88         .id                     = 0,
89         .dev.platform_data      = mcf_uart_platform_data,
90 };
91
92 #if IS_ENABLED(CONFIG_FEC)
93
94 #ifdef CONFIG_M5441x
95 #define FEC_NAME        "enet-fec"
96 static struct fec_platform_data fec_pdata = {
97         .phy            = PHY_INTERFACE_MODE_RMII,
98 };
99 #define FEC_PDATA       (&fec_pdata)
100 #else
101 #define FEC_NAME        "fec"
102 #define FEC_PDATA       NULL
103 #endif
104
105 /*
106  *      Some ColdFire cores contain the Fast Ethernet Controller (FEC)
107  *      block. It is Freescale's own hardware block. Some ColdFires
108  *      have 2 of these.
109  */
110 static struct resource mcf_fec0_resources[] = {
111         {
112                 .start          = MCFFEC_BASE0,
113                 .end            = MCFFEC_BASE0 + MCFFEC_SIZE0 - 1,
114                 .flags          = IORESOURCE_MEM,
115         },
116         {
117                 .start          = MCF_IRQ_FECRX0,
118                 .end            = MCF_IRQ_FECRX0,
119                 .flags          = IORESOURCE_IRQ,
120         },
121         {
122                 .start          = MCF_IRQ_FECTX0,
123                 .end            = MCF_IRQ_FECTX0,
124                 .flags          = IORESOURCE_IRQ,
125         },
126         {
127                 .start          = MCF_IRQ_FECENTC0,
128                 .end            = MCF_IRQ_FECENTC0,
129                 .flags          = IORESOURCE_IRQ,
130         },
131 };
132
133 static struct platform_device mcf_fec0 = {
134         .name                   = FEC_NAME,
135         .id                     = 0,
136         .num_resources          = ARRAY_SIZE(mcf_fec0_resources),
137         .resource               = mcf_fec0_resources,
138         .dev = {
139                 .dma_mask               = &mcf_fec0.dev.coherent_dma_mask,
140                 .coherent_dma_mask      = DMA_BIT_MASK(32),
141                 .platform_data          = FEC_PDATA,
142         }
143 };
144
145 #ifdef MCFFEC_BASE1
146 static struct resource mcf_fec1_resources[] = {
147         {
148                 .start          = MCFFEC_BASE1,
149                 .end            = MCFFEC_BASE1 + MCFFEC_SIZE1 - 1,
150                 .flags          = IORESOURCE_MEM,
151         },
152         {
153                 .start          = MCF_IRQ_FECRX1,
154                 .end            = MCF_IRQ_FECRX1,
155                 .flags          = IORESOURCE_IRQ,
156         },
157         {
158                 .start          = MCF_IRQ_FECTX1,
159                 .end            = MCF_IRQ_FECTX1,
160                 .flags          = IORESOURCE_IRQ,
161         },
162         {
163                 .start          = MCF_IRQ_FECENTC1,
164                 .end            = MCF_IRQ_FECENTC1,
165                 .flags          = IORESOURCE_IRQ,
166         },
167 };
168
169 static struct platform_device mcf_fec1 = {
170         .name                   = FEC_NAME,
171         .id                     = 1,
172         .num_resources          = ARRAY_SIZE(mcf_fec1_resources),
173         .resource               = mcf_fec1_resources,
174         .dev = {
175                 .dma_mask               = &mcf_fec1.dev.coherent_dma_mask,
176                 .coherent_dma_mask      = DMA_BIT_MASK(32),
177                 .platform_data          = FEC_PDATA,
178         }
179 };
180 #endif /* MCFFEC_BASE1 */
181 #endif /* CONFIG_FEC */
182
183 #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
184 /*
185  *      The ColdFire QSPI module is an SPI protocol hardware block used
186  *      on a number of different ColdFire CPUs.
187  */
188 static struct resource mcf_qspi_resources[] = {
189         {
190                 .start          = MCFQSPI_BASE,
191                 .end            = MCFQSPI_BASE + MCFQSPI_SIZE - 1,
192                 .flags          = IORESOURCE_MEM,
193         },
194         {
195                 .start          = MCF_IRQ_QSPI,
196                 .end            = MCF_IRQ_QSPI,
197                 .flags          = IORESOURCE_IRQ,
198         },
199 };
200
201 static int mcf_cs_setup(struct mcfqspi_cs_control *cs_control)
202 {
203         int status;
204
205         status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
206         if (status) {
207                 pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
208                 goto fail0;
209         }
210         status = gpio_direction_output(MCFQSPI_CS0, 1);
211         if (status) {
212                 pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
213                 goto fail1;
214         }
215
216         status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
217         if (status) {
218                 pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
219                 goto fail1;
220         }
221         status = gpio_direction_output(MCFQSPI_CS1, 1);
222         if (status) {
223                 pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
224                 goto fail2;
225         }
226
227         status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
228         if (status) {
229                 pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
230                 goto fail2;
231         }
232         status = gpio_direction_output(MCFQSPI_CS2, 1);
233         if (status) {
234                 pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
235                 goto fail3;
236         }
237
238 #ifdef MCFQSPI_CS3
239         status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
240         if (status) {
241                 pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
242                 goto fail3;
243         }
244         status = gpio_direction_output(MCFQSPI_CS3, 1);
245         if (status) {
246                 pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
247                 gpio_free(MCFQSPI_CS3);
248                 goto fail3;
249         }
250 #endif
251
252         return 0;
253
254 fail3:
255         gpio_free(MCFQSPI_CS2);
256 fail2:
257         gpio_free(MCFQSPI_CS1);
258 fail1:
259         gpio_free(MCFQSPI_CS0);
260 fail0:
261         return status;
262 }
263
264 static void mcf_cs_teardown(struct mcfqspi_cs_control *cs_control)
265 {
266 #ifdef MCFQSPI_CS3
267         gpio_free(MCFQSPI_CS3);
268 #endif
269         gpio_free(MCFQSPI_CS2);
270         gpio_free(MCFQSPI_CS1);
271         gpio_free(MCFQSPI_CS0);
272 }
273
274 static void mcf_cs_select(struct mcfqspi_cs_control *cs_control,
275                           u8 chip_select, bool cs_high)
276 {
277         switch (chip_select) {
278         case 0:
279                 gpio_set_value(MCFQSPI_CS0, cs_high);
280                 break;
281         case 1:
282                 gpio_set_value(MCFQSPI_CS1, cs_high);
283                 break;
284         case 2:
285                 gpio_set_value(MCFQSPI_CS2, cs_high);
286                 break;
287 #ifdef MCFQSPI_CS3
288         case 3:
289                 gpio_set_value(MCFQSPI_CS3, cs_high);
290                 break;
291 #endif
292         }
293 }
294
295 static void mcf_cs_deselect(struct mcfqspi_cs_control *cs_control,
296                             u8 chip_select, bool cs_high)
297 {
298         switch (chip_select) {
299         case 0:
300                 gpio_set_value(MCFQSPI_CS0, !cs_high);
301                 break;
302         case 1:
303                 gpio_set_value(MCFQSPI_CS1, !cs_high);
304                 break;
305         case 2:
306                 gpio_set_value(MCFQSPI_CS2, !cs_high);
307                 break;
308 #ifdef MCFQSPI_CS3
309         case 3:
310                 gpio_set_value(MCFQSPI_CS3, !cs_high);
311                 break;
312 #endif
313         }
314 }
315
316 static struct mcfqspi_cs_control mcf_cs_control = {
317         .setup                  = mcf_cs_setup,
318         .teardown               = mcf_cs_teardown,
319         .select                 = mcf_cs_select,
320         .deselect               = mcf_cs_deselect,
321 };
322
323 static struct mcfqspi_platform_data mcf_qspi_data = {
324         .bus_num                = 0,
325         .num_chipselect         = 4,
326         .cs_control             = &mcf_cs_control,
327 };
328
329 static struct platform_device mcf_qspi = {
330         .name                   = "mcfqspi",
331         .id                     = 0,
332         .num_resources          = ARRAY_SIZE(mcf_qspi_resources),
333         .resource               = mcf_qspi_resources,
334         .dev.platform_data      = &mcf_qspi_data,
335 };
336 #endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
337
338 static struct platform_device *mcf_devices[] __initdata = {
339         &mcf_uart,
340 #if IS_ENABLED(CONFIG_FEC)
341         &mcf_fec0,
342 #ifdef MCFFEC_BASE1
343         &mcf_fec1,
344 #endif
345 #endif
346 #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
347         &mcf_qspi,
348 #endif
349 };
350
351 /*
352  *      Some ColdFire UARTs let you set the IRQ line to use.
353  */
354 static void __init mcf_uart_set_irq(void)
355 {
356 #ifdef MCFUART_UIVR
357         /* UART0 interrupt setup */
358         writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCFSIM_UART1ICR);
359         writeb(MCF_IRQ_UART0, MCFUART_BASE0 + MCFUART_UIVR);
360         mcf_mapirq2imr(MCF_IRQ_UART0, MCFINTC_UART0);
361
362         /* UART1 interrupt setup */
363         writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCFSIM_UART2ICR);
364         writeb(MCF_IRQ_UART1, MCFUART_BASE1 + MCFUART_UIVR);
365         mcf_mapirq2imr(MCF_IRQ_UART1, MCFINTC_UART1);
366 #endif
367 }
368
369 static int __init mcf_init_devices(void)
370 {
371         mcf_uart_set_irq();
372         platform_add_devices(mcf_devices, ARRAY_SIZE(mcf_devices));
373         return 0;
374 }
375
376 arch_initcall(mcf_init_devices);
377