From ce1d43b9a9e8a3db8fe91696c0b0e3ac1a154e34 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Tue, 2 Aug 2011 19:51:03 +0200 Subject: MIPS: Alchemy: support multiple GPIO styles in one kernel For GPIOLIB=y decide at runtime which gpiochips to register; in the GPIOLIB=n case, the gpio headers need to be reshuffled a bit to make multiple implementations coexist peacefully. Signed-off-by: Manuel Lauss To: Linux-MIPS Patchwork: https://patchwork.linux-mips.org/patch/2679/ Signed-off-by: Ralf Baechle --- arch/mips/alchemy/common/Makefile | 4 +- arch/mips/alchemy/common/gpiolib-au1000.c | 126 ---------------------------- arch/mips/alchemy/common/gpiolib.c | 133 ++++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 129 deletions(-) delete mode 100644 arch/mips/alchemy/common/gpiolib-au1000.c create mode 100644 arch/mips/alchemy/common/gpiolib.c (limited to 'arch/mips/alchemy') diff --git a/arch/mips/alchemy/common/Makefile b/arch/mips/alchemy/common/Makefile index 27811fe341d..62f0d39e93c 100644 --- a/arch/mips/alchemy/common/Makefile +++ b/arch/mips/alchemy/common/Makefile @@ -12,9 +12,7 @@ obj-$(CONFIG_ALCHEMY_GPIOINT_AU1000) += irq.o # optional gpiolib support ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),) - ifeq ($(CONFIG_GPIOLIB),y) - obj-$(CONFIG_ALCHEMY_GPIOINT_AU1000) += gpiolib-au1000.o - endif + obj-$(CONFIG_GPIOLIB) += gpiolib.o endif obj-$(CONFIG_PCI) += pci.o diff --git a/arch/mips/alchemy/common/gpiolib-au1000.c b/arch/mips/alchemy/common/gpiolib-au1000.c deleted file mode 100644 index c8e1a94d4a9..00000000000 --- a/arch/mips/alchemy/common/gpiolib-au1000.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) 2007-2009, OpenWrt.org, Florian Fainelli - * GPIOLIB support for Au1000, Au1500, Au1100, Au1550 and Au12x0. - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Notes : - * au1000 SoC have only one GPIO block : GPIO1 - * Au1100, Au15x0, Au12x0 have a second one : GPIO2 - */ - -#include -#include -#include -#include -#include - -#include -#include - -static int gpio2_get(struct gpio_chip *chip, unsigned offset) -{ - return alchemy_gpio2_get_value(offset + ALCHEMY_GPIO2_BASE); -} - -static void gpio2_set(struct gpio_chip *chip, unsigned offset, int value) -{ - alchemy_gpio2_set_value(offset + ALCHEMY_GPIO2_BASE, value); -} - -static int gpio2_direction_input(struct gpio_chip *chip, unsigned offset) -{ - return alchemy_gpio2_direction_input(offset + ALCHEMY_GPIO2_BASE); -} - -static int gpio2_direction_output(struct gpio_chip *chip, unsigned offset, - int value) -{ - return alchemy_gpio2_direction_output(offset + ALCHEMY_GPIO2_BASE, - value); -} - -static int gpio2_to_irq(struct gpio_chip *chip, unsigned offset) -{ - return alchemy_gpio2_to_irq(offset + ALCHEMY_GPIO2_BASE); -} - - -static int gpio1_get(struct gpio_chip *chip, unsigned offset) -{ - return alchemy_gpio1_get_value(offset + ALCHEMY_GPIO1_BASE); -} - -static void gpio1_set(struct gpio_chip *chip, - unsigned offset, int value) -{ - alchemy_gpio1_set_value(offset + ALCHEMY_GPIO1_BASE, value); -} - -static int gpio1_direction_input(struct gpio_chip *chip, unsigned offset) -{ - return alchemy_gpio1_direction_input(offset + ALCHEMY_GPIO1_BASE); -} - -static int gpio1_direction_output(struct gpio_chip *chip, - unsigned offset, int value) -{ - return alchemy_gpio1_direction_output(offset + ALCHEMY_GPIO1_BASE, - value); -} - -static int gpio1_to_irq(struct gpio_chip *chip, unsigned offset) -{ - return alchemy_gpio1_to_irq(offset + ALCHEMY_GPIO1_BASE); -} - -struct gpio_chip alchemy_gpio_chip[] = { - [0] = { - .label = "alchemy-gpio1", - .direction_input = gpio1_direction_input, - .direction_output = gpio1_direction_output, - .get = gpio1_get, - .set = gpio1_set, - .to_irq = gpio1_to_irq, - .base = ALCHEMY_GPIO1_BASE, - .ngpio = ALCHEMY_GPIO1_NUM, - }, - [1] = { - .label = "alchemy-gpio2", - .direction_input = gpio2_direction_input, - .direction_output = gpio2_direction_output, - .get = gpio2_get, - .set = gpio2_set, - .to_irq = gpio2_to_irq, - .base = ALCHEMY_GPIO2_BASE, - .ngpio = ALCHEMY_GPIO2_NUM, - }, -}; - -static int __init alchemy_gpiolib_init(void) -{ - gpiochip_add(&alchemy_gpio_chip[0]); - if (alchemy_get_cputype() != ALCHEMY_CPU_AU1000) - gpiochip_add(&alchemy_gpio_chip[1]); - - return 0; -} -arch_initcall(alchemy_gpiolib_init); diff --git a/arch/mips/alchemy/common/gpiolib.c b/arch/mips/alchemy/common/gpiolib.c new file mode 100644 index 00000000000..91fb4d9e30f --- /dev/null +++ b/arch/mips/alchemy/common/gpiolib.c @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2007-2009, OpenWrt.org, Florian Fainelli + * GPIOLIB support for Alchemy chips. + * + * 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; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Notes : + * This file must ONLY be built when CONFIG_GPIOLIB=y and + * CONFIG_ALCHEMY_GPIO_INDIRECT=n, otherwise compilation will fail! + * au1000 SoC have only one GPIO block : GPIO1 + * Au1100, Au15x0, Au12x0 have a second one : GPIO2 + */ + +#include +#include +#include +#include +#include +#include + +static int gpio2_get(struct gpio_chip *chip, unsigned offset) +{ + return alchemy_gpio2_get_value(offset + ALCHEMY_GPIO2_BASE); +} + +static void gpio2_set(struct gpio_chip *chip, unsigned offset, int value) +{ + alchemy_gpio2_set_value(offset + ALCHEMY_GPIO2_BASE, value); +} + +static int gpio2_direction_input(struct gpio_chip *chip, unsigned offset) +{ + return alchemy_gpio2_direction_input(offset + ALCHEMY_GPIO2_BASE); +} + +static int gpio2_direction_output(struct gpio_chip *chip, unsigned offset, + int value) +{ + return alchemy_gpio2_direction_output(offset + ALCHEMY_GPIO2_BASE, + value); +} + +static int gpio2_to_irq(struct gpio_chip *chip, unsigned offset) +{ + return alchemy_gpio2_to_irq(offset + ALCHEMY_GPIO2_BASE); +} + + +static int gpio1_get(struct gpio_chip *chip, unsigned offset) +{ + return alchemy_gpio1_get_value(offset + ALCHEMY_GPIO1_BASE); +} + +static void gpio1_set(struct gpio_chip *chip, + unsigned offset, int value) +{ + alchemy_gpio1_set_value(offset + ALCHEMY_GPIO1_BASE, value); +} + +static int gpio1_direction_input(struct gpio_chip *chip, unsigned offset) +{ + return alchemy_gpio1_direction_input(offset + ALCHEMY_GPIO1_BASE); +} + +static int gpio1_direction_output(struct gpio_chip *chip, + unsigned offset, int value) +{ + return alchemy_gpio1_direction_output(offset + ALCHEMY_GPIO1_BASE, + value); +} + +static int gpio1_to_irq(struct gpio_chip *chip, unsigned offset) +{ + return alchemy_gpio1_to_irq(offset + ALCHEMY_GPIO1_BASE); +} + +struct gpio_chip alchemy_gpio_chip[] = { + [0] = { + .label = "alchemy-gpio1", + .direction_input = gpio1_direction_input, + .direction_output = gpio1_direction_output, + .get = gpio1_get, + .set = gpio1_set, + .to_irq = gpio1_to_irq, + .base = ALCHEMY_GPIO1_BASE, + .ngpio = ALCHEMY_GPIO1_NUM, + }, + [1] = { + .label = "alchemy-gpio2", + .direction_input = gpio2_direction_input, + .direction_output = gpio2_direction_output, + .get = gpio2_get, + .set = gpio2_set, + .to_irq = gpio2_to_irq, + .base = ALCHEMY_GPIO2_BASE, + .ngpio = ALCHEMY_GPIO2_NUM, + }, +}; + +static int __init alchemy_gpiochip_init(void) +{ + int ret = 0; + + switch (alchemy_get_cputype()) { + case ALCHEMY_CPU_AU1000: + ret = gpiochip_add(&alchemy_gpio_chip[0]); + break; + case ALCHEMY_CPU_AU1500...ALCHEMY_CPU_AU1200: + ret = gpiochip_add(&alchemy_gpio_chip[0]); + ret |= gpiochip_add(&alchemy_gpio_chip[1]); + break; + } + return ret; +} +arch_initcall(alchemy_gpiochip_init); -- cgit v1.2.3-18-g5258