diff options
Diffstat (limited to 'arch/m68knommu')
-rw-r--r-- | arch/m68knommu/Kconfig | 2 | ||||
-rw-r--r-- | arch/m68knommu/mm/fault.c | 10 | ||||
-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 |
11 files changed, 1141 insertions, 9 deletions
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig index 064f5913db1..efeb6033fc1 100644 --- a/arch/m68knommu/Kconfig +++ b/arch/m68knommu/Kconfig @@ -566,7 +566,7 @@ config RAMBASE processor address space. config RAMSIZE - hex "Size of RAM (in bytes)" + hex "Size of RAM (in bytes), or 0 for automatic" default "0x400000" help Define the size of the system RAM. If you select 0 then the diff --git a/arch/m68knommu/mm/fault.c b/arch/m68knommu/mm/fault.c index 6f6673cb582..bc05cf74d9c 100644 --- a/arch/m68knommu/mm/fault.c +++ b/arch/m68knommu/mm/fault.c @@ -2,7 +2,7 @@ * linux/arch/m68knommu/mm/fault.c * * Copyright (C) 1998 D. Jeff Dionne <jeff@lineo.ca>, - * Copyright (C) 2000 Lineo, Inc. (www.lineo.com) + * Copyright (C) 2000 Lineo, Inc. (www.lineo.com) * * Based on: * @@ -36,7 +36,7 @@ asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address, unsigned long error_code) { #ifdef DEBUG - printk (KERN_DEBUG "regs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld\n", + printk(KERN_DEBUG "regs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld\n", regs->sr, regs->pc, address, error_code); #endif @@ -44,11 +44,11 @@ asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address, * Oops. The kernel tried to access some bad page. We'll have to * terminate things with extreme prejudice. */ - if ((unsigned long) address < PAGE_SIZE) { + if ((unsigned long) address < PAGE_SIZE) printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference"); - } else + else printk(KERN_ALERT "Unable to handle kernel access"); - printk(KERN_ALERT " at virtual address %08lx\n",address); + printk(KERN_ALERT " at virtual address %08lx\n", address); die_if_kernel("Oops", regs, error_code); do_exit(SIGKILL); 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 an |