diff options
27 files changed, 475 insertions, 198 deletions
diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile index 683fc387c8a..a9bb94fabaa 100644 --- a/arch/arm/mach-exynos4/Makefile +++ b/arch/arm/mach-exynos4/Makefile @@ -13,7 +13,7 @@ obj- := # Core support for EXYNOS4 system obj-$(CONFIG_CPU_EXYNOS4210) += cpu.o init.o clock.o irq-combiner.o -obj-$(CONFIG_CPU_EXYNOS4210) += setup-i2c0.o gpiolib.o irq-eint.o dma.o +obj-$(CONFIG_CPU_EXYNOS4210) += setup-i2c0.o irq-eint.o dma.o obj-$(CONFIG_PM) += pm.o sleep.o obj-$(CONFIG_CPU_FREQ) += cpufreq.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o diff --git a/arch/arm/mach-nomadik/Kconfig b/arch/arm/mach-nomadik/Kconfig index 71f3ea62397..3c5e0f522e9 100644 --- a/arch/arm/mach-nomadik/Kconfig +++ b/arch/arm/mach-nomadik/Kconfig @@ -6,7 +6,6 @@ config MACH_NOMADIK_8815NHK bool "ST 8815 Nomadik Hardware Kit (evaluation board)" select NOMADIK_8815 select HAS_MTU - select NOMADIK_GPIO endmenu diff --git a/arch/arm/mach-s5pc100/Makefile b/arch/arm/mach-s5pc100/Makefile index eecab57d2e5..a5e6e608b49 100644 --- a/arch/arm/mach-s5pc100/Makefile +++ b/arch/arm/mach-s5pc100/Makefile @@ -11,7 +11,7 @@ obj- := # Core support for S5PC100 system -obj-$(CONFIG_CPU_S5PC100) += cpu.o init.o clock.o gpiolib.o +obj-$(CONFIG_CPU_S5PC100) += cpu.o init.o clock.o obj-$(CONFIG_CPU_S5PC100) += setup-i2c0.o obj-$(CONFIG_CPU_S5PC100) += dma.o diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile index 11f17907b4e..50907aca006 100644 --- a/arch/arm/mach-s5pv210/Makefile +++ b/arch/arm/mach-s5pv210/Makefile @@ -12,7 +12,7 @@ obj- := # Core support for S5PV210 system -obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o dma.o gpiolib.o +obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o dma.o obj-$(CONFIG_CPU_S5PV210) += setup-i2c0.o obj-$(CONFIG_S5PV210_PM) += pm.o sleep.o obj-$(CONFIG_CPU_FREQ) += cpufreq.o diff --git a/arch/arm/mach-u300/Makefile b/arch/arm/mach-u300/Makefile index fab46fe9a71..8fd354aaf0a 100644 --- a/arch/arm/mach-u300/Makefile +++ b/arch/arm/mach-u300/Makefile @@ -2,7 +2,7 @@ # Makefile for the linux kernel, U300 machine. # -obj-y := core.o clock.o timer.o gpio.o padmux.o +obj-y := core.o clock.o timer.o padmux.o obj-m := obj-n := obj- := diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index 54429d01595..f8b9392ee34 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -5,7 +5,6 @@ config UX500_SOC_COMMON default y select ARM_GIC select HAS_MTU - select NOMADIK_GPIO select ARM_ERRATA_753970 menu "Ux500 SoC" diff --git a/arch/arm/plat-nomadik/Kconfig b/arch/arm/plat-nomadik/Kconfig index 18296ee6880..ce659015535 100644 --- a/arch/arm/plat-nomadik/Kconfig +++ b/arch/arm/plat-nomadik/Kconfig @@ -21,9 +21,4 @@ config HAS_MTU to multiple interrupt generating programmable 32-bit free running decrementing counters. -config NOMADIK_GPIO - bool - help - Support for the Nomadik GPIO controller. - endif diff --git a/arch/arm/plat-nomadik/Makefile b/arch/arm/plat-nomadik/Makefile index c33547361bd..37c7cdd0f8f 100644 --- a/arch/arm/plat-nomadik/Makefile +++ b/arch/arm/plat-nomadik/Makefile @@ -3,4 +3,3 @@ # Licensed under GPLv2 obj-$(CONFIG_HAS_MTU) += timer.o -obj-$(CONFIG_NOMADIK_GPIO) += gpio.o diff --git a/arch/arm/plat-nomadik/include/plat/gpio.h b/arch/arm/plat-nomadik/include/plat/gpio.h index 1b9f6f0843d..ea19a5b2f22 100644 --- a/arch/arm/plat-nomadik/include/plat/gpio.h +++ b/arch/arm/plat-nomadik/include/plat/gpio.h @@ -78,6 +78,8 @@ extern int nmk_gpio_get_mode(int gpio); extern void nmk_gpio_wakeups_suspend(void); extern void nmk_gpio_wakeups_resume(void); +extern void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up); + /* * Platform data to register a block: only the initial gpio/irq number. */ diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile index a4a12859fdd..f0233e6abcd 100644 --- a/arch/arm/plat-omap/Makefile +++ b/arch/arm/plat-omap/Makefile @@ -3,7 +3,7 @@ # # Common support -obj-y := common.o sram.o clock.o devices.o dma.o mux.o gpio.o \ +obj-y := common.o sram.o clock.o devices.o dma.o mux.o \ usb.o fb.o io.o counter_32k.o obj-m := obj-n := diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h index cac2e8ac696..ec97e00cb58 100644 --- a/arch/arm/plat-omap/include/plat/gpio.h +++ b/arch/arm/plat-omap/include/plat/gpio.h @@ -52,6 +52,109 @@ #define OMAP34XX_NR_GPIOS 6 +/* + * OMAP1510 GPIO registers + */ +#define OMAP1510_GPIO_DATA_INPUT 0x00 +#define OMAP1510_GPIO_DATA_OUTPUT 0x04 +#define OMAP1510_GPIO_DIR_CONTROL 0x08 +#define OMAP1510_GPIO_INT_CONTROL 0x0c +#define OMAP1510_GPIO_INT_MASK 0x10 +#define OMAP1510_GPIO_INT_STATUS 0x14 +#define OMAP1510_GPIO_PIN_CONTROL 0x18 + +#define OMAP1510_IH_GPIO_BASE 64 + +/* + * OMAP1610 specific GPIO registers + */ +#define OMAP1610_GPIO_REVISION 0x0000 +#define OMAP1610_GPIO_SYSCONFIG 0x0010 +#define OMAP1610_GPIO_SYSSTATUS 0x0014 +#define OMAP1610_GPIO_IRQSTATUS1 0x0018 +#define OMAP1610_GPIO_IRQENABLE1 0x001c +#define OMAP1610_GPIO_WAKEUPENABLE 0x0028 +#define OMAP1610_GPIO_DATAIN 0x002c +#define OMAP1610_GPIO_DATAOUT 0x0030 +#define OMAP1610_GPIO_DIRECTION 0x0034 +#define OMAP1610_GPIO_EDGE_CTRL1 0x0038 +#define OMAP1610_GPIO_EDGE_CTRL2 0x003c +#define OMAP1610_GPIO_CLEAR_IRQENABLE1 0x009c +#define OMAP1610_GPIO_CLEAR_WAKEUPENA 0x00a8 +#define OMAP1610_GPIO_CLEAR_DATAOUT 0x00b0 +#define OMAP1610_GPIO_SET_IRQENABLE1 0x00dc +#define OMAP1610_GPIO_SET_WAKEUPENA 0x00e8 +#define OMAP1610_GPIO_SET_DATAOUT 0x00f0 + +/* + * OMAP7XX specific GPIO registers + */ +#define OMAP7XX_GPIO_DATA_INPUT 0x00 +#define OMAP7XX_GPIO_DATA_OUTPUT 0x04 +#define OMAP7XX_GPIO_DIR_CONTROL 0x08 +#define OMAP7XX_GPIO_INT_CONTROL 0x0c +#define OMAP7XX_GPIO_INT_MASK 0x10 +#define OMAP7XX_GPIO_INT_STATUS 0x14 + +/* + * omap2+ specific GPIO registers + */ +#define OMAP24XX_GPIO_REVISION 0x0000 +#define OMAP24XX_GPIO_IRQSTATUS1 0x0018 +#define OMAP24XX_GPIO_IRQSTATUS2 0x0028 +#define OMAP24XX_GPIO_IRQENABLE2 0x002c +#define OMAP24XX_GPIO_IRQENABLE1 0x001c +#define OMAP24XX_GPIO_WAKE_EN 0x0020 +#define OMAP24XX_GPIO_CTRL 0x0030 +#define OMAP24XX_GPIO_OE 0x0034 +#define OMAP24XX_GPIO_DATAIN 0x0038 +#define OMAP24XX_GPIO_DATAOUT 0x003c +#define OMAP24XX_GPIO_LEVELDETECT0 0x0040 +#define OMAP24XX_GPIO_LEVELDETECT1 0x0044 +#define OMAP24XX_GPIO_RISINGDETECT 0x0048 +#define OMAP24XX_GPIO_FALLINGDETECT 0x004c +#define OMAP24XX_GPIO_DEBOUNCE_EN 0x0050 +#define OMAP24XX_GPIO_DEBOUNCE_VAL 0x0054 +#define OMAP24XX_GPIO_CLEARIRQENABLE1 0x0060 +#define OMAP24XX_GPIO_SETIRQENABLE1 0x0064 +#define OMAP24XX_GPIO_CLEARWKUENA 0x0080 +#define OMAP24XX_GPIO_SETWKUENA 0x0084 +#define OMAP24XX_GPIO_CLEARDATAOUT 0x0090 +#define OMAP24XX_GPIO_SETDATAOUT 0x0094 + +#define OMAP4_GPIO_REVISION 0x0000 +#define OMAP4_GPIO_EOI 0x0020 +#define OMAP4_GPIO_IRQSTATUSRAW0 0x0024 +#define OMAP4_GPIO_IRQSTATUSRAW1 0x0028 +#define OMAP4_GPIO_IRQSTATUS0 0x002c +#define OMAP4_GPIO_IRQSTATUS1 0x0030 +#define OMAP4_GPIO_IRQSTATUSSET0 0x0034 +#define OMAP4_GPIO_IRQSTATUSSET1 0x0038 +#define OMAP4_GPIO_IRQSTATUSCLR0 0x003c +#define OMAP4_GPIO_IRQSTATUSCLR1 0x0040 +#define OMAP4_GPIO_IRQWAKEN0 0x0044 +#define OMAP4_GPIO_IRQWAKEN1 0x0048 +#define OMAP4_GPIO_IRQENABLE1 0x011c +#define OMAP4_GPIO_WAKE_EN 0x0120 +#define OMAP4_GPIO_IRQSTATUS2 0x0128 +#define OMAP4_GPIO_IRQENABLE2 0x012c +#define OMAP4_GPIO_CTRL 0x0130 +#define OMAP4_GPIO_OE 0x0134 +#define OMAP4_GPIO_DATAIN 0x0138 +#define OMAP4_GPIO_DATAOUT 0x013c +#define OMAP4_GPIO_LEVELDETECT0 0x0140 +#define OMAP4_GPIO_LEVELDETECT1 0x0144 +#define OMAP4_GPIO_RISINGDETECT 0x0148 +#define OMAP4_GPIO_FALLINGDETECT 0x014c +#define OMAP4_GPIO_DEBOUNCENABLE 0x0150 +#define OMAP4_GPIO_DEBOUNCINGTIME 0x0154 +#define OMAP4_GPIO_CLEARIRQENABLE1 0x0160 +#define OMAP4_GPIO_SETIRQENABLE1 0x0164 +#define OMAP4_GPIO_CLEARWKUENA 0x0180 +#define OMAP4_GPIO_SETWKUENA 0x0184 +#define OMAP4_GPIO_CLEARDATAOUT 0x0190 +#define OMAP4_GPIO_SETDATAOUT 0x0194 + #define OMAP_MPUIO(nr) (OMAP_MAX_GPIO_LINES + (nr)) #define OMAP_GPIO_IS_MPUIO(nr) ((nr) >= OMAP_MAX_GPIO_LINES) diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index e9de58a2e29..53eb15b0a07 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -19,7 +19,6 @@ obj-y += gpio.o obj-y += gpio-config.o obj-y += dev-asocdma.o -obj-$(CONFIG_SAMSUNG_GPIOLIB_4BIT) += gpiolib.o obj-$(CONFIG_SAMSUNG_CLKSRC) += clock-clksrc.o obj-$(CONFIG_SAMSUNG_IRQ_UART) += irq-uart.o diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index d2136460375..592397629dd 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -86,6 +86,30 @@ config GPIO_IT8761E help Say yes here to support GPIO functionality of IT8761E super I/O chip. +config GPIO_EXYNOS4 + bool "Samsung Exynos4 GPIO library support" + default y if CPU_EXYNOS4210 + help + Say yes here to support Samsung Exynos4 series SoCs GPIO library + +config GPIO_PLAT_SAMSUNG + bool "Samsung SoCs GPIO library support" + default y if SAMSUNG_GPIOLIB_4BIT + help + Say yes here to support Samsung SoCs GPIO library + +config GPIO_S5PC100 + bool "Samsung S5PC100 GPIO library support" + default y if CPU_S5PC100 + help + Say yes here to support Samsung S5PC100 SoCs GPIO library + +config GPIO_S5PV210 + bool "Samsung S5PV210/S5PC110 GPIO library support" + default y if CPU_S5PV210 + help + Say yes here to support Samsung S5PV210/S5PC110 SoCs GPIO library + config GPIO_PL061 bool "PrimeCell PL061 GPIO support" depends on ARM_AMBA @@ -303,7 +327,7 @@ comment "PCI GPIO expanders:" config GPIO_CS5535 tristate "AMD CS5535/CS5536 GPIO support" - depends on PCI && X86 && !CS5535_GPIO + depends on PCI && X86 && !CS5535_GPIO && MFD_CS5535 help The AMD CS5535 and CS5536 southbridges support 28 GPIO pins that can be used for quite a number of things. The CS5535/6 is found on @@ -334,13 +358,19 @@ config GPIO_LANGWELL Say Y here to support Intel Langwell/Penwell GPIO. config GPIO_PCH - tristate "PCH GPIO of Intel Topcliff" + tristate "Intel EG20T PCH / OKI SEMICONDUCTOR ML7223 IOH GPIO" depends on PCI && X86 help This driver is for PCH(Platform controller Hub) GPIO of Intel Topcliff which is an IOH(Input/Output Hub) for x86 embedded processor. This driver can access PCH GPIO device. + This driver also can be used for OKI SEMICONDUCTOR IOH(Input/ + Output Hub), ML7223. + ML7223 IOH is for MP(Media Phone) use. + ML7223 is companion chip for Intel Atom E6xx series. + ML7223 is completely compatible for Intel EG20T PCH. + config GPIO_ML_IOH tristate "OKI SEMICONDUCTOR ML7213 IOH GPIO support" depends on PCI diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 6a3387acc0e..b605f8ec6fb 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -8,6 +8,10 @@ obj-$(CONFIG_GPIO_ADP5520) += adp5520-gpio.o obj-$(CONFIG_GPIO_ADP5588) += adp5588-gpio.o obj-$(CONFIG_GPIO_BASIC_MMIO_CORE) += basic_mmio_gpio.o obj-$(CONFIG_GPIO_BASIC_MMIO) += basic_mmio_gpio.o +obj-$(CONFIG_GPIO_EXYNOS4) += gpio-exynos4.o +obj-$(CONFIG_GPIO_PLAT_SAMSUNG) += gpio-plat-samsung.o +obj-$(CONFIG_GPIO_S5PC100) += gpio-s5pc100.o +obj-$(CONFIG_GPIO_S5PV210) += gpio-s5pv210.o obj-$(CONFIG_GPIO_LANGWELL) += langwell_gpio.o obj-$(CONFIG_GPIO_MAX730X) += max730x.o obj-$(CONFIG_GPIO_MAX7300) += max7300.o @@ -16,6 +20,7 @@ obj-$(CONFIG_GPIO_MAX732X) += max732x.o obj-$(CONFIG_GPIO_MC33880) += mc33880.o obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o obj-$(CONFIG_GPIO_74X164) += 74x164.o +obj-$(CONFIG_ARCH_OMAP) += gpio-omap.o obj-$(CONFIG_GPIO_PCA953X) += pca953x.o obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o obj-$(CONFIG_GPIO_PCH) += pch_gpio.o @@ -34,6 +39,8 @@ obj-$(CONFIG_GPIO_WM831X) += wm831x-gpio.o obj-$(CONFIG_GPIO_WM8350) += wm8350-gpiolib.o obj-$(CONFIG_GPIO_WM8994) += wm8994-gpio.o obj-$(CONFIG_GPIO_SCH) += sch_gpio.o +obj-$(CONFIG_MACH_U300) += gpio-u300.o +obj-$(CONFIG_PLAT_NOMADIK) += gpio-nomadik.o obj-$(CONFIG_GPIO_RDC321X) += rdc321x-gpio.o obj-$(CONFIG_GPIO_JANZ_TTL) += janz-ttl.o obj-$(CONFIG_GPIO_SX150X) += sx150x.o diff --git a/arch/arm/mach-exynos4/gpiolib.c b/drivers/gpio/gpio-exynos4.c index d54ca6adb66..d54ca6adb66 100644 --- a/arch/arm/mach-exynos4/gpiolib.c +++ b/drivers/gpio/gpio-exynos4.c diff --git a/arch/arm/plat-nomadik/gpio.c b/drivers/gpio/gpio-nomadik.c index 307b8131aa8..4961ef9bc15 100644 --- a/arch/arm/plat-nomadik/gpio.c +++ b/drivers/gpio/gpio-nomadik.c @@ -57,6 +57,7 @@ struct nmk_gpio_chip { u32 fwimsc; u32 slpm; u32 enabled; + u32 pull_up; }; static struct nmk_gpio_chip * @@ -103,16 +104,22 @@ static void __nmk_gpio_set_pull(struct nmk_gpio_chip *nmk_chip, u32 pdis; pdis = readl(nmk_chip->addr + NMK_GPIO_PDIS); - if (pull == NMK_GPIO_PULL_NONE) + if (pull == NMK_GPIO_PULL_NONE) { pdis |= bit; - else + nmk_chip->pull_up &= ~bit; + } else { pdis &= ~bit; + } + writel(pdis, nmk_chip->addr + NMK_GPIO_PDIS); - if (pull == NMK_GPIO_PULL_UP) + if (pull == NMK_GPIO_PULL_UP) { + nmk_chip->pull_up |= bit; writel(bit, nmk_chip->addr + NMK_GPIO_DATS); - else if (pull == NMK_GPIO_PULL_DOWN) + } else if (pull == NMK_GPIO_PULL_DOWN) { + nmk_chip->pull_up &= ~bit; writel(bit, nmk_chip->addr + NMK_GPIO_DATC); + } } static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip, @@ -811,20 +818,43 @@ static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) bool pull; u32 bit = 1 << i; - if (!label) - continue; - is_out = readl(nmk_chip->addr + NMK_GPIO_DIR) & bit; pull = !(readl(nmk_chip->addr + NMK_GPIO_PDIS) & bit); mode = nmk_gpio_get_mode(gpio); seq_printf(s, " gpio-%-3d (%-20.20s) %s %s %s %s", - gpio, label, + gpio, label ?: "(none)", is_out ? "out" : "in ", chip->get ? (chip->get(chip, i) ? "hi" : "lo") : "? ", (mode < 0) ? "unknown" : modes[mode], pull ? "pull" : "none"); + + if (label && !is_out) { + int irq = gpio_to_irq(gpio); + struct irq_desc *desc = irq_to_desc(irq); + + /* This races with request_irq(), set_irq_type(), + * and set_irq_wake() ... but those are "rare". + */ + if (irq >= 0 && desc->action) { + char *trigger; + u32 bitmask = nmk_gpio_get_bitmask(gpio); + + if (nmk_chip->edge_rising & bitmask) + trigger = "edge-rising"; + else if (nmk_chip->edge_falling & bitmask) + trigger = "edge-falling"; + else + trigger = "edge-undefined"; + + seq_printf(s, " irq-%d %s%s", + irq, trigger, + irqd_is_wakeup_set(&desc->irq_data) + ? " wakeup" : ""); + } + } + seq_printf(s, "\n"); } } @@ -898,6 +928,25 @@ void nmk_gpio_wakeups_resume(void) } } +/* + * Read the pull up/pull down status. + * A bit set in 'pull_up' means that pull up + * is selected if pull is enabled in PDIS register. + * Note: only pull up/down set via this driver can + * be detected due to HW limitations. + */ +void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up) +{ + if (gpio_bank < NUM_BANKS) { + struct nmk_gpio_chip *chip = nmk_gpio_chips[gpio_bank]; + + if (!chip) + return; + + *pull_up = chip->pull_up; + } +} + static int __devinit nmk_gpio_probe(struct platform_device *dev) { struct nmk_gpio_platform_data *pdata = dev->dev.platform_data; diff --git a/arch/arm/plat-omap/gpio.c b/drivers/gpio/gpio-omap.c index efb86939019..6c51191da56 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/drivers/gpio/gpio-omap.c @@ -1,6 +1,4 @@ /* - * linux/arch/arm/plat-omap/gpio.c - * * Support functions for OMAP GPIO * * Copyright (C) 2003-2005 Nokia Corporation @@ -30,109 +28,6 @@ #include <mach/gpio.h> #include <asm/mach/irq.h> -/* - * OMAP1510 GPIO registers - */ -#define OMAP1510_GPIO_DATA_INPUT 0x00 -#define OMAP1510_GPIO_DATA_OUTPUT 0x04 -#define OMAP1510_GPIO_DIR_CONTROL 0x08 -#define OMAP1510_GPIO_INT_CONTROL 0x0c -#define OMAP1510_GPIO_INT_MASK 0x10 -#define OMAP1510_GPIO_INT_STATUS 0x14 -#define OMAP1510_GPIO_PIN_CONTROL 0x18 - -#define OMAP1510_IH_GPIO_BASE 64 - -/* - * OMAP1610 specific GPIO registers - */ -#define OMAP1610_GPIO_REVISION 0x0000 -#define OMAP1610_GPIO_SYSCONFIG 0x0010 -#define OMAP1610_GPIO_SYSSTATUS 0x0014 -#define OMAP1610_GPIO_IRQSTATUS1 0x0018 -#define OMAP1610_GPIO_IRQENABLE1 0x001c -#define OMAP1610_GPIO_WAKEUPENABLE 0x0028 -#define OMAP1610_GPIO_DATAIN 0x002c -#define OMAP1610_GPIO_DATAOUT 0x0030 -#define OMAP1610_GPIO_DIRECTION 0x0034 -#define OMAP1610_GPIO_EDGE_CTRL1 0x0038 -#define OMAP1610_GPIO_EDGE_CTRL2 0x003c -#define OMAP1610_GPIO_CLEAR_IRQENABLE1 0x009c -#define OMAP1610_GPIO_CLEAR_WAKEUPENA 0x00a8 -#define OMAP1610_GPIO_CLEAR_DATAOUT 0x00b0 -#define OMAP1610_GPIO_SET_IRQENABLE1 0x00dc -#define OMAP1610_GPIO_SET_WAKEUPENA 0x00e8 -#define OMAP1610_GPIO_SET_DATAOUT 0x00f0 - -/* - * OMAP7XX specific GPIO registers - */ -#define OMAP7XX_GPIO_DATA_INPUT 0x00 -#define OMAP7XX_GPIO_DATA_OUTPUT 0x04 -#define OMAP7XX_GPIO_DIR_CONTROL 0x08 -#define OMAP7XX_GPIO_INT_CONTROL 0x0c -#define OMAP7XX_GPIO_INT_MASK 0x10 -#define OMAP7XX_GPIO_INT_STATUS 0x14 - -/* - * omap2+ specific GPIO registers - */ -#define OMAP24XX_GPIO_REVISION 0x0000 -#define OMAP24XX_GPIO_IRQSTATUS1 0x0018 -#define OMAP24XX_GPIO_IRQSTATUS2 0x0028 -#define OMAP24XX_GPIO_IRQENABLE2 0x002c -#define OMAP24XX_GPIO_IRQENABLE1 0x001c -#define OMAP24XX_GPIO_WAKE_EN 0x0020 -#define OMAP24XX_GPIO_CTRL 0x0030 -#define OMAP24XX_GPIO_OE 0x0034 -#define OMAP24XX_GPIO_DATAIN 0x0038 -#define OMAP24XX_GPIO_DATAOUT 0x003c -#define OMAP24XX_GPIO_LEVELDETECT0 0x0040 -#define OMAP24XX_GPIO_LEVELDETECT1 0x0044 -#define OMAP24XX_GPIO_RISINGDETECT 0x0048 -#define OMAP24XX_GPIO_FALLINGDETECT 0x004c -#define OMAP24XX_GPIO_DEBOUNCE_EN 0x0050 -#define OMAP24XX_GPIO_DEBOUNCE_VAL 0x0054 -#define OMAP24XX_GPIO_CLEARIRQENABLE1 0x0060 -#define OMAP24XX_GPIO_SETIRQENABLE1 0x0064 -#define OMAP24XX_GPIO_CLEARWKUENA 0x0080 -#define OMAP24XX_GPIO_SETWKUENA 0x0084 -#define OMAP24XX_GPIO_CLEARDATAOUT 0x0090 -#define OMAP24XX_GPIO_SETDATAOUT 0x0094 - -#define OMAP4_GPIO_REVISION 0x0000 -#define OMAP4_GPIO_EOI 0x0020 -#define OMAP4_GPIO_IRQSTATUSRAW0 0x0024 -#define OMAP4_GPIO_IRQSTATUSRAW1 0x0028 -#define OMAP4_GPIO_IRQSTATUS0 0x002c -#define OMAP4_GPIO_IRQSTATUS1 0x0030 -#define OMAP4_GPIO_IRQSTATUSSET0 0x0034 -#define OMAP4_GPIO_IRQSTATUSSET1 0x0038 -#define OMAP4_GPIO_IRQSTATUSCLR0 0x003c -#define OMAP4_GPIO_IRQSTATUSCLR1 0x0040 -#define OMAP4_GPIO_IRQWAKEN0 0x0044 -#define OMAP4_GPIO_IRQWAKEN1 0x0048 -#define OMAP4_GPIO_IRQENABLE1 0x011c -#define OMAP4_GPIO_WAKE_EN 0x0120 -#define OMAP4_GPIO_IRQSTATUS2 0x0128 -#define OMAP4_GPIO_IRQENABLE2 0x012c -#define OMAP4_GPIO_CTRL 0x0130 -#define OMAP4_GPIO_OE 0x0134 -#define OMAP4_GPIO_DATAIN 0x0138 -#define OMAP4_GPIO_DATAOUT 0x013c -#define OMAP4_GPIO_LEVELDETECT0 0x0140 -#define OMAP4_GPIO_LEVELDETECT1 0x0144 -#define OMAP4_GPIO_RISINGDETECT 0x0148 -#define OMAP4_GPIO_FALLINGDETECT 0x014c -#define OMAP4_GPIO_DEBOUNCENABLE 0x0150 -#define OMAP4_GPIO_DEBOUNCINGTIME 0x0154 -#define OMAP4_GPIO_CLEARIRQENABLE1 0x0160 -#define OMAP4_GPIO_SETIRQENABLE1 0x0164 -#define OMAP4_GPIO_CLEARWKUENA 0x0180 -#define OMAP4_GPIO_SETWKUENA 0x0184 -#define OMAP4_GPIO_CLEARDATAOUT 0x0190 -#define OMAP4_GPIO_SETDATAOUT 0x0194 - struct gpio_bank { unsigned long pbase; void __iomem *base; diff --git a/arch/arm/plat-samsung/gpiolib.c b/drivers/gpio/gpio-plat-samsung.c index ea37c046178..ea37c046178 100644 --- a/arch/arm/plat-samsung/gpiolib.c +++ b/drivers/gpio/gpio-plat-samsung.c diff --git a/arch/arm/mach-s5pc100/gpiolib.c b/drivers/gpio/gpio-s5pc100.c index 2842394b28b..2842394b28b 100644 --- a/arch/arm/mach-s5pc100/gpiolib.c +++ b/drivers/gpio/gpio-s5pc100.c diff --git a/arch/arm/mach-s5pv210/gpiolib.c b/drivers/gpio/gpio-s5pv210.c index 1ba20a703e0..1ba20a703e0 100644 --- a/arch/arm/mach-s5pv210/gpiolib.c +++ b/drivers/gpio/gpio-s5pv210.c diff --git a/arch/arm/mach-u300/gpio.c b/drivers/gpio/gpio-u300.c index d92790140fe..d92790140fe 100644 --- a/arch/arm/mach-u300/gpio.c +++ b/drivers/gpio/gpio-u300.c diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 137a8ca6782..a971e3d043b 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1296,7 +1296,7 @@ EXPORT_SYMBOL_GPL(gpio_request_one); * @array: array of the 'struct gpio' * @num: how many GPIOs in the array */ -int gpio_request_array(struct gpio *array, size_t num) +int gpio_request_array(const struct gpio *array, size_t num) { int i, err; @@ -1319,7 +1319,7 @@ EXPORT_SYMBOL_GPL(gpio_request_array); * @array: array of the 'struct gpio' * @num: how many GPIOs in the array */ -void gpio_free_array(struct gpio *array, size_t num) +void gpio_free_array(const struct gpio *array, size_t num) { while (num--) gpio_free((array++)->gpio); diff --git a/drivers/gpio/langwell_gpio.c b/drivers/gpio/langwell_gpio.c index 1b06f67e1f6..bd6571e0097 100644 --- a/drivers/gpio/langwell_gpio.c +++ b/drivers/gpio/langwell_gpio.c @@ -33,6 +33,7 @@ #include <linux/io.h> #include <linux/gpio.h> #include <linux/slab.h> +#include <linux/pm_runtime.h> /* * Langwell chip has 64 pins and thus there are 2 32bit registers to control @@ -63,6 +64,7 @@ struct lnw_gpio { void *reg_base; spinlock_t lock; unsigned irq_base; + struct pci_dev *pdev; }; static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned offset, @@ -104,11 +106,18 @@ static int lnw_gpio_direction_input(struct gpio_chip *chip, unsigned offset) u32 value; unsigned long flags; + if (lnw->pdev) + pm_runtime_get(&lnw->pdev->dev); + spin_lock_irqsave(&lnw->lock, flags); value = readl(gpdr); value &= ~BIT(offset % 32); writel(value, gpdr); spin_unlock_irqrestore(&lnw->lock, flags); + + if (lnw->pdev) + pm_runtime_put(&lnw->pdev->dev); + return 0; } @@ -120,11 +129,19 @@ static int lnw_gpio_direction_output(struct gpio_chip *chip, unsigned long flags; lnw_gpio_set(chip, offset, value); + + if (lnw->pdev) + pm_runtime_get(&lnw->pdev->dev); + spin_lock_irqsave(&lnw->lock, flags); value = readl(gpdr); value |= BIT(offset % 32); writel(value, gpdr); spin_unlock_irqrestore(&lnw->lock, flags); + + if (lnw->pdev) + pm_runtime_put(&lnw->pdev->dev); + return 0; } @@ -145,6 +162,10 @@ static int lnw_irq_type(struct irq_data *d, unsigned type) if (gpio >= lnw->chip.ngpio) return -EINVAL; + + if (lnw->pdev) + pm_runtime_get(&lnw->pdev->dev); + spin_lock_irqsave(&lnw->lock, flags); if (type & IRQ_TYPE_EDGE_RISING) value = readl(grer) | BIT(gpio % 32); @@ -159,6 +180,9 @@ static int lnw_irq_type(struct irq_data *d, unsigned type) writel(value, gfer); spin_unlock_irqrestore(&lnw->lock, flags); + if (lnw->pdev) + pm_runtime_put(&lnw->pdev->dev); + return 0; } @@ -211,6 +235,39 @@ static void lnw_irq_handler(unsigned irq, struct irq_desc *desc) chip->irq_eoi(data); } +#ifdef CONFIG_PM +static int lnw_gpio_runtime_resume(struct device *dev) +{ + return 0; +} + +static int lnw_gpio_runtime_suspend(struct device *dev) +{ + return 0; +} + +static int lnw_gpio_runtime_idle(struct device *dev) +{ + int err = pm_schedule_suspend(dev, 500); + + if (!err) + return 0; + + return -EBUSY; +} + +#else +#define lnw_gpio_runtime_suspend NULL +#define lnw_gpio_runtime_resume NULL +#define lnw_gpio_runtime_idle NULL +#endif + +static const struct dev_pm_ops lnw_gpio_pm_ops = { + .runtime_suspend = lnw_gpio_runtime_suspend, + .runtime_resume = lnw_gpio_runtime_resume, + .runtime_idle = lnw_gpio_runtime_idle, +}; + static int __devinit lnw_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -270,6 +327,7 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, lnw->chip.base = gpio_base; 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) { @@ -285,6 +343,10 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, } spin_lock_init(&lnw->lock); + + pm_runtime_put_noidle(&pdev->dev); + pm_runtime_allow(&pdev->dev); + goto done; err5: kfree(lnw); @@ -302,6 +364,9 @@ static struct pci_driver lnw_gpio_driver = { .name = "langwell_gpio", .id_table = lnw_gpio_ids, .probe = lnw_gpio_probe, + .driver = { + .pm = &lnw_gpio_pm_ops, + }, }; diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c index 78a843947d8..0451d7ac94a 100644 --- a/drivers/gpio/pca953x.c +++ b/drivers/gpio/pca953x.c @@ -24,33 +24,46 @@ #include <linux/of_gpio.h> #endif -#define PCA953X_INPUT 0 -#define PCA953X_OUTPUT 1 -#define PCA953X_INVERT 2 -#define PCA953X_DIRECTION 3 - -#define PCA953X_GPIOS 0x00FF -#define PCA953X_INT 0x0100 +#define PCA953X_INPUT 0 +#define PCA953X_OUTPUT 1 +#define PCA953X_INVERT 2 +#define PCA953X_DIRECTION 3 + +#define PCA957X_IN 0 +#define PCA957X_INVRT 1 +#define PCA957X_BKEN 2 +#define PCA957X_PUPD 3 +#define PCA957X_CFG 4 +#define PCA957X_OUT 5 +#define PCA957X_MSK 6 +#define PCA957X_INTS 7 + +#define PCA_GPIO_MASK 0x00FF +#define PCA_INT 0x0100 +#define PCA953X_TYPE 0x1000 +#define PCA957X_TYPE 0x2000 static const struct i2c_device_id pca953x_id[] = { - { "pca9534", 8 | PCA953X_INT, }, - { "pca9535", 16 | PCA953X_INT, }, - { "pca9536", 4, }, - { "pca9537", 4 | PCA953X_INT, }, - { "pca9538", 8 | PCA953X_INT, }, - { "pca9539", 16 | PCA953X_INT, }, - { "pca9554", 8 | PCA953X_INT, }, - { "pca9555", 16 | PCA953X_INT, }, - { "pca9556", 8, }, - { "pca9557", 8, }, - - { "max7310", 8, }, - { "max7312", 16 | PCA953X_INT, }, - { "max7313", 16 | PCA953X_INT, }, - { "max7315", 8 | PCA953X_INT, }, - { "pca6107", 8 | PCA953X_INT, }, - { "tca6408", 8 | PCA953X_INT, }, - { "tca6416", 16 | PCA953X_INT, }, + { "pca9534", 8 | PCA953X_TYPE | PCA_INT, }, + { "pca9535", 16 | PCA953X_TYPE | PCA_INT, }, + { "pca9536", 4 | PCA953X_TYPE, }, + { "pca9537", 4 | PCA953X_TYPE | PCA_INT, }, + { "pca9538", 8 | PCA953X_TYPE | PCA_INT, }, + { "pca9539", 16 | PCA953X_TYPE | PCA_INT, }, + { "pca9554", 8 | PCA953X_TYPE | PCA_INT, }, + { "pca9555", 16 | PCA953X_TYPE | PCA_INT, }, + { "pca9556", 8 | PCA953X_TYPE, }, + { "pca9557", 8 | PCA953X_TYPE, }, + { "pca9574", 8 | PCA957X_TYPE | PCA_INT, }, + { "pca9575", 16 | PCA957X_TYPE | PCA_INT, }, + + { "max7310 |