162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * device.c  -- common ColdFire SoC device support
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * (C) Copyright 2011, Greg Ungerer <gerg@uclinux.org>
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
762306a36Sopenharmony_ci * License.  See the file COPYING in the main directory of this archive
862306a36Sopenharmony_ci * for more details.
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <linux/kernel.h>
1262306a36Sopenharmony_ci#include <linux/init.h>
1362306a36Sopenharmony_ci#include <linux/io.h>
1462306a36Sopenharmony_ci#include <linux/spi/spi.h>
1562306a36Sopenharmony_ci#include <linux/gpio.h>
1662306a36Sopenharmony_ci#include <linux/fec.h>
1762306a36Sopenharmony_ci#include <linux/dmaengine.h>
1862306a36Sopenharmony_ci#include <asm/traps.h>
1962306a36Sopenharmony_ci#include <asm/coldfire.h>
2062306a36Sopenharmony_ci#include <asm/mcfsim.h>
2162306a36Sopenharmony_ci#include <asm/mcfuart.h>
2262306a36Sopenharmony_ci#include <asm/mcfqspi.h>
2362306a36Sopenharmony_ci#include <linux/platform_data/edma.h>
2462306a36Sopenharmony_ci#include <linux/platform_data/dma-mcf-edma.h>
2562306a36Sopenharmony_ci#include <linux/platform_data/mmc-esdhc-mcf.h>
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci/*
2862306a36Sopenharmony_ci *	All current ColdFire parts contain from 2, 3, 4 or 10 UARTS.
2962306a36Sopenharmony_ci */
3062306a36Sopenharmony_cistatic struct mcf_platform_uart mcf_uart_platform_data[] = {
3162306a36Sopenharmony_ci	{
3262306a36Sopenharmony_ci		.mapbase	= MCFUART_BASE0,
3362306a36Sopenharmony_ci		.irq		= MCF_IRQ_UART0,
3462306a36Sopenharmony_ci	},
3562306a36Sopenharmony_ci	{
3662306a36Sopenharmony_ci		.mapbase	= MCFUART_BASE1,
3762306a36Sopenharmony_ci		.irq		= MCF_IRQ_UART1,
3862306a36Sopenharmony_ci	},
3962306a36Sopenharmony_ci#ifdef MCFUART_BASE2
4062306a36Sopenharmony_ci	{
4162306a36Sopenharmony_ci		.mapbase	= MCFUART_BASE2,
4262306a36Sopenharmony_ci		.irq		= MCF_IRQ_UART2,
4362306a36Sopenharmony_ci	},
4462306a36Sopenharmony_ci#endif
4562306a36Sopenharmony_ci#ifdef MCFUART_BASE3
4662306a36Sopenharmony_ci	{
4762306a36Sopenharmony_ci		.mapbase	= MCFUART_BASE3,
4862306a36Sopenharmony_ci		.irq		= MCF_IRQ_UART3,
4962306a36Sopenharmony_ci	},
5062306a36Sopenharmony_ci#endif
5162306a36Sopenharmony_ci#ifdef MCFUART_BASE4
5262306a36Sopenharmony_ci	{
5362306a36Sopenharmony_ci		.mapbase	= MCFUART_BASE4,
5462306a36Sopenharmony_ci		.irq		= MCF_IRQ_UART4,
5562306a36Sopenharmony_ci	},
5662306a36Sopenharmony_ci#endif
5762306a36Sopenharmony_ci#ifdef MCFUART_BASE5
5862306a36Sopenharmony_ci	{
5962306a36Sopenharmony_ci		.mapbase	= MCFUART_BASE5,
6062306a36Sopenharmony_ci		.irq		= MCF_IRQ_UART5,
6162306a36Sopenharmony_ci	},
6262306a36Sopenharmony_ci#endif
6362306a36Sopenharmony_ci#ifdef MCFUART_BASE6
6462306a36Sopenharmony_ci	{
6562306a36Sopenharmony_ci		.mapbase	= MCFUART_BASE6,
6662306a36Sopenharmony_ci		.irq		= MCF_IRQ_UART6,
6762306a36Sopenharmony_ci	},
6862306a36Sopenharmony_ci#endif
6962306a36Sopenharmony_ci#ifdef MCFUART_BASE7
7062306a36Sopenharmony_ci	{
7162306a36Sopenharmony_ci		.mapbase	= MCFUART_BASE7,
7262306a36Sopenharmony_ci		.irq		= MCF_IRQ_UART7,
7362306a36Sopenharmony_ci	},
7462306a36Sopenharmony_ci#endif
7562306a36Sopenharmony_ci#ifdef MCFUART_BASE8
7662306a36Sopenharmony_ci	{
7762306a36Sopenharmony_ci		.mapbase	= MCFUART_BASE8,
7862306a36Sopenharmony_ci		.irq		= MCF_IRQ_UART8,
7962306a36Sopenharmony_ci	},
8062306a36Sopenharmony_ci#endif
8162306a36Sopenharmony_ci#ifdef MCFUART_BASE9
8262306a36Sopenharmony_ci	{
8362306a36Sopenharmony_ci		.mapbase	= MCFUART_BASE9,
8462306a36Sopenharmony_ci		.irq		= MCF_IRQ_UART9,
8562306a36Sopenharmony_ci	},
8662306a36Sopenharmony_ci#endif
8762306a36Sopenharmony_ci	{ },
8862306a36Sopenharmony_ci};
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_cistatic struct platform_device mcf_uart = {
9162306a36Sopenharmony_ci	.name			= "mcfuart",
9262306a36Sopenharmony_ci	.id			= 0,
9362306a36Sopenharmony_ci	.dev.platform_data	= mcf_uart_platform_data,
9462306a36Sopenharmony_ci};
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_FEC)
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci#ifdef CONFIG_M5441x
9962306a36Sopenharmony_ci#define FEC_NAME	"enet-fec"
10062306a36Sopenharmony_cistatic struct fec_platform_data fec_pdata = {
10162306a36Sopenharmony_ci	.phy		= PHY_INTERFACE_MODE_RMII,
10262306a36Sopenharmony_ci};
10362306a36Sopenharmony_ci#define FEC_PDATA	(&fec_pdata)
10462306a36Sopenharmony_ci#else
10562306a36Sopenharmony_ci#define FEC_NAME	"fec"
10662306a36Sopenharmony_ci#define FEC_PDATA	NULL
10762306a36Sopenharmony_ci#endif
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci/*
11062306a36Sopenharmony_ci *	Some ColdFire cores contain the Fast Ethernet Controller (FEC)
11162306a36Sopenharmony_ci *	block. It is Freescale's own hardware block. Some ColdFires
11262306a36Sopenharmony_ci *	have 2 of these.
11362306a36Sopenharmony_ci */
11462306a36Sopenharmony_cistatic struct resource mcf_fec0_resources[] = {
11562306a36Sopenharmony_ci	{
11662306a36Sopenharmony_ci		.start		= MCFFEC_BASE0,
11762306a36Sopenharmony_ci		.end		= MCFFEC_BASE0 + MCFFEC_SIZE0 - 1,
11862306a36Sopenharmony_ci		.flags		= IORESOURCE_MEM,
11962306a36Sopenharmony_ci	},
12062306a36Sopenharmony_ci	{
12162306a36Sopenharmony_ci		.start		= MCF_IRQ_FECRX0,
12262306a36Sopenharmony_ci		.end		= MCF_IRQ_FECRX0,
12362306a36Sopenharmony_ci		.flags		= IORESOURCE_IRQ,
12462306a36Sopenharmony_ci	},
12562306a36Sopenharmony_ci	{
12662306a36Sopenharmony_ci		.start		= MCF_IRQ_FECTX0,
12762306a36Sopenharmony_ci		.end		= MCF_IRQ_FECTX0,
12862306a36Sopenharmony_ci		.flags		= IORESOURCE_IRQ,
12962306a36Sopenharmony_ci	},
13062306a36Sopenharmony_ci	{
13162306a36Sopenharmony_ci		.start		= MCF_IRQ_FECENTC0,
13262306a36Sopenharmony_ci		.end		= MCF_IRQ_FECENTC0,
13362306a36Sopenharmony_ci		.flags		= IORESOURCE_IRQ,
13462306a36Sopenharmony_ci	},
13562306a36Sopenharmony_ci};
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_cistatic struct platform_device mcf_fec0 = {
13862306a36Sopenharmony_ci	.name			= FEC_NAME,
13962306a36Sopenharmony_ci	.id			= 0,
14062306a36Sopenharmony_ci	.num_resources		= ARRAY_SIZE(mcf_fec0_resources),
14162306a36Sopenharmony_ci	.resource		= mcf_fec0_resources,
14262306a36Sopenharmony_ci	.dev = {
14362306a36Sopenharmony_ci		.dma_mask		= &mcf_fec0.dev.coherent_dma_mask,
14462306a36Sopenharmony_ci		.coherent_dma_mask	= DMA_BIT_MASK(32),
14562306a36Sopenharmony_ci		.platform_data		= FEC_PDATA,
14662306a36Sopenharmony_ci	}
14762306a36Sopenharmony_ci};
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci#ifdef MCFFEC_BASE1
15062306a36Sopenharmony_cistatic struct resource mcf_fec1_resources[] = {
15162306a36Sopenharmony_ci	{
15262306a36Sopenharmony_ci		.start		= MCFFEC_BASE1,
15362306a36Sopenharmony_ci		.end		= MCFFEC_BASE1 + MCFFEC_SIZE1 - 1,
15462306a36Sopenharmony_ci		.flags		= IORESOURCE_MEM,
15562306a36Sopenharmony_ci	},
15662306a36Sopenharmony_ci	{
15762306a36Sopenharmony_ci		.start		= MCF_IRQ_FECRX1,
15862306a36Sopenharmony_ci		.end		= MCF_IRQ_FECRX1,
15962306a36Sopenharmony_ci		.flags		= IORESOURCE_IRQ,
16062306a36Sopenharmony_ci	},
16162306a36Sopenharmony_ci	{
16262306a36Sopenharmony_ci		.start		= MCF_IRQ_FECTX1,
16362306a36Sopenharmony_ci		.end		= MCF_IRQ_FECTX1,
16462306a36Sopenharmony_ci		.flags		= IORESOURCE_IRQ,
16562306a36Sopenharmony_ci	},
16662306a36Sopenharmony_ci	{
16762306a36Sopenharmony_ci		.start		= MCF_IRQ_FECENTC1,
16862306a36Sopenharmony_ci		.end		= MCF_IRQ_FECENTC1,
16962306a36Sopenharmony_ci		.flags		= IORESOURCE_IRQ,
17062306a36Sopenharmony_ci	},
17162306a36Sopenharmony_ci};
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_cistatic struct platform_device mcf_fec1 = {
17462306a36Sopenharmony_ci	.name			= FEC_NAME,
17562306a36Sopenharmony_ci	.id			= 1,
17662306a36Sopenharmony_ci	.num_resources		= ARRAY_SIZE(mcf_fec1_resources),
17762306a36Sopenharmony_ci	.resource		= mcf_fec1_resources,
17862306a36Sopenharmony_ci	.dev = {
17962306a36Sopenharmony_ci		.dma_mask		= &mcf_fec1.dev.coherent_dma_mask,
18062306a36Sopenharmony_ci		.coherent_dma_mask	= DMA_BIT_MASK(32),
18162306a36Sopenharmony_ci		.platform_data		= FEC_PDATA,
18262306a36Sopenharmony_ci	}
18362306a36Sopenharmony_ci};
18462306a36Sopenharmony_ci#endif /* MCFFEC_BASE1 */
18562306a36Sopenharmony_ci#endif /* CONFIG_FEC */
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
18862306a36Sopenharmony_ci/*
18962306a36Sopenharmony_ci *	The ColdFire QSPI module is an SPI protocol hardware block used
19062306a36Sopenharmony_ci *	on a number of different ColdFire CPUs.
19162306a36Sopenharmony_ci */
19262306a36Sopenharmony_cistatic struct resource mcf_qspi_resources[] = {
19362306a36Sopenharmony_ci	{
19462306a36Sopenharmony_ci		.start		= MCFQSPI_BASE,
19562306a36Sopenharmony_ci		.end		= MCFQSPI_BASE + MCFQSPI_SIZE - 1,
19662306a36Sopenharmony_ci		.flags		= IORESOURCE_MEM,
19762306a36Sopenharmony_ci	},
19862306a36Sopenharmony_ci	{
19962306a36Sopenharmony_ci		.start		= MCF_IRQ_QSPI,
20062306a36Sopenharmony_ci		.end		= MCF_IRQ_QSPI,
20162306a36Sopenharmony_ci		.flags		= IORESOURCE_IRQ,
20262306a36Sopenharmony_ci	},
20362306a36Sopenharmony_ci};
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_cistatic int mcf_cs_setup(struct mcfqspi_cs_control *cs_control)
20662306a36Sopenharmony_ci{
20762306a36Sopenharmony_ci	int status;
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci	status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
21062306a36Sopenharmony_ci	if (status) {
21162306a36Sopenharmony_ci		pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
21262306a36Sopenharmony_ci		goto fail0;
21362306a36Sopenharmony_ci	}
21462306a36Sopenharmony_ci	status = gpio_direction_output(MCFQSPI_CS0, 1);
21562306a36Sopenharmony_ci	if (status) {
21662306a36Sopenharmony_ci		pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
21762306a36Sopenharmony_ci		goto fail1;
21862306a36Sopenharmony_ci	}
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci	status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
22162306a36Sopenharmony_ci	if (status) {
22262306a36Sopenharmony_ci		pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
22362306a36Sopenharmony_ci		goto fail1;
22462306a36Sopenharmony_ci	}
22562306a36Sopenharmony_ci	status = gpio_direction_output(MCFQSPI_CS1, 1);
22662306a36Sopenharmony_ci	if (status) {
22762306a36Sopenharmony_ci		pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
22862306a36Sopenharmony_ci		goto fail2;
22962306a36Sopenharmony_ci	}
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci	status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
23262306a36Sopenharmony_ci	if (status) {
23362306a36Sopenharmony_ci		pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
23462306a36Sopenharmony_ci		goto fail2;
23562306a36Sopenharmony_ci	}
23662306a36Sopenharmony_ci	status = gpio_direction_output(MCFQSPI_CS2, 1);
23762306a36Sopenharmony_ci	if (status) {
23862306a36Sopenharmony_ci		pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
23962306a36Sopenharmony_ci		goto fail3;
24062306a36Sopenharmony_ci	}
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ci#ifdef MCFQSPI_CS3
24362306a36Sopenharmony_ci	status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
24462306a36Sopenharmony_ci	if (status) {
24562306a36Sopenharmony_ci		pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
24662306a36Sopenharmony_ci		goto fail3;
24762306a36Sopenharmony_ci	}
24862306a36Sopenharmony_ci	status = gpio_direction_output(MCFQSPI_CS3, 1);
24962306a36Sopenharmony_ci	if (status) {
25062306a36Sopenharmony_ci		pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
25162306a36Sopenharmony_ci		gpio_free(MCFQSPI_CS3);
25262306a36Sopenharmony_ci		goto fail3;
25362306a36Sopenharmony_ci	}
25462306a36Sopenharmony_ci#endif
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_ci	return 0;
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_cifail3:
25962306a36Sopenharmony_ci	gpio_free(MCFQSPI_CS2);
26062306a36Sopenharmony_cifail2:
26162306a36Sopenharmony_ci	gpio_free(MCFQSPI_CS1);
26262306a36Sopenharmony_cifail1:
26362306a36Sopenharmony_ci	gpio_free(MCFQSPI_CS0);
26462306a36Sopenharmony_cifail0:
26562306a36Sopenharmony_ci	return status;
26662306a36Sopenharmony_ci}
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_cistatic void mcf_cs_teardown(struct mcfqspi_cs_control *cs_control)
26962306a36Sopenharmony_ci{
27062306a36Sopenharmony_ci#ifdef MCFQSPI_CS3
27162306a36Sopenharmony_ci	gpio_free(MCFQSPI_CS3);
27262306a36Sopenharmony_ci#endif
27362306a36Sopenharmony_ci	gpio_free(MCFQSPI_CS2);
27462306a36Sopenharmony_ci	gpio_free(MCFQSPI_CS1);
27562306a36Sopenharmony_ci	gpio_free(MCFQSPI_CS0);
27662306a36Sopenharmony_ci}
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_cistatic void mcf_cs_select(struct mcfqspi_cs_control *cs_control,
27962306a36Sopenharmony_ci			  u8 chip_select, bool cs_high)
28062306a36Sopenharmony_ci{
28162306a36Sopenharmony_ci	switch (chip_select) {
28262306a36Sopenharmony_ci	case 0:
28362306a36Sopenharmony_ci		gpio_set_value(MCFQSPI_CS0, cs_high);
28462306a36Sopenharmony_ci		break;
28562306a36Sopenharmony_ci	case 1:
28662306a36Sopenharmony_ci		gpio_set_value(MCFQSPI_CS1, cs_high);
28762306a36Sopenharmony_ci		break;
28862306a36Sopenharmony_ci	case 2:
28962306a36Sopenharmony_ci		gpio_set_value(MCFQSPI_CS2, cs_high);
29062306a36Sopenharmony_ci		break;
29162306a36Sopenharmony_ci#ifdef MCFQSPI_CS3
29262306a36Sopenharmony_ci	case 3:
29362306a36Sopenharmony_ci		gpio_set_value(MCFQSPI_CS3, cs_high);
29462306a36Sopenharmony_ci		break;
29562306a36Sopenharmony_ci#endif
29662306a36Sopenharmony_ci	}
29762306a36Sopenharmony_ci}
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_cistatic void mcf_cs_deselect(struct mcfqspi_cs_control *cs_control,
30062306a36Sopenharmony_ci			    u8 chip_select, bool cs_high)
30162306a36Sopenharmony_ci{
30262306a36Sopenharmony_ci	switch (chip_select) {
30362306a36Sopenharmony_ci	case 0:
30462306a36Sopenharmony_ci		gpio_set_value(MCFQSPI_CS0, !cs_high);
30562306a36Sopenharmony_ci		break;
30662306a36Sopenharmony_ci	case 1:
30762306a36Sopenharmony_ci		gpio_set_value(MCFQSPI_CS1, !cs_high);
30862306a36Sopenharmony_ci		break;
30962306a36Sopenharmony_ci	case 2:
31062306a36Sopenharmony_ci		gpio_set_value(MCFQSPI_CS2, !cs_high);
31162306a36Sopenharmony_ci		break;
31262306a36Sopenharmony_ci#ifdef MCFQSPI_CS3
31362306a36Sopenharmony_ci	case 3:
31462306a36Sopenharmony_ci		gpio_set_value(MCFQSPI_CS3, !cs_high);
31562306a36Sopenharmony_ci		break;
31662306a36Sopenharmony_ci#endif
31762306a36Sopenharmony_ci	}
31862306a36Sopenharmony_ci}
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_cistatic struct mcfqspi_cs_control mcf_cs_control = {
32162306a36Sopenharmony_ci	.setup			= mcf_cs_setup,
32262306a36Sopenharmony_ci	.teardown		= mcf_cs_teardown,
32362306a36Sopenharmony_ci	.select			= mcf_cs_select,
32462306a36Sopenharmony_ci	.deselect		= mcf_cs_deselect,
32562306a36Sopenharmony_ci};
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_cistatic struct mcfqspi_platform_data mcf_qspi_data = {
32862306a36Sopenharmony_ci	.bus_num		= 0,
32962306a36Sopenharmony_ci	.num_chipselect		= 4,
33062306a36Sopenharmony_ci	.cs_control		= &mcf_cs_control,
33162306a36Sopenharmony_ci};
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_cistatic struct platform_device mcf_qspi = {
33462306a36Sopenharmony_ci	.name			= "mcfqspi",
33562306a36Sopenharmony_ci	.id			= 0,
33662306a36Sopenharmony_ci	.num_resources		= ARRAY_SIZE(mcf_qspi_resources),
33762306a36Sopenharmony_ci	.resource		= mcf_qspi_resources,
33862306a36Sopenharmony_ci	.dev.platform_data	= &mcf_qspi_data,
33962306a36Sopenharmony_ci};
34062306a36Sopenharmony_ci#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_I2C_IMX)
34362306a36Sopenharmony_cistatic struct resource mcf_i2c0_resources[] = {
34462306a36Sopenharmony_ci	{
34562306a36Sopenharmony_ci		.start          = MCFI2C_BASE0,
34662306a36Sopenharmony_ci		.end            = MCFI2C_BASE0 + MCFI2C_SIZE0 - 1,
34762306a36Sopenharmony_ci		.flags          = IORESOURCE_MEM,
34862306a36Sopenharmony_ci	},
34962306a36Sopenharmony_ci	{
35062306a36Sopenharmony_ci		.start          = MCF_IRQ_I2C0,
35162306a36Sopenharmony_ci		.end            = MCF_IRQ_I2C0,
35262306a36Sopenharmony_ci		.flags          = IORESOURCE_IRQ,
35362306a36Sopenharmony_ci	},
35462306a36Sopenharmony_ci};
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_cistatic struct platform_device mcf_i2c0 = {
35762306a36Sopenharmony_ci	.name                   = "imx1-i2c",
35862306a36Sopenharmony_ci	.id                     = 0,
35962306a36Sopenharmony_ci	.num_resources          = ARRAY_SIZE(mcf_i2c0_resources),
36062306a36Sopenharmony_ci	.resource               = mcf_i2c0_resources,
36162306a36Sopenharmony_ci};
36262306a36Sopenharmony_ci#ifdef MCFI2C_BASE1
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_cistatic struct resource mcf_i2c1_resources[] = {
36562306a36Sopenharmony_ci	{
36662306a36Sopenharmony_ci		.start          = MCFI2C_BASE1,
36762306a36Sopenharmony_ci		.end            = MCFI2C_BASE1 + MCFI2C_SIZE1 - 1,
36862306a36Sopenharmony_ci		.flags          = IORESOURCE_MEM,
36962306a36Sopenharmony_ci	},
37062306a36Sopenharmony_ci	{
37162306a36Sopenharmony_ci		.start          = MCF_IRQ_I2C1,
37262306a36Sopenharmony_ci		.end            = MCF_IRQ_I2C1,
37362306a36Sopenharmony_ci		.flags          = IORESOURCE_IRQ,
37462306a36Sopenharmony_ci	},
37562306a36Sopenharmony_ci};
37662306a36Sopenharmony_ci
37762306a36Sopenharmony_cistatic struct platform_device mcf_i2c1 = {
37862306a36Sopenharmony_ci	.name                   = "imx1-i2c",
37962306a36Sopenharmony_ci	.id                     = 1,
38062306a36Sopenharmony_ci	.num_resources          = ARRAY_SIZE(mcf_i2c1_resources),
38162306a36Sopenharmony_ci	.resource               = mcf_i2c1_resources,
38262306a36Sopenharmony_ci};
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_ci#endif /* MCFI2C_BASE1 */
38562306a36Sopenharmony_ci
38662306a36Sopenharmony_ci#ifdef MCFI2C_BASE2
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_cistatic struct resource mcf_i2c2_resources[] = {
38962306a36Sopenharmony_ci	{
39062306a36Sopenharmony_ci		.start          = MCFI2C_BASE2,
39162306a36Sopenharmony_ci		.end            = MCFI2C_BASE2 + MCFI2C_SIZE2 - 1,
39262306a36Sopenharmony_ci		.flags          = IORESOURCE_MEM,
39362306a36Sopenharmony_ci	},
39462306a36Sopenharmony_ci	{
39562306a36Sopenharmony_ci		.start          = MCF_IRQ_I2C2,
39662306a36Sopenharmony_ci		.end            = MCF_IRQ_I2C2,
39762306a36Sopenharmony_ci		.flags          = IORESOURCE_IRQ,
39862306a36Sopenharmony_ci	},
39962306a36Sopenharmony_ci};
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_cistatic struct platform_device mcf_i2c2 = {
40262306a36Sopenharmony_ci	.name                   = "imx1-i2c",
40362306a36Sopenharmony_ci	.id                     = 2,
40462306a36Sopenharmony_ci	.num_resources          = ARRAY_SIZE(mcf_i2c2_resources),
40562306a36Sopenharmony_ci	.resource               = mcf_i2c2_resources,
40662306a36Sopenharmony_ci};
40762306a36Sopenharmony_ci
40862306a36Sopenharmony_ci#endif /* MCFI2C_BASE2 */
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_ci#ifdef MCFI2C_BASE3
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_cistatic struct resource mcf_i2c3_resources[] = {
41362306a36Sopenharmony_ci	{
41462306a36Sopenharmony_ci		.start          = MCFI2C_BASE3,
41562306a36Sopenharmony_ci		.end            = MCFI2C_BASE3 + MCFI2C_SIZE3 - 1,
41662306a36Sopenharmony_ci		.flags          = IORESOURCE_MEM,
41762306a36Sopenharmony_ci	},
41862306a36Sopenharmony_ci	{
41962306a36Sopenharmony_ci		.start          = MCF_IRQ_I2C3,
42062306a36Sopenharmony_ci		.end            = MCF_IRQ_I2C3,
42162306a36Sopenharmony_ci		.flags          = IORESOURCE_IRQ,
42262306a36Sopenharmony_ci	},
42362306a36Sopenharmony_ci};
42462306a36Sopenharmony_ci
42562306a36Sopenharmony_cistatic struct platform_device mcf_i2c3 = {
42662306a36Sopenharmony_ci	.name                   = "imx1-i2c",
42762306a36Sopenharmony_ci	.id                     = 3,
42862306a36Sopenharmony_ci	.num_resources          = ARRAY_SIZE(mcf_i2c3_resources),
42962306a36Sopenharmony_ci	.resource               = mcf_i2c3_resources,
43062306a36Sopenharmony_ci};
43162306a36Sopenharmony_ci
43262306a36Sopenharmony_ci#endif /* MCFI2C_BASE3 */
43362306a36Sopenharmony_ci
43462306a36Sopenharmony_ci#ifdef MCFI2C_BASE4
43562306a36Sopenharmony_ci
43662306a36Sopenharmony_cistatic struct resource mcf_i2c4_resources[] = {
43762306a36Sopenharmony_ci	{
43862306a36Sopenharmony_ci		.start          = MCFI2C_BASE4,
43962306a36Sopenharmony_ci		.end            = MCFI2C_BASE4 + MCFI2C_SIZE4 - 1,
44062306a36Sopenharmony_ci		.flags          = IORESOURCE_MEM,
44162306a36Sopenharmony_ci	},
44262306a36Sopenharmony_ci	{
44362306a36Sopenharmony_ci		.start          = MCF_IRQ_I2C4,
44462306a36Sopenharmony_ci		.end            = MCF_IRQ_I2C4,
44562306a36Sopenharmony_ci		.flags          = IORESOURCE_IRQ,
44662306a36Sopenharmony_ci	},
44762306a36Sopenharmony_ci};
44862306a36Sopenharmony_ci
44962306a36Sopenharmony_cistatic struct platform_device mcf_i2c4 = {
45062306a36Sopenharmony_ci	.name                   = "imx1-i2c",
45162306a36Sopenharmony_ci	.id                     = 4,
45262306a36Sopenharmony_ci	.num_resources          = ARRAY_SIZE(mcf_i2c4_resources),
45362306a36Sopenharmony_ci	.resource               = mcf_i2c4_resources,
45462306a36Sopenharmony_ci};
45562306a36Sopenharmony_ci
45662306a36Sopenharmony_ci#endif /* MCFI2C_BASE4 */
45762306a36Sopenharmony_ci
45862306a36Sopenharmony_ci#ifdef MCFI2C_BASE5
45962306a36Sopenharmony_ci
46062306a36Sopenharmony_cistatic struct resource mcf_i2c5_resources[] = {
46162306a36Sopenharmony_ci	{
46262306a36Sopenharmony_ci		.start          = MCFI2C_BASE5,
46362306a36Sopenharmony_ci		.end            = MCFI2C_BASE5 + MCFI2C_SIZE5 - 1,
46462306a36Sopenharmony_ci		.flags          = IORESOURCE_MEM,
46562306a36Sopenharmony_ci	},
46662306a36Sopenharmony_ci	{
46762306a36Sopenharmony_ci		.start          = MCF_IRQ_I2C5,
46862306a36Sopenharmony_ci		.end            = MCF_IRQ_I2C5,
46962306a36Sopenharmony_ci		.flags          = IORESOURCE_IRQ,
47062306a36Sopenharmony_ci	},
47162306a36Sopenharmony_ci};
47262306a36Sopenharmony_ci
47362306a36Sopenharmony_cistatic struct platform_device mcf_i2c5 = {
47462306a36Sopenharmony_ci	.name                   = "imx1-i2c",
47562306a36Sopenharmony_ci	.id                     = 5,
47662306a36Sopenharmony_ci	.num_resources          = ARRAY_SIZE(mcf_i2c5_resources),
47762306a36Sopenharmony_ci	.resource               = mcf_i2c5_resources,
47862306a36Sopenharmony_ci};
47962306a36Sopenharmony_ci
48062306a36Sopenharmony_ci#endif /* MCFI2C_BASE5 */
48162306a36Sopenharmony_ci#endif /* IS_ENABLED(CONFIG_I2C_IMX) */
48262306a36Sopenharmony_ci
48362306a36Sopenharmony_ci#ifdef MCFEDMA_BASE
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_cistatic const struct dma_slave_map mcf_edma_map[] = {
48662306a36Sopenharmony_ci	{ "dreq0", "rx-tx", MCF_EDMA_FILTER_PARAM(0) },
48762306a36Sopenharmony_ci	{ "dreq1", "rx-tx", MCF_EDMA_FILTER_PARAM(1) },
48862306a36Sopenharmony_ci	{ "uart.0", "rx", MCF_EDMA_FILTER_PARAM(2) },
48962306a36Sopenharmony_ci	{ "uart.0", "tx", MCF_EDMA_FILTER_PARAM(3) },
49062306a36Sopenharmony_ci	{ "uart.1", "rx", MCF_EDMA_FILTER_PARAM(4) },
49162306a36Sopenharmony_ci	{ "uart.1", "tx", MCF_EDMA_FILTER_PARAM(5) },
49262306a36Sopenharmony_ci	{ "uart.2", "rx", MCF_EDMA_FILTER_PARAM(6) },
49362306a36Sopenharmony_ci	{ "uart.2", "tx", MCF_EDMA_FILTER_PARAM(7) },
49462306a36Sopenharmony_ci	{ "timer0", "rx-tx", MCF_EDMA_FILTER_PARAM(8) },
49562306a36Sopenharmony_ci	{ "timer1", "rx-tx", MCF_EDMA_FILTER_PARAM(9) },
49662306a36Sopenharmony_ci	{ "timer2", "rx-tx", MCF_EDMA_FILTER_PARAM(10) },
49762306a36Sopenharmony_ci	{ "timer3", "rx-tx", MCF_EDMA_FILTER_PARAM(11) },
49862306a36Sopenharmony_ci	{ "fsl-dspi.0", "rx", MCF_EDMA_FILTER_PARAM(12) },
49962306a36Sopenharmony_ci	{ "fsl-dspi.0", "tx", MCF_EDMA_FILTER_PARAM(13) },
50062306a36Sopenharmony_ci	{ "fsl-dspi.1", "rx", MCF_EDMA_FILTER_PARAM(14) },
50162306a36Sopenharmony_ci	{ "fsl-dspi.1", "tx", MCF_EDMA_FILTER_PARAM(15) },
50262306a36Sopenharmony_ci};
50362306a36Sopenharmony_ci
50462306a36Sopenharmony_cistatic struct mcf_edma_platform_data mcf_edma_data = {
50562306a36Sopenharmony_ci	.dma_channels		= 64,
50662306a36Sopenharmony_ci	.slave_map		= mcf_edma_map,
50762306a36Sopenharmony_ci	.slavecnt		= ARRAY_SIZE(mcf_edma_map),
50862306a36Sopenharmony_ci};
50962306a36Sopenharmony_ci
51062306a36Sopenharmony_cistatic struct resource mcf_edma_resources[] = {
51162306a36Sopenharmony_ci	{
51262306a36Sopenharmony_ci		.start		= MCFEDMA_BASE,
51362306a36Sopenharmony_ci		.end		= MCFEDMA_BASE + MCFEDMA_SIZE - 1,
51462306a36Sopenharmony_ci		.flags		= IORESOURCE_MEM,
51562306a36Sopenharmony_ci	},
51662306a36Sopenharmony_ci	{
51762306a36Sopenharmony_ci		.start		= MCFEDMA_IRQ_INTR0,
51862306a36Sopenharmony_ci		.end		= MCFEDMA_IRQ_INTR0 + 15,
51962306a36Sopenharmony_ci		.flags		= IORESOURCE_IRQ,
52062306a36Sopenharmony_ci		.name		= "edma-tx-00-15",
52162306a36Sopenharmony_ci	},
52262306a36Sopenharmony_ci	{
52362306a36Sopenharmony_ci		.start		= MCFEDMA_IRQ_INTR16,
52462306a36Sopenharmony_ci		.end		= MCFEDMA_IRQ_INTR16 + 39,
52562306a36Sopenharmony_ci		.flags		= IORESOURCE_IRQ,
52662306a36Sopenharmony_ci		.name		= "edma-tx-16-55",
52762306a36Sopenharmony_ci	},
52862306a36Sopenharmony_ci	{
52962306a36Sopenharmony_ci		.start		= MCFEDMA_IRQ_INTR56,
53062306a36Sopenharmony_ci		.end		= MCFEDMA_IRQ_INTR56,
53162306a36Sopenharmony_ci		.flags		= IORESOURCE_IRQ,
53262306a36Sopenharmony_ci		.name		= "edma-tx-56-63",
53362306a36Sopenharmony_ci	},
53462306a36Sopenharmony_ci	{
53562306a36Sopenharmony_ci		.start		= MCFEDMA_IRQ_ERR,
53662306a36Sopenharmony_ci		.end		= MCFEDMA_IRQ_ERR,
53762306a36Sopenharmony_ci		.flags		= IORESOURCE_IRQ,
53862306a36Sopenharmony_ci		.name		= "edma-err",
53962306a36Sopenharmony_ci	},
54062306a36Sopenharmony_ci};
54162306a36Sopenharmony_ci
54262306a36Sopenharmony_cistatic u64 mcf_edma_dmamask = DMA_BIT_MASK(32);
54362306a36Sopenharmony_ci
54462306a36Sopenharmony_cistatic struct platform_device mcf_edma = {
54562306a36Sopenharmony_ci	.name			= "mcf-edma",
54662306a36Sopenharmony_ci	.id			= 0,
54762306a36Sopenharmony_ci	.num_resources		= ARRAY_SIZE(mcf_edma_resources),
54862306a36Sopenharmony_ci	.resource		= mcf_edma_resources,
54962306a36Sopenharmony_ci	.dev = {
55062306a36Sopenharmony_ci		.dma_mask = &mcf_edma_dmamask,
55162306a36Sopenharmony_ci		.coherent_dma_mask = DMA_BIT_MASK(32),
55262306a36Sopenharmony_ci		.platform_data = &mcf_edma_data,
55362306a36Sopenharmony_ci	}
55462306a36Sopenharmony_ci};
55562306a36Sopenharmony_ci#endif /* MCFEDMA_BASE */
55662306a36Sopenharmony_ci
55762306a36Sopenharmony_ci#ifdef MCFSDHC_BASE
55862306a36Sopenharmony_cistatic struct mcf_esdhc_platform_data mcf_esdhc_data = {
55962306a36Sopenharmony_ci	.max_bus_width = 4,
56062306a36Sopenharmony_ci	.cd_type = ESDHC_CD_NONE,
56162306a36Sopenharmony_ci};
56262306a36Sopenharmony_ci
56362306a36Sopenharmony_cistatic struct resource mcf_esdhc_resources[] = {
56462306a36Sopenharmony_ci	{
56562306a36Sopenharmony_ci		.start = MCFSDHC_BASE,
56662306a36Sopenharmony_ci		.end = MCFSDHC_BASE + MCFSDHC_SIZE - 1,
56762306a36Sopenharmony_ci		.flags = IORESOURCE_MEM,
56862306a36Sopenharmony_ci	}, {
56962306a36Sopenharmony_ci		.start = MCF_IRQ_SDHC,
57062306a36Sopenharmony_ci		.end = MCF_IRQ_SDHC,
57162306a36Sopenharmony_ci		.flags = IORESOURCE_IRQ,
57262306a36Sopenharmony_ci	},
57362306a36Sopenharmony_ci};
57462306a36Sopenharmony_ci
57562306a36Sopenharmony_cistatic struct platform_device mcf_esdhc = {
57662306a36Sopenharmony_ci	.name			= "sdhci-esdhc-mcf",
57762306a36Sopenharmony_ci	.id			= 0,
57862306a36Sopenharmony_ci	.num_resources		= ARRAY_SIZE(mcf_esdhc_resources),
57962306a36Sopenharmony_ci	.resource		= mcf_esdhc_resources,
58062306a36Sopenharmony_ci	.dev.platform_data	= &mcf_esdhc_data,
58162306a36Sopenharmony_ci};
58262306a36Sopenharmony_ci#endif /* MCFSDHC_BASE */
58362306a36Sopenharmony_ci
58462306a36Sopenharmony_ci#ifdef MCFFLEXCAN_SIZE
58562306a36Sopenharmony_ci
58662306a36Sopenharmony_ci#include <linux/can/platform/flexcan.h>
58762306a36Sopenharmony_ci
58862306a36Sopenharmony_cistatic struct flexcan_platform_data mcf5441x_flexcan_info = {
58962306a36Sopenharmony_ci	.clk_src = 1,
59062306a36Sopenharmony_ci	.clock_frequency = 120000000,
59162306a36Sopenharmony_ci};
59262306a36Sopenharmony_ci
59362306a36Sopenharmony_cistatic struct resource mcf5441x_flexcan0_resource[] = {
59462306a36Sopenharmony_ci	{
59562306a36Sopenharmony_ci		.start = MCFFLEXCAN_BASE0,
59662306a36Sopenharmony_ci		.end = MCFFLEXCAN_BASE0 + MCFFLEXCAN_SIZE,
59762306a36Sopenharmony_ci		.flags = IORESOURCE_MEM,
59862306a36Sopenharmony_ci	},
59962306a36Sopenharmony_ci	{
60062306a36Sopenharmony_ci		.start = MCF_IRQ_IFL0,
60162306a36Sopenharmony_ci		.end = MCF_IRQ_IFL0,
60262306a36Sopenharmony_ci		.flags = IORESOURCE_IRQ,
60362306a36Sopenharmony_ci	},
60462306a36Sopenharmony_ci	{
60562306a36Sopenharmony_ci		.start = MCF_IRQ_BOFF0,
60662306a36Sopenharmony_ci		.end = MCF_IRQ_BOFF0,
60762306a36Sopenharmony_ci		.flags = IORESOURCE_IRQ,
60862306a36Sopenharmony_ci	},
60962306a36Sopenharmony_ci	{
61062306a36Sopenharmony_ci		.start = MCF_IRQ_ERR0,
61162306a36Sopenharmony_ci		.end = MCF_IRQ_ERR0,
61262306a36Sopenharmony_ci		.flags = IORESOURCE_IRQ,
61362306a36Sopenharmony_ci	},
61462306a36Sopenharmony_ci};
61562306a36Sopenharmony_ci
61662306a36Sopenharmony_cistatic struct platform_device mcf_flexcan0 = {
61762306a36Sopenharmony_ci	.name = "flexcan-mcf5441x",
61862306a36Sopenharmony_ci	.id = 0,
61962306a36Sopenharmony_ci	.num_resources = ARRAY_SIZE(mcf5441x_flexcan0_resource),
62062306a36Sopenharmony_ci	.resource = mcf5441x_flexcan0_resource,
62162306a36Sopenharmony_ci	.dev.platform_data = &mcf5441x_flexcan_info,
62262306a36Sopenharmony_ci};
62362306a36Sopenharmony_ci#endif /* MCFFLEXCAN_SIZE */
62462306a36Sopenharmony_ci
62562306a36Sopenharmony_cistatic struct platform_device *mcf_devices[] __initdata = {
62662306a36Sopenharmony_ci	&mcf_uart,
62762306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_FEC)
62862306a36Sopenharmony_ci	&mcf_fec0,
62962306a36Sopenharmony_ci#ifdef MCFFEC_BASE1
63062306a36Sopenharmony_ci	&mcf_fec1,
63162306a36Sopenharmony_ci#endif
63262306a36Sopenharmony_ci#endif
63362306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
63462306a36Sopenharmony_ci	&mcf_qspi,
63562306a36Sopenharmony_ci#endif
63662306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_I2C_IMX)
63762306a36Sopenharmony_ci	&mcf_i2c0,
63862306a36Sopenharmony_ci#ifdef MCFI2C_BASE1
63962306a36Sopenharmony_ci	&mcf_i2c1,
64062306a36Sopenharmony_ci#endif
64162306a36Sopenharmony_ci#ifdef MCFI2C_BASE2
64262306a36Sopenharmony_ci	&mcf_i2c2,
64362306a36Sopenharmony_ci#endif
64462306a36Sopenharmony_ci#ifdef MCFI2C_BASE3
64562306a36Sopenharmony_ci	&mcf_i2c3,
64662306a36Sopenharmony_ci#endif
64762306a36Sopenharmony_ci#ifdef MCFI2C_BASE4
64862306a36Sopenharmony_ci	&mcf_i2c4,
64962306a36Sopenharmony_ci#endif
65062306a36Sopenharmony_ci#ifdef MCFI2C_BASE5
65162306a36Sopenharmony_ci	&mcf_i2c5,
65262306a36Sopenharmony_ci#endif
65362306a36Sopenharmony_ci#endif
65462306a36Sopenharmony_ci#ifdef MCFEDMA_BASE
65562306a36Sopenharmony_ci	&mcf_edma,
65662306a36Sopenharmony_ci#endif
65762306a36Sopenharmony_ci#ifdef MCFSDHC_BASE
65862306a36Sopenharmony_ci	&mcf_esdhc,
65962306a36Sopenharmony_ci#endif
66062306a36Sopenharmony_ci#ifdef MCFFLEXCAN_SIZE
66162306a36Sopenharmony_ci	&mcf_flexcan0,
66262306a36Sopenharmony_ci#endif
66362306a36Sopenharmony_ci};
66462306a36Sopenharmony_ci
66562306a36Sopenharmony_ci/*
66662306a36Sopenharmony_ci *	Some ColdFire UARTs let you set the IRQ line to use.
66762306a36Sopenharmony_ci */
66862306a36Sopenharmony_cistatic void __init mcf_uart_set_irq(void)
66962306a36Sopenharmony_ci{
67062306a36Sopenharmony_ci#ifdef MCFUART_UIVR
67162306a36Sopenharmony_ci	/* UART0 interrupt setup */
67262306a36Sopenharmony_ci	writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCFSIM_UART1ICR);
67362306a36Sopenharmony_ci	writeb(MCF_IRQ_UART0, MCFUART_BASE0 + MCFUART_UIVR);
67462306a36Sopenharmony_ci	mcf_mapirq2imr(MCF_IRQ_UART0, MCFINTC_UART0);
67562306a36Sopenharmony_ci
67662306a36Sopenharmony_ci	/* UART1 interrupt setup */
67762306a36Sopenharmony_ci	writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCFSIM_UART2ICR);
67862306a36Sopenharmony_ci	writeb(MCF_IRQ_UART1, MCFUART_BASE1 + MCFUART_UIVR);
67962306a36Sopenharmony_ci	mcf_mapirq2imr(MCF_IRQ_UART1, MCFINTC_UART1);
68062306a36Sopenharmony_ci#endif
68162306a36Sopenharmony_ci}
68262306a36Sopenharmony_ci
68362306a36Sopenharmony_cistatic int __init mcf_init_devices(void)
68462306a36Sopenharmony_ci{
68562306a36Sopenharmony_ci	mcf_uart_set_irq();
68662306a36Sopenharmony_ci	platform_add_devices(mcf_devices, ARRAY_SIZE(mcf_devices));
68762306a36Sopenharmony_ci	return 0;
68862306a36Sopenharmony_ci}
68962306a36Sopenharmony_ci
69062306a36Sopenharmony_ciarch_initcall(mcf_init_devices);
691