diff options
Diffstat (limited to 'arch/m68knommu/platform')
-rw-r--r-- | arch/m68knommu/platform/520x/config.c | 149 | ||||
-rw-r--r-- | arch/m68knommu/platform/523x/config.c | 170 | ||||
-rw-r--r-- | arch/m68knommu/platform/5249/config.c | 215 | ||||
-rw-r--r-- | arch/m68knommu/platform/527x/config.c | 182 | ||||
-rw-r--r-- | arch/m68knommu/platform/528x/config.c | 137 | ||||
-rw-r--r-- | arch/m68knommu/platform/5307/Makefile | 4 | ||||
-rw-r--r-- | arch/m68knommu/platform/5307/nettel.c | 153 | ||||
-rw-r--r-- | arch/m68knommu/platform/532x/config.c | 124 | ||||
-rw-r--r-- | arch/m68knommu/platform/68360/commproc.c | 4 |
9 files changed, 1135 insertions, 3 deletions
diff --git a/arch/m68knommu/platform/520x/config.c b/arch/m68knommu/platform/520x/config.c index 92614de42cd..71d2ba474c6 100644 --- a/arch/m68knommu/platform/520x/config.c +++ b/arch/m68knommu/platform/520x/config.c @@ -15,10 +15,13 @@ #include <linux/param.h> #include <linux/init.h> #include <linux/io.h> +#include <linux/spi/spi.h> +#include <linux/gpio.h> #include <asm/machdep.h> #include <asm/coldfire.h> #include <asm/mcfsim.h> #include <asm/mcfuart.h> +#include <asm/mcfqspi.h> /***************************************************************************/ @@ -74,9 +77,152 @@ static struct platform_device m520x_fec = { .resource = m520x_fec_resources, }; +#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) +static struct resource m520x_qspi_resources[] = { + { + .start = MCFQSPI_IOBASE, + .end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = MCFINT_VECBASE + MCFINT_QSPI, + .end = MCFINT_VECBASE + MCFINT_QSPI, + .flags = IORESOURCE_IRQ, + }, +}; + +#define MCFQSPI_CS0 62 +#define MCFQSPI_CS1 63 +#define MCFQSPI_CS2 44 + +static int m520x_cs_setup(struct mcfqspi_cs_control *cs_control) +{ + int status; + + status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0"); + if (status) { + pr_debug("gpio_request for MCFQSPI_CS0 failed\n"); + goto fail0; + } + status = gpio_direction_output(MCFQSPI_CS0, 1); + if (status) { + pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n"); + goto fail1; + } + + status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1"); + if (status) { + pr_debug("gpio_request for MCFQSPI_CS1 failed\n"); + goto fail1; + } + status = gpio_direction_output(MCFQSPI_CS1, 1); + if (status) { + pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n"); + goto fail2; + } + + status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2"); + if (status) { + pr_debug("gpio_request for MCFQSPI_CS2 failed\n"); + goto fail2; + } + status = gpio_direction_output(MCFQSPI_CS2, 1); + if (status) { + pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n"); + goto fail3; + } + + return 0; + +fail3: + gpio_free(MCFQSPI_CS2); +fail2: + gpio_free(MCFQSPI_CS1); +fail1: + gpio_free(MCFQSPI_CS0); +fail0: + return status; +} + +static void m520x_cs_teardown(struct mcfqspi_cs_control *cs_control) +{ + gpio_free(MCFQSPI_CS2); + gpio_free(MCFQSPI_CS1); + gpio_free(MCFQSPI_CS0); +} + +static void m520x_cs_select(struct mcfqspi_cs_control *cs_control, + u8 chip_select, bool cs_high) +{ + switch (chip_select) { + case 0: + gpio_set_value(MCFQSPI_CS0, cs_high); + break; + case 1: + gpio_set_value(MCFQSPI_CS1, cs_high); + break; + case 2: + gpio_set_value(MCFQSPI_CS2, cs_high); + break; + } +} + +static void m520x_cs_deselect(struct mcfqspi_cs_control *cs_control, + u8 chip_select, bool cs_high) +{ + switch (chip_select) { + case 0: + gpio_set_value(MCFQSPI_CS0, !cs_high); + break; + case 1: + gpio_set_value(MCFQSPI_CS1, !cs_high); + break; + case 2: + gpio_set_value(MCFQSPI_CS2, !cs_high); + break; + } +} + +static struct mcfqspi_cs_control m520x_cs_control = { + .setup = m520x_cs_setup, + .teardown = m520x_cs_teardown, + .select = m520x_cs_select, + .deselect = m520x_cs_deselect, +}; + +static struct mcfqspi_platform_data m520x_qspi_data = { + .bus_num = 0, + .num_chipselect = 3, + .cs_control = &m520x_cs_control, +}; + +static struct platform_device m520x_qspi = { + .name = "mcfqspi", + .id = 0, + .num_resources = ARRAY_SIZE(m520x_qspi_resources), + .resource = m520x_qspi_resources, + .dev.platform_data = &m520x_qspi_data, +}; + +static void __init m520x_qspi_init(void) +{ + u16 par; + /* setup Port QS for QSPI with gpio CS control */ + writeb(0x3f, MCF_IPSBAR + MCF_GPIO_PAR_QSPI); + /* make U1CTS and U2RTS gpio for cs_control */ + par = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART); + par &= 0x00ff; + writew(par, MCF_IPSBAR + MCF_GPIO_PAR_UART); +} +#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */ + + static struct platform_device *m520x_devices[] __initdata = { &m520x_uart, &m520x_fec, +#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) + &m520x_qspi, +#endif }; /***************************************************************************/ @@ -147,6 +293,9 @@ void __init config_BSP(char *commandp, int size) mach_reset = m520x_cpu_reset; m520x_uarts_init(); m520x_fec_init(); +#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) + m520x_qspi_init(); +#endif } /***************************************************************************/ diff --git a/arch/m68knommu/platform/523x/config.c b/arch/m68knommu/platform/523x/config.c index 6ba84f2aa39..8980f6d7715 100644 --- a/arch/m68knommu/platform/523x/config.c +++ b/arch/m68knommu/platform/523x/config.c @@ -16,10 +16,13 @@ #include <linux/param.h> #include <linux/init.h> #include <linux/io.h> +#include <linux/spi/spi.h> +#include <linux/gpio.h> #include <asm/machdep.h> #include <asm/coldfire.h> #include <asm/mcfsim.h> #include <asm/mcfuart.h> +#include <asm/mcfqspi.h> /***************************************************************************/ @@ -75,9 +78,173 @@ static struct platform_device m523x_fec = { .resource = m523x_fec_resources, }; +#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) +static struct resource m523x_qspi_resources[] = { + { + .start = MCFQSPI_IOBASE, + .end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = MCFINT_VECBASE + MCFINT_QSPI, + .end = MCFINT_VECBASE + MCFINT_QSPI, + .flags = IORESOURCE_IRQ, + }, +}; + +#define MCFQSPI_CS0 91 +#define MCFQSPI_CS1 92 +#define MCFQSPI_CS2 103 +#define MCFQSPI_CS3 99 + +static int m523x_cs_setup(struct mcfqspi_cs_control *cs_control) +{ + int status; + + status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0"); + if (status) { + pr_debug("gpio_request for MCFQSPI_CS0 failed\n"); + goto fail0; + } + status = gpio_direction_output(MCFQSPI_CS0, 1); + if (status) { + pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n"); + goto fail1; + } + + status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1"); + if (status) { + pr_debug("gpio_request for MCFQSPI_CS1 failed\n"); + goto fail1; + } + status = gpio_direction_output(MCFQSPI_CS1, 1); + if (status) { + pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n"); + goto fail2; + } + + status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2"); + if (status) { + pr_debug("gpio_request for MCFQSPI_CS2 failed\n"); + goto fail2; + } + status = gpio_direction_output(MCFQSPI_CS2, 1); + if (status) { + pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n"); + goto fail3; + } + + status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3"); + if (status) { + pr_debug("gpio_request for MCFQSPI_CS3 failed\n"); + goto fail3; + } + status = gpio_direction_output(MCFQSPI_CS3, 1); + if (status) { + pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n"); + goto fail4; + } + + return 0; + +fail4: + gpio_free(MCFQSPI_CS3); +fail3: + gpio_free(MCFQSPI_CS2); +fail2: + gpio_free(MCFQSPI_CS1); +fail1: + gpio_free(MCFQSPI_CS0); +fail0: + return status; +} + +static void m523x_cs_teardown(struct mcfqspi_cs_control *cs_control) +{ + gpio_free(MCFQSPI_CS3); + gpio_free(MCFQSPI_CS2); + gpio_free(MCFQSPI_CS1); + gpio_free(MCFQSPI_CS0); +} + +static void m523x_cs_select(struct mcfqspi_cs_control *cs_control, + u8 chip_select, bool cs_high) +{ + switch (chip_select) { + case 0: + gpio_set_value(MCFQSPI_CS0, cs_high); + break; + case 1: + gpio_set_value(MCFQSPI_CS1, cs_high); + break; + case 2: + gpio_set_value(MCFQSPI_CS2, cs_high); + break; + case 3: + gpio_set_value(MCFQSPI_CS3, cs_high); + break; + } +} + +static void m523x_cs_deselect(struct mcfqspi_cs_control *cs_control, + u8 chip_select, bool cs_high) +{ + switch (chip_select) { + case 0: + gpio_set_value(MCFQSPI_CS0, !cs_high); + break; + case 1: + gpio_set_value(MCFQSPI_CS1, !cs_high); + break; + case 2: + gpio_set_value(MCFQSPI_CS2, !cs_high); + break; + case 3: + gpio_set_value(MCFQSPI_CS3, !cs_high); + break; + } +} + +static struct mcfqspi_cs_control m523x_cs_control = { + .setup = m523x_cs_setup, + .teardown = m523x_cs_teardown, + .select = m523x_cs_select, + .deselect = m523x_cs_deselect, +}; + +static struct mcfqspi_platform_data m523x_qspi_data = { + .bus_num = 0, + .num_chipselect = 4, + .cs_control = &m523x_cs_control, +}; + +static struct platform_device m523x_qspi = { + .name = "mcfqspi", + .id = 0, + .num_resources = ARRAY_SIZE(m523x_qspi_resources), + .resource = m523x_qspi_resources, + .dev.platform_data = &m523x_qspi_data, +}; + +static void __init m523x_qspi_init(void) +{ + u16 par; + + /* setup QSPS pins for QSPI with gpio CS control */ + writeb(0x1f, MCFGPIO_PAR_QSPI); + /* and CS2 & CS3 as gpio */ + par = readw(MCFGPIO_PAR_TIMER); + par &= 0x3f3f; + writew(par, MCFGPIO_PAR_TIMER); +} +#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */ + static struct platform_device *m523x_devices[] __initdata = { &m523x_uart, &m523x_fec, +#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) + &m523x_qspi, +#endif }; /***************************************************************************/ @@ -114,6 +281,9 @@ void __init config_BSP(char *commandp, int size) static int __init init_BSP(void) { m523x_fec_init(); +#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) + m523x_qspi_init(); +#endif platform_add_devices(m523x_devices, ARRAY_SIZE(m523x_devices)); return 0; } diff --git a/arch/m68knommu/platform/5249/config.c b/arch/m68knommu/platform/5249/config.c index 646f5ba462f..ceb31e5744a 100644 --- a/arch/m68knommu/platform/5249/config.c +++ b/arch/m68knommu/platform/5249/config.c @@ -12,10 +12,13 @@ #include <linux/param.h> #include <linux/init.h> #include <linux/io.h> +#include <linux/spi/spi.h> +#include <linux/gpio.h> #include <asm/machdep.h> #include <asm/coldfire.h> #include <asm/mcfsim.h> #include <asm/mcfuart.h> +#include <asm/mcfqspi.h> /***************************************************************************/ @@ -37,8 +40,196 @@ static struct platform_device m5249_uart = { .dev.platform_data = m5249_uart_platform, }; +#ifdef CONFIG_M5249C3 + +static struct resource m5249_smc91x_resources[] = { + { + .start = 0xe0000300, + .end = 0xe0000300 + 0x100, + .flags = IORESOURCE_MEM, + }, + { + .start = MCFINTC2_GPIOIRQ6, + .end = MCFINTC2_GPIOIRQ6, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device m5249_smc91x = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(m5249_smc91x_resources), + .resource = m5249_smc91x_resources, +}; + +#endif /* CONFIG_M5249C3 */ + +#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) +static struct resource m5249_qspi_resources[] = { + { + .start = MCFQSPI_IOBASE, + .end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = MCF_IRQ_QSPI, + .end = MCF_IRQ_QSPI, + .flags = IORESOURCE_IRQ, + }, +}; + +#define MCFQSPI_CS0 29 +#define MCFQSPI_CS1 24 +#define MCFQSPI_CS2 21 +#define MCFQSPI_CS3 22 + +static int m5249_cs_setup(struct mcfqspi_cs_control *cs_control) +{ + int status; + + status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0"); + if (status) { + pr_debug("gpio_request for MCFQSPI_CS0 failed\n"); + goto fail0; + } + status = gpio_direction_output(MCFQSPI_CS0, 1); + if (status) { + pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n"); + goto fail1; + } + + status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1"); + if (status) { + pr_debug("gpio_request for MCFQSPI_CS1 failed\n"); + goto fail1; + } + status = gpio_direction_output(MCFQSPI_CS1, 1); + if (status) { + pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n"); + goto fail2; + } + + status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2"); + if (status) { + pr_debug("gpio_request for MCFQSPI_CS2 failed\n"); + goto fail2; + } + status = gpio_direction_output(MCFQSPI_CS2, 1); + if (status) { + pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n"); + goto fail3; + } + + status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3"); + if (status) { + pr_debug("gpio_request for MCFQSPI_CS3 failed\n"); + goto fail3; + } + status = gpio_direction_output(MCFQSPI_CS3, 1); + if (status) { + pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n"); + goto fail4; + } + + return 0; + +fail4: + gpio_free(MCFQSPI_CS3); +fail3: + gpio_free(MCFQSPI_CS2); +fail2: + gpio_free(MCFQSPI_CS1); +fail1: + gpio_free(MCFQSPI_CS0); +fail0: + return status; +} + +static void m5249_cs_teardown(struct mcfqspi_cs_control *cs_control) +{ + gpio_free(MCFQSPI_CS3); + gpio_free(MCFQSPI_CS2); + gpio_free(MCFQSPI_CS1); + gpio_free(MCFQSPI_CS0); +} + +static void m5249_cs_select(struct mcfqspi_cs_control *cs_control, + u8 chip_select, bool cs_high) +{ + switch (chip_select) { + case 0: + gpio_set_value(MCFQSPI_CS0, cs_high); + break; + case 1: + gpio_set_value(MCFQSPI_CS1, cs_high); + break; + case 2: + gpio_set_value(MCFQSPI_CS2, cs_high); + break; + case 3: + gpio_set_value(MCFQSPI_CS3, cs_high); + break; + } +} + +static void m5249_cs_deselect(struct mcfqspi_cs_control *cs_control, + u8 chip_select, bool cs_high) +{ + switch (chip_select) { + case 0: + gpio_set_value(MCFQSPI_CS0, !cs_high); + break; + case 1: + gpio_set_value(MCFQSPI_CS1, !cs_high); + break; + case 2: + gpio_set_value(MCFQSPI_CS2, !cs_high); + break; + case 3: + gpio_set_value(MCFQSPI_CS3, !cs_high); + break; + } +} + +static struct mcfqspi_cs_control m5249_cs_control = { + .setup = m5249_cs_setup, + .teardown = m5249_cs_teardown, + .select = m5249_cs_select, + .deselect = m5249_cs_deselect, +}; + +static struct mcfqspi_platform_data m5249_qspi_data = { + .bus_num = 0, + .num_chipselect = 4, + .cs_control = &m5249_cs_control, +}; + +static struct platform_device m5249_qspi = { + .name = "mcfqspi", + .id = 0, + .num_resources = ARRAY_SIZE(m5249_qspi_resources), + .resource = m5249_qspi_resources, + .dev.platform_data = &m5249_qspi_data, +}; + +static void __init m5249_qspi_init(void) +{ + /* QSPI irq setup */ + writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI0, + MCF_MBAR + MCFSIM_QSPIICR); + mcf_mapirq2imr(MCF_IRQ_QSPI, MCFINTC_QSPI); +} +#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */ + + static struct platform_device *m5249_devices[] __initdata = { &m5249_uart, +#ifdef CONFIG_M5249C3 + &m5249_smc91x, +#endif +#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) + &m5249_qspi, +#endif }; /***************************************************************************/ @@ -67,6 +258,24 @@ static void __init m5249_uarts_init(void) /***************************************************************************/ +#ifdef CONFIG_M5249C3 + +static void __init m5249_smc91x_init(void) +{ + u32 gpio; + + /* Set the GPIO line as interrupt source for smc91x device */ + gpio = readl(MCF_MBAR2 + MCFSIM2_GPIOINTENABLE); + writel(gpio | 0x40, MCF_MBAR2 + MCFSIM2_GPIOINTENABLE); + + gpio = readl(MCF_MBAR2 + MCFSIM2_INTLEVEL5); + writel(gpio | 0x04000000, MCF_MBAR2 + MCFSIM2_INTLEVEL5); +} + +#endif /* CONFIG_M5249C3 */ + +/***************************************************************************/ + static void __init m5249_timers_init(void) { /* Timer1 is always used as system timer */ @@ -100,6 +309,12 @@ void __init config_BSP(char *commandp, int size) mach_reset = m5249_cpu_reset; m5249_timers_init(); m5249_uarts_init(); +#ifdef CONFIG_M5249C3 + m5249_smc91x_init(); +#endif +#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) + m5249_qspi_init(); +#endif } /***************************************************************************/ diff --git a/arch/m68knommu/platform/527x/config.c b/arch/m68knommu/platform/527x/config.c index fa51be17283..3d9c35c98b9 100644 --- a/arch/m68knommu/platform/527x/config.c +++ b/arch/m68knommu/platform/527x/config.c @@ -16,10 +16,13 @@ #include <linux/param.h> #include <linux/init.h> #include <linux/io.h> +#include <linux/spi/spi.h> +#include <linux/gpio.h> #include <asm/machdep.h> #include <asm/coldfire.h> #include <asm/mcfsim.h> #include <asm/mcfuart.h> +#include <asm/mcfqspi.h> /***************************************************************************/ @@ -106,12 +109,188 @@ static struct platform_device m527x_fec[] = { }, }; +#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) +static struct resource m527x_qspi_resources[] = { + { + .start = MCFQSPI_IOBASE, + .end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = MCFINT_VECBASE + MCFINT_QSPI, + .end = MCFINT_VECBASE + MCFINT_QSPI, + .flags = IORESOURCE_IRQ, + }, +}; + +#if defined(CONFIG_M5271) +#define MCFQSPI_CS0 91 +#define MCFQSPI_CS1 92 +#define MCFQSPI_CS2 99 +#define MCFQSPI_CS3 103 +#elif defined(CONFIG_M5275) +#define MCFQSPI_CS0 59 +#define MCFQSPI_CS1 60 +#define MCFQSPI_CS2 61 +#define MCFQSPI_CS3 62 +#endif + +static int m527x_cs_setup(struct mcfqspi_cs_control *cs_control) +{ + int status; + + status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0"); + if (status) { + pr_debug("gpio_request for MCFQSPI_CS0 failed\n"); + goto fail0; + } + status = gpio_direction_output(MCFQSPI_CS0, 1); + if (status) { + pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n"); + goto fail1; + } + + status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1"); + if (status) { + pr_debug("gpio_request for MCFQSPI_CS1 failed\n"); + goto fail1; + } + status = gpio_direction_output(MCFQSPI_CS1, 1); + if (status) { + pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n"); + goto fail2; + } + + status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2"); + if (status) { + pr_debug("gpio_request for MCFQSPI_CS2 failed\n"); + goto fail2; + } + status = gpio_direction_output(MCFQSPI_CS2, 1); + if (status) { + pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n"); + goto fail3; + } + + status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3"); + if (status) { + pr_debug("gpio_request for MCFQSPI_CS3 failed\n"); + goto fail3; + } + status = gpio_direction_output(MCFQSPI_CS3, 1); + if (status) { + pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n"); + goto fail4; + } + + return 0; + +fail4: + gpio_free(MCFQSPI_CS3); +fail3: + gpio_free(MCFQSPI_CS2); +fail2: + gpio_free(MCFQSPI_CS1); +fail1: + gpio_free(MCFQSPI_CS0); +fail0: + return status; +} + +static void m527x_cs_teardown(struct mcfqspi_cs_control *cs_control) +{ + gpio_free(MCFQSPI_CS3); + gpio_free(MCFQSPI_CS2); + gpio_free(MCFQSPI_CS1); + gpio_free(MCFQSPI_CS0); +} + +static void m527x_cs_select(struct mcfqspi_cs_control *cs_control, + u8 chip_select, bool cs_high) +{ + switch (chip_select) { + case 0: + gpio_set_value(MCFQSPI_CS0, cs_high); + break; + case 1: + gpio_set_value(MCFQSPI_CS1, cs_high); + break; + case 2: + gpio_set_value(MCFQSPI_CS2, cs_high); + break; + case 3: + gpio_set_value(MCFQSPI_CS3, cs_high); + break; + } +} + +static void m527x_cs_deselect(struct mcfqspi_cs_control *cs_control, + u8 chip_select, bool cs_high) +{ + switch (chip_select) { + case 0: + gpio_set_value(MCFQSPI_CS0, !cs_high); + break; + case 1: + gpio_set_value(MCFQSPI_CS1, !cs_high); + break; + case 2: + gpio_set_value(MCFQSPI_CS2, !cs_high); + break; + case 3: + gpio_set_value(MCFQSPI_CS3, !cs_high); + break; + } +} + +static struct mcfqspi_cs_control m527x_cs_control = { + .setup = m527x_cs_setup, + .teardown = m527x_cs_teardown, + .select = m527x_cs_select, + .deselect = m527x_cs_deselect, +}; + +static struct mcfqspi_platform_data m527x_qspi_data = { + .bus_num = 0, + .num_chipselect = 4, + .cs_control = &m527x_cs_control, +}; + +static struct platform_device m527x_qspi = { + .name = "mcfqspi", + .id = 0, + .num_resources = ARRAY_SIZE(m527x_qspi_resources), + .resource = m527x_qspi_resources, + .dev.platform_data = &m527x_qspi_data, +}; + +static void __init m527x_qspi_init(void) +{ +#if defined(CONFIG_M5271) + u16 par; + + /* setup QSPS pins for QSPI with gpio CS control */ + writeb(0x1f, MCFGPIO_PAR_QSPI); + /* and CS2 & CS3 as gpio */ + par = readw(MCFGPIO_PAR_TIMER); + par &= 0x3f3f; + writew(par, MCFGPIO_PAR_TIMER); +#elif defined(CONFIG_M5275) + /* setup QSPS pins for QSPI with gpio CS control */ + writew(0x003e, MCFGPIO_PAR_QSPI); +#endif +} +#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */ + static struct platform_device *m527x_devices[] __initdata = { &m527x_uart, &m527x_fec[0], #ifdef CONFIG_FEC2 &m527x_fec[1], #endif +#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) + &m527x_qspi, +#endif }; /***************************************************************************/ @@ -187,6 +366,9 @@ void __init config_BSP(char *commandp, int size) mach_reset = m527x_cpu_reset; m527x_uarts_init(); m527x_fec_init(); +#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) + m527x_qspi_init(); +#endif } /***************************************************************************/ diff --git a/arch/m68knommu/platform/528x/config.c b/arch/m68knommu/platform/528x/config.c index 6e608d1836f..76b743343bf 100644 --- a/arch/m68knommu/platform/528x/config.c +++ b/arch/m68knommu/platform/528x/config.c @@ -17,10 +17,13 @@ #include <linux/init.h> #include <linux/platform_device.h> #include <linux/io.h> +#include <linux/spi/spi.h> +#include <linux/gpio.h> #include <asm/machdep.h> #include <asm/coldfire.h> #include <asm/mcfsim.h> #include <asm/mcfuart.h> +#include <asm/mcfqspi.h> /***************************************************************************/ @@ -76,10 +79,141 @@ static struct platform_device m528x_fec = { .resource = m528x_fec_resources, }; +#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) +static struct resource m528x_qspi_resources[] = { + { + .start = MCFQSPI_IOBASE, + .end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = MCFINT_VECBASE + MCFINT_QSPI, + .end = MCFINT_VECBASE + MCFINT_QSPI, + .flags = IORESOURCE_IRQ, + }, +}; + +#define MCFQSPI_CS0 147 +#define MCFQSPI_CS1 148 +#define MCFQSPI_CS2 149 +#define MCFQSPI_CS3 150 + +static int m528x_cs_setup(struct mcfqspi_cs_control *cs_control) +{ + int status; + + status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0"); + if (status) { + pr_debug("gpio_request for MCFQSPI_CS0 failed\n"); + goto fail0; + } + status = gpio_direction_output(MCFQSPI_CS0, 1); + if (status) { + pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n"); + goto fail1; + } + + status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1"); + if (status) { + pr_debug("gpio_request for MCFQSPI_CS1 failed\n"); + goto fail1; + } + status = gpio_direction_output(MCFQSPI_CS1, 1); + if (status) { + pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n"); + goto fail2; + } + + status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2"); + if (status) { + pr_debug("gpio_request for MCFQSPI_CS2 failed\n"); + goto fail2; + } + status = gpio_direction_output(MCFQSPI_CS2, 1); + if (status) { + pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n"); + goto fail3; + } + + status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3"); + if (status) { + pr_debug("gpio_request for MCFQSPI_CS3 failed\n"); + goto fail3; + } + status = gpio_direction_output(MCFQSPI_CS3, 1); + if (status) { + pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n"); + goto fail4; + } + + return 0; + +fail4: + gpio_free(MCFQSPI_CS3); +fail3: + gpio_free(MCFQSPI_CS2); +fail2: + gpio_free(MCFQSPI_CS1); +fail1: + gpio_free(MCFQSPI_CS0); +fail0: + return status; +} + +static void m528x_cs_teardown(struct mcfqspi_cs_control *cs_control) +{ + gpio_free(MCFQSPI_CS3); + gpio_free(MCFQSPI_CS2); + gpio_free(MCFQSPI_CS1); + gpio_free(MCFQSPI_CS0); +} + +static void m528x_cs_select(struct mcfqspi_cs_control *cs_control, + u8 chip_select, bool cs_high) +{ + gpio_set_value(MCFQSPI_CS0 + chip_select, cs_high); +} + +static void m528x_cs_deselect(struct mcfqspi_cs_control *cs_control, + u8 chip_select, bool cs_high) +{ + gpio_set_value(MCFQSPI_CS0 + chip_select, !cs_high); +} + +static struct mcfqspi_cs_control m528x_cs_control = { + .setup = m528x_cs_setup, + .teardown = m528x_cs_teardown, + .select = m528x_cs_select, + .deselect = m528x_cs_deselect, +}; + +static struct mcfqspi_platform_data m528x_qspi_data = { + .bus_num = 0, + .num_chipselect = 4, + .cs_control = &m528x_cs_control, +}; + +static struct platform_device m528x_qspi = { + .name = "mcfqspi", + .id = 0, + .num_resources = ARRAY_SIZE(m528x_qspi_resources), + .resource = m528x_qspi_resources, + .dev.platform_data = &m528x_qspi_data, +}; + +static void __init m528x_qspi_init(void) +{ + /* setup Port QS for QSPI with gpio CS control */ + __raw_writeb(0x07, MCFGPIO_PQSPAR); +} +#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */ static struct platform_device *m528x_devices[] __initdata = { &m528x_uart, &m528x_fec, +#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) + &m528x_qspi, +#endif }; /***************************************************************************/ @@ -174,6 +308,9 @@ static int __init init_BSP(void) mach_reset = m528x_cpu_reset; m528x_uarts_init(); m528x_fec_init(); +#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) + m528x_qspi_init(); +#endif platform_add_devices(m528x_devices, ARRAY_SIZE(m528x_devices)); return 0; } diff --git a/arch/m68knommu/platform/5307/Makefile b/arch/m68knommu/platform/5307/Makefile index 667db659845..6de52697682 100644 --- a/arch/m68knommu/platform/5307/Makefile +++ b/arch/m68knommu/platform/5307/Makefile @@ -14,5 +14,7 @@ asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 -obj-y += config.o gpio.o +obj-y += config.o gpio.o +obj-$(CONFIG_NETtel) += nettel.o +obj-$(CONFIG_CLEOPATRA) += nettel.o diff --git a/arch/m68knommu/platform/5307/nettel.c b/arch/m68knommu/platform/5307/nettel.c new file mode 100644 index 00000000000..e925ea4602f --- /dev/null +++ b/arch/m68knommu/platform/5307/nettel.c @@ -0,0 +1,153 @@ +/***************************************************************************/ + +/* + * nettel.c -- startup code support for the NETtel boards + * + * Copyright (C) 2009, Greg Ungerer (gerg@snapgear.com) + */ + +/***************************************************************************/ + +#include <linux/kernel.h> +#include <linux/param.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/platform_device.h> +#include <asm/coldfire.h> +#include <asm/mcfsim.h> +#include <asm/nettel.h> + +/***************************************************************************/ + +/* + * Define the IO and interrupt resources of the 2 SMC9196 interfaces. + */ +#define NETTEL_SMC0_ADDR 0x30600300 +#define NETTEL_SMC0_IRQ 29 + +#define NETTEL_SMC1_ADDR 0x30600000 +#define NETTEL_SMC1_IRQ 27 + +/* + * We need some access into the SMC9196 registers. Define those registers + * we will need here (including the smc91x.h doesn't seem to give us these + * in a simple form). + */ +#define SMC91xx_BANKSELECT 14 +#define SMC91xx_BASEADDR 2 +#define SMC91xx_BASEMAC 4 + +/***************************************************************************/ + +static struct resource nettel_smc91x_0_resources[] = { + { + .start = NETTEL_SMC0_ADDR, + .end = NETTEL_SMC0_ADDR + 0x20, + .flags = IORESOURCE_MEM, + }, + { + .start = NETTEL_SMC0_IRQ, + .end = NETTEL_SMC0_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource nettel_smc91x_1_resources[] = { + { + .start = NETTEL_SMC1_ADDR, + .end = NETTEL_SMC1_ADDR + 0x20, + .flags = IORESOURCE_MEM, + }, + { + .start = NETTEL_SMC1_IRQ, + .end = NETTEL_SMC1_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device nettel_smc91x[] = { + { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(nettel_smc91x_0_resources), + .resource = nettel_smc91x_0_resources, + }, + { + .name = "smc91x", + .id = 1, + .num_resources = ARRAY_SIZE(nettel_smc91x_1_resources), + .resource = nettel_smc91x_1_resources, + }, +}; + +static struct platform_device *nettel_devices[] __initdata = { + &nettel_smc91x[0], + &nettel_smc91x[1], +}; + +/***************************************************************************/ + +static u8 nettel_macdefault[] __initdata = { + 0x00, 0xd0, 0xcf, 0x00, 0x00, 0x01, +}; + +/* + * Set flash contained MAC address into SMC9196 core. Make sure the flash + * MAC address is sane, and not an empty flash. If no good use the Moreton + * Bay default MAC address instead. + */ + +static void __init nettel_smc91x_setmac(unsigned int ioaddr, unsigned int flashaddr) +{ + u16 *macp; + + macp = (u16 *) flashaddr; + if ((macp[0] == 0xffff) && (macp[1] == 0xffff) && (macp[2] == 0xffff)) + macp = (u16 *) &nettel_macdefault[0]; + + writew(1, NETTEL_SMC0_ADDR + SMC91xx_BANKSELECT); + writew(macp[0], ioaddr + SMC91xx_BASEMAC); + writew(macp[1], ioaddr + SMC91xx_BASEMAC + 2); + writew(macp[2], ioaddr + SMC91xx_BASEMAC + 4); +} + +/***************************************************************************/ + +/* + * Re-map the address space of at least one of the SMC ethernet + * parts. Both parts power up decoding the same address, so we + * need to move one of them first, before doing anything else. + */ + +static void __init nettel_smc91x_init(void) +{ + writew(0x00ec, MCF_MBAR + MCFSIM_PADDR); + mcf_setppdata(0, 0x0080); + writew(1, NETTEL_SMC0_ADDR + SMC91xx_BANKSELECT); + writew(0x0067, NETTEL_SMC0_ADDR + SMC91xx_BASEADDR); + mcf_setppdata(0x0080, 0); + + /* Set correct chip select timing for SMC9196 accesses */ + writew(0x1180, MCF_MBAR + MCFSIM_CSCR3); + + /* Set the SMC interrupts to be auto-vectored */ + mcf_autovector(NETTEL_SMC0_IRQ); + mcf_autovector(NETTEL_SMC1_IRQ); + + /* Set MAC addresses from flash for both interfaces */ + nettel_smc91x_setmac(NETTEL_SMC0_ADDR, 0xf0006000); + nettel_smc91x_setmac(NETTEL_SMC1_ADDR, 0xf0006006); +} + +/***************************************************************************/ + +static int __init init_nettel(void) +{ + nettel_smc91x_init(); + platform_add_devices(nettel_devices, ARRAY_SIZE(nettel_devices)); + return 0; +} + +arch_initcall(init_nettel); + +/***************************************************************************/ diff --git a/arch/m68knommu/platform/532x/config.c b/arch/m68knommu/platform/532x/config.c index d632948e64e..ca51323f957 100644 --- a/arch/m68knommu/platform/532x/config.c +++ b/arch/m68knommu/platform/532x/config.c @@ -21,12 +21,15 @@ #include <linux/param.h> #include <linux/init.h> #include <linux/io.h> +#include <linux/spi/spi.h> +#include <linux/gpio.h> #include <asm/machdep.h> #include <asm/coldfire.h> #include <asm/mcfsim.h> #include <asm/mcfuart.h> #include <asm/mcfdma.h> #include <asm/mcfwdebug.h> +#include <asm/mcfqspi.h> /***************************************************************************/ @@ -82,9 +85,127 @@ static struct platform_device m532x_fec = { .resource = m532x_fec_resources, }; +#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) +static struct resource m532x_qspi_resources[] = { + { + .start = MCFQSPI_IOBASE, + .end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = MCFINT_VECBASE + MCFINT_QSPI, + .end = MCFINT_VECBASE + MCFINT_QSPI, + .flags = IORESOURCE_IRQ, + }, +}; + +#define MCFQSPI_CS0 84 +#define MCFQSPI_CS1 85 +#define MCFQSPI_CS2 86 + +static int m532x_cs_setup(struct mcfqspi_cs_control *cs_control) +{ + int status; + + status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0"); + if (status) { + pr_debug("gpio_request for MCFQSPI_CS0 failed\n"); + goto fail0; + } + status = gpio_direction_output(MCFQSPI_CS0, 1); + if (status) { + pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n"); + goto fail1; + } + + status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1"); + if (status) { + pr_debug("gpio_request for MCFQSPI_CS1 failed\n"); + goto fail1; + } + status = gpio_direction_output(MCFQSPI_CS1, 1); + if (status) { + pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n"); + goto fail2; + } + + status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2"); + if (status) { + pr_debug("gpio_request for MCFQSPI_CS2 failed\n"); + goto fail2; + } + status = gpio_direction_output(MCFQSPI_CS2, 1); + if (status) { + pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n"); + goto fail3; + } + + return 0; + +fail3: + gpio_free(MCFQSPI_CS2); +fail2: + gpio_free(MCFQSPI_CS1); +fail1: + gpio_free(MCFQSPI_CS0); +fail0: + return status; +} + +static void m532x_cs_teardown(struct mcfqspi_cs_control *cs_control) +{ + gpio_free(MCFQSPI_CS2); + gpio_free(MCFQSPI_CS1); + gpio_free(MCFQSPI_CS0); +} + +static void m532x_cs_select(struct mcfqspi_cs_control *cs_control, + u8 chip_select, bool cs_high) +{ + gpio_set_value(MCFQSPI_CS0 + chip_select, cs_high); +} + +static void m532x_cs_deselect(struct mcfqspi_cs_control *cs_control, + u8 chip_select, bool cs_high) +{ + gpio_set_value(MCFQSPI_CS0 + chip_select, !cs_high); +} + +static struct mcfqspi_cs_control m532x_cs_control = { + .setup = m532x_cs_setup, + .teardown = m532x_cs_teardown, + .select = m532x_cs_select, + .deselect = m532x_cs_deselect, +}; + +static struct mcfqspi_platform_data m532x_qspi_data = { + .bus_num = 0, + .num_chipselect = 3, + .cs_control = &m532x_cs_control, +}; + +static struct platform_device m532x_qspi = { + .name = "mcfqspi", + .id = 0, + .num_resources = ARRAY_SIZE(m532x_qspi_resources), + .resource = m532x_qspi_resources, + .dev.platform_data = &m532x_qspi_data, +}; + +static void __init m532x_qspi_init(void) +{ + /* setup QSPS pins for QSPI with gpio CS control */ + writew(0x01f0, MCF_GPIO_PAR_QSPI); +} +#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */ + + static struct platform_device *m532x_devices[] __initdata = { &m532x_uart, &m532x_fec, +#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) + &m532x_qspi, +#endif }; /***************************************************************************/ @@ -158,6 +279,9 @@ static int __init init_BSP(void) { m532x_uarts_init(); m532x_fec_init(); +#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) + m532x_qspi_init(); +#endif platform_add_devices(m532x_devices, ARRAY_SIZE(m532x_devices)); return 0; } diff --git a/arch/m68knommu/platform/68360/commproc.c b/arch/m68knommu/platform/68360/commproc.c index 6acb8d294cb..f27e688c404 100644 --- a/arch/m68knommu/platform/68360/commproc.c +++ b/arch/m68knommu/platform/68360/commproc.c @@ -110,7 +110,7 @@ void m360_cpm_reset() /* pte = find_pte(&init_mm, host_page_addr); */ /* pte_val(*pte) |= _PAGE_NO_CACHE; */ /* flush_tlb_page(current->mm->mmap, host_buffer); */ - + /* Tell everyone where the comm processor resides. */ /* cpmp = (cpm360_t *)commproc; */ @@ -191,7 +191,7 @@ cpm_interrupt(int irq, void * dev, struct pt_regs * regs) */ ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cisr |= (1 << vec); #endif - + } /* The CPM can generate the error interrupt when there is a race condition |