Merge branch 'gpio/next' of git://git.secretlab.ca/git/linux-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 28 May 2011 17:56:34 +0000 (10:56 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 28 May 2011 17:56:34 +0000 (10:56 -0700)
* 'gpio/next' of git://git.secretlab.ca/git/linux-2.6:
  gpio/pch_gpio: Support new device ML7223
  gpio: make gpio_{request,free}_array gpio array parameter const
  GPIO: OMAP: move to drivers/gpio
  GPIO: OMAP: move register offset defines into <plat/gpio.h>
  gpio: Convert gpio_is_valid to return bool
  gpio: Move the s5pc100 GPIO to drivers/gpio
  gpio: Move the s5pv210 GPIO to drivers/gpio
  gpio: Move the exynos4 GPIO to drivers/gpio
  gpio: Move to Samsung common GPIO library to drivers/gpio
  gpio/nomadik: add function to read GPIO pull down status
  gpio/nomadik: show all pins in debug
  gpio: move Nomadik GPIO driver to drivers/gpio
  gpio: move U300 GPIO driver to drivers/gpio
  langwell_gpio: add runtime pm support
  gpio/pca953x: Add support for pca9574 and pca9575 devices
  gpio/cs5535: Show explicit dependency between gpio_cs5535 and mfd_cs5535

27 files changed:
arch/arm/mach-exynos4/Makefile
arch/arm/mach-nomadik/Kconfig
arch/arm/mach-s5pc100/Makefile
arch/arm/mach-s5pv210/Makefile
arch/arm/mach-u300/Makefile
arch/arm/mach-ux500/Kconfig
arch/arm/plat-nomadik/Kconfig
arch/arm/plat-nomadik/Makefile
arch/arm/plat-nomadik/include/plat/gpio.h
arch/arm/plat-omap/Makefile
arch/arm/plat-omap/include/plat/gpio.h
arch/arm/plat-samsung/Makefile
drivers/gpio/Kconfig
drivers/gpio/Makefile
drivers/gpio/gpio-exynos4.c [moved from arch/arm/mach-exynos4/gpiolib.c with 100% similarity]
drivers/gpio/gpio-nomadik.c [moved from arch/arm/plat-nomadik/gpio.c with 95% similarity]
drivers/gpio/gpio-omap.c [moved from arch/arm/plat-omap/gpio.c with 93% similarity]
drivers/gpio/gpio-plat-samsung.c [moved from arch/arm/plat-samsung/gpiolib.c with 100% similarity]
drivers/gpio/gpio-s5pc100.c [moved from arch/arm/mach-s5pc100/gpiolib.c with 100% similarity]
drivers/gpio/gpio-s5pv210.c [moved from arch/arm/mach-s5pv210/gpiolib.c with 100% similarity]
drivers/gpio/gpio-u300.c [moved from arch/arm/mach-u300/gpio.c with 100% similarity]
drivers/gpio/gpiolib.c
drivers/gpio/langwell_gpio.c
drivers/gpio/pca953x.c
drivers/gpio/pch_gpio.c
include/asm-generic/gpio.h
include/linux/gpio.h

index 683fc38..a9bb94f 100644 (file)
@@ -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
index 71f3ea6..3c5e0f5 100644 (file)
@@ -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
 
index eecab57..a5e6e60 100644 (file)
@@ -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
 
index 11f1790..50907ac 100644 (file)
@@ -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
index fab46fe..8fd354a 100644 (file)
@@ -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-           :=
index 54429d0..f8b9392 100644 (file)
@@ -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"
index 18296ee..ce65901 100644 (file)
@@ -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
index c335473..37c7cdd 100644 (file)
@@ -3,4 +3,3 @@
 # Licensed under GPLv2
 
 obj-$(CONFIG_HAS_MTU)  += timer.o
-obj-$(CONFIG_NOMADIK_GPIO)     += gpio.o
index 1b9f6f0..ea19a5b 100644 (file)
@@ -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.
  */
index a4a1285..f0233e6 100644 (file)
@@ -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 :=
index cac2e8a..ec97e00 100644 (file)
 
 #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)
 
index e9de58a..53eb15b 100644 (file)
@@ -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
index d213646..5923976 100644 (file)
@@ -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
index 6a3387a..b605f8e 100644 (file)
@@ -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
similarity index 95%
rename from arch/arm/plat-nomadik/gpio.c
rename to drivers/gpio/gpio-nomadik.c
index 307b813..4961ef9 100644 (file)
@@ -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;
similarity index 93%
rename from arch/arm/plat-omap/gpio.c
rename to drivers/gpio/gpio-omap.c
index efb8693..6c51191 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  linux/arch/arm/plat-omap/gpio.c
- *
  * Support functions for OMAP GPIO
  *
  * Copyright (C) 2003-2005 Nokia Corporation
 #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;
index 137a8ca..a971e3d 100644 (file)
@@ -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);
index 1b06f67..bd6571e 100644 (file)
@@ -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,
+       },
 };
 
 
index 78a8439..0451d7a 100644 (file)
 #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", 8  | PCA953X_TYPE, },
+       { "max7312", 16 | PCA953X_TYPE | PCA_INT, },
+       { "max7313", 16 | PCA953X_TYPE | PCA_INT, },
+       { "max7315", 8  | PCA953X_TYPE | PCA_INT, },
+       { "pca6107", 8  | PCA953X_TYPE | PCA_INT, },
+       { "tca6408", 8  | PCA953X_TYPE | PCA_INT, },
+       { "tca6416", 16 | PCA953X_TYPE | PCA_INT, },
        /* NYET:  { "tca6424", 24, }, */
        { }
 };
@@ -75,16 +88,32 @@ struct pca953x_chip {
        struct pca953x_platform_data *dyn_pdata;
        struct gpio_chip gpio_chip;
        const char *const *names;
+       int     chip_type;
 };
 
 static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val)
 {
-       int ret;
+       int ret = 0;
 
        if (chip->gpio_chip.ngpio <= 8)
                ret = i2c_smbus_write_byte_data(chip->client, reg, val);
-       else
-               ret = i2c_smbus_write_word_data(chip->client, reg << 1, val);
+       else {
+               switch (chip->chip_type) {
+               case PCA953X_TYPE:
+                       ret = i2c_smbus_write_word_data(chip->client,
+                                                       reg << 1, val);
+                       break;
+               case PCA957X_TYPE:
+                       ret = i2c_smbus_write_byte_data(chip->client, reg << 1,
+                                                       val & 0xff);
+                       if (ret < 0)
+                               break;
+                       ret = i2c_smbus_write_byte_data(chip->client,
+                                                       (reg << 1) + 1,
+                                                       (val & 0xff00) >> 8);
+                       break;
+               }
+       }
 
        if (ret < 0) {
                dev_err(&chip->client->dev, "failed writing register\n");
@@ -116,13 +145,22 @@ static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off)
 {
        struct pca953x_chip *chip;
        uint16_t reg_val;
-       int ret;
+       int ret, offset = 0;
 
        chip = container_of(gc, struct pca953x_chip, gpio_chip);
 
        mutex_lock(&chip->i2c_lock);
        reg_val = chip->reg_direction | (1u << off);
-       ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val);
+
+       switch (chip->chip_type) {
+       case PCA953X_TYPE:
+               offset = PCA953X_DIRECTION;
+               break;
+       case PCA957X_TYPE:
+               offset = PCA957X_CFG;
+               break;
+       }
+       ret = pca953x_write_reg(chip, offset, reg_val);
        if (ret)
                goto exit;
 
@@ -138,7 +176,7 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
 {
        struct pca953x_chip *chip;
        uint16_t reg_val;
-       int ret;
+       int ret, offset = 0;
 
        chip = container_of(gc, struct pca953x_chip, gpio_chip);
 
@@ -149,7 +187,15 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
        else
                reg_val = chip->reg_output & ~(1u << off);
 
-       ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val);
+       switch (chip->chip_type) {
+       case PCA953X_TYPE:
+               offset = PCA953X_OUTPUT;
+               break;
+       case PCA957X_TYPE:
+               offset = PCA957X_OUT;
+               break;
+       }
+       ret = pca953x_write_reg(chip, offset, reg_val);
        if (ret)
                goto exit;
 
@@ -157,7 +203,15 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
 
        /* then direction */
        reg_val = chip->reg_direction & ~(1u << off);
-       ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val);
+       switch (chip->chip_type) {
+       case PCA953X_TYPE:
+               offset = PCA953X_DIRECTION;
+               break;
+       case PCA957X_TYPE:
+               offset = PCA957X_CFG;
+               break;
+       }
+       ret = pca953x_write_reg(chip, offset, reg_val);
        if (ret)
                goto exit;
 
@@ -172,12 +226,20 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off)
 {
        struct pca953x_chip *chip;
        uint16_t reg_val;
-       int ret;
+       int ret, offset = 0;
 
        chip = container_of(gc, struct pca953x_chip, gpio_chip);
 
        mutex_lock(&chip->i2c_lock);
-       ret = pca953x_read_reg(chip, PCA953X_INPUT, &reg_val);
+       switch (chip->chip_type) {
+       case PCA953X_TYPE:
+               offset = PCA953X_INPUT;
+               break;
+       case PCA957X_TYPE:
+               offset = PCA957X_IN;
+               break;
+       }
+       ret = pca953x_read_reg(chip, offset, &reg_val);
        mutex_unlock(&chip->i2c_lock);
        if (ret < 0) {
                /* NOTE:  diagnostic already emitted; that's all we should
@@ -194,7 +256,7 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
 {
        struct pca953x_chip *chip;
        uint16_t reg_val;
-       int ret;
+       int ret, offset = 0;
 
        chip = container_of(gc, struct pca953x_chip, gpio_chip);
 
@@ -204,7 +266,15 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
        else
                reg_val = chip->reg_output & ~(1u << off);
 
-       ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val);
+       switch (chip->chip_type) {
+       case PCA953X_TYPE:
+               offset = PCA953X_OUTPUT;
+               break;
+       case PCA957X_TYPE:
+               offset = PCA957X_OUT;
+               break;
+       }
+       ret = pca953x_write_reg(chip, offset, reg_val);
        if (ret)
                goto exit;
 
@@ -322,9 +392,17 @@ static uint16_t pca953x_irq_pending(struct pca953x_chip *chip)
        uint16_t old_stat;
        uint16_t pending;
        uint16_t trigger;
-       int ret;
-
-       ret = pca953x_read_reg(chip, PCA953X_INPUT, &cur_stat);
+       int ret, offset = 0;
+
+       switch (chip->chip_type) {
+       case PCA953X_TYPE:
+               offset = PCA953X_INPUT;
+               break;
+       case PCA957X_TYPE:
+               offset = PCA957X_IN;
+               break;
+       }
+       ret = pca953x_read_reg(chip, offset, &cur_stat);
        if (ret)
                return 0;
 
@@ -372,14 +450,21 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
 {
        struct i2c_client *client = chip->client;
        struct pca953x_platform_data *pdata = client->dev.platform_data;
-       int ret;
+       int ret, offset = 0;
 
        if (pdata->irq_base != -1
-                       && (id->driver_data & PCA953X_INT)) {
+                       && (id->driver_data & PCA_INT)) {
                int lvl;
 
-               ret = pca953x_read_reg(chip, PCA953X_INPUT,
-                                      &chip->irq_stat);
+               switch (chip->chip_type) {
+               case PCA953X_TYPE:
+                       offset = PCA953X_INPUT;
+                       break;
+               case PCA957X_TYPE:
+                       offset = PCA957X_IN;
+                       break;
+               }
+               ret = pca953x_read_reg(chip, offset, &chip->irq_stat);
                if (ret)
                        goto out_failed;
 
@@ -439,7 +524,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
        struct i2c_client *client = chip->client;
        struct pca953x_platform_data *pdata = client->dev.platform_data;
 
-       if (pdata->irq_base != -1 && (id->driver_data & PCA953X_INT))
+       if (pdata->irq_base != -1 && (id->driver_data & PCA_INT))
                dev_warn(&client->dev, "interrupt support not compiled in\n");
 
        return 0;
@@ -499,12 +584,65 @@ pca953x_get_alt_pdata(struct i2c_client *client)
 }
 #endif
 
+static int __devinit device_pca953x_init(struct pca953x_chip *chip, int invert)
+{
+       int ret;
+
+       ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output);
+       if (ret)
+               goto out;
+
+       ret = pca953x_read_reg(chip, PCA953X_DIRECTION,
+                              &chip->reg_direction);
+       if (ret)
+               goto out;
+
+       /* set platform specific polarity inversion */
+       ret = pca953x_write_reg(chip, PCA953X_INVERT, invert);
+       if (ret)
+               goto out;
+       return 0;
+out:
+       return ret;
+}
+
+static int __devinit device_pca957x_init(struct pca953x_chip *chip, int invert)
+{
+       int ret;
+       uint16_t val = 0;
+
+       /* Let every port in proper state, that could save power */
+       pca953x_write_reg(chip, PCA957X_PUPD, 0x0);
+       pca953x_write_reg(chip, PCA957X_CFG, 0xffff);
+       pca953x_write_reg(chip, PCA957X_OUT, 0x0);
+
+       ret = pca953x_read_reg(chip, PCA957X_IN, &val);
+       if (ret)
+               goto out;
+       ret = pca953x_read_reg(chip, PCA957X_OUT, &chip->reg_output);
+       if (ret)
+               goto out;
+       ret = pca953x_read_reg(chip, PCA957X_CFG, &chip->reg_direction);
+       if (ret)
+               goto out;
+
+       /* set platform specific polarity inversion */
+       pca953x_write_reg(chip, PCA957X_INVRT, invert);
+
+       /* To enable register 6, 7 to controll pull up and pull down */
+       pca953x_write_reg(chip, PCA957X_BKEN, 0x202);
+
+       return 0;
+out:
+       return ret;
+}
+
 static int __devinit pca953x_probe(struct i2c_client *client,
                                   const struct i2c_device_id *id)
 {
        struct pca953x_platform_data *pdata;
        struct pca953x_chip *chip;
-       int ret;
+       int ret = 0;
 
        chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL);
        if (chip == NULL)
@@ -531,25 +669,20 @@ static int __devinit pca953x_probe(struct i2c_client *client,
        chip->gpio_start = pdata->gpio_base;
 
        chip->names = pdata->names;
+       chip->chip_type = id->driver_data & (PCA953X_TYPE | PCA957X_TYPE);
 
        mutex_init(&chip->i2c_lock);
 
        /* initialize cached registers from their original values.
         * we can't share this chip with another i2c master.
         */
-       pca953x_setup_gpio(chip, id->driver_data & PCA953X_GPIOS);
+       pca953x_setup_gpio(chip, id->driver_data & PCA_GPIO_MASK);
 
-       ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output);
-       if (ret)
-               goto out_failed;
-
-       ret = pca953x_read_reg(chip, PCA953X_DIRECTION, &chip->reg_direction);
-       if (ret)
-               goto out_failed;
-
-       /* set platform specific polarity inversion */
-       ret = pca953x_write_reg(chip, PCA953X_INVERT, pdata->invert);
-       if (ret)
+       if (chip->chip_type == PCA953X_TYPE)
+               device_pca953x_init(chip, pdata->invert);
+       else if (chip->chip_type == PCA957X_TYPE)
+               device_pca957x_init(chip, pdata->invert);
+       else
                goto out_failed;
 
        ret = pca953x_irq_setup(chip, id);
index f970a5f..36919e7 100644 (file)
@@ -283,8 +283,10 @@ static int pch_gpio_resume(struct pci_dev *pdev)
 #define pch_gpio_resume NULL
 #endif
 
+#define PCI_VENDOR_ID_ROHM             0x10DB
 static DEFINE_PCI_DEVICE_TABLE(pch_gpio_pcidev_id) = {
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8803) },
+       { PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8014) },
        { 0, }
 };
 MODULE_DEVICE_TABLE(pci, pch_gpio_pcidev_id);
index ff5c660..fcdcb5d 100644 (file)
@@ -35,9 +35,9 @@
  * platform data and other tables.
  */
 
-static inline int gpio_is_valid(int number)
+static inline bool gpio_is_valid(int number)
 {
-       return ((unsigned)number) < ARCH_NR_GPIOS;
+       return number >= 0 && number < ARCH_NR_GPIOS;
 }
 
 struct device;
@@ -193,8 +193,8 @@ struct gpio {
 };
 
 extern int gpio_request_one(unsigned gpio, unsigned long flags, const char *label);
-extern int gpio_request_array(struct gpio *array, size_t num);
-extern void gpio_free_array(struct gpio *array, size_t num);
+extern int gpio_request_array(const struct gpio *array, size_t num);
+extern void gpio_free_array(const struct gpio *array, size_t num);
 
 #ifdef CONFIG_GPIO_SYSFS
 
@@ -212,7 +212,7 @@ extern void gpio_unexport(unsigned gpio);
 
 #else  /* !CONFIG_GPIOLIB */
 
-static inline int gpio_is_valid(int number)
+static inline bool gpio_is_valid(int number)
 {
        /* only non-negative numbers are valid */
        return number >= 0;
index 32720ba..32d47e7 100644 (file)
@@ -25,9 +25,9 @@ struct gpio_chip;
  * warning when something is wrongly called.
  */
 
-static inline int gpio_is_valid(int number)
+static inline bool gpio_is_valid(int number)
 {
-       return 0;
+       return false;
 }
 
 static inline int gpio_request(unsigned gpio, const char *label)
@@ -41,7 +41,7 @@ static inline int gpio_request_one(unsigned gpio,
        return -ENOSYS;
 }
 
-static inline int gpio_request_array(struct gpio *array, size_t num)
+static inline int gpio_request_array(const struct gpio *array, size_t num)
 {
        return -ENOSYS;
 }
@@ -54,7 +54,7 @@ static inline void gpio_free(unsigned gpio)
        WARN_ON(1);
 }
 
-static inline void gpio_free_array(struct gpio *array, size_t num)
+static inline void gpio_free_array(const struct gpio *array, size_t num)
 {
        might_sleep();