diff options
Diffstat (limited to 'arch/m68k/platform/528x')
-rw-r--r-- | arch/m68k/platform/528x/Makefile | 18 | ||||
-rw-r--r-- | arch/m68k/platform/528x/config.c | 320 | ||||
-rw-r--r-- | arch/m68k/platform/528x/gpio.c | 438 |
3 files changed, 776 insertions, 0 deletions
diff --git a/arch/m68k/platform/528x/Makefile b/arch/m68k/platform/528x/Makefile new file mode 100644 index 000000000000..6ac4b57370ea --- /dev/null +++ b/arch/m68k/platform/528x/Makefile @@ -0,0 +1,18 @@ +# +# Makefile for the linux kernel. +# + +# +# If you want to play with the HW breakpoints then you will +# need to add define this, which will give you a stack backtrace +# on the console port whenever a DBG interrupt occurs. You have to +# set up you HW breakpoints to trigger a DBG interrupt: +# +# ccflags-y := -DTRAP_DBG_INTERRUPT +# asflags-y := -DTRAP_DBG_INTERRUPT +# + +asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 + +obj-y := config.o gpio.o + diff --git a/arch/m68k/platform/528x/config.c b/arch/m68k/platform/528x/config.c new file mode 100644 index 000000000000..ac39fc661219 --- /dev/null +++ b/arch/m68k/platform/528x/config.c @@ -0,0 +1,320 @@ +/***************************************************************************/ + +/* + * linux/arch/m68knommu/platform/528x/config.c + * + * Sub-architcture dependant initialization code for the Freescale + * 5280, 5281 and 5282 CPUs. + * + * Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com) + * Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com) + */ + +/***************************************************************************/ + +#include <linux/kernel.h> +#include <linux/param.h> +#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> + +/***************************************************************************/ + +static struct mcf_platform_uart m528x_uart_platform[] = { + { + .mapbase = MCFUART_BASE1, + .irq = MCFINT_VECBASE + MCFINT_UART0, + }, + { + .mapbase = MCFUART_BASE2, + .irq = MCFINT_VECBASE + MCFINT_UART0 + 1, + }, + { + .mapbase = MCFUART_BASE3, + .irq = MCFINT_VECBASE + MCFINT_UART0 + 2, + }, + { }, +}; + +static struct platform_device m528x_uart = { + .name = "mcfuart", + .id = 0, + .dev.platform_data = m528x_uart_platform, +}; + +static struct resource m528x_fec_resources[] = { + { + .start = MCFFEC_BASE, + .end = MCFFEC_BASE + MCFFEC_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = 64 + 23, + .end = 64 + 23, + .flags = IORESOURCE_IRQ, + }, + { + .start = 64 + 27, + .end = 64 + 27, + .flags = IORESOURCE_IRQ, + }, + { + .start = 64 + 29, + .end = 64 + 29, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device m528x_fec = { + .name = "fec", + .id = 0, + .num_resources = ARRAY_SIZE(m528x_fec_resources), + .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 +}; + +/***************************************************************************/ + +static void __init m528x_uart_init_line(int line, int irq) +{ + u8 port; + + if ((line < 0) || (line > 2)) + return; + + /* make sure PUAPAR is set for UART0 and UART1 */ + if (line < 2) { + port = readb(MCF5282_GPIO_PUAPAR); + port |= (0x03 << (line * 2)); + writeb(port, MCF5282_GPIO_PUAPAR); + } +} + +static void __init m528x_uarts_init(void) +{ + const int nrlines = ARRAY_SIZE(m528x_uart_platform); + int line; + + for (line = 0; (line < nrlines); line++) + m528x_uart_init_line(line, m528x_uart_platform[line].irq); +} + +/***************************************************************************/ + +static void __init m528x_fec_init(void) +{ + u16 v16; + + /* Set multi-function pins to ethernet mode for fec0 */ + v16 = readw(MCF_IPSBAR + 0x100056); + writew(v16 | 0xf00, MCF_IPSBAR + 0x100056); + writeb(0xc0, MCF_IPSBAR + 0x100058); +} + +/***************************************************************************/ + +static void m528x_cpu_reset(void) +{ + local_irq_disable(); + __raw_writeb(MCF_RCR_SWRESET, MCF_IPSBAR + MCF_RCR); +} + +/***************************************************************************/ + +#ifdef CONFIG_WILDFIRE +void wildfire_halt(void) +{ + writeb(0, 0x30000007); + writeb(0x2, 0x30000007); +} +#endif + +#ifdef CONFIG_WILDFIREMOD +void wildfiremod_halt(void) +{ + printk(KERN_INFO "WildFireMod hibernating...\n"); + + /* Set portE.5 to Digital IO */ + MCF5282_GPIO_PEPAR &= ~(1 << (5 * 2)); + + /* Make portE.5 an output */ + MCF5282_GPIO_DDRE |= (1 << 5); + + /* Now toggle portE.5 from low to high */ + MCF5282_GPIO_PORTE &= ~(1 << 5); + MCF5282_GPIO_PORTE |= (1 << 5); + + printk(KERN_EMERG "Failed to hibernate. Halting!\n"); +} +#endif + +void __init config_BSP(char *commandp, int size) +{ +#ifdef CONFIG_WILDFIRE + mach_halt = wildfire_halt; +#endif +#ifdef CONFIG_WILDFIREMOD + mach_halt = wildfiremod_halt; +#endif +} + +/***************************************************************************/ + +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; +} + +arch_initcall(init_BSP); + +/***************************************************************************/ diff --git a/arch/m68k/platform/528x/gpio.c b/arch/m68k/platform/528x/gpio.c new file mode 100644 index 000000000000..526db665d87e --- /dev/null +++ b/arch/m68k/platform/528x/gpio.c @@ -0,0 +1,438 @@ +/* + * Coldfire generic GPIO support + * + * (C) Copyright 2009, Steven King <sfking@fdwdc.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. +*/ + +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/coldfire.h> +#include <asm/mcfsim.h> +#include <asm/mcfgpio.h> + +static struct mcf_gpio_chip mcf_gpio_chips[] = { + { + .gpio_chip = { + .label = "NQ", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .base = 1, + .ngpio = 7, + }, + .pddr = (void __iomem *)MCFEPORT_EPDDR, + .podr = (void __iomem *)MCFEPORT_EPDR, + .ppdr = (void __iomem *)MCFEPORT_EPPDR, + }, + { + .gpio_chip = { + .label = "TA", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 8, + .ngpio = 4, + }, + .pddr = (void __iomem *)MCFGPTA_GPTDDR, + .podr = (void __iomem *)MCFGPTA_GPTPORT, + .ppdr = (void __iomem *)MCFGPTB_GPTPORT, + }, + { + .gpio_chip = { + .label = "TB", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 16, + .ngpio = 4, + }, + .pddr = (void __iomem *)MCFGPTB_GPTDDR, + .podr = (void __iomem *)MCFGPTB_GPTPORT, + .ppdr = (void __iomem *)MCFGPTB_GPTPORT, + }, + { + .gpio_chip = { + .label = "QA", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 24, + .ngpio = 4, + }, + .pddr = (void __iomem *)MCFQADC_DDRQA, + .podr = (void __iomem *)MCFQADC_PORTQA, + .ppdr = (void __iomem *)MCFQADC_PORTQA, + }, + { + .gpio_chip = { + .label = "QB", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 32, + .ngpio = 4, + }, + .pddr = (void __iomem *)MCFQADC_DDRQB, + .podr = (void __iomem *)MCFQADC_PORTQB, + .ppdr = (void __iomem *)MCFQADC_PORTQB, + }, + { + .gpio_chip = { + .label = "A", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 40, + .ngpio = 8, + }, + .pddr = (void __iomem *)MCFGPIO_DDRA, + .podr = (void __iomem *)MCFGPIO_PORTA, + .ppdr = (void __iomem *)MCFGPIO_PORTAP, + .setr = (void __iomem *)MCFGPIO_SETA, + .clrr = (void __iomem *)MCFGPIO_CLRA, + }, + { + .gpio_chip = { + .label = "B", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 48, + .ngpio = 8, + }, + .pddr = (void __iomem *)MCFGPIO_DDRB, + .podr = (void __iomem *)MCFGPIO_PORTB, + .ppdr = (void __iomem *)MCFGPIO_PORTBP, + .setr = (void __iomem *)MCFGPIO_SETB, + .clrr = (void __iomem *)MCFGPIO_CLRB, + }, + { + .gpio_chip = { + .label = "C", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 56, + .ngpio = 8, + }, + .pddr = (void __iomem *)MCFGPIO_DDRC, + .podr = (void __iomem *)MCFGPIO_PORTC, + .ppdr = (void __iomem *)MCFGPIO_PORTCP, + .setr = (void __iomem *)MCFGPIO_SETC, + .clrr = (void __iomem *)MCFGPIO_CLRC, + }, + { + .gpio_chip = { + .label = "D", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 64, + .ngpio = 8, + }, + .pddr = (void __iomem *)MCFGPIO_DDRD, + .podr = (void __iomem *)MCFGPIO_PORTD, + .ppdr = (void __iomem *)MCFGPIO_PORTDP, + .setr = (void __iomem *)MCFGPIO_SETD, + .clrr = (void __iomem *)MCFGPIO_CLRD, + }, + { + .gpio_chip = { + .label = "E", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 72, + .ngpio = 8, + }, + .pddr = (void __iomem *)MCFGPIO_DDRE, + .podr = (void __iomem *)MCFGPIO_PORTE, + .ppdr = (void __iomem *)MCFGPIO_PORTEP, + .setr = (void __iomem *)MCFGPIO_SETE, + .clrr = (void __iomem *)MCFGPIO_CLRE, + }, + { + .gpio_chip = { + .label = "F", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 80, + .ngpio = 8, + }, + .pddr = (void __iomem *)MCFGPIO_DDRF, + .podr = (void __iomem *)MCFGPIO_PORTF, + .ppdr = (void __iomem *)MCFGPIO_PORTFP, + .setr = (void __iomem *)MCFGPIO_SETF, + .clrr = (void __iomem *)MCFGPIO_CLRF, + }, + { + .gpio_chip = { + .label = "G", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 88, + .ngpio = 8, + }, + .pddr = (void __iomem *)MCFGPIO_DDRG, + .podr = (void __iomem *)MCFGPIO_PORTG, + .ppdr = (void __iomem *)MCFGPIO_PORTGP, + .setr = (void __iomem *)MCFGPIO_SETG, + .clrr = (void __iomem *)MCFGPIO_CLRG, + }, + { + .gpio_chip = { + .label = "H", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 96, + .ngpio = 8, + }, + .pddr = (void __iomem *)MCFGPIO_DDRH, + .podr = (void __iomem *)MCFGPIO_PORTH, + .ppdr = (void __iomem *)MCFGPIO_PORTHP, + .setr = (void __iomem *)MCFGPIO_SETH, + .clrr = (void __iomem *)MCFGPIO_CLRH, + }, + { + .gpio_chip = { + .label = "J", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 104, + .ngpio = 8, + }, + .pddr = (void __iomem *)MCFGPIO_DDRJ, + .podr = (void __iomem *)MCFGPIO_PORTJ, + .ppdr = (void __iomem *)MCFGPIO_PORTJP, + .setr = (void __iomem *)MCFGPIO_SETJ, + .clrr = (void __iomem *)MCFGPIO_CLRJ, + }, + { + .gpio_chip = { + .label = "DD", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 112, + .ngpio = 8, + }, + .pddr = (void __iomem *)MCFGPIO_DDRDD, + .podr = (void __iomem *)MCFGPIO_PORTDD, + .ppdr = (void __iomem *)MCFGPIO_PORTDDP, + .setr = (void __iomem *)MCFGPIO_SETDD, + .clrr = (void __iomem *)MCFGPIO_CLRDD, + }, + { + .gpio_chip = { + .label = "EH", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 120, + .ngpio = 8, + }, + .pddr = (void __iomem *)MCFGPIO_DDREH, + .podr = (void __iomem *)MCFGPIO_PORTEH, + .ppdr = (void __iomem *)MCFGPIO_PORTEHP, + .setr = (void __iomem *)MCFGPIO_SETEH, + .clrr = (void __iomem *)MCFGPIO_CLREH, + }, + { + .gpio_chip = { + .label = "EL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 128, + .ngpio = 8, + }, + .pddr = (void __iomem *)MCFGPIO_DDREL, + .podr = (void __iomem *)MCFGPIO_PORTEL, + .ppdr = (void __iomem *)MCFGPIO_PORTELP, + .setr = (void __iomem *)MCFGPIO_SETEL, + .clrr = (void __iomem *)MCFGPIO_CLREL, + }, + { + .gpio_chip = { + .label = "AS", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 136, + .ngpio = 6, + }, + .pddr = (void __iomem *)MCFGPIO_DDRAS, + .podr = (void __iomem *)MCFGPIO_PORTAS, + .ppdr = (void __iomem *)MCFGPIO_PORTASP, + .setr = (void __iomem *)MCFGPIO_SETAS, + .clrr = (void __iomem *)MCFGPIO_CLRAS, + }, + { + .gpio_chip = { + .label = "QS", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 144, + .ngpio = 7, + }, + .pddr = (void __iomem *)MCFGPIO_DDRQS, + .podr = (void __iomem *)MCFGPIO_PORTQS, + .ppdr = (void __iomem *)MCFGPIO_PORTQSP, + .setr = (void __iomem *)MCFGPIO_SETQS, + .clrr = (void __iomem *)MCFGPIO_CLRQS, + }, + { + .gpio_chip = { + .label = "SD", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 152, + .ngpio = 6, + }, + .pddr = (void __iomem *)MCFGPIO_DDRSD, + .podr = (void __iomem *)MCFGPIO_PORTSD, + .ppdr = (void __iomem *)MCFGPIO_PORTSDP, + .setr = (void __iomem *)MCFGPIO_SETSD, + .clrr = (void __iomem *)MCFGPIO_CLRSD, + }, + { + .gpio_chip = { + .label = "TC", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 160, + .ngpio = 4, + }, + .pddr = (void __iomem *)MCFGPIO_DDRTC, + .podr = (void __iomem *)MCFGPIO_PORTTC, + .ppdr = (void __iomem *)MCFGPIO_PORTTCP, + .setr = (void __iomem *)MCFGPIO_SETTC, + .clrr = (void __iomem *)MCFGPIO_CLRTC, + }, + { + .gpio_chip = { + .label = "TD", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 168, + .ngpio = 4, + }, + .pddr = (void __iomem *)MCFGPIO_DDRTD, + .podr = (void __iomem *)MCFGPIO_PORTTD, + .ppdr = (void __iomem *)MCFGPIO_PORTTDP, + .setr = (void __iomem *)MCFGPIO_SETTD, + .clrr = (void __iomem *)MCFGPIO_CLRTD, + }, + { + .gpio_chip = { + .label = "UA", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 176, + .ngpio = 4, + }, + .pddr = (void __iomem *)MCFGPIO_DDRUA, + .podr = (void __iomem *)MCFGPIO_PORTUA, + .ppdr = (void __iomem *)MCFGPIO_PORTUAP, + .setr = (void __iomem *)MCFGPIO_SETUA, + .clrr = (void __iomem *)MCFGPIO_CLRUA, + }, +}; + +static int __init mcf_gpio_init(void) +{ + unsigned i = 0; + while (i < ARRAY_SIZE(mcf_gpio_chips)) + (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); + return 0; +} + +core_initcall(mcf_gpio_init); |