2 * device.c -- common ColdFire SoC device support
4 * (C) Copyright 2011, Greg Ungerer <gerg@uclinux.org>
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
11 #include <linux/kernel.h>
12 #include <linux/init.h>
14 #include <linux/spi/spi.h>
15 #include <linux/gpio.h>
16 #include <asm/traps.h>
17 #include <asm/coldfire.h>
18 #include <asm/mcfsim.h>
19 #include <asm/mcfuart.h>
20 #include <asm/mcfqspi.h>
23 * All current ColdFire parts contain from 2, 3 or 4 UARTS.
25 static struct mcf_platform_uart mcf_uart_platform_data[] = {
27 .mapbase = MCFUART_BASE0,
31 .mapbase = MCFUART_BASE1,
36 .mapbase = MCFUART_BASE2,
42 .mapbase = MCFUART_BASE3,
49 static struct platform_device mcf_uart = {
52 .dev.platform_data = mcf_uart_platform_data,
57 * Some ColdFire cores contain the Fast Ethernet Controller (FEC)
58 * block. It is Freescale's own hardware block. Some ColdFires
61 static struct resource mcf_fec0_resources[] = {
63 .start = MCFFEC_BASE0,
64 .end = MCFFEC_BASE0 + MCFFEC_SIZE0 - 1,
65 .flags = IORESOURCE_MEM,
68 .start = MCF_IRQ_FECRX0,
69 .end = MCF_IRQ_FECRX0,
70 .flags = IORESOURCE_IRQ,
73 .start = MCF_IRQ_FECTX0,
74 .end = MCF_IRQ_FECTX0,
75 .flags = IORESOURCE_IRQ,
78 .start = MCF_IRQ_FECENTC0,
79 .end = MCF_IRQ_FECENTC0,
80 .flags = IORESOURCE_IRQ,
84 static struct platform_device mcf_fec0 = {
87 .num_resources = ARRAY_SIZE(mcf_fec0_resources),
88 .resource = mcf_fec0_resources,
92 static struct resource mcf_fec1_resources[] = {
94 .start = MCFFEC_BASE1,
95 .end = MCFFEC_BASE1 + MCFFEC_SIZE1 - 1,
96 .flags = IORESOURCE_MEM,
99 .start = MCF_IRQ_FECRX1,
100 .end = MCF_IRQ_FECRX1,
101 .flags = IORESOURCE_IRQ,
104 .start = MCF_IRQ_FECTX1,
105 .end = MCF_IRQ_FECTX1,
106 .flags = IORESOURCE_IRQ,
109 .start = MCF_IRQ_FECENTC1,
110 .end = MCF_IRQ_FECENTC1,
111 .flags = IORESOURCE_IRQ,
115 static struct platform_device mcf_fec1 = {
118 .num_resources = ARRAY_SIZE(mcf_fec1_resources),
119 .resource = mcf_fec1_resources,
121 #endif /* MCFFEC_BASE1 */
122 #endif /* CONFIG_FEC */
124 #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
126 * The ColdFire QSPI module is an SPI protocol hardware block used
127 * on a number of different ColdFire CPUs.
129 static struct resource mcf_qspi_resources[] = {
131 .start = MCFQSPI_BASE,
132 .end = MCFQSPI_BASE + MCFQSPI_SIZE - 1,
133 .flags = IORESOURCE_MEM,
136 .start = MCF_IRQ_QSPI,
138 .flags = IORESOURCE_IRQ,
142 static int mcf_cs_setup(struct mcfqspi_cs_control *cs_control)
146 status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
148 pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
151 status = gpio_direction_output(MCFQSPI_CS0, 1);
153 pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
157 status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
159 pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
162 status = gpio_direction_output(MCFQSPI_CS1, 1);
164 pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
168 status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
170 pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
173 status = gpio_direction_output(MCFQSPI_CS2, 1);
175 pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
180 status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
182 pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
185 status = gpio_direction_output(MCFQSPI_CS3, 1);
187 pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
188 gpio_free(MCFQSPI_CS3);
196 gpio_free(MCFQSPI_CS2);
198 gpio_free(MCFQSPI_CS1);
200 gpio_free(MCFQSPI_CS0);
205 static void mcf_cs_teardown(struct mcfqspi_cs_control *cs_control)
208 gpio_free(MCFQSPI_CS3);
210 gpio_free(MCFQSPI_CS2);
211 gpio_free(MCFQSPI_CS1);
212 gpio_free(MCFQSPI_CS0);
215 static void mcf_cs_select(struct mcfqspi_cs_control *cs_control,
216 u8 chip_select, bool cs_high)
218 switch (chip_select) {
220 gpio_set_value(MCFQSPI_CS0, cs_high);
223 gpio_set_value(MCFQSPI_CS1, cs_high);
226 gpio_set_value(MCFQSPI_CS2, cs_high);
230 gpio_set_value(MCFQSPI_CS3, cs_high);
236 static void mcf_cs_deselect(struct mcfqspi_cs_control *cs_control,
237 u8 chip_select, bool cs_high)
239 switch (chip_select) {
241 gpio_set_value(MCFQSPI_CS0, !cs_high);
244 gpio_set_value(MCFQSPI_CS1, !cs_high);
247 gpio_set_value(MCFQSPI_CS2, !cs_high);
251 gpio_set_value(MCFQSPI_CS3, !cs_high);
257 static 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,
264 static struct mcfqspi_platform_data mcf_qspi_data = {
267 .cs_control = &mcf_cs_control,
270 static struct platform_device mcf_qspi = {
273 .num_resources = ARRAY_SIZE(mcf_qspi_resources),
274 .resource = mcf_qspi_resources,
275 .dev.platform_data = &mcf_qspi_data,
277 #endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
279 static struct platform_device *mcf_devices[] __initdata = {
287 #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
293 * Some ColdFire UARTs let you set the IRQ line to use.
295 static void __init mcf_uart_set_irq(void)
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);
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);
310 static int __init mcf_init_devices(void)
313 platform_add_devices(mcf_devices, ARRAY_SIZE(mcf_devices));
317 arch_initcall(mcf_init_devices);