diff --git a/[refs] b/[refs] index d29761d297f2..25c17361e78e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: d6de85e85edcc38c9edcde45a0a568818fcddc13 +refs/heads/master: 22770de11cb13e7120f973bca6c800de371a6717 diff --git a/trunk/Documentation/devicetree/bindings/gpio/gpio_lpc32xx.txt b/trunk/Documentation/devicetree/bindings/gpio/gpio_lpc32xx.txt deleted file mode 100644 index 49819367a011..000000000000 --- a/trunk/Documentation/devicetree/bindings/gpio/gpio_lpc32xx.txt +++ /dev/null @@ -1,43 +0,0 @@ -NXP LPC32xx SoC GPIO controller - -Required properties: -- compatible: must be "nxp,lpc3220-gpio" -- reg: Physical base address and length of the controller's registers. -- gpio-controller: Marks the device node as a GPIO controller. -- #gpio-cells: Should be 3: - 1) bank: - 0: GPIO P0 - 1: GPIO P1 - 2: GPIO P2 - 3: GPIO P3 - 4: GPI P3 - 5: GPO P3 - 2) pin number - 3) optional parameters: - - bit 0 specifies polarity (0 for normal, 1 for inverted) -- reg: Index of the GPIO group - -Example: - - gpio: gpio@40028000 { - compatible = "nxp,lpc3220-gpio"; - reg = <0x40028000 0x1000>; - gpio-controller; - #gpio-cells = <3>; /* bank, pin, flags */ - }; - - leds { - compatible = "gpio-leds"; - - led0 { - gpios = <&gpio 5 1 1>; /* GPO_P3 1, active low */ - linux,default-trigger = "heartbeat"; - default-state = "off"; - }; - - led1 { - gpios = <&gpio 5 14 1>; /* GPO_P3 14, active low */ - linux,default-trigger = "timer"; - default-state = "off"; - }; - }; diff --git a/trunk/Documentation/gpio.txt b/trunk/Documentation/gpio.txt index e08a883de36e..620a07844e8c 100644 --- a/trunk/Documentation/gpio.txt +++ b/trunk/Documentation/gpio.txt @@ -322,9 +322,6 @@ where 'flags' is currently defined to specify the following properties: * GPIOF_OPEN_DRAIN - gpio pin is open drain type. * GPIOF_OPEN_SOURCE - gpio pin is open source type. - * GPIOF_EXPORT_DIR_FIXED - export gpio to sysfs, keep direction - * GPIOF_EXPORT_DIR_CHANGEABLE - also export, allow changing direction - since GPIOF_INIT_* are only valid when configured as output, so group valid combinations as: diff --git a/trunk/arch/alpha/include/asm/gpio.h b/trunk/arch/alpha/include/asm/gpio.h index b3799d88ffcf..7dc6a6343c06 100644 --- a/trunk/arch/alpha/include/asm/gpio.h +++ b/trunk/arch/alpha/include/asm/gpio.h @@ -1,4 +1,55 @@ -#ifndef __LINUX_GPIO_H -#warning Include linux/gpio.h instead of asm/gpio.h -#include -#endif +/* + * Generic GPIO API implementation for Alpha. + * + * A stright copy of that for PowerPC which was: + * + * Copyright (c) 2007-2008 MontaVista Software, Inc. + * + * Author: Anton Vorontsov + * + * 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. + */ + +#ifndef _ASM_ALPHA_GPIO_H +#define _ASM_ALPHA_GPIO_H + +#include +#include + +#ifdef CONFIG_GPIOLIB + +/* + * We don't (yet) implement inlined/rapid versions for on-chip gpios. + * Just call gpiolib. + */ +static inline int gpio_get_value(unsigned int gpio) +{ + return __gpio_get_value(gpio); +} + +static inline void gpio_set_value(unsigned int gpio, int value) +{ + __gpio_set_value(gpio, value); +} + +static inline int gpio_cansleep(unsigned int gpio) +{ + return __gpio_cansleep(gpio); +} + +static inline int gpio_to_irq(unsigned int gpio) +{ + return __gpio_to_irq(gpio); +} + +static inline int irq_to_gpio(unsigned int irq) +{ + return -EINVAL; +} + +#endif /* CONFIG_GPIOLIB */ + +#endif /* _ASM_ALPHA_GPIO_H */ diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 777025e773d9..36586dba6fa6 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -1,7 +1,6 @@ config ARM bool default y - select ARCH_HAVE_CUSTOM_GPIO_H select HAVE_AOUT select HAVE_DMA_API_DEBUG select HAVE_IDE if PCI || ISA || PCMCIA diff --git a/trunk/arch/arm/mach-imx/mach-mx35_3ds.c b/trunk/arch/arm/mach-imx/mach-mx35_3ds.c index 6a7cf91ee819..6ae51c6b95b7 100644 --- a/trunk/arch/arm/mach-imx/mach-mx35_3ds.c +++ b/trunk/arch/arm/mach-imx/mach-mx35_3ds.c @@ -96,7 +96,8 @@ static struct i2c_board_info __initdata i2c_devices_3ds[] = { static int lcd_power_gpio = -ENXIO; -static int mc9s08dz60_gpiochip_match(struct gpio_chip *chip, void *data) +static int mc9s08dz60_gpiochip_match(struct gpio_chip *chip, + const void *data) { return !strcmp(chip->label, data); } diff --git a/trunk/arch/arm/mach-lpc32xx/include/mach/gpio.h b/trunk/arch/arm/mach-lpc32xx/include/mach/gpio.h index 2ba6ca412bef..40a8c178f10d 100644 --- a/trunk/arch/arm/mach-lpc32xx/include/mach/gpio.h +++ b/trunk/arch/arm/mach-lpc32xx/include/mach/gpio.h @@ -1,8 +1 @@ -#ifndef __MACH_GPIO_H -#define __MACH_GPIO_H - -#include "gpio-lpc32xx.h" - -#define ARCH_NR_GPIOS (LPC32XX_GPO_P3_GRP + LPC32XX_GPO_P3_MAX) - -#endif /* __MACH_GPIO_H */ +/* empty */ diff --git a/trunk/arch/avr32/Kconfig b/trunk/arch/avr32/Kconfig index 859b2de4a624..3dea7231f637 100644 --- a/trunk/arch/avr32/Kconfig +++ b/trunk/arch/avr32/Kconfig @@ -11,7 +11,6 @@ config AVR32 select GENERIC_ATOMIC64 select HARDIRQS_SW_RESEND select GENERIC_IRQ_SHOW - select ARCH_HAVE_CUSTOM_GPIO_H select ARCH_HAVE_NMI_SAFE_CMPXCHG help AVR32 is a high-performance 32-bit RISC microprocessor core, diff --git a/trunk/arch/blackfin/Kconfig b/trunk/arch/blackfin/Kconfig index bf3d80f9738b..373a6902d8fa 100644 --- a/trunk/arch/blackfin/Kconfig +++ b/trunk/arch/blackfin/Kconfig @@ -31,7 +31,6 @@ config BLACKFIN select HAVE_KERNEL_LZO if RAMKERNEL select HAVE_OPROFILE select HAVE_PERF_EVENTS - select ARCH_HAVE_CUSTOM_GPIO_H select ARCH_WANT_OPTIONAL_GPIOLIB select HAVE_GENERIC_HARDIRQS select GENERIC_ATOMIC64 diff --git a/trunk/arch/ia64/include/asm/gpio.h b/trunk/arch/ia64/include/asm/gpio.h index b3799d88ffcf..590a20debc4e 100644 --- a/trunk/arch/ia64/include/asm/gpio.h +++ b/trunk/arch/ia64/include/asm/gpio.h @@ -1,4 +1,55 @@ -#ifndef __LINUX_GPIO_H -#warning Include linux/gpio.h instead of asm/gpio.h -#include -#endif +/* + * Generic GPIO API implementation for IA-64. + * + * A stright copy of that for PowerPC which was: + * + * Copyright (c) 2007-2008 MontaVista Software, Inc. + * + * Author: Anton Vorontsov + * + * 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. + */ + +#ifndef _ASM_IA64_GPIO_H +#define _ASM_IA64_GPIO_H + +#include +#include + +#ifdef CONFIG_GPIOLIB + +/* + * We don't (yet) implement inlined/rapid versions for on-chip gpios. + * Just call gpiolib. + */ +static inline int gpio_get_value(unsigned int gpio) +{ + return __gpio_get_value(gpio); +} + +static inline void gpio_set_value(unsigned int gpio, int value) +{ + __gpio_set_value(gpio, value); +} + +static inline int gpio_cansleep(unsigned int gpio) +{ + return __gpio_cansleep(gpio); +} + +static inline int gpio_to_irq(unsigned int gpio) +{ + return __gpio_to_irq(gpio); +} + +static inline int irq_to_gpio(unsigned int irq) +{ + return -EINVAL; +} + +#endif /* CONFIG_GPIOLIB */ + +#endif /* _ASM_IA64_GPIO_H */ diff --git a/trunk/arch/m68k/Kconfig.cpu b/trunk/arch/m68k/Kconfig.cpu index 8941af1d3ad2..8a9c767125a4 100644 --- a/trunk/arch/m68k/Kconfig.cpu +++ b/trunk/arch/m68k/Kconfig.cpu @@ -24,7 +24,6 @@ config COLDFIRE bool "Coldfire CPU family support" select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB - select ARCH_HAVE_CUSTOM_GPIO_H select CPU_HAS_NO_BITFIELDS select CPU_HAS_NO_MULDIV64 select GENERIC_CSUM diff --git a/trunk/arch/microblaze/include/asm/gpio.h b/trunk/arch/microblaze/include/asm/gpio.h index b3799d88ffcf..2b2c18be71c6 100644 --- a/trunk/arch/microblaze/include/asm/gpio.h +++ b/trunk/arch/microblaze/include/asm/gpio.h @@ -1,4 +1,53 @@ -#ifndef __LINUX_GPIO_H -#warning Include linux/gpio.h instead of asm/gpio.h -#include -#endif +/* + * Generic GPIO API implementation for PowerPC. + * + * Copyright (c) 2007-2008 MontaVista Software, Inc. + * + * Author: Anton Vorontsov + * + * 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. + */ + +#ifndef _ASM_MICROBLAZE_GPIO_H +#define _ASM_MICROBLAZE_GPIO_H + +#include +#include + +#ifdef CONFIG_GPIOLIB + +/* + * We don't (yet) implement inlined/rapid versions for on-chip gpios. + * Just call gpiolib. + */ +static inline int gpio_get_value(unsigned int gpio) +{ + return __gpio_get_value(gpio); +} + +static inline void gpio_set_value(unsigned int gpio, int value) +{ + __gpio_set_value(gpio, value); +} + +static inline int gpio_cansleep(unsigned int gpio) +{ + return __gpio_cansleep(gpio); +} + +static inline int gpio_to_irq(unsigned int gpio) +{ + return __gpio_to_irq(gpio); +} + +static inline int irq_to_gpio(unsigned int irq) +{ + return -EINVAL; +} + +#endif /* CONFIG_GPIOLIB */ + +#endif /* _ASM_MICROBLAZE_GPIO_H */ diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index 63321b283fe4..ce30e2f91d77 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -8,7 +8,6 @@ config MIPS select HAVE_PERF_EVENTS select PERF_USE_VMALLOC select HAVE_ARCH_KGDB - select ARCH_HAVE_CUSTOM_GPIO_H select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_TRACE_MCOUNT_TEST select HAVE_DYNAMIC_FTRACE diff --git a/trunk/arch/openrisc/include/asm/gpio.h b/trunk/arch/openrisc/include/asm/gpio.h index b3799d88ffcf..0b0d174f47cd 100644 --- a/trunk/arch/openrisc/include/asm/gpio.h +++ b/trunk/arch/openrisc/include/asm/gpio.h @@ -1,4 +1,65 @@ -#ifndef __LINUX_GPIO_H -#warning Include linux/gpio.h instead of asm/gpio.h -#include -#endif +/* + * OpenRISC Linux + * + * Linux architectural port borrowing liberally from similar works of + * others. All original copyrights apply as per the original source + * declaration. + * + * OpenRISC implementation: + * Copyright (C) 2003 Matjaz Breskvar + * Copyright (C) 2010-2011 Jonas Bonn + * et al. + * + * 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. + */ + +#ifndef __ASM_OPENRISC_GPIO_H +#define __ASM_OPENRISC_GPIO_H + +#include +#include + +#ifdef CONFIG_GPIOLIB + +/* + * OpenRISC (or1k) does not have on-chip GPIO's so there is not really + * any standardized implementation that makes sense here. If passing + * through gpiolib becomes a bottleneck then it may make sense, on a + * case-by-case basis, to implement these inlined/rapid versions. + * + * Just call gpiolib. + */ +static inline int gpio_get_value(unsigned int gpio) +{ + return __gpio_get_value(gpio); +} + +static inline void gpio_set_value(unsigned int gpio, int value) +{ + __gpio_set_value(gpio, value); +} + +static inline int gpio_cansleep(unsigned int gpio) +{ + return __gpio_cansleep(gpio); +} + +/* + * Not implemented, yet. + */ +static inline int gpio_to_irq(unsigned int gpio) +{ + return -ENOSYS; +} + +static inline int irq_to_gpio(unsigned int irq) +{ + return -EINVAL; +} + +#endif /* CONFIG_GPIOLIB */ + +#endif /* __ASM_OPENRISC_GPIO_H */ diff --git a/trunk/arch/powerpc/include/asm/gpio.h b/trunk/arch/powerpc/include/asm/gpio.h index b3799d88ffcf..38762edb5e58 100644 --- a/trunk/arch/powerpc/include/asm/gpio.h +++ b/trunk/arch/powerpc/include/asm/gpio.h @@ -1,4 +1,53 @@ -#ifndef __LINUX_GPIO_H -#warning Include linux/gpio.h instead of asm/gpio.h -#include -#endif +/* + * Generic GPIO API implementation for PowerPC. + * + * Copyright (c) 2007-2008 MontaVista Software, Inc. + * + * Author: Anton Vorontsov + * + * 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. + */ + +#ifndef __ASM_POWERPC_GPIO_H +#define __ASM_POWERPC_GPIO_H + +#include +#include + +#ifdef CONFIG_GPIOLIB + +/* + * We don't (yet) implement inlined/rapid versions for on-chip gpios. + * Just call gpiolib. + */ +static inline int gpio_get_value(unsigned int gpio) +{ + return __gpio_get_value(gpio); +} + +static inline void gpio_set_value(unsigned int gpio, int value) +{ + __gpio_set_value(gpio, value); +} + +static inline int gpio_cansleep(unsigned int gpio) +{ + return __gpio_cansleep(gpio); +} + +static inline int gpio_to_irq(unsigned int gpio) +{ + return __gpio_to_irq(gpio); +} + +static inline int irq_to_gpio(unsigned int irq) +{ + return -EINVAL; +} + +#endif /* CONFIG_GPIOLIB */ + +#endif /* __ASM_POWERPC_GPIO_H */ diff --git a/trunk/arch/sh/Kconfig b/trunk/arch/sh/Kconfig index c40b29ac3644..ff9e033ce626 100644 --- a/trunk/arch/sh/Kconfig +++ b/trunk/arch/sh/Kconfig @@ -13,7 +13,6 @@ config SUPERH select HAVE_DMA_ATTRS select HAVE_IRQ_WORK select HAVE_PERF_EVENTS - select ARCH_HAVE_CUSTOM_GPIO_H select ARCH_HAVE_NMI_SAFE_CMPXCHG if (GUSA_RB || CPU_SH4A) select PERF_USE_VMALLOC select HAVE_KERNEL_GZIP diff --git a/trunk/arch/sparc/include/asm/gpio.h b/trunk/arch/sparc/include/asm/gpio.h index b3799d88ffcf..a0e3ac0af599 100644 --- a/trunk/arch/sparc/include/asm/gpio.h +++ b/trunk/arch/sparc/include/asm/gpio.h @@ -1,4 +1,36 @@ -#ifndef __LINUX_GPIO_H -#warning Include linux/gpio.h instead of asm/gpio.h -#include -#endif +#ifndef __ASM_SPARC_GPIO_H +#define __ASM_SPARC_GPIO_H + +#include +#include + +#ifdef CONFIG_GPIOLIB + +static inline int gpio_get_value(unsigned int gpio) +{ + return __gpio_get_value(gpio); +} + +static inline void gpio_set_value(unsigned int gpio, int value) +{ + __gpio_set_value(gpio, value); +} + +static inline int gpio_cansleep(unsigned int gpio) +{ + return __gpio_cansleep(gpio); +} + +static inline int gpio_to_irq(unsigned int gpio) +{ + return -ENOSYS; +} + +static inline int irq_to_gpio(unsigned int irq) +{ + return -EINVAL; +} + +#endif /* CONFIG_GPIOLIB */ + +#endif /* __ASM_SPARC_GPIO_H */ diff --git a/trunk/arch/unicore32/Kconfig b/trunk/arch/unicore32/Kconfig index 7ff6d10c0be2..eeb8054c7cd8 100644 --- a/trunk/arch/unicore32/Kconfig +++ b/trunk/arch/unicore32/Kconfig @@ -8,7 +8,6 @@ config UNICORE32 select HAVE_KERNEL_BZIP2 select HAVE_KERNEL_LZO select HAVE_KERNEL_LZMA - select ARCH_HAVE_CUSTOM_GPIO_H select GENERIC_FIND_FIRST_BIT select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW diff --git a/trunk/arch/x86/include/asm/gpio.h b/trunk/arch/x86/include/asm/gpio.h index b3799d88ffcf..91d915a65259 100644 --- a/trunk/arch/x86/include/asm/gpio.h +++ b/trunk/arch/x86/include/asm/gpio.h @@ -1,4 +1,53 @@ -#ifndef __LINUX_GPIO_H -#warning Include linux/gpio.h instead of asm/gpio.h -#include -#endif +/* + * Generic GPIO API implementation for x86. + * + * Derived from the generic GPIO API for powerpc: + * + * Copyright (c) 2007-2008 MontaVista Software, Inc. + * + * Author: Anton Vorontsov + * + * 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. + */ + +#ifndef _ASM_X86_GPIO_H +#define _ASM_X86_GPIO_H + +#include + +#ifdef CONFIG_GPIOLIB + +/* + * Just call gpiolib. + */ +static inline int gpio_get_value(unsigned int gpio) +{ + return __gpio_get_value(gpio); +} + +static inline void gpio_set_value(unsigned int gpio, int value) +{ + __gpio_set_value(gpio, value); +} + +static inline int gpio_cansleep(unsigned int gpio) +{ + return __gpio_cansleep(gpio); +} + +static inline int gpio_to_irq(unsigned int gpio) +{ + return __gpio_to_irq(gpio); +} + +static inline int irq_to_gpio(unsigned int irq) +{ + return -EINVAL; +} + +#endif /* CONFIG_GPIOLIB */ + +#endif /* _ASM_X86_GPIO_H */ diff --git a/trunk/arch/xtensa/include/asm/gpio.h b/trunk/arch/xtensa/include/asm/gpio.h index b3799d88ffcf..a8c9fc46c790 100644 --- a/trunk/arch/xtensa/include/asm/gpio.h +++ b/trunk/arch/xtensa/include/asm/gpio.h @@ -1,4 +1,56 @@ -#ifndef __LINUX_GPIO_H -#warning Include linux/gpio.h instead of asm/gpio.h -#include -#endif +/* + * Generic GPIO API implementation for xtensa. + * + * Stolen from x86, which is derived from the generic GPIO API for powerpc: + * + * Copyright (c) 2007-2008 MontaVista Software, Inc. + * + * Author: Anton Vorontsov + * + * 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. + */ + +#ifndef _ASM_XTENSA_GPIO_H +#define _ASM_XTENSA_GPIO_H + +#include + +#ifdef CONFIG_GPIOLIB + +/* + * Just call gpiolib. + */ +static inline int gpio_get_value(unsigned int gpio) +{ + return __gpio_get_value(gpio); +} + +static inline void gpio_set_value(unsigned int gpio, int value) +{ + __gpio_set_value(gpio, value); +} + +static inline int gpio_cansleep(unsigned int gpio) +{ + return __gpio_cansleep(gpio); +} + +static inline int gpio_to_irq(unsigned int gpio) +{ + return __gpio_to_irq(gpio); +} + +/* + * Not implemented, yet. + */ +static inline int irq_to_gpio(unsigned int irq) +{ + return -EINVAL; +} + +#endif /* CONFIG_GPIOLIB */ + +#endif /* _ASM_XTENSA_GPIO_H */ diff --git a/trunk/drivers/gpio/Kconfig b/trunk/drivers/gpio/Kconfig index 25535ebf4f90..e03653d69357 100644 --- a/trunk/drivers/gpio/Kconfig +++ b/trunk/drivers/gpio/Kconfig @@ -2,14 +2,6 @@ # GPIO infrastructure and drivers # -config ARCH_HAVE_CUSTOM_GPIO_H - bool - help - Selecting this config option from the architecture Kconfig allows - the architecture to provide a custom asm/gpio.h implementation - overriding the default implementations. New uses of this are - strongly discouraged. - config ARCH_WANT_OPTIONAL_GPIOLIB bool help @@ -45,10 +37,6 @@ menuconfig GPIOLIB if GPIOLIB -config OF_GPIO - def_bool y - depends on OF && !SPARC - config DEBUG_GPIO bool "Debug GPIO calls" depends on DEBUG_KERNEL @@ -255,7 +243,7 @@ config GPIO_MC9S08DZ60 Select this to enable the MC9S08DZ60 GPIO driver config GPIO_PCA953X - tristate "PCA953x, PCA955x, PCA957x, TCA64xx, and MAX7310 I/O ports" + tristate "PCA953x, PCA955x, TCA64xx, and MAX7310 I/O ports" depends on I2C help Say yes here to provide access to several register-oriented @@ -264,11 +252,10 @@ config GPIO_PCA953X 4 bits: pca9536, pca9537 - 8 bits: max7310, max7315, pca6107, pca9534, pca9538, pca9554, - pca9556, pca9557, pca9574, tca6408 + 8 bits: max7310, pca9534, pca9538, pca9554, pca9557, + tca6408 - 16 bits: max7312, max7313, pca9535, pca9539, pca9555, pca9575, - tca6416 + 16 bits: pca9535, pca9539, pca9555, tca6416 config GPIO_PCA953X_IRQ bool "Interrupt controller support for PCA953x" @@ -412,7 +399,6 @@ config GPIO_BT8XX config GPIO_LANGWELL bool "Intel Langwell/Penwell GPIO support" depends on PCI && X86 - select IRQ_DOMAIN help Say Y here to support Intel Langwell/Penwell GPIO. @@ -528,12 +514,4 @@ config GPIO_TPS65910 help Select this option to enable GPIO driver for the TPS65910 chip family. - -config GPIO_MSIC - bool "Intel MSIC mixed signal gpio support" - depends on MFD_INTEL_MSIC - help - Enable support for GPIO on intel MSIC controllers found in - intel MID devices - endif diff --git a/trunk/drivers/gpio/Makefile b/trunk/drivers/gpio/Makefile index 7862f49b4d05..007f54bd0081 100644 --- a/trunk/drivers/gpio/Makefile +++ b/trunk/drivers/gpio/Makefile @@ -3,7 +3,6 @@ ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG obj-$(CONFIG_GPIOLIB) += gpiolib.o devres.o -obj-$(CONFIG_OF_GPIO) += gpiolib-of.o # Device drivers. Generally keep list sorted alphabetically obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o @@ -33,7 +32,6 @@ obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o obj-$(CONFIG_GPIO_ML_IOH) += gpio-ml-ioh.o obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o obj-$(CONFIG_GPIO_MPC8XXX) += gpio-mpc8xxx.o -obj-$(CONFIG_GPIO_MSIC) += gpio-msic.o obj-$(CONFIG_GPIO_MSM_V1) += gpio-msm-v1.o obj-$(CONFIG_GPIO_MSM_V2) += gpio-msm-v2.o obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o diff --git a/trunk/drivers/gpio/devres.c b/trunk/drivers/gpio/devres.c index d21a9ff38551..3dd29399cef5 100644 --- a/trunk/drivers/gpio/devres.c +++ b/trunk/drivers/gpio/devres.c @@ -70,35 +70,6 @@ int devm_gpio_request(struct device *dev, unsigned gpio, const char *label) } EXPORT_SYMBOL(devm_gpio_request); -/** - * devm_gpio_request_one - request a single GPIO with initial setup - * @dev: device to request for - * @gpio: the GPIO number - * @flags: GPIO configuration as specified by GPIOF_* - * @label: a literal description string of this GPIO - */ -int devm_gpio_request_one(struct device *dev, unsigned gpio, - unsigned long flags, const char *label) -{ - unsigned *dr; - int rc; - - dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL); - if (!dr) - return -ENOMEM; - - rc = gpio_request_one(gpio, flags, label); - if (rc) { - devres_free(dr); - return rc; - } - - *dr = gpio; - devres_add(dev, dr); - - return 0; -} - /** * devm_gpio_free - free an interrupt * @dev: device to free gpio for diff --git a/trunk/drivers/gpio/gpio-bt8xx.c b/trunk/drivers/gpio/gpio-bt8xx.c index e4cc7eb69bb2..5ca4098ba092 100644 --- a/trunk/drivers/gpio/gpio-bt8xx.c +++ b/trunk/drivers/gpio/gpio-bt8xx.c @@ -328,7 +328,17 @@ static struct pci_driver bt8xxgpio_pci_driver = { .resume = bt8xxgpio_resume, }; -module_pci_driver(bt8xxgpio_pci_driver); +static int __init bt8xxgpio_init(void) +{ + return pci_register_driver(&bt8xxgpio_pci_driver); +} +module_init(bt8xxgpio_init) + +static void __exit bt8xxgpio_exit(void) +{ + pci_unregister_driver(&bt8xxgpio_pci_driver); +} +module_exit(bt8xxgpio_exit) MODULE_LICENSE("GPL"); MODULE_AUTHOR("Michael Buesch"); diff --git a/trunk/drivers/gpio/gpio-langwell.c b/trunk/drivers/gpio/gpio-langwell.c index a1c8754f52cf..00692e89ef87 100644 --- a/trunk/drivers/gpio/gpio-langwell.c +++ b/trunk/drivers/gpio/gpio-langwell.c @@ -36,7 +36,6 @@ #include #include #include -#include /* * Langwell chip has 64 pins and thus there are 2 32bit registers to control @@ -67,8 +66,8 @@ struct lnw_gpio { struct gpio_chip chip; void *reg_base; spinlock_t lock; + unsigned irq_base; struct pci_dev *pdev; - struct irq_domain *domain; }; static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned offset, @@ -177,13 +176,13 @@ static int lnw_gpio_direction_output(struct gpio_chip *chip, static int lnw_gpio_to_irq(struct gpio_chip *chip, unsigned offset) { struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip); - return irq_create_mapping(lnw->domain, offset); + return lnw->irq_base + offset; } static int lnw_irq_type(struct irq_data *d, unsigned type) { struct lnw_gpio *lnw = irq_data_get_irq_chip_data(d); - u32 gpio = irqd_to_hwirq(d); + u32 gpio = d->irq - lnw->irq_base; unsigned long flags; u32 value; void __iomem *grer = gpio_reg(&lnw->chip, gpio, GRER); @@ -250,55 +249,20 @@ static void lnw_irq_handler(unsigned irq, struct irq_desc *desc) /* check GPIO controller to check which pin triggered the interrupt */ for (base = 0; base < lnw->chip.ngpio; base += 32) { gedr = gpio_reg(&lnw->chip, base, GEDR); - while ((pending = readl(gedr))) { + pending = readl(gedr); + while (pending) { gpio = __ffs(pending); mask = BIT(gpio); + pending &= ~mask; /* Clear before handling so we can't lose an edge */ writel(mask, gedr); - generic_handle_irq(irq_find_mapping(lnw->domain, - base + gpio)); + generic_handle_irq(lnw->irq_base + base + gpio); } } chip->irq_eoi(data); } -static void lnw_irq_init_hw(struct lnw_gpio *lnw) -{ - void __iomem *reg; - unsigned base; - - for (base = 0; base < lnw->chip.ngpio; base += 32) { - /* Clear the rising-edge detect register */ - reg = gpio_reg(&lnw->chip, base, GRER); - writel(0, reg); - /* Clear the falling-edge detect register */ - reg = gpio_reg(&lnw->chip, base, GFER); - writel(0, reg); - /* Clear the edge detect status register */ - reg = gpio_reg(&lnw->chip, base, GEDR); - writel(~0, reg); - } -} - -static int lnw_gpio_irq_map(struct irq_domain *d, unsigned int virq, - irq_hw_number_t hw) -{ - struct lnw_gpio *lnw = d->host_data; - - irq_set_chip_and_handler_name(virq, &lnw_irqchip, handle_simple_irq, - "demux"); - irq_set_chip_data(virq, lnw); - irq_set_irq_type(virq, IRQ_TYPE_NONE); - - return 0; -} - -static const struct irq_domain_ops lnw_gpio_irq_ops = { - .map = lnw_gpio_irq_map, - .xlate = irq_domain_xlate_twocell, -}; - #ifdef CONFIG_PM static int lnw_gpio_runtime_resume(struct device *dev) { @@ -336,22 +300,23 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id) { void *base; + int i; resource_size_t start, len; struct lnw_gpio *lnw; + u32 irq_base; u32 gpio_base; int retval = 0; - int ngpio = id->driver_data; retval = pci_enable_device(pdev); if (retval) - return retval; + goto done; retval = pci_request_regions(pdev, "langwell_gpio"); if (retval) { dev_err(&pdev->dev, "error requesting resources\n"); goto err2; } - /* get the gpio_base from bar1 */ + /* get the irq_base from bar1 */ start = pci_resource_start(pdev, 1); len = pci_resource_len(pdev, 1); base = ioremap_nocache(start, len); @@ -359,32 +324,28 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, dev_err(&pdev->dev, "error mapping bar1\n"); goto err3; } + irq_base = *(u32 *)base; gpio_base = *((u32 *)base + 1); /* release the IO mapping, since we already get the info from bar1 */ iounmap(base); /* get the register base from bar0 */ start = pci_resource_start(pdev, 0); len = pci_resource_len(pdev, 0); - base = devm_ioremap_nocache(&pdev->dev, start, len); + base = ioremap_nocache(start, len); if (!base) { dev_err(&pdev->dev, "error mapping bar0\n"); retval = -EFAULT; goto err3; } - lnw = devm_kzalloc(&pdev->dev, sizeof(struct lnw_gpio), GFP_KERNEL); + lnw = kzalloc(sizeof(struct lnw_gpio), GFP_KERNEL); if (!lnw) { dev_err(&pdev->dev, "can't allocate langwell_gpio chip data\n"); retval = -ENOMEM; - goto err3; + goto err4; } - - lnw->domain = irq_domain_add_linear(pdev->dev.of_node, ngpio, - &lnw_gpio_irq_ops, lnw); - if (!lnw->domain) - goto err3; - lnw->reg_base = base; + lnw->irq_base = irq_base; lnw->chip.label = dev_name(&pdev->dev); lnw->chip.request = lnw_gpio_request; lnw->chip.direction_input = lnw_gpio_direction_input; @@ -393,32 +354,38 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, lnw->chip.set = lnw_gpio_set; lnw->chip.to_irq = lnw_gpio_to_irq; lnw->chip.base = gpio_base; - lnw->chip.ngpio = ngpio; + lnw->chip.ngpio = id->driver_data; lnw->chip.can_sleep = 0; lnw->pdev = pdev; pci_set_drvdata(pdev, lnw); retval = gpiochip_add(&lnw->chip); if (retval) { dev_err(&pdev->dev, "langwell gpiochip_add error %d\n", retval); - goto err3; + goto err5; } - - lnw_irq_init_hw(lnw); - irq_set_handler_data(pdev->irq, lnw); irq_set_chained_handler(pdev->irq, lnw_irq_handler); + for (i = 0; i < lnw->chip.ngpio; i++) { + irq_set_chip_and_handler_name(i + lnw->irq_base, &lnw_irqchip, + handle_simple_irq, "demux"); + irq_set_chip_data(i + lnw->irq_base, lnw); + } spin_lock_init(&lnw->lock); pm_runtime_put_noidle(&pdev->dev); pm_runtime_allow(&pdev->dev); - return 0; - + goto done; +err5: + kfree(lnw); +err4: + iounmap(base); err3: pci_release_regions(pdev); err2: pci_disable_device(pdev); +done: return retval; } diff --git a/trunk/drivers/gpio/gpio-lpc32xx.c b/trunk/drivers/gpio/gpio-lpc32xx.c index c2199beca98a..61c2d08d37b6 100644 --- a/trunk/drivers/gpio/gpio-lpc32xx.c +++ b/trunk/drivers/gpio/gpio-lpc32xx.c @@ -21,9 +21,6 @@ #include #include #include -#include -#include -#include #include #include @@ -457,57 +454,10 @@ static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = { }, }; -/* Empty now, can be removed later when mach-lpc32xx is finally switched over - * to DT support - */ void __init lpc32xx_gpio_init(void) -{ -} - -static int lpc32xx_of_xlate(struct gpio_chip *gc, - const struct of_phandle_args *gpiospec, u32 *flags) -{ - /* Is this the correct bank? */ - u32 bank = gpiospec->args[0]; - if ((bank > ARRAY_SIZE(lpc32xx_gpiochip) || - (gc != &lpc32xx_gpiochip[bank].chip))) - return -EINVAL; - - if (flags) - *flags = gpiospec->args[2]; - return gpiospec->args[1]; -} - -static int __devinit lpc32xx_gpio_probe(struct platform_device *pdev) { int i; - for (i = 0; i < ARRAY_SIZE(lpc32xx_gpiochip); i++) { - if (pdev->dev.of_node) { - lpc32xx_gpiochip[i].chip.of_xlate = lpc32xx_of_xlate; - lpc32xx_gpiochip[i].chip.of_gpio_n_cells = 3; - lpc32xx_gpiochip[i].chip.of_node = pdev->dev.of_node; - } + for (i = 0; i < ARRAY_SIZE(lpc32xx_gpiochip); i++) gpiochip_add(&lpc32xx_gpiochip[i].chip); - } - - return 0; } - -#ifdef CONFIG_OF -static struct of_device_id lpc32xx_gpio_of_match[] __devinitdata = { - { .compatible = "nxp,lpc3220-gpio", }, - { }, -}; -#endif - -static struct platform_driver lpc32xx_gpio_driver = { - .driver = { - .name = "lpc32xx-gpio", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(lpc32xx_gpio_of_match), - }, - .probe = lpc32xx_gpio_probe, -}; - -module_platform_driver(lpc32xx_gpio_driver); diff --git a/trunk/drivers/gpio/gpio-mcp23s08.c b/trunk/drivers/gpio/gpio-mcp23s08.c index 0f425189de11..c5d83a8a91c2 100644 --- a/trunk/drivers/gpio/gpio-mcp23s08.c +++ b/trunk/drivers/gpio/gpio-mcp23s08.c @@ -353,7 +353,7 @@ static void mcp23s08_dbg_show(struct seq_file *s, struct gpio_chip *chip) chip->base + t, bank, t, label, (mcp->cache[MCP_IODIR] & mask) ? "in " : "out", (mcp->cache[MCP_GPIO] & mask) ? "hi" : "lo", - (mcp->cache[MCP_GPPU] & mask) ? "up" : " "); + (mcp->cache[MCP_GPPU] & mask) ? " " : "up"); /* NOTE: ignoring the irq-related registers */ seq_printf(s, "\n"); } diff --git a/trunk/drivers/gpio/gpio-ml-ioh.c b/trunk/drivers/gpio/gpio-ml-ioh.c index db01f151d41c..f0febe5b8221 100644 --- a/trunk/drivers/gpio/gpio-ml-ioh.c +++ b/trunk/drivers/gpio/gpio-ml-ioh.c @@ -611,7 +611,17 @@ static struct pci_driver ioh_gpio_driver = { .resume = ioh_gpio_resume }; -module_pci_driver(ioh_gpio_driver); +static int __init ioh_gpio_pci_init(void) +{ + return pci_register_driver(&ioh_gpio_driver); +} +module_init(ioh_gpio_pci_init); + +static void __exit ioh_gpio_pci_exit(void) +{ + pci_unregister_driver(&ioh_gpio_driver); +} +module_exit(ioh_gpio_pci_exit); MODULE_DESCRIPTION("OKI SEMICONDUCTOR ML-IOH series GPIO Driver"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/gpio/gpio-mpc8xxx.c b/trunk/drivers/gpio/gpio-mpc8xxx.c index 5a1817eedd1b..e6568c19c939 100644 --- a/trunk/drivers/gpio/gpio-mpc8xxx.c +++ b/trunk/drivers/gpio/gpio-mpc8xxx.c @@ -163,8 +163,7 @@ static void mpc8xxx_gpio_irq_cascade(unsigned int irq, struct irq_desc *desc) if (mask) generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq, 32 - ffs(mask))); - if (chip->irq_eoi) - chip->irq_eoi(&desc->irq_data); + chip->irq_eoi(&desc->irq_data); } static void mpc8xxx_irq_unmask(struct irq_data *d) diff --git a/trunk/drivers/gpio/gpio-msic.c b/trunk/drivers/gpio/gpio-msic.c deleted file mode 100644 index 71a838f44501..000000000000 --- a/trunk/drivers/gpio/gpio-msic.c +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Intel Medfield MSIC GPIO driver> - * Copyright (c) 2011, Intel Corporation. - * - * Author: Mathias Nyman - * Based on intel_pmic_gpio.c - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * 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., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* the offset for the mapping of global gpio pin to irq */ -#define MSIC_GPIO_IRQ_OFFSET 0x100 - -#define MSIC_GPIO_DIR_IN 0 -#define MSIC_GPIO_DIR_OUT BIT(5) -#define MSIC_GPIO_TRIG_FALL BIT(1) -#define MSIC_GPIO_TRIG_RISE BIT(2) - -/* masks for msic gpio output GPIOxxxxCTLO registers */ -#define MSIC_GPIO_DIR_MASK BIT(5) -#define MSIC_GPIO_DRV_MASK BIT(4) -#define MSIC_GPIO_REN_MASK BIT(3) -#define MSIC_GPIO_RVAL_MASK (BIT(2) | BIT(1)) -#define MSIC_GPIO_DOUT_MASK BIT(0) - -/* masks for msic gpio input GPIOxxxxCTLI registers */ -#define MSIC_GPIO_GLBYP_MASK BIT(5) -#define MSIC_GPIO_DBNC_MASK (BIT(4) | BIT(3)) -#define MSIC_GPIO_INTCNT_MASK (BIT(2) | BIT(1)) -#define MSIC_GPIO_DIN_MASK BIT(0) - -#define MSIC_NUM_GPIO 24 - -struct msic_gpio { - struct platform_device *pdev; - struct mutex buslock; - struct gpio_chip chip; - int irq; - unsigned irq_base; - unsigned long trig_change_mask; - unsigned trig_type; -}; - -/* - * MSIC has 24 gpios, 16 low voltage (1.2-1.8v) and 8 high voltage (3v). - * Both the high and low voltage gpios are divided in two banks. - * GPIOs are numbered with GPIO0LV0 as gpio_base in the following order: - * GPIO0LV0..GPIO0LV7: low voltage, bank 0, gpio_base - * GPIO1LV0..GPIO1LV7: low voltage, bank 1, gpio_base + 8 - * GPIO0HV0..GPIO0HV3: high voltage, bank 0, gpio_base + 16 - * GPIO1HV0..GPIO1HV3: high voltage, bank 1, gpio_base + 20 - */ - -static int msic_gpio_to_ireg(unsigned offset) -{ - if (offset >= MSIC_NUM_GPIO) - return -EINVAL; - - if (offset < 8) - return INTEL_MSIC_GPIO0LV0CTLI - offset; - if (offset < 16) - return INTEL_MSIC_GPIO1LV0CTLI - offset + 8; - if (offset < 20) - return INTEL_MSIC_GPIO0HV0CTLI - offset + 16; - - return INTEL_MSIC_GPIO1HV0CTLI - offset + 20; -} - -static int msic_gpio_to_oreg(unsigned offset) -{ - if (offset >= MSIC_NUM_GPIO) - return -EINVAL; - - if (offset < 8) - return INTEL_MSIC_GPIO0LV0CTLO - offset; - if (offset < 16) - return INTEL_MSIC_GPIO1LV0CTLO - offset + 8; - if (offset < 20) - return INTEL_MSIC_GPIO0HV0CTLO - offset + 16; - - return INTEL_MSIC_GPIO1HV0CTLO + offset + 20; -} - -static int msic_gpio_direction_input(struct gpio_chip *chip, unsigned offset) -{ - int reg; - - reg = msic_gpio_to_oreg(offset); - if (reg < 0) - return reg; - - return intel_msic_reg_update(reg, MSIC_GPIO_DIR_IN, MSIC_GPIO_DIR_MASK); -} - -static int msic_gpio_direction_output(struct gpio_chip *chip, - unsigned offset, int value) -{ - int reg; - unsigned mask; - - value = (!!value) | MSIC_GPIO_DIR_OUT; - mask = MSIC_GPIO_DIR_MASK | MSIC_GPIO_DOUT_MASK; - - reg = msic_gpio_to_oreg(offset); - if (reg < 0) - return reg; - - return intel_msic_reg_update(reg, value, mask); -} - -static int msic_gpio_get(struct gpio_chip *chip, unsigned offset) -{ - u8 r; - int ret; - int reg; - - reg = msic_gpio_to_ireg(offset); - if (reg < 0) - return reg; - - ret = intel_msic_reg_read(reg, &r); - if (ret < 0) - return ret; - - return r & MSIC_GPIO_DIN_MASK; -} - -static void msic_gpio_set(struct gpio_chip *chip, unsigned offset, int value) -{ - int reg; - - reg = msic_gpio_to_oreg(offset); - if (reg < 0) - return; - - intel_msic_reg_update(reg, !!value , MSIC_GPIO_DOUT_MASK); -} - -/* - * This is called from genirq with mg->buslock locked and - * irq_desc->lock held. We can not access the scu bus here, so we - * store the change and update in the bus_sync_unlock() function below - */ -static int msic_irq_type(struct irq_data *data, unsigned type) -{ - struct msic_gpio *mg = irq_data_get_irq_chip_data(data); - u32 gpio = data->irq - mg->irq_base; - - if (gpio >= mg->chip.ngpio) - return -EINVAL; - - /* mark for which gpio the trigger changed, protected by buslock */ - mg->trig_change_mask |= (1 << gpio); - mg->trig_type = type; - - return 0; -} - -static int msic_gpio_to_irq(struct gpio_chip *chip, unsigned offset) -{ - struct msic_gpio *mg = container_of(chip, struct msic_gpio, chip); - return mg->irq_base + offset; -} - -static void msic_bus_lock(struct irq_data *data) -{ - struct msic_gpio *mg = irq_data_get_irq_chip_data(data); - mutex_lock(&mg->buslock); -} - -static void msic_bus_sync_unlock(struct irq_data *data) -{ - struct msic_gpio *mg = irq_data_get_irq_chip_data(data); - int offset; - int reg; - u8 trig = 0; - - /* We can only get one change at a time as the buslock covers the - entire transaction. The irq_desc->lock is dropped before we are - called but that is fine */ - if (mg->trig_change_mask) { - offset = __ffs(mg->trig_change_mask); - - reg = msic_gpio_to_ireg(offset); - if (reg < 0) - goto out; - - if (mg->trig_type & IRQ_TYPE_EDGE_RISING) - trig |= MSIC_GPIO_TRIG_RISE; - if (mg->trig_type & IRQ_TYPE_EDGE_FALLING) - trig |= MSIC_GPIO_TRIG_FALL; - - intel_msic_reg_update(reg, trig, MSIC_GPIO_INTCNT_MASK); - mg->trig_change_mask = 0; - } -out: - mutex_unlock(&mg->buslock); -} - -/* Firmware does all the masking and unmasking for us, no masking here. */ -static void msic_irq_unmask(struct irq_data *data) { } - -static void msic_irq_mask(struct irq_data *data) { } - -static struct irq_chip msic_irqchip = { - .name = "MSIC-GPIO", - .irq_mask = msic_irq_mask, - .irq_unmask = msic_irq_unmask, - .irq_set_type = msic_irq_type, - .irq_bus_lock = msic_bus_lock, - .irq_bus_sync_unlock = msic_bus_sync_unlock, -}; - -static void msic_gpio_irq_handler(unsigned irq, struct irq_desc *desc) -{ - struct irq_data *data = irq_desc_get_irq_data(desc); - struct msic_gpio *mg = irq_data_get_irq_handler_data(data); - struct irq_chip *chip = irq_data_get_irq_chip(data); - struct intel_msic *msic = pdev_to_intel_msic(mg->pdev); - int i; - int bitnr; - u8 pin; - unsigned long pending = 0; - - for (i = 0; i < (mg->chip.ngpio / BITS_PER_BYTE); i++) { - intel_msic_irq_read(msic, INTEL_MSIC_GPIO0LVIRQ + i, &pin); - pending = pin; - - if (pending) { - for_each_set_bit(bitnr, &pending, BITS_PER_BYTE) - generic_handle_irq(mg->irq_base + - (i * BITS_PER_BYTE) + bitnr); - } - } - chip->irq_eoi(data); -} - -static int __devinit platform_msic_gpio_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct intel_msic_gpio_pdata *pdata = dev->platform_data; - struct msic_gpio *mg; - int irq = platform_get_irq(pdev, 0); - int retval; - int i; - - if (irq < 0) { - dev_err(dev, "no IRQ line\n"); - return -EINVAL; - } - - if (!pdata || !pdata->gpio_base) { - dev_err(dev, "incorrect or missing platform data\n"); - return -EINVAL; - } - - mg = kzalloc(sizeof(*mg), GFP_KERNEL); - if (!mg) - return -ENOMEM; - - dev_set_drvdata(dev, mg); - - mg->pdev = pdev; - mg->irq = irq; - mg->irq_base = pdata->gpio_base + MSIC_GPIO_IRQ_OFFSET; - mg->chip.label = "msic_gpio"; - mg->chip.direction_input = msic_gpio_direction_input; - mg->chip.direction_output = msic_gpio_direction_output; - mg->chip.get = msic_gpio_get; - mg->chip.set = msic_gpio_set; - mg->chip.to_irq = msic_gpio_to_irq; - mg->chip.base = pdata->gpio_base; - mg->chip.ngpio = MSIC_NUM_GPIO; - mg->chip.can_sleep = 1; - mg->chip.dev = dev; - - mutex_init(&mg->buslock); - - retval = gpiochip_add(&mg->chip); - if (retval) { - dev_err(dev, "Adding MSIC gpio chip failed\n"); - goto err; - } - - for (i = 0; i < mg->chip.ngpio; i++) { - irq_set_chip_data(i + mg->irq_base, mg); - irq_set_chip_and_handler_name(i + mg->irq_base, - &msic_irqchip, - handle_simple_irq, - "demux"); - } - irq_set_chained_handler(mg->irq, msic_gpio_irq_handler); - irq_set_handler_data(mg->irq, mg); - - return 0; -err: - kfree(mg); - return retval; -} - -static struct platform_driver platform_msic_gpio_driver = { - .driver = { - .name = "msic_gpio", - .owner = THIS_MODULE, - }, - .probe = platform_msic_gpio_probe, -}; - -static int __init platform_msic_gpio_init(void) -{ - return platform_driver_register(&platform_msic_gpio_driver); -} - -subsys_initcall(platform_msic_gpio_init); - -MODULE_AUTHOR("Mathias Nyman "); -MODULE_DESCRIPTION("Intel Medfield MSIC GPIO driver"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/gpio/gpio-omap.c b/trunk/drivers/gpio/gpio-omap.c index 9b71f04538aa..b570a6aae6e6 100644 --- a/trunk/drivers/gpio/gpio-omap.c +++ b/trunk/drivers/gpio/gpio-omap.c @@ -1238,8 +1238,7 @@ static int omap_gpio_runtime_resume(struct device *dev) if (bank->get_context_loss_count) { context_lost_cnt_after = bank->get_context_loss_count(bank->dev); - if (context_lost_cnt_after != bank->context_loss_count || - !context_lost_cnt_after) { + if (context_lost_cnt_after != bank->context_loss_count) { omap_gpio_restore_context(bank); } else { spin_unlock_irqrestore(&bank->lock, flags); diff --git a/trunk/drivers/gpio/gpio-pca953x.c b/trunk/drivers/gpio/gpio-pca953x.c index 1c313c710be3..d3f3e8f54561 100644 --- a/trunk/drivers/gpio/gpio-pca953x.c +++ b/trunk/drivers/gpio/gpio-pca953x.c @@ -28,8 +28,6 @@ #define PCA953X_INVERT 2 #define PCA953X_DIRECTION 3 -#define REG_ADDR_AI 0x80 - #define PCA957X_IN 0 #define PCA957X_INVRT 1 #define PCA957X_BKEN 2 @@ -65,15 +63,15 @@ static const struct i2c_device_id pca953x_id[] = { { "pca6107", 8 | PCA953X_TYPE | PCA_INT, }, { "tca6408", 8 | PCA953X_TYPE | PCA_INT, }, { "tca6416", 16 | PCA953X_TYPE | PCA_INT, }, - { "tca6424", 24 | PCA953X_TYPE | PCA_INT, }, + /* NYET: { "tca6424", 24, }, */ { } }; MODULE_DEVICE_TABLE(i2c, pca953x_id); struct pca953x_chip { unsigned gpio_start; - u32 reg_output; - u32 reg_direction; + uint16_t reg_output; + uint16_t reg_direction; struct mutex i2c_lock; #ifdef CONFIG_GPIO_PCA953X_IRQ @@ -91,20 +89,12 @@ struct pca953x_chip { int chip_type; }; -static int pca953x_write_reg(struct pca953x_chip *chip, int reg, u32 val) +static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val) { int ret = 0; if (chip->gpio_chip.ngpio <= 8) ret = i2c_smbus_write_byte_data(chip->client, reg, val); - else if (chip->gpio_chip.ngpio == 24) { - ret = i2c_smbus_write_word_data(chip->client, - (reg << 2) | REG_ADDR_AI, - val & 0xffff); - ret = i2c_smbus_write_byte_data(chip->client, - (reg << 2) + 2, - (val & 0xff0000) >> 16); - } else { switch (chip->chip_type) { case PCA953X_TYPE: @@ -131,17 +121,12 @@ static int pca953x_write_reg(struct pca953x_chip *chip, int reg, u32 val) return 0; } -static int pca953x_read_reg(struct pca953x_chip *chip, int reg, u32 *val) +static int pca953x_read_reg(struct pca953x_chip *chip, int reg, uint16_t *val) { int ret; if (chip->gpio_chip.ngpio <= 8) ret = i2c_smbus_read_byte_data(chip->client, reg); - else if (chip->gpio_chip.ngpio == 24) { - ret = i2c_smbus_read_word_data(chip->client, reg << 2); - ret |= (i2c_smbus_read_byte_data(chip->client, - (reg << 2) + 2)<<16); - } else ret = i2c_smbus_read_word_data(chip->client, reg << 1); @@ -150,14 +135,14 @@ static int pca953x_read_reg(struct pca953x_chip *chip, int reg, u32 *val) return ret; } - *val = (u32)ret; + *val = (uint16_t)ret; return 0; } static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off) { struct pca953x_chip *chip; - uint reg_val; + uint16_t reg_val; int ret, offset = 0; chip = container_of(gc, struct pca953x_chip, gpio_chip); @@ -188,7 +173,7 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc, unsigned off, int val) { struct pca953x_chip *chip; - uint reg_val; + uint16_t reg_val; int ret, offset = 0; chip = container_of(gc, struct pca953x_chip, gpio_chip); @@ -238,7 +223,7 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc, static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) { struct pca953x_chip *chip; - u32 reg_val; + uint16_t reg_val; int ret, offset = 0; chip = container_of(gc, struct pca953x_chip, gpio_chip); @@ -268,7 +253,7 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val) { struct pca953x_chip *chip; - u32 reg_val; + uint16_t reg_val; int ret, offset = 0; chip = container_of(gc, struct pca953x_chip, gpio_chip); @@ -401,7 +386,7 @@ static struct irq_chip pca953x_irq_chip = { static uint16_t pca953x_irq_pending(struct pca953x_chip *chip) { - u32 cur_stat; + uint16_t cur_stat; uint16_t old_stat; uint16_t pending; uint16_t trigger; @@ -464,7 +449,6 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, { struct i2c_client *client = chip->client; int ret, offset = 0; - u32 temporary; if (irq_base != -1 && (id->driver_data & PCA_INT)) { @@ -478,8 +462,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, offset = PCA957X_IN; break; } - ret = pca953x_read_reg(chip, offset, &temporary); - chip->irq_stat = temporary; + ret = pca953x_read_reg(chip, offset, &chip->irq_stat); if (ret) goto out_failed; @@ -620,7 +603,7 @@ static int __devinit device_pca953x_init(struct pca953x_chip *chip, int invert) static int __devinit device_pca957x_init(struct pca953x_chip *chip, int invert) { int ret; - u32 val = 0; + uint16_t val = 0; /* Let every port in proper state, that could save power */ pca953x_write_reg(chip, PCA957X_PUPD, 0x0); diff --git a/trunk/drivers/gpio/gpio-pch.c b/trunk/drivers/gpio/gpio-pch.c index a05fdb6c464c..e8729cc2ba2b 100644 --- a/trunk/drivers/gpio/gpio-pch.c +++ b/trunk/drivers/gpio/gpio-pch.c @@ -539,7 +539,17 @@ static struct pci_driver pch_gpio_driver = { .resume = pch_gpio_resume }; -module_pci_driver(pch_gpio_driver); +static int __init pch_gpio_pci_init(void) +{ + return pci_register_driver(&pch_gpio_driver); +} +module_init(pch_gpio_pci_init); + +static void __exit pch_gpio_pci_exit(void) +{ + pci_unregister_driver(&pch_gpio_driver); +} +module_exit(pch_gpio_pci_exit); MODULE_DESCRIPTION("PCH GPIO PCI Driver"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/gpio/gpio-samsung.c b/trunk/drivers/gpio/gpio-samsung.c index 5d49aff3bb9e..19d6fc0229c3 100644 --- a/trunk/drivers/gpio/gpio-samsung.c +++ b/trunk/drivers/gpio/gpio-samsung.c @@ -2714,224 +2714,12 @@ static __init void exynos_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip, } #endif /* defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF) */ -static __init void exynos4_gpiolib_init(void) -{ -#ifdef CONFIG_CPU_EXYNOS4210 - struct samsung_gpio_chip *chip; - int i, nr_chips; - void __iomem *gpio_base1, *gpio_base2, *gpio_base3; - int group = 0; - void __iomem *gpx_base; - - /* gpio part1 */ - gpio_base1 = ioremap(EXYNOS4_PA_GPIO1, SZ_4K); - if (gpio_base1 == NULL) { - pr_err("unable to ioremap for gpio_base1\n"); - goto err_ioremap1; - } - - chip = exynos4_gpios_1; - nr_chips = ARRAY_SIZE(exynos4_gpios_1); - - for (i = 0; i < nr_chips; i++, chip++) { - if (!chip->config) { - chip->config = &exynos_gpio_cfg; - chip->group = group++; - } - exynos_gpiolib_attach_ofnode(chip, - EXYNOS4_PA_GPIO1, i * 0x20); - } - samsung_gpiolib_add_4bit_chips(exynos4_gpios_1, - nr_chips, gpio_base1); - - /* gpio part2 */ - gpio_base2 = ioremap(EXYNOS4_PA_GPIO2, SZ_4K); - if (gpio_base2 == NULL) { - pr_err("unable to ioremap for gpio_base2\n"); - goto err_ioremap2; - } - - /* need to set base address for gpx */ - chip = &exynos4_gpios_2[16]; - gpx_base = gpio_base2 + 0xC00; - for (i = 0; i < 4; i++, chip++, gpx_base += 0x20) - chip->base = gpx_base; - - chip = exynos4_gpios_2; - nr_chips = ARRAY_SIZE(exynos4_gpios_2); - - for (i = 0; i < nr_chips; i++, chip++) { - if (!chip->config) { - chip->config = &exynos_gpio_cfg; - chip->group = group++; - } - exynos_gpiolib_attach_ofnode(chip, - EXYNOS4_PA_GPIO2, i * 0x20); - } - samsung_gpiolib_add_4bit_chips(exynos4_gpios_2, - nr_chips, gpio_base2); - - /* gpio part3 */ - gpio_base3 = ioremap(EXYNOS4_PA_GPIO3, SZ_256); - if (gpio_base3 == NULL) { - pr_err("unable to ioremap for gpio_base3\n"); - goto err_ioremap3; - } - - chip = exynos4_gpios_3; - nr_chips = ARRAY_SIZE(exynos4_gpios_3); - - for (i = 0; i < nr_chips; i++, chip++) { - if (!chip->config) { - chip->config = &exynos_gpio_cfg; - chip->group = group++; - } - exynos_gpiolib_attach_ofnode(chip, - EXYNOS4_PA_GPIO3, i * 0x20); - } - samsung_gpiolib_add_4bit_chips(exynos4_gpios_3, - nr_chips, gpio_base3); - -#if defined(CONFIG_CPU_EXYNOS4210) && defined(CONFIG_S5P_GPIO_INT) - s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS); - s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS); -#endif - - return; - -err_ioremap3: - iounmap(gpio_base2); -err_ioremap2: - iounmap(gpio_base1); -err_ioremap1: - return; -#endif /* CONFIG_CPU_EXYNOS4210 */ -} - -static __init void exynos5_gpiolib_init(void) -{ -#ifdef CONFIG_SOC_EXYNOS5250 - struct samsung_gpio_chip *chip; - int i, nr_chips; - void __iomem *gpio_base1, *gpio_base2, *gpio_base3, *gpio_base4; - int group = 0; - void __iomem *gpx_base; - - /* gpio part1 */ - gpio_base1 = ioremap(EXYNOS5_PA_GPIO1, SZ_4K); - if (gpio_base1 == NULL) { - pr_err("unable to ioremap for gpio_base1\n"); - goto err_ioremap1; - } - - /* need to set base address for gpx */ - chip = &exynos5_gpios_1[20]; - gpx_base = gpio_base1 + 0xC00; - for (i = 0; i < 4; i++, chip++, gpx_base += 0x20) - chip->base = gpx_base; - - chip = exynos5_gpios_1; - nr_chips = ARRAY_SIZE(exynos5_gpios_1); - - for (i = 0; i < nr_chips; i++, chip++) { - if (!chip->config) { - chip->config = &exynos_gpio_cfg; - chip->group = group++; - } - exynos_gpiolib_attach_ofnode(chip, - EXYNOS5_PA_GPIO1, i * 0x20); - } - samsung_gpiolib_add_4bit_chips(exynos5_gpios_1, - nr_chips, gpio_base1); - - /* gpio part2 */ - gpio_base2 = ioremap(EXYNOS5_PA_GPIO2, SZ_4K); - if (gpio_base2 == NULL) { - pr_err("unable to ioremap for gpio_base2\n"); - goto err_ioremap2; - } - - chip = exynos5_gpios_2; - nr_chips = ARRAY_SIZE(exynos5_gpios_2); - - for (i = 0; i < nr_chips; i++, chip++) { - if (!chip->config) { - chip->config = &exynos_gpio_cfg; - chip->group = group++; - } - exynos_gpiolib_attach_ofnode(chip, - EXYNOS5_PA_GPIO2, i * 0x20); - } - samsung_gpiolib_add_4bit_chips(exynos5_gpios_2, - nr_chips, gpio_base2); - - /* gpio part3 */ - gpio_base3 = ioremap(EXYNOS5_PA_GPIO3, SZ_4K); - if (gpio_base3 == NULL) { - pr_err("unable to ioremap for gpio_base3\n"); - goto err_ioremap3; - } - - /* need to set base address for gpv */ - exynos5_gpios_3[0].base = gpio_base3; - exynos5_gpios_3[1].base = gpio_base3 + 0x20; - exynos5_gpios_3[2].base = gpio_base3 + 0x60; - exynos5_gpios_3[3].base = gpio_base3 + 0x80; - exynos5_gpios_3[4].base = gpio_base3 + 0xC0; - - chip = exynos5_gpios_3; - nr_chips = ARRAY_SIZE(exynos5_gpios_3); - - for (i = 0; i < nr_chips; i++, chip++) { - if (!chip->config) { - chip->config = &exynos_gpio_cfg; - chip->group = group++; - } - exynos_gpiolib_attach_ofnode(chip, - EXYNOS5_PA_GPIO3, i * 0x20); - } - samsung_gpiolib_add_4bit_chips(exynos5_gpios_3, - nr_chips, gpio_base3); - - /* gpio part4 */ - gpio_base4 = ioremap(EXYNOS5_PA_GPIO4, SZ_4K); - if (gpio_base4 == NULL) { - pr_err("unable to ioremap for gpio_base4\n"); - goto err_ioremap4; - } - - chip = exynos5_gpios_4; - nr_chips = ARRAY_SIZE(exynos5_gpios_4); - - for (i = 0; i < nr_chips; i++, chip++) { - if (!chip->config) { - chip->config = &exynos_gpio_cfg; - chip->group = group++; - } - exynos_gpiolib_attach_ofnode(chip, - EXYNOS5_PA_GPIO4, i * 0x20); - } - samsung_gpiolib_add_4bit_chips(exynos5_gpios_4, - nr_chips, gpio_base4); - return; - -err_ioremap4: - iounmap(gpio_base3); -err_ioremap3: - iounmap(gpio_base2); -err_ioremap2: - iounmap(gpio_base1); -err_ioremap1: - return; - -#endif /* CONFIG_SOC_EXYNOS5250 */ -} - /* TODO: cleanup soc_is_* */ static __init int samsung_gpiolib_init(void) { struct samsung_gpio_chip *chip; int i, nr_chips; + void __iomem *gpio_base1, *gpio_base2, *gpio_base3, *gpio_base4; int group = 0; samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs)); @@ -2997,15 +2785,200 @@ static __init int samsung_gpiolib_init(void) s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR); #endif } else if (soc_is_exynos4210()) { - exynos4_gpiolib_init(); +#ifdef CONFIG_CPU_EXYNOS4210 + void __iomem *gpx_base; + + /* gpio part1 */ + gpio_base1 = ioremap(EXYNOS4_PA_GPIO1, SZ_4K); + if (gpio_base1 == NULL) { + pr_err("unable to ioremap for gpio_base1\n"); + goto err_ioremap1; + } + + chip = exynos4_gpios_1; + nr_chips = ARRAY_SIZE(exynos4_gpios_1); + + for (i = 0; i < nr_chips; i++, chip++) { + if (!chip->config) { + chip->config = &exynos_gpio_cfg; + chip->group = group++; + } + exynos_gpiolib_attach_ofnode(chip, + EXYNOS4_PA_GPIO1, i * 0x20); + } + samsung_gpiolib_add_4bit_chips(exynos4_gpios_1, + nr_chips, gpio_base1); + + /* gpio part2 */ + gpio_base2 = ioremap(EXYNOS4_PA_GPIO2, SZ_4K); + if (gpio_base2 == NULL) { + pr_err("unable to ioremap for gpio_base2\n"); + goto err_ioremap2; + } + + /* need to set base address for gpx */ + chip = &exynos4_gpios_2[16]; + gpx_base = gpio_base2 + 0xC00; + for (i = 0; i < 4; i++, chip++, gpx_base += 0x20) + chip->base = gpx_base; + + chip = exynos4_gpios_2; + nr_chips = ARRAY_SIZE(exynos4_gpios_2); + + for (i = 0; i < nr_chips; i++, chip++) { + if (!chip->config) { + chip->config = &exynos_gpio_cfg; + chip->group = group++; + } + exynos_gpiolib_attach_ofnode(chip, + EXYNOS4_PA_GPIO2, i * 0x20); + } + samsung_gpiolib_add_4bit_chips(exynos4_gpios_2, + nr_chips, gpio_base2); + + /* gpio part3 */ + gpio_base3 = ioremap(EXYNOS4_PA_GPIO3, SZ_256); + if (gpio_base3 == NULL) { + pr_err("unable to ioremap for gpio_base3\n"); + goto err_ioremap3; + } + + chip = exynos4_gpios_3; + nr_chips = ARRAY_SIZE(exynos4_gpios_3); + + for (i = 0; i < nr_chips; i++, chip++) { + if (!chip->config) { + chip->config = &exynos_gpio_cfg; + chip->group = group++; + } + exynos_gpiolib_attach_ofnode(chip, + EXYNOS4_PA_GPIO3, i * 0x20); + } + samsung_gpiolib_add_4bit_chips(exynos4_gpios_3, + nr_chips, gpio_base3); + +#if defined(CONFIG_CPU_EXYNOS4210) && defined(CONFIG_S5P_GPIO_INT) + s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS); + s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS); +#endif + +#endif /* CONFIG_CPU_EXYNOS4210 */ } else if (soc_is_exynos5250()) { - exynos5_gpiolib_init(); +#ifdef CONFIG_SOC_EXYNOS5250 + void __iomem *gpx_base; + + /* gpio part1 */ + gpio_base1 = ioremap(EXYNOS5_PA_GPIO1, SZ_4K); + if (gpio_base1 == NULL) { + pr_err("unable to ioremap for gpio_base1\n"); + goto err_ioremap1; + } + + /* need to set base address for gpx */ + chip = &exynos5_gpios_1[20]; + gpx_base = gpio_base1 + 0xC00; + for (i = 0; i < 4; i++, chip++, gpx_base += 0x20) + chip->base = gpx_base; + + chip = exynos5_gpios_1; + nr_chips = ARRAY_SIZE(exynos5_gpios_1); + + for (i = 0; i < nr_chips; i++, chip++) { + if (!chip->config) { + chip->config = &exynos_gpio_cfg; + chip->group = group++; + } + exynos_gpiolib_attach_ofnode(chip, + EXYNOS5_PA_GPIO1, i * 0x20); + } + samsung_gpiolib_add_4bit_chips(exynos5_gpios_1, + nr_chips, gpio_base1); + + /* gpio part2 */ + gpio_base2 = ioremap(EXYNOS5_PA_GPIO2, SZ_4K); + if (gpio_base2 == NULL) { + pr_err("unable to ioremap for gpio_base2\n"); + goto err_ioremap2; + } + + chip = exynos5_gpios_2; + nr_chips = ARRAY_SIZE(exynos5_gpios_2); + + for (i = 0; i < nr_chips; i++, chip++) { + if (!chip->config) { + chip->config = &exynos_gpio_cfg; + chip->group = group++; + } + exynos_gpiolib_attach_ofnode(chip, + EXYNOS5_PA_GPIO2, i * 0x20); + } + samsung_gpiolib_add_4bit_chips(exynos5_gpios_2, + nr_chips, gpio_base2); + + /* gpio part3 */ + gpio_base3 = ioremap(EXYNOS5_PA_GPIO3, SZ_4K); + if (gpio_base3 == NULL) { + pr_err("unable to ioremap for gpio_base3\n"); + goto err_ioremap3; + } + + /* need to set base address for gpv */ + exynos5_gpios_3[0].base = gpio_base3; + exynos5_gpios_3[1].base = gpio_base3 + 0x20; + exynos5_gpios_3[2].base = gpio_base3 + 0x60; + exynos5_gpios_3[3].base = gpio_base3 + 0x80; + exynos5_gpios_3[4].base = gpio_base3 + 0xC0; + + chip = exynos5_gpios_3; + nr_chips = ARRAY_SIZE(exynos5_gpios_3); + + for (i = 0; i < nr_chips; i++, chip++) { + if (!chip->config) { + chip->config = &exynos_gpio_cfg; + chip->group = group++; + } + exynos_gpiolib_attach_ofnode(chip, + EXYNOS5_PA_GPIO3, i * 0x20); + } + samsung_gpiolib_add_4bit_chips(exynos5_gpios_3, + nr_chips, gpio_base3); + + /* gpio part4 */ + gpio_base4 = ioremap(EXYNOS5_PA_GPIO4, SZ_4K); + if (gpio_base4 == NULL) { + pr_err("unable to ioremap for gpio_base4\n"); + goto err_ioremap4; + } + + chip = exynos5_gpios_4; + nr_chips = ARRAY_SIZE(exynos5_gpios_4); + + for (i = 0; i < nr_chips; i++, chip++) { + if (!chip->config) { + chip->config = &exynos_gpio_cfg; + chip->group = group++; + } + exynos_gpiolib_attach_ofnode(chip, + EXYNOS5_PA_GPIO4, i * 0x20); + } + samsung_gpiolib_add_4bit_chips(exynos5_gpios_4, + nr_chips, gpio_base4); +#endif /* CONFIG_SOC_EXYNOS5250 */ } else { WARN(1, "Unknown SoC in gpio-samsung, no GPIOs added\n"); return -ENODEV; } return 0; + +err_ioremap4: + iounmap(gpio_base3); +err_ioremap3: + iounmap(gpio_base2); +err_ioremap2: + iounmap(gpio_base1); +err_ioremap1: + return -ENOMEM; } core_initcall(samsung_gpiolib_init); diff --git a/trunk/drivers/gpio/gpio-sodaville.c b/trunk/drivers/gpio/gpio-sodaville.c index 820209c420e3..031e5d24837d 100644 --- a/trunk/drivers/gpio/gpio-sodaville.c +++ b/trunk/drivers/gpio/gpio-sodaville.c @@ -282,7 +282,17 @@ static struct pci_driver sdv_gpio_driver = { .remove = sdv_gpio_remove, }; -module_pci_driver(sdv_gpio_driver); +static int __init sdv_gpio_init(void) +{ + return pci_register_driver(&sdv_gpio_driver); +} +module_init(sdv_gpio_init); + +static void __exit sdv_gpio_exit(void) +{ + pci_unregister_driver(&sdv_gpio_driver); +} +module_exit(sdv_gpio_exit); MODULE_AUTHOR("Hans J. Koch "); MODULE_DESCRIPTION("GPIO interface for Intel Sodaville SoCs"); diff --git a/trunk/drivers/gpio/gpiolib.c b/trunk/drivers/gpio/gpiolib.c index 38353c028fdd..5a75510d66bb 100644 --- a/trunk/drivers/gpio/gpiolib.c +++ b/trunk/drivers/gpio/gpiolib.c @@ -1156,7 +1156,7 @@ EXPORT_SYMBOL_GPL(gpiochip_remove); */ struct gpio_chip *gpiochip_find(const void *data, int (*match)(struct gpio_chip *chip, - void *data)) + const void *data)) { struct gpio_chip *chip = NULL; unsigned long flags; @@ -1302,18 +1302,8 @@ int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) (flags & GPIOF_INIT_HIGH) ? 1 : 0); if (err) - goto free_gpio; - - if (flags & GPIOF_EXPORT) { - err = gpio_export(gpio, flags & GPIOF_EXPORT_CHANGEABLE); - if (err) - goto free_gpio; - } - - return 0; + gpio_free(gpio); - free_gpio: - gpio_free(gpio); return err; } EXPORT_SYMBOL_GPL(gpio_request_one); diff --git a/trunk/drivers/of/Kconfig b/trunk/drivers/of/Kconfig index ce00d11144de..8e84ce9765a9 100644 --- a/trunk/drivers/of/Kconfig +++ b/trunk/drivers/of/Kconfig @@ -51,6 +51,12 @@ config OF_IRQ config OF_DEVICE def_bool y +config OF_GPIO + def_bool y + depends on GPIOLIB && !SPARC + help + OpenFirmware GPIO accessors + config OF_I2C def_tristate I2C depends on I2C && !SPARC diff --git a/trunk/drivers/of/Makefile b/trunk/drivers/of/Makefile index aff2c6230390..aa90e602c8a7 100644 --- a/trunk/drivers/of/Makefile +++ b/trunk/drivers/of/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_OF_PROMTREE) += pdt.o obj-$(CONFIG_OF_ADDRESS) += address.o obj-$(CONFIG_OF_IRQ) += irq.o obj-$(CONFIG_OF_DEVICE) += device.o platform.o +obj-$(CONFIG_OF_GPIO) += gpio.o obj-$(CONFIG_OF_I2C) += of_i2c.o obj-$(CONFIG_OF_NET) += of_net.o obj-$(CONFIG_OF_SPI) += of_spi.o diff --git a/trunk/drivers/gpio/gpiolib-of.c b/trunk/drivers/of/gpio.c similarity index 86% rename from trunk/drivers/gpio/gpiolib-of.c rename to trunk/drivers/of/gpio.c index d18068a9f3ec..bf984b6dc477 100644 --- a/trunk/drivers/gpio/gpiolib-of.c +++ b/trunk/drivers/of/gpio.c @@ -15,39 +15,11 @@ #include #include #include -#include #include #include #include #include -/* Private data structure for of_gpiochip_is_match */ -struct gg_data { - enum of_gpio_flags *flags; - struct of_phandle_args gpiospec; - - int out_gpio; -}; - -/* Private function for resolving node pointer to gpio_chip */ -static int of_gpiochip_find_and_xlate(struct gpio_chip *gc, void *data) -{ - struct gg_data *gg_data = data; - int ret; - - if ((gc->of_node != gg_data->gpiospec.np) || - (gc->of_gpio_n_cells != gg_data->gpiospec.args_count) || - (!gc->of_xlate)) - return false; - - ret = gc->of_xlate(gc, &gg_data->gpiospec, gg_data->flags); - if (ret < 0) - return false; - - gg_data->out_gpio = ret + gc->base; - return true; -} - /** * of_get_named_gpio_flags() - Get a GPIO number and flags to use with GPIO API * @np: device node to get GPIO from @@ -62,25 +34,46 @@ static int of_gpiochip_find_and_xlate(struct gpio_chip *gc, void *data) int of_get_named_gpio_flags(struct device_node *np, const char *propname, int index, enum of_gpio_flags *flags) { - struct gg_data gg_data = { .flags = flags, .out_gpio = -ENODEV }; int ret; - - /* .of_xlate might decide to not fill in the flags, so clear it. */ - if (flags) - *flags = 0; + struct gpio_chip *gc; + struct of_phandle_args gpiospec; ret = of_parse_phandle_with_args(np, propname, "#gpio-cells", index, - &gg_data.gpiospec); + &gpiospec); if (ret) { pr_debug("%s: can't parse gpios property\n", __func__); - return -EINVAL; + goto err0; } - gpiochip_find(&gg_data, of_gpiochip_find_and_xlate); + gc = of_node_to_gpiochip(gpiospec.np); + if (!gc) { + pr_debug("%s: gpio controller %s isn't registered\n", + np->full_name, gpiospec.np->full_name); + ret = -ENODEV; + goto err1; + } - of_node_put(gg_data.gpiospec.np); + if (gpiospec.args_count != gc->of_gpio_n_cells) { + pr_debug("%s: wrong #gpio-cells for %s\n", + np->full_name, gpiospec.np->full_name); + ret = -EINVAL; + goto err1; + } + + /* .xlate might decide to not fill in the flags, so clear it. */ + if (flags) + *flags = 0; + + ret = gc->of_xlate(gc, &gpiospec, flags); + if (ret < 0) + goto err1; + + ret += gc->base; +err1: + of_node_put(gpiospec.np); +err0: pr_debug("%s exited with status %d\n", __func__, ret); - return gg_data.out_gpio; + return ret; } EXPORT_SYMBOL(of_get_named_gpio_flags); @@ -234,3 +227,14 @@ void of_gpiochip_remove(struct gpio_chip *chip) if (chip->of_node) of_node_put(chip->of_node); } + +/* Private function for resolving node pointer to gpio_chip */ +static int of_gpiochip_is_match(struct gpio_chip *chip, const void *data) +{ + return chip->of_node == data; +} + +struct gpio_chip *of_node_to_gpiochip(struct device_node *np) +{ + return gpiochip_find(np, of_gpiochip_is_match); +} diff --git a/trunk/include/asm-generic/gpio.h b/trunk/include/asm-generic/gpio.h index 1ba08f0e49a3..5f52690c3c8f 100644 --- a/trunk/include/asm-generic/gpio.h +++ b/trunk/include/asm-generic/gpio.h @@ -144,7 +144,7 @@ extern int gpiochip_add(struct gpio_chip *chip); extern int __must_check gpiochip_remove(struct gpio_chip *chip); extern struct gpio_chip *gpiochip_find(const void *data, int (*match)(struct gpio_chip *chip, - void *data)); + const void *data)); /* Always use the library code for GPIO management calls, @@ -179,8 +179,6 @@ extern void gpio_free_array(const struct gpio *array, size_t num); /* bindings for managed devices that want to request gpios */ int devm_gpio_request(struct device *dev, unsigned gpio, const char *label); -int devm_gpio_request_one(struct device *dev, unsigned gpio, - unsigned long flags, const char *label); void devm_gpio_free(struct device *dev, unsigned int gpio); #ifdef CONFIG_GPIO_SYSFS diff --git a/trunk/include/linux/gpio.h b/trunk/include/linux/gpio.h index f07fc2d08159..6155ecf192b0 100644 --- a/trunk/include/linux/gpio.h +++ b/trunk/include/linux/gpio.h @@ -1,8 +1,6 @@ #ifndef __LINUX_GPIO_H #define __LINUX_GPIO_H -#include - /* see Documentation/gpio.txt */ /* make these flag values available regardless of GPIO kconfig options */ @@ -22,11 +20,6 @@ /* Gpio pin is open source */ #define GPIOF_OPEN_SOURCE (1 << 3) -#define GPIOF_EXPORT (1 << 2) -#define GPIOF_EXPORT_CHANGEABLE (1 << 3) -#define GPIOF_EXPORT_DIR_FIXED (GPIOF_EXPORT) -#define GPIOF_EXPORT_DIR_CHANGEABLE (GPIOF_EXPORT | GPIOF_EXPORT_CHANGEABLE) - /** * struct gpio - a structure describing a GPIO with configuration * @gpio: the GPIO number @@ -40,39 +33,7 @@ struct gpio { }; #ifdef CONFIG_GENERIC_GPIO - -#ifdef CONFIG_ARCH_HAVE_CUSTOM_GPIO_H #include -#else - -#include - -static inline int gpio_get_value(unsigned int gpio) -{ - return __gpio_get_value(gpio); -} - -static inline void gpio_set_value(unsigned int gpio, int value) -{ - __gpio_set_value(gpio, value); -} - -static inline int gpio_cansleep(unsigned int gpio) -{ - return __gpio_cansleep(gpio); -} - -static inline int gpio_to_irq(unsigned int gpio) -{ - return __gpio_to_irq(gpio); -} - -static inline int irq_to_gpio(unsigned int irq) -{ - return -EINVAL; -} - -#endif #else @@ -94,24 +55,12 @@ static inline int gpio_request(unsigned gpio, const char *label) return -ENOSYS; } -static inline int devm_gpio_request(struct device *dev, unsigned gpio, - const char *label) -{ - return -ENOSYS; -} - static inline int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) { return -ENOSYS; } -static inline int devm_gpio_request_one(struct device *dev, unsigned gpio, - unsigned long flags, const char *label) -{ - return -ENOSYS; -} - static inline int gpio_request_array(const struct gpio *array, size_t num) { return -ENOSYS; @@ -125,14 +74,6 @@ static inline void gpio_free(unsigned gpio) WARN_ON(1); } -static inline void devm_gpio_free(struct device *dev, unsigned gpio) -{ - might_sleep(); - - /* GPIO can never have been requested */ - WARN_ON(1); -} - static inline void gpio_free_array(const struct gpio *array, size_t num) { might_sleep(); diff --git a/trunk/include/linux/of_gpio.h b/trunk/include/linux/of_gpio.h index c454f5796747..81733d12cbea 100644 --- a/trunk/include/linux/of_gpio.h +++ b/trunk/include/linux/of_gpio.h @@ -58,6 +58,7 @@ extern int of_mm_gpiochip_add(struct device_node *np, extern void of_gpiochip_add(struct gpio_chip *gc); extern void of_gpiochip_remove(struct gpio_chip *gc); +extern struct gpio_chip *of_node_to_gpiochip(struct device_node *np); extern int of_gpio_simple_xlate(struct gpio_chip *gc, const struct of_phandle_args *gpiospec, u32 *flags);