diff -ruN a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c --- a/arch/arm/mach-ixp4xx/common.c 2008-10-08 20:24:05.000000000 -0700 +++ b/arch/arm/mach-ixp4xx/common.c 2009-01-16 20:55:10.000000000 -0800 @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -374,12 +375,39 @@ 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; +} +EXPORT_SYMBOL(ixp4xx_gpio_direction_input); + +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; +} +EXPORT_SYMBOL(ixp4xx_gpio_direction_output); + +static struct gpio_chip ixp4xx_gpio_chip = { + .label = "IXP4XX_GPIO_CHIP", + .direction_input = ixp4xx_gpio_direction_input, + .direction_output = ixp4xx_gpio_direction_output, + .get = gpio_get_value, + .set = 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; diff -ruN a/arch/arm/Kconfig b/arch/arm/Kconfig --- a/arch/arm/Kconfig 2009-01-18 19:45:37.000000000 +0100 +++ b/arch/arm/Kconfig 2009-01-28 15:30:22.000000000 +0100 @@ -355,6 +355,7 @@ select GENERIC_GPIO select GENERIC_TIME select GENERIC_CLOCKEVENTS + select ARCH_WANT_OPTIONAL_GPIOLIB select DMABOUNCE if PCI help Support for Intel's IXP4XX (XScale) family of processors. diff -ruN a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig --- a/arch/arm/mach-ixp4xx/Kconfig 2008-12-31 10:29:21.000000000 -0800 +++ b/arch/arm/mach-ixp4xx/Kconfig 2009-01-16 15:17:54.000000000 -0800 @@ -28,6 +28,7 @@ config MACH_CAMBRIA bool "Cambria" select PCI + select GPIOLIB help Say 'Y' here if you want your kernel to support the Gateworks Cambria series. For more information on this platform, diff -ruN a/include/asm-arm/arch-ixp4xx/gpio.h b/include/asm-arm/arch-ixp4xx/gpio.h --- a/arch/arm/mach-ixp4xx/include/mach/gpio.h 2008-10-08 20:24:05.000000000 -0700 +++ b/arch/arm/mach-ixp4xx/include/mach/gpio.h 2009-01-16 20:55:25.000000000 -0800 @@ -27,47 +27,31 @@ #include #include +#include /* cansleep wrappers */ -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); extern int irq_to_gpio(int gpio);