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