10d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer/*
20d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer * device.c  -- common ColdFire SoC device support
30d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer *
40d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer * (C) Copyright 2011, Greg Ungerer <gerg@uclinux.org>
50d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer *
60d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer * This file is subject to the terms and conditions of the GNU General Public
70d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer * License.  See the file COPYING in the main directory of this archive
80d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer * for more details.
90d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer */
100d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer
110d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer#include <linux/kernel.h>
120d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer#include <linux/init.h>
130d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer#include <linux/io.h>
14fa1fc24662d57170259948314b0759376eb75777Greg Ungerer#include <linux/spi/spi.h>
15fa1fc24662d57170259948314b0759376eb75777Greg Ungerer#include <linux/gpio.h>
16bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King#include <linux/fec.h>
170d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer#include <asm/traps.h>
180d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer#include <asm/coldfire.h>
190d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer#include <asm/mcfsim.h>
200d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer#include <asm/mcfuart.h>
21fa1fc24662d57170259948314b0759376eb75777Greg Ungerer#include <asm/mcfqspi.h>
220d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer
23b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer/*
24bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King *	All current ColdFire parts contain from 2, 3, 4 or 10 UARTS.
25b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer */
260d2fe946474196e586e492d9e9b381e184c774eaGreg Ungererstatic struct mcf_platform_uart mcf_uart_platform_data[] = {
270d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer	{
280d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer		.mapbase	= MCFUART_BASE0,
290d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer		.irq		= MCF_IRQ_UART0,
300d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer	},
310d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer	{
320d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer		.mapbase	= MCFUART_BASE1,
330d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer		.irq		= MCF_IRQ_UART1,
340d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer	},
350d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer#ifdef MCFUART_BASE2
360d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer	{
370d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer		.mapbase	= MCFUART_BASE2,
380d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer		.irq		= MCF_IRQ_UART2,
390d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer	},
400d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer#endif
410d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer#ifdef MCFUART_BASE3
420d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer	{
430d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer		.mapbase	= MCFUART_BASE3,
440d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer		.irq		= MCF_IRQ_UART3,
450d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer	},
460d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer#endif
47bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King#ifdef MCFUART_BASE4
48bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King	{
49bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King		.mapbase	= MCFUART_BASE4,
50bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King		.irq		= MCF_IRQ_UART4,
51bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King	},
52bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King#endif
53bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King#ifdef MCFUART_BASE5
54bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King	{
55bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King		.mapbase	= MCFUART_BASE5,
56bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King		.irq		= MCF_IRQ_UART5,
57bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King	},
58bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King#endif
59bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King#ifdef MCFUART_BASE6
60bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King	{
61bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King		.mapbase	= MCFUART_BASE6,
62bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King		.irq		= MCF_IRQ_UART6,
63bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King	},
64bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King#endif
65bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King#ifdef MCFUART_BASE7
66bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King	{
67bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King		.mapbase	= MCFUART_BASE7,
68bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King		.irq		= MCF_IRQ_UART7,
69bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King	},
70bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King#endif
71bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King#ifdef MCFUART_BASE8
72bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King	{
73bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King		.mapbase	= MCFUART_BASE8,
74bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King		.irq		= MCF_IRQ_UART8,
75bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King	},
76bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King#endif
77bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King#ifdef MCFUART_BASE9
78bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King	{
79bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King		.mapbase	= MCFUART_BASE9,
80bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King		.irq		= MCF_IRQ_UART9,
81bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King	},
82bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King#endif
830d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer	{ },
840d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer};
850d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer
860d2fe946474196e586e492d9e9b381e184c774eaGreg Ungererstatic struct platform_device mcf_uart = {
870d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer	.name			= "mcfuart",
880d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer	.id			= 0,
890d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer	.dev.platform_data	= mcf_uart_platform_data,
900d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer};
910d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer
92b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer#ifdef CONFIG_FEC
93bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King
94bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King#ifdef CONFIG_M5441x
95bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King#define FEC_NAME	"enet-fec"
96bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven Kingstatic struct fec_platform_data fec_pdata = {
97bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King	.phy		= PHY_INTERFACE_MODE_RMII,
98bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King};
99bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King#define FEC_PDATA	(&fec_pdata)
100bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King#else
101bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King#define FEC_NAME	"fec"
102bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King#define FEC_PDATA	NULL
103bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King#endif
104bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King
105b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer/*
106b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer *	Some ColdFire cores contain the Fast Ethernet Controller (FEC)
107b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer *	block. It is Freescale's own hardware block. Some ColdFires
108b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer *	have 2 of these.
109b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer */
110b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungererstatic struct resource mcf_fec0_resources[] = {
111b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer	{
112b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer		.start		= MCFFEC_BASE0,
113b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer		.end		= MCFFEC_BASE0 + MCFFEC_SIZE0 - 1,
114b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer		.flags		= IORESOURCE_MEM,
115b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer	},
116b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer	{
117b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer		.start		= MCF_IRQ_FECRX0,
118b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer		.end		= MCF_IRQ_FECRX0,
119b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer		.flags		= IORESOURCE_IRQ,
120b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer	},
121b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer	{
122b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer		.start		= MCF_IRQ_FECTX0,
123b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer		.end		= MCF_IRQ_FECTX0,
124b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer		.flags		= IORESOURCE_IRQ,
125b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer	},
126b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer	{
127b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer		.start		= MCF_IRQ_FECENTC0,
128b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer		.end		= MCF_IRQ_FECENTC0,
129b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer		.flags		= IORESOURCE_IRQ,
130b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer	},
131b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer};
132b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer
133b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungererstatic struct platform_device mcf_fec0 = {
134bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King	.name			= FEC_NAME,
135b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer	.id			= 0,
136b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer	.num_resources		= ARRAY_SIZE(mcf_fec0_resources),
137b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer	.resource		= mcf_fec0_resources,
138bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King	.dev.platform_data	= FEC_PDATA,
139b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer};
140b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer
141b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer#ifdef MCFFEC_BASE1
142b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungererstatic struct resource mcf_fec1_resources[] = {
143b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer	{
144b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer		.start		= MCFFEC_BASE1,
145b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer		.end		= MCFFEC_BASE1 + MCFFEC_SIZE1 - 1,
146b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer		.flags		= IORESOURCE_MEM,
147b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer	},
148b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer	{
149b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer		.start		= MCF_IRQ_FECRX1,
150b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer		.end		= MCF_IRQ_FECRX1,
151b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer		.flags		= IORESOURCE_IRQ,
152b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer	},
153b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer	{
154b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer		.start		= MCF_IRQ_FECTX1,
155b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer		.end		= MCF_IRQ_FECTX1,
156b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer		.flags		= IORESOURCE_IRQ,
157b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer	},
158b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer	{
159b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer		.start		= MCF_IRQ_FECENTC1,
160b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer		.end		= MCF_IRQ_FECENTC1,
161b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer		.flags		= IORESOURCE_IRQ,
162b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer	},
163b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer};
164b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer
165b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungererstatic struct platform_device mcf_fec1 = {
166bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King	.name			= FEC_NAME,
167bfdd769ac51cb68cb99902192fac81bc67cb23b0Greg Ungerer	.id			= 1,
168b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer	.num_resources		= ARRAY_SIZE(mcf_fec1_resources),
169b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer	.resource		= mcf_fec1_resources,
170bea8bcb12da09bd35cdada395d0d0db1aee2ba4cSteven King	.dev.platform_data	= FEC_PDATA,
171b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer};
172b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer#endif /* MCFFEC_BASE1 */
173b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer#endif /* CONFIG_FEC */
174b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer
17583ca60094e5e907b8b43c60b4c29b1119604cbb8Steven King#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
176fa1fc24662d57170259948314b0759376eb75777Greg Ungerer/*
177fa1fc24662d57170259948314b0759376eb75777Greg Ungerer *	The ColdFire QSPI module is an SPI protocol hardware block used
178fa1fc24662d57170259948314b0759376eb75777Greg Ungerer *	on a number of different ColdFire CPUs.
179fa1fc24662d57170259948314b0759376eb75777Greg Ungerer */
180fa1fc24662d57170259948314b0759376eb75777Greg Ungererstatic struct resource mcf_qspi_resources[] = {
181fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	{
182fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		.start		= MCFQSPI_BASE,
183fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		.end		= MCFQSPI_BASE + MCFQSPI_SIZE - 1,
184fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		.flags		= IORESOURCE_MEM,
185fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	},
186fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	{
187fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		.start		= MCF_IRQ_QSPI,
188fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		.end		= MCF_IRQ_QSPI,
189fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		.flags		= IORESOURCE_IRQ,
190fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	},
191fa1fc24662d57170259948314b0759376eb75777Greg Ungerer};
192fa1fc24662d57170259948314b0759376eb75777Greg Ungerer
193fa1fc24662d57170259948314b0759376eb75777Greg Ungererstatic int mcf_cs_setup(struct mcfqspi_cs_control *cs_control)
194fa1fc24662d57170259948314b0759376eb75777Greg Ungerer{
195fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	int status;
196fa1fc24662d57170259948314b0759376eb75777Greg Ungerer
197fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
198fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	if (status) {
199fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
200fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		goto fail0;
201fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	}
202fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	status = gpio_direction_output(MCFQSPI_CS0, 1);
203fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	if (status) {
204fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
205fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		goto fail1;
206fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	}
207fa1fc24662d57170259948314b0759376eb75777Greg Ungerer
208fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
209fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	if (status) {
210fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
211fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		goto fail1;
212fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	}
213fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	status = gpio_direction_output(MCFQSPI_CS1, 1);
214fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	if (status) {
215fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
216fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		goto fail2;
217fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	}
218fa1fc24662d57170259948314b0759376eb75777Greg Ungerer
219fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
220fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	if (status) {
221fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
222fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		goto fail2;
223fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	}
224fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	status = gpio_direction_output(MCFQSPI_CS2, 1);
225fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	if (status) {
226fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
227fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		goto fail3;
228fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	}
229fa1fc24662d57170259948314b0759376eb75777Greg Ungerer
230fa1fc24662d57170259948314b0759376eb75777Greg Ungerer#ifdef MCFQSPI_CS3
231fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
232fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	if (status) {
233fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
234fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		goto fail3;
235fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	}
236fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	status = gpio_direction_output(MCFQSPI_CS3, 1);
237fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	if (status) {
238fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
239fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		gpio_free(MCFQSPI_CS3);
240fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		goto fail3;
241fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	}
242fa1fc24662d57170259948314b0759376eb75777Greg Ungerer#endif
243fa1fc24662d57170259948314b0759376eb75777Greg Ungerer
244fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	return 0;
245fa1fc24662d57170259948314b0759376eb75777Greg Ungerer
246fa1fc24662d57170259948314b0759376eb75777Greg Ungererfail3:
247fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	gpio_free(MCFQSPI_CS2);
248fa1fc24662d57170259948314b0759376eb75777Greg Ungererfail2:
249fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	gpio_free(MCFQSPI_CS1);
250fa1fc24662d57170259948314b0759376eb75777Greg Ungererfail1:
251fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	gpio_free(MCFQSPI_CS0);
252fa1fc24662d57170259948314b0759376eb75777Greg Ungererfail0:
253fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	return status;
254fa1fc24662d57170259948314b0759376eb75777Greg Ungerer}
255fa1fc24662d57170259948314b0759376eb75777Greg Ungerer
256fa1fc24662d57170259948314b0759376eb75777Greg Ungererstatic void mcf_cs_teardown(struct mcfqspi_cs_control *cs_control)
257fa1fc24662d57170259948314b0759376eb75777Greg Ungerer{
258fa1fc24662d57170259948314b0759376eb75777Greg Ungerer#ifdef MCFQSPI_CS3
259fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	gpio_free(MCFQSPI_CS3);
260fa1fc24662d57170259948314b0759376eb75777Greg Ungerer#endif
261fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	gpio_free(MCFQSPI_CS2);
262fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	gpio_free(MCFQSPI_CS1);
263fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	gpio_free(MCFQSPI_CS0);
264fa1fc24662d57170259948314b0759376eb75777Greg Ungerer}
265fa1fc24662d57170259948314b0759376eb75777Greg Ungerer
266fa1fc24662d57170259948314b0759376eb75777Greg Ungererstatic void mcf_cs_select(struct mcfqspi_cs_control *cs_control,
267fa1fc24662d57170259948314b0759376eb75777Greg Ungerer			  u8 chip_select, bool cs_high)
268fa1fc24662d57170259948314b0759376eb75777Greg Ungerer{
269fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	switch (chip_select) {
270fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	case 0:
271fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		gpio_set_value(MCFQSPI_CS0, cs_high);
272fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		break;
273fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	case 1:
274fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		gpio_set_value(MCFQSPI_CS1, cs_high);
275fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		break;
276fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	case 2:
277fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		gpio_set_value(MCFQSPI_CS2, cs_high);
278fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		break;
279fa1fc24662d57170259948314b0759376eb75777Greg Ungerer#ifdef MCFQSPI_CS3
280fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	case 3:
281fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		gpio_set_value(MCFQSPI_CS3, cs_high);
282fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		break;
283fa1fc24662d57170259948314b0759376eb75777Greg Ungerer#endif
284fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	}
285fa1fc24662d57170259948314b0759376eb75777Greg Ungerer}
286fa1fc24662d57170259948314b0759376eb75777Greg Ungerer
287fa1fc24662d57170259948314b0759376eb75777Greg Ungererstatic void mcf_cs_deselect(struct mcfqspi_cs_control *cs_control,
288fa1fc24662d57170259948314b0759376eb75777Greg Ungerer			    u8 chip_select, bool cs_high)
289fa1fc24662d57170259948314b0759376eb75777Greg Ungerer{
290fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	switch (chip_select) {
291fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	case 0:
292fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		gpio_set_value(MCFQSPI_CS0, !cs_high);
293fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		break;
294fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	case 1:
295fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		gpio_set_value(MCFQSPI_CS1, !cs_high);
296fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		break;
297fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	case 2:
298fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		gpio_set_value(MCFQSPI_CS2, !cs_high);
299fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		break;
300fa1fc24662d57170259948314b0759376eb75777Greg Ungerer#ifdef MCFQSPI_CS3
301fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	case 3:
302fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		gpio_set_value(MCFQSPI_CS3, !cs_high);
303fa1fc24662d57170259948314b0759376eb75777Greg Ungerer		break;
304fa1fc24662d57170259948314b0759376eb75777Greg Ungerer#endif
305fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	}
306fa1fc24662d57170259948314b0759376eb75777Greg Ungerer}
307fa1fc24662d57170259948314b0759376eb75777Greg Ungerer
308fa1fc24662d57170259948314b0759376eb75777Greg Ungererstatic struct mcfqspi_cs_control mcf_cs_control = {
309fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	.setup			= mcf_cs_setup,
310fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	.teardown		= mcf_cs_teardown,
311fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	.select			= mcf_cs_select,
312fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	.deselect		= mcf_cs_deselect,
313fa1fc24662d57170259948314b0759376eb75777Greg Ungerer};
314fa1fc24662d57170259948314b0759376eb75777Greg Ungerer
315fa1fc24662d57170259948314b0759376eb75777Greg Ungererstatic struct mcfqspi_platform_data mcf_qspi_data = {
316fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	.bus_num		= 0,
317fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	.num_chipselect		= 4,
318fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	.cs_control		= &mcf_cs_control,
319fa1fc24662d57170259948314b0759376eb75777Greg Ungerer};
320fa1fc24662d57170259948314b0759376eb75777Greg Ungerer
321fa1fc24662d57170259948314b0759376eb75777Greg Ungererstatic struct platform_device mcf_qspi = {
322fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	.name			= "mcfqspi",
323fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	.id			= 0,
324fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	.num_resources		= ARRAY_SIZE(mcf_qspi_resources),
325fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	.resource		= mcf_qspi_resources,
326fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	.dev.platform_data	= &mcf_qspi_data,
327fa1fc24662d57170259948314b0759376eb75777Greg Ungerer};
32883ca60094e5e907b8b43c60b4c29b1119604cbb8Steven King#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
329fa1fc24662d57170259948314b0759376eb75777Greg Ungerer
3300d2fe946474196e586e492d9e9b381e184c774eaGreg Ungererstatic struct platform_device *mcf_devices[] __initdata = {
3310d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer	&mcf_uart,
332b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer#ifdef CONFIG_FEC
333b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer	&mcf_fec0,
334b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer#ifdef MCFFEC_BASE1
335b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer	&mcf_fec1,
336b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer#endif
337b7ce7f0d0efc1a95154fa6872d5d7c970d281c71Greg Ungerer#endif
33883ca60094e5e907b8b43c60b4c29b1119604cbb8Steven King#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
339fa1fc24662d57170259948314b0759376eb75777Greg Ungerer	&mcf_qspi,
340fa1fc24662d57170259948314b0759376eb75777Greg Ungerer#endif
3410d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer};
3420d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer
34355148f6f886a1b77dba1a5c3169208606827b9dbGreg Ungerer/*
34455148f6f886a1b77dba1a5c3169208606827b9dbGreg Ungerer *	Some ColdFire UARTs let you set the IRQ line to use.
34555148f6f886a1b77dba1a5c3169208606827b9dbGreg Ungerer */
34655148f6f886a1b77dba1a5c3169208606827b9dbGreg Ungererstatic void __init mcf_uart_set_irq(void)
34755148f6f886a1b77dba1a5c3169208606827b9dbGreg Ungerer{
34855148f6f886a1b77dba1a5c3169208606827b9dbGreg Ungerer#ifdef MCFUART_UIVR
34955148f6f886a1b77dba1a5c3169208606827b9dbGreg Ungerer	/* UART0 interrupt setup */
350c986a3d520395604ca29a7fb9fca60a455abcc44Greg Ungerer	writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCFSIM_UART1ICR);
35155148f6f886a1b77dba1a5c3169208606827b9dbGreg Ungerer	writeb(MCF_IRQ_UART0, MCFUART_BASE0 + MCFUART_UIVR);
35255148f6f886a1b77dba1a5c3169208606827b9dbGreg Ungerer	mcf_mapirq2imr(MCF_IRQ_UART0, MCFINTC_UART0);
35355148f6f886a1b77dba1a5c3169208606827b9dbGreg Ungerer
35455148f6f886a1b77dba1a5c3169208606827b9dbGreg Ungerer	/* UART1 interrupt setup */
355c986a3d520395604ca29a7fb9fca60a455abcc44Greg Ungerer	writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCFSIM_UART2ICR);
35655148f6f886a1b77dba1a5c3169208606827b9dbGreg Ungerer	writeb(MCF_IRQ_UART1, MCFUART_BASE1 + MCFUART_UIVR);
35755148f6f886a1b77dba1a5c3169208606827b9dbGreg Ungerer	mcf_mapirq2imr(MCF_IRQ_UART1, MCFINTC_UART1);
35855148f6f886a1b77dba1a5c3169208606827b9dbGreg Ungerer#endif
35955148f6f886a1b77dba1a5c3169208606827b9dbGreg Ungerer}
36055148f6f886a1b77dba1a5c3169208606827b9dbGreg Ungerer
3610d2fe946474196e586e492d9e9b381e184c774eaGreg Ungererstatic int __init mcf_init_devices(void)
3620d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer{
36355148f6f886a1b77dba1a5c3169208606827b9dbGreg Ungerer	mcf_uart_set_irq();
3640d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer	platform_add_devices(mcf_devices, ARRAY_SIZE(mcf_devices));
3650d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer	return 0;
3660d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer}
3670d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer
3680d2fe946474196e586e492d9e9b381e184c774eaGreg Ungererarch_initcall(mcf_init_devices);
3690d2fe946474196e586e492d9e9b381e184c774eaGreg Ungerer
370