From: Imre Kaloz Subject: [RFC/PATCH] ARM: ixp4xx gpiolib support Date: Mon, 5 Sep 2011 14:49:51 +0200 This patch adds gpiolib support for the IXP4xx platform Signed-off-by: Imre Kaloz [bwh: Forward-ported to 3.4] --- arch/arm/Kconfig | 2 +- arch/arm/mach-ixp4xx/common.c | 39 +++++++++++++++++++++++++ arch/arm/mach-ixp4xx/include/mach/gpio.h | 46 ++++++++++-------------------- 3 files changed, 55 insertions(+), 32 deletions(-) Index: source_armel_none/arch/arm/Kconfig =================================================================== --- source_armel_none.orig/arch/arm/Kconfig 2012-01-07 20:47:15.000000000 +0100 +++ source_armel_none/arch/arm/Kconfig 2012-01-07 20:51:00.390593917 +0100 @@ -520,7 +520,7 @@ config ARCH_IXP4XX select ARCH_HAS_DMA_SET_COHERENT_MASK select CLKSRC_MMIO select CPU_XSCALE - select GENERIC_GPIO + select ARCH_REQUIRE_GPIOLIB select GENERIC_CLOCKEVENTS select MIGHT_HAVE_PCI select NEED_MACH_IO_H Index: source_armel_none/arch/arm/mach-ixp4xx/common.c =================================================================== --- source_armel_none.orig/arch/arm/mach-ixp4xx/common.c 2012-01-07 20:47:15.000000000 +0100 +++ source_armel_none/arch/arm/mach-ixp4xx/common.c 2012-01-07 20:51:00.390593917 +0100 @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -376,12 +377,50 @@ static struct platform_device *ixp46x_de unsigned long ixp4xx_exp_bus_size; EXPORT_SYMBOL(ixp4xx_exp_bus_size); +static int ixp4xx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) +{ + gpio_line_config(gpio, IXP4XX_GPIO_IN); + return 0; +} + +static int ixp4xx_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int level) +{ + gpio_line_set(gpio, level); + gpio_line_config(gpio, IXP4XX_GPIO_OUT); + return 0; +} + +static int ixp4xx_gpio_get_value(struct gpio_chip *chip, unsigned gpio) +{ + int value; + + gpio_line_get(gpio, &value); + return value; +} + +static void ixp4xx_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value) +{ + gpio_line_set(gpio, value); +} + +static struct gpio_chip ixp4xx_gpio_chip = { + .label = "IXP4XX_GPIO_CHIP", + .direction_input = ixp4xx_gpio_direction_input, + .direction_output = ixp4xx_gpio_direction_output, + .get = ixp4xx_gpio_get_value, + .set = ixp4xx_gpio_set_value, + .base = 0, + .ngpio = 16, +}; + void __init ixp4xx_sys_init(void) { ixp4xx_exp_bus_size = SZ_16M; platform_add_devices(ixp4xx_devices, ARRAY_SIZE(ixp4xx_devices)); + gpiochip_add(&ixp4xx_gpio_chip); + if (cpu_is_ixp46x()) { int region; Index: source_armel_none/arch/arm/mach-ixp4xx/include/mach/gpio.h =================================================================== --- source_armel_none.orig/arch/arm/mach-ixp4xx/include/mach/gpio.h 2012-01-07 20:47:15.000000000 +0100 +++ source_armel_none/arch/arm/mach-ixp4xx/include/mach/gpio.h 2012-01-07 20:51:00.390593917 +0100 @@ -27,49 +27,33 @@ #include #include +#include /* cansleep wrappers */ #define __ARM_GPIOLIB_COMPLEX -static inline int gpio_request(unsigned gpio, const char *label) -{ - return 0; -} - -static inline void gpio_free(unsigned gpio) -{ - might_sleep(); - - return; -} - -static inline int gpio_direction_input(unsigned gpio) -{ - gpio_line_config(gpio, IXP4XX_GPIO_IN); - return 0; -} - -static inline int gpio_direction_output(unsigned gpio, int level) -{ - gpio_line_set(gpio, level); - gpio_line_config(gpio, IXP4XX_GPIO_OUT); - return 0; -} +#define NR_BUILTIN_GPIO 16 static inline int gpio_get_value(unsigned gpio) { - int value; - - gpio_line_get(gpio, &value); - - return value; + if (gpio < NR_BUILTIN_GPIO) + { + int value; + gpio_line_get(gpio, &value); + return value; + } + else + return __gpio_get_value(gpio); } static inline void gpio_set_value(unsigned gpio, int value) { - gpio_line_set(gpio, value); + if (gpio < NR_BUILTIN_GPIO) + gpio_line_set(gpio, value); + else + __gpio_set_value(gpio, value); } -#include /* cansleep wrappers */ +#define gpio_cansleep __gpio_cansleep extern int gpio_to_irq(int gpio); #define gpio_to_irq gpio_to_irq