Merge branch 'gpio/next' of git://git.secretlab.ca/git/linux-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 22 Jul 2011 21:50:57 +0000 (14:50 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 22 Jul 2011 21:50:57 +0000 (14:50 -0700)
* 'gpio/next' of git://git.secretlab.ca/git/linux-2.6: (61 commits)
  gpio/mxc/mxs: fix build error introduced by the irq_gc_ack() renaming
  mcp23s08: add i2c support
  mcp23s08: isolate spi specific parts
  mcp23s08: get rid of setup/teardown callbacks
  gpio/tegra: dt: add binding for gpio polarity
  mcp23s08: remove unused work queue
  gpio/da9052: remove a redundant assignment for gpio->da9052
  gpio/mxc: add device tree probe support
  ARM: mxc: use ARCH_NR_GPIOS to define gpio number
  gpio/mxc: get rid of the uses of cpu_is_mx()
  gpio/mxc: add missing initialization of basic_mmio_gpio shadow variables
  gpio: Move mpc5200 gpio driver to drivers/gpio
  GPIO: DA9052 GPIO module v3
  gpio/tegra: Use engineering names in DT compatible property
  of/gpio: Add new method for getting gpios under different property names
  gpio/dt: Refine GPIO device tree binding
  gpio/ml-ioh: fix off-by-one for displaying variable i in dev_err
  gpio/pca953x: Deprecate meaningless device-tree bindings
  gpio/pca953x: Remove dynamic platform data pointer
  gpio/pca953x: Fix IRQ support.
  ...

137 files changed:
Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt [new file with mode: 0644]
Documentation/devicetree/bindings/gpio/gpio.txt
Documentation/devicetree/bindings/gpio/gpio_nvidia.txt [new file with mode: 0644]
arch/arm/mach-ep93xx/Makefile
arch/arm/mach-ep93xx/core.c
arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
arch/arm/mach-imx/mach-apf9328.c
arch/arm/mach-imx/mach-armadillo5x0.c
arch/arm/mach-imx/mach-bug.c
arch/arm/mach-imx/mach-cpuimx27.c
arch/arm/mach-imx/mach-cpuimx35.c
arch/arm/mach-imx/mach-eukrea_cpuimx25.c
arch/arm/mach-imx/mach-imx27_visstrim_m10.c
arch/arm/mach-imx/mach-imx27ipcam.c
arch/arm/mach-imx/mach-imx27lite.c
arch/arm/mach-imx/mach-kzm_arm11_01.c
arch/arm/mach-imx/mach-mx1ads.c
arch/arm/mach-imx/mach-mx21ads.c
arch/arm/mach-imx/mach-mx25_3ds.c
arch/arm/mach-imx/mach-mx27_3ds.c
arch/arm/mach-imx/mach-mx27ads.c
arch/arm/mach-imx/mach-mx31_3ds.c
arch/arm/mach-imx/mach-mx31ads.c
arch/arm/mach-imx/mach-mx31lilly.c
arch/arm/mach-imx/mach-mx31lite.c
arch/arm/mach-imx/mach-mx31moboard.c
arch/arm/mach-imx/mach-mx35_3ds.c
arch/arm/mach-imx/mach-mxt_td60.c
arch/arm/mach-imx/mach-pca100.c
arch/arm/mach-imx/mach-pcm037.c
arch/arm/mach-imx/mach-pcm038.c
arch/arm/mach-imx/mach-pcm043.c
arch/arm/mach-imx/mach-qong.c
arch/arm/mach-imx/mach-scb9328.c
arch/arm/mach-imx/mach-vpr200.c
arch/arm/mach-imx/mm-imx1.c
arch/arm/mach-imx/mm-imx21.c
arch/arm/mach-imx/mm-imx25.c
arch/arm/mach-imx/mm-imx27.c
arch/arm/mach-imx/mm-imx31.c
arch/arm/mach-imx/mm-imx35.c
arch/arm/mach-mx5/board-cpuimx51.c
arch/arm/mach-mx5/board-cpuimx51sd.c
arch/arm/mach-mx5/board-mx50_rdp.c
arch/arm/mach-mx5/board-mx51_3ds.c
arch/arm/mach-mx5/board-mx51_babbage.c
arch/arm/mach-mx5/board-mx51_efikamx.c
arch/arm/mach-mx5/board-mx51_efikasb.c
arch/arm/mach-mx5/board-mx53_evk.c
arch/arm/mach-mx5/board-mx53_loco.c
arch/arm/mach-mx5/board-mx53_smd.c
arch/arm/mach-mx5/devices.c
arch/arm/mach-mx5/mm-mx50.c
arch/arm/mach-mx5/mm.c
arch/arm/mach-mxs/Makefile
arch/arm/mach-mxs/devices.c
arch/arm/mach-mxs/devices/Makefile
arch/arm/mach-mxs/devices/platform-gpio-mxs.c [new file with mode: 0644]
arch/arm/mach-mxs/gpio.c [deleted file]
arch/arm/mach-mxs/gpio.h [deleted file]
arch/arm/mach-mxs/include/mach/devices-common.h
arch/arm/mach-mxs/mach-mx28evk.c
arch/arm/mach-mxs/mm-mx23.c
arch/arm/mach-mxs/mm-mx28.c
arch/arm/mach-omap1/gpio15xx.c
arch/arm/mach-omap1/gpio16xx.c
arch/arm/mach-omap1/gpio7xx.c
arch/arm/mach-omap2/gpio.c
arch/arm/mach-tegra/Makefile
arch/arm/plat-mxc/Makefile
arch/arm/plat-mxc/devices.c
arch/arm/plat-mxc/devices/Makefile
arch/arm/plat-mxc/devices/platform-gpio-mxc.c [new file with mode: 0644]
arch/arm/plat-mxc/gpio.c [deleted file]
arch/arm/plat-mxc/include/mach/common.h
arch/arm/plat-mxc/include/mach/devices-common.h
arch/arm/plat-mxc/include/mach/gpio.h
arch/arm/plat-mxc/include/mach/irqs.h
arch/arm/plat-omap/include/plat/gpio.h
arch/powerpc/platforms/52xx/Kconfig
arch/powerpc/platforms/52xx/Makefile
drivers/gpio/Kconfig
drivers/gpio/Makefile
drivers/gpio/gpio-74x164.c [moved from drivers/gpio/74x164.c with 88% similarity]
drivers/gpio/gpio-ab8500.c [moved from drivers/gpio/ab8500-gpio.c with 100% similarity]
drivers/gpio/gpio-adp5520.c [moved from drivers/gpio/adp5520-gpio.c with 100% similarity]
drivers/gpio/gpio-adp5588.c [moved from drivers/gpio/adp5588-gpio.c with 100% similarity]
drivers/gpio/gpio-bt8xx.c [moved from drivers/gpio/bt8xxgpio.c with 100% similarity]
drivers/gpio/gpio-cs5535.c [moved from drivers/gpio/cs5535-gpio.c with 100% similarity]
drivers/gpio/gpio-da9052.c [new file with mode: 0644]
drivers/gpio/gpio-ep93xx.c [moved from arch/arm/mach-ep93xx/gpio.c with 69% similarity]
drivers/gpio/gpio-exynos4.c
drivers/gpio/gpio-generic.c [moved from drivers/gpio/basic_mmio_gpio.c with 99% similarity]
drivers/gpio/gpio-it8761e.c [moved from drivers/gpio/it8761e_gpio.c with 98% similarity]
drivers/gpio/gpio-janz-ttl.c [moved from drivers/gpio/janz-ttl.c with 100% similarity]
drivers/gpio/gpio-langwell.c [moved from drivers/gpio/langwell_gpio.c with 99% similarity]
drivers/gpio/gpio-max7300.c [moved from drivers/gpio/max7300.c with 98% similarity]
drivers/gpio/gpio-max7301.c [moved from drivers/gpio/max7301.c with 98% similarity]
drivers/gpio/gpio-max730x.c [moved from drivers/gpio/max730x.c with 99% similarity]
drivers/gpio/gpio-max732x.c [moved from drivers/gpio/max732x.c with 99% similarity]
drivers/gpio/gpio-mc33880.c [moved from drivers/gpio/mc33880.c with 98% similarity]
drivers/gpio/gpio-mcp23s08.c [moved from drivers/gpio/mcp23s08.c with 68% similarity]
drivers/gpio/gpio-ml-ioh.c [moved from drivers/gpio/ml_ioh_gpio.c with 99% similarity]
drivers/gpio/gpio-mpc5200.c [moved from arch/powerpc/platforms/52xx/mpc52xx_gpio.c with 98% similarity]
drivers/gpio/gpio-mxc.c [new file with mode: 0644]
drivers/gpio/gpio-mxs.c [new file with mode: 0644]
drivers/gpio/gpio-omap.c
drivers/gpio/gpio-pca953x.c [moved from drivers/gpio/pca953x.c with 89% similarity]
drivers/gpio/gpio-pcf857x.c [moved from drivers/gpio/pcf857x.c with 99% similarity]
drivers/gpio/gpio-pch.c [moved from drivers/gpio/pch_gpio.c with 100% similarity]
drivers/gpio/gpio-pl061.c [moved from drivers/gpio/pl061.c with 99% similarity]
drivers/gpio/gpio-plat-samsung.c
drivers/gpio/gpio-rdc321x.c [moved from drivers/gpio/rdc321x-gpio.c with 100% similarity]
drivers/gpio/gpio-s5pc100.c
drivers/gpio/gpio-s5pv210.c
drivers/gpio/gpio-sch.c [moved from drivers/gpio/sch_gpio.c with 99% similarity]
drivers/gpio/gpio-stmpe.c [moved from drivers/gpio/stmpe-gpio.c with 100% similarity]
drivers/gpio/gpio-sx150x.c [moved from drivers/gpio/sx150x.c with 100% similarity]
drivers/gpio/gpio-tc3589x.c [moved from drivers/gpio/tc3589x-gpio.c with 100% similarity]
drivers/gpio/gpio-tegra.c [moved from arch/arm/mach-tegra/gpio.c with 97% similarity]
drivers/gpio/gpio-timberdale.c [moved from drivers/gpio/timbgpio.c with 99% similarity]
drivers/gpio/gpio-tps65910.c [moved from drivers/gpio/tps65910-gpio.c with 98% similarity]
drivers/gpio/gpio-twl4030.c [moved from drivers/gpio/twl4030-gpio.c with 99% similarity]
drivers/gpio/gpio-u300.c
drivers/gpio/gpio-ucb1400.c [moved from drivers/gpio/ucb1400_gpio.c with 100% similarity]
drivers/gpio/gpio-vr41xx.c [moved from drivers/gpio/vr41xx_giu.c with 99% similarity]
drivers/gpio/gpio-vx855.c [moved from drivers/gpio/vx855_gpio.c with 100% similarity]
drivers/gpio/gpio-wm831x.c [moved from drivers/gpio/wm831x-gpio.c with 99% similarity]
drivers/gpio/gpio-wm8350.c [moved from drivers/gpio/wm8350-gpiolib.c with 98% similarity]
drivers/gpio/gpio-wm8994.c [moved from drivers/gpio/wm8994-gpio.c with 99% similarity]
drivers/gpio/gpio-xilinx.c [moved from drivers/gpio/xilinx_gpio.c with 100% similarity]
drivers/leds/Kconfig
drivers/leds/leds-gpio.c
drivers/of/gpio.c
include/linux/of_gpio.h
include/linux/spi/74x164.h
include/linux/spi/mcp23s08.h

diff --git a/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt b/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt
new file mode 100644 (file)
index 0000000..4363ae4
--- /dev/null
@@ -0,0 +1,22 @@
+* Freescale i.MX/MXC GPIO controller
+
+Required properties:
+- compatible : Should be "fsl,<soc>-gpio"
+- reg : Address and length of the register set for the device
+- interrupts : Should be the port interrupt shared by all 32 pins, if
+  one number.  If two numbers, the first one is the interrupt shared
+  by low 16 pins and the second one is for high 16 pins.
+- gpio-controller : Marks the device node as a gpio controller.
+- #gpio-cells : Should be two.  The first cell is the pin number and
+  the second cell is used to specify optional parameters (currently
+  unused).
+
+Example:
+
+gpio0: gpio@73f84000 {
+       compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+       reg = <0x73f84000 0x4000>;
+       interrupts = <50 51>;
+       gpio-controller;
+       #gpio-cells = <2>;
+};
index edaa84d..4e16ba4 100644 (file)
@@ -4,17 +4,45 @@ Specifying GPIO information for devices
 1) gpios property
 -----------------
 
-Nodes that makes use of GPIOs should define them using `gpios' property,
-format of which is: <&gpio-controller1-phandle gpio1-specifier
-                    &gpio-controller2-phandle gpio2-specifier
-                    0 /* holes are permitted, means no GPIO 3 */
-                    &gpio-controller4-phandle gpio4-specifier
-                    ...>;
+Nodes that makes use of GPIOs should specify them using one or more
+properties, each containing a 'gpio-list':
 
-Note that gpio-specifier length is controller dependent.
+       gpio-list ::= <single-gpio> [gpio-list]
+       single-gpio ::= <gpio-phandle> <gpio-specifier>
+       gpio-phandle : phandle to gpio controller node
+       gpio-specifier : Array of #gpio-cells specifying specific gpio
+                        (controller specific)
+
+GPIO properties should be named "[<name>-]gpios".  Exact
+meaning of each gpios property must be documented in the device tree
+binding for each device.
+
+For example, the following could be used to describe gpios pins to use
+as chip select lines; with chip selects 0, 1 and 3 populated, and chip
+select 2 left empty:
+
+       gpio1: gpio1 {
+               gpio-controller
+                #gpio-cells = <2>;
+       };
+       gpio2: gpio2 {
+               gpio-controller
+                #gpio-cells = <1>;
+       };
+       [...]
+        chipsel-gpios = <&gpio1 12 0>,
+                        <&gpio1 13 0>,
+                        <0>, /* holes are permitted, means no GPIO 2 */
+                        <&gpio2 2>;
+
+Note that gpio-specifier length is controller dependent.  In the
+above example, &gpio1 uses 2 cells to specify a gpio, while &gpio2
+only uses one.
 
 gpio-specifier may encode: bank, pin position inside the bank,
 whether pin is open-drain and whether pin is logically inverted.
+Exact meaning of each specifier cell is controller specific, and must
+be documented in the device tree binding for the device.
 
 Example of the node using GPIOs:
 
@@ -28,8 +56,8 @@ and empty GPIO flags as accepted by the "qe_pio_e" gpio-controller.
 2) gpio-controller nodes
 ------------------------
 
-Every GPIO controller node must have #gpio-cells property defined,
-this information will be used to translate gpio-specifiers.
+Every GPIO controller node must both an empty "gpio-controller"
+property, and have #gpio-cells contain the size of the gpio-specifier.
 
 Example of two SOC GPIO banks defined as gpio-controller nodes:
 
diff --git a/Documentation/devicetree/bindings/gpio/gpio_nvidia.txt b/Documentation/devicetree/bindings/gpio/gpio_nvidia.txt
new file mode 100644 (file)
index 0000000..eb4b530
--- /dev/null
@@ -0,0 +1,8 @@
+NVIDIA Tegra 2 GPIO controller
+
+Required properties:
+- compatible : "nvidia,tegra20-gpio"
+- #gpio-cells : Should be two. The first cell is the pin number and the
+  second cell is used to specify optional parameters:
+  - bit 0 specifies polarity (0 for normal, 1 for inverted)
+- gpio-controller : Marks the device node as a GPIO controller.
index 33ee2c8..6b7c41d 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Makefile for the linux kernel.
 #
-obj-y                  := core.o clock.o dma-m2p.o gpio.o
+obj-y                  := core.o clock.o dma-m2p.o
 obj-m                  :=
 obj-n                  :=
 obj-                   :=
index 6659a0d..c488e4b 100644 (file)
@@ -174,14 +174,10 @@ struct sys_timer ep93xx_timer = {
 /*************************************************************************
  * EP93xx IRQ handling
  *************************************************************************/
-extern void ep93xx_gpio_init_irq(void);
-
 void __init ep93xx_init_irq(void)
 {
        vic_init(EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK, 0);
        vic_init(EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK, 0);
-
-       ep93xx_gpio_init_irq();
 }
 
 
@@ -241,6 +237,24 @@ unsigned int ep93xx_chip_revision(void)
 }
 
 /*************************************************************************
+ * EP93xx GPIO
+ *************************************************************************/
+static struct resource ep93xx_gpio_resource[] = {
+       {
+               .start          = EP93XX_GPIO_PHYS_BASE,
+               .end            = EP93XX_GPIO_PHYS_BASE + 0xcc - 1,
+               .flags          = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device ep93xx_gpio_device = {
+       .name           = "gpio-ep93xx",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(ep93xx_gpio_resource),
+       .resource       = ep93xx_gpio_resource,
+};
+
+/*************************************************************************
  * EP93xx peripheral handling
  *************************************************************************/
 #define EP93XX_UART_MCR_OFFSET         (0x0100)
@@ -870,14 +884,13 @@ void __init ep93xx_register_ac97(void)
        platform_device_register(&ep93xx_pcm_device);
 }
 
-extern void ep93xx_gpio_init(void);
-
 void __init ep93xx_init_devices(void)
 {
        /* Disallow access to MaverickCrunch initially */
        ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_CPENA);
 
-       ep93xx_gpio_init();
+       /* Get the GPIO working early, other devices need it */
+       platform_device_register(&ep93xx_gpio_device);
 
        amba_device_register(&uart1_device, &iomem_resource);
        amba_device_register(&uart2_device, &iomem_resource);
index 9ac4d10..c4a7b84 100644 (file)
@@ -98,6 +98,7 @@
 
 #define EP93XX_SECURITY_BASE           EP93XX_APB_IOMEM(0x00030000)
 
+#define EP93XX_GPIO_PHYS_BASE          EP93XX_APB_PHYS(0x00040000)
 #define EP93XX_GPIO_BASE               EP93XX_APB_IOMEM(0x00040000)
 #define EP93XX_GPIO_REG(x)             (EP93XX_GPIO_BASE + (x))
 #define EP93XX_GPIO_F_INT_STATUS       EP93XX_GPIO_REG(0x5c)
index 15e45c8..59d2a3b 100644 (file)
@@ -115,6 +115,8 @@ static struct platform_device *devices[] __initdata = {
 
 static void __init apf9328_init(void)
 {
+       imx1_soc_init();
+
        mxc_gpio_setup_multiple_pins(apf9328_pins,
                        ARRAY_SIZE(apf9328_pins),
                        "APF9328");
index ffb40ff..ede2710 100644 (file)
@@ -490,6 +490,8 @@ static struct platform_device *devices[] __initdata = {
  */
 static void __init armadillo5x0_init(void)
 {
+       imx31_soc_init();
+
        mxc_iomux_setup_multiple_pins(armadillo5x0_pins,
                        ARRAY_SIZE(armadillo5x0_pins), "armadillo5x0");
 
index 42e4f07..f494705 100644 (file)
@@ -42,6 +42,8 @@ static const unsigned int bug_pins[] __initconst = {
 
 static void __init bug_board_init(void)
 {
+       imx31_soc_init();
+
        mxc_iomux_setup_multiple_pins(bug_pins,
                                      ARRAY_SIZE(bug_pins), "uart-4");
        imx31_add_imx_uart4(&uart_pdata);
index 46a2e41..87887ac 100644 (file)
@@ -250,6 +250,8 @@ __setup("otg_mode=", eukrea_cpuimx27_otg_mode);
 
 static void __init eukrea_cpuimx27_init(void)
 {
+       imx27_soc_init();
+
        mxc_gpio_setup_multiple_pins(eukrea_cpuimx27_pins,
                ARRAY_SIZE(eukrea_cpuimx27_pins), "CPUIMX27");
 
index 3f8ef82..f39a478 100644 (file)
@@ -156,6 +156,8 @@ __setup("otg_mode=", eukrea_cpuimx35_otg_mode);
  */
 static void __init eukrea_cpuimx35_init(void)
 {
+       imx35_soc_init();
+
        mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx35_pads,
                        ARRAY_SIZE(eukrea_cpuimx35_pads));
 
index 148cff2..da36da5 100644 (file)
@@ -125,6 +125,8 @@ __setup("otg_mode=", eukrea_cpuimx25_otg_mode);
 
 static void __init eukrea_cpuimx25_init(void)
 {
+       imx25_soc_init();
+
        if (mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx25_pads,
                        ARRAY_SIZE(eukrea_cpuimx25_pads)))
                printk(KERN_ERR "error setting cpuimx25 pads !\n");
index 7ae43b1..c6269d6 100644 (file)
@@ -231,6 +231,8 @@ static void __init visstrim_m10_board_init(void)
 {
        int ret;
 
+       imx27_soc_init();
+
        ret = mxc_gpio_setup_multiple_pins(visstrim_m10_pins,
                        ARRAY_SIZE(visstrim_m10_pins), "VISSTRIM_M10");
        if (ret)
index 9be6cd6..272f793 100644 (file)
@@ -50,6 +50,8 @@ static const int mx27ipcam_pins[] __initconst = {
 
 static void __init mx27ipcam_init(void)
 {
+       imx27_soc_init();
+
        mxc_gpio_setup_multiple_pins(mx27ipcam_pins, ARRAY_SIZE(mx27ipcam_pins),
                "mx27ipcam");
 
index 8411405..d81a769 100644 (file)
@@ -59,6 +59,8 @@ static const struct imxuart_platform_data uart_pdata __initconst = {
 
 static void __init mx27lite_init(void)
 {
+       imx27_soc_init();
+
        mxc_gpio_setup_multiple_pins(mx27lite_pins, ARRAY_SIZE(mx27lite_pins),
                "imx27lite");
        imx27_add_imx_uart0(&uart_pdata);
index 1ecae20..e472a1d 100644 (file)
@@ -223,6 +223,8 @@ static int kzm_pins[] __initdata = {
  */
 static void __init kzm_board_init(void)
 {
+       imx31_soc_init();
+
        mxc_iomux_setup_multiple_pins(kzm_pins,
                                      ARRAY_SIZE(kzm_pins), "kzm");
        kzm_init_ext_uart();
index 38ec5cb..5cd8bee 100644 (file)
@@ -115,6 +115,8 @@ static struct i2c_board_info mx1ads_i2c_devices[] = {
  */
 static void __init mx1ads_init(void)
 {
+       imx1_soc_init();
+
        mxc_gpio_setup_multiple_pins(mx1ads_pins,
                ARRAY_SIZE(mx1ads_pins), "mx1ads");
 
index 74ac889..d389ecf 100644 (file)
@@ -279,6 +279,8 @@ static struct platform_device *platform_devices[] __initdata = {
 
 static void __init mx21ads_board_init(void)
 {
+       imx21_soc_init();
+
        mxc_gpio_setup_multiple_pins(mx21ads_pins, ARRAY_SIZE(mx21ads_pins),
                        "mx21ads");
 
index 58ea3fd..01534bb 100644 (file)
@@ -219,6 +219,8 @@ static const struct esdhc_platform_data mx25pdk_esdhc_pdata __initconst = {
 
 static void __init mx25pdk_init(void)
 {
+       imx25_soc_init();
+
        mxc_iomux_v3_setup_multiple_pads(mx25pdk_pads,
                        ARRAY_SIZE(mx25pdk_pads));
 
index 6e1accf..117ce0a 100644 (file)
@@ -267,6 +267,8 @@ static const struct imxi2c_platform_data mx27_3ds_i2c0_data __initconst = {
 
 static void __init mx27pdk_init(void)
 {
+       imx27_soc_init();
+
        mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins),
                "mx27pdk");
        mx27_3ds_sdhc1_enable_level_translator();
index 1db7950..fc26ed7 100644 (file)
@@ -288,6 +288,8 @@ static const struct imxuart_platform_data uart_pdata __initconst = {
 
 static void __init mx27ads_board_init(void)
 {
+       imx27_soc_init();
+
        mxc_gpio_setup_multiple_pins(mx27ads_pins, ARRAY_SIZE(mx27ads_pins),
                        "mx27ads");
 
index b5ecc26..441fbb8 100644 (file)
@@ -690,6 +690,8 @@ static void __init mx31_3ds_init(void)
 {
        int ret;
 
+       imx31_soc_init();
+
        mxc_iomux_setup_multiple_pins(mx31_3ds_pins, ARRAY_SIZE(mx31_3ds_pins),
                                      "mx31_3ds");
 
index f4dee02..0ce4947 100644 (file)
@@ -516,6 +516,8 @@ static void __init mx31ads_init_irq(void)
 
 static void __init mx31ads_init(void)
 {
+       imx31_soc_init();
+
        mxc_init_extuart();
        mxc_init_imx_uart();
        mxc_init_i2c();
index 410e676..750368d 100644 (file)
@@ -243,6 +243,8 @@ core_param(mx31lilly_baseboard, mx31lilly_baseboard, int, 0444);
 
 static void __init mx31lilly_board_init(void)
 {
+       imx31_soc_init();
+
        switch (mx31lilly_baseboard) {
        case MX31LILLY_NOBOARD:
                break;
index ac9b4ca..4b47fd9 100644 (file)
@@ -230,6 +230,8 @@ static void __init mx31lite_init(void)
 {
        int ret;
 
+       imx31_soc_init();
+
        switch (mx31lite_baseboard) {
        case MX31LITE_NOBOARD:
                break;
index eaa51e4..a52fd36 100644 (file)
@@ -507,6 +507,8 @@ core_param(mx31moboard_baseboard, mx31moboard_baseboard, int, 0444);
  */
 static void __init mx31moboard_init(void)
 {
+       imx31_soc_init();
+
        mxc_iomux_setup_multiple_pins(moboard_pins, ARRAY_SIZE(moboard_pins),
                "moboard");
 
index 882880a..48b3c6f 100644 (file)
@@ -179,6 +179,8 @@ static const struct imxi2c_platform_data mx35_3ds_i2c0_data __initconst = {
  */
 static void __init mx35_3ds_init(void)
 {
+       imx35_soc_init();
+
        mxc_iomux_v3_setup_multiple_pads(mx35pdk_pads, ARRAY_SIZE(mx35pdk_pads));
 
        imx35_add_fec(NULL);
index 2774541..c85876f 100644 (file)
@@ -233,6 +233,8 @@ static const struct imxuart_platform_data uart_pdata __initconst = {
 
 static void __init mxt_td60_board_init(void)
 {
+       imx27_soc_init();
+
        mxc_gpio_setup_multiple_pins(mxt_td60_pins, ARRAY_SIZE(mxt_td60_pins),
                        "MXT_TD60");
 
index bbddc5a..71083aa 100644 (file)
@@ -357,6 +357,8 @@ static void __init pca100_init(void)
 {
        int ret;
 
+       imx27_soc_init();
+
        /* SSI unit */
        mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
                                  MXC_AUDMUX_V1_PCR_SYN | /* 4wire mode */
index 89c213b..f45b7cd 100644 (file)
@@ -576,6 +576,8 @@ static void __init pcm037_init(void)
 {
        int ret;
 
+       imx31_soc_init();
+
        mxc_iomux_set_gpr(MUX_PGP_UH2, 1);
 
        mxc_iomux_setup_multiple_pins(pcm037_pins, ARRAY_SIZE(pcm037_pins),
index 853bb87..2d6a64b 100644 (file)
@@ -295,6 +295,8 @@ static const struct mxc_usbh_platform_data usbh2_pdata __initconst = {
 
 static void __init pcm038_init(void)
 {
+       imx27_soc_init();
+
        mxc_gpio_setup_multiple_pins(pcm038_pins, ARRAY_SIZE(pcm038_pins),
                        "PCM038");
 
index 0264416..163cc31 100644 (file)
@@ -356,6 +356,8 @@ static struct esdhc_platform_data sd1_pdata = {
  */
 static void __init pcm043_init(void)
 {
+       imx35_soc_init();
+
        mxc_iomux_v3_setup_multiple_pads(pcm043_pads, ARRAY_SIZE(pcm043_pads));
 
        mxc_audmux_v2_configure_port(3,
index c163287..3626f48 100644 (file)
@@ -244,6 +244,8 @@ static void __init qong_init_fpga(void)
  */
 static void __init qong_init(void)
 {
+       imx31_soc_init();
+
        mxc_init_imx_uart();
        qong_init_nor_mtd();
        qong_init_fpga();
index dcaee04..8280526 100644 (file)
@@ -129,6 +129,8 @@ static struct platform_device *devices[] __initdata = {
  */
 static void __init scb9328_init(void)
 {
+       imx1_soc_init();
+
        imx1_add_imx_uart0(&uart_pdata);
 
        printk(KERN_INFO"Scb9328: Adding devices\n");
index d74e347..7d8e012 100644 (file)
@@ -267,6 +267,8 @@ static struct platform_device *devices[] __initdata = {
  */
 static void __init vpr200_board_init(void)
 {
+       imx35_soc_init();
+
        mxc_iomux_v3_setup_multiple_pads(vpr200_pads, ARRAY_SIZE(vpr200_pads));
 
        imx35_add_fec(NULL);
index 2e482ba..2bded59 100644 (file)
@@ -23,7 +23,6 @@
 
 #include <mach/common.h>
 #include <mach/hardware.h>
-#include <mach/gpio.h>
 #include <mach/irqs.h>
 #include <mach/iomux-v1.h>
 
@@ -44,15 +43,19 @@ void __init imx1_init_early(void)
                        MX1_NUM_GPIO_PORT);
 }
 
-static struct mxc_gpio_port imx1_gpio_ports[] = {
-       DEFINE_IMX_GPIO_PORT_IRQ(MX1, 0, 1, MX1_GPIO_INT_PORTA),
-       DEFINE_IMX_GPIO_PORT_IRQ(MX1, 1, 2, MX1_GPIO_INT_PORTB),
-       DEFINE_IMX_GPIO_PORT_IRQ(MX1, 2, 3, MX1_GPIO_INT_PORTC),
-       DEFINE_IMX_GPIO_PORT_IRQ(MX1, 3, 4, MX1_GPIO_INT_PORTD),
-};
-
 void __init mx1_init_irq(void)
 {
        mxc_init_irq(MX1_IO_ADDRESS(MX1_AVIC_BASE_ADDR));
-       mxc_gpio_init(imx1_gpio_ports,  ARRAY_SIZE(imx1_gpio_ports));
+}
+
+void __init imx1_soc_init(void)
+{
+       mxc_register_gpio("imx1-gpio", 0, MX1_GPIO1_BASE_ADDR, SZ_256,
+                                               MX1_GPIO_INT_PORTA, 0);
+       mxc_register_gpio("imx1-gpio", 1, MX1_GPIO2_BASE_ADDR, SZ_256,
+                                               MX1_GPIO_INT_PORTB, 0);
+       mxc_register_gpio("imx1-gpio", 2, MX1_GPIO3_BASE_ADDR, SZ_256,
+                                               MX1_GPIO_INT_PORTC, 0);
+       mxc_register_gpio("imx1-gpio", 3, MX1_GPIO4_BASE_ADDR, SZ_256,
+                                               MX1_GPIO_INT_PORTD, 0);
 }
index 7a0c500..6d7d518 100644 (file)
@@ -24,7 +24,6 @@
 #include <mach/common.h>
 #include <asm/pgtable.h>
 #include <asm/mach/map.h>
-#include <mach/gpio.h>
 #include <mach/irqs.h>
 #include <mach/iomux-v1.h>
 
@@ -70,17 +69,17 @@ void __init imx21_init_early(void)
                        MX21_NUM_GPIO_PORT);
 }
 
-static struct mxc_gpio_port imx21_gpio_ports[] = {
-       DEFINE_IMX_GPIO_PORT_IRQ(MX21, 0, 1, MX21_INT_GPIO),
-       DEFINE_IMX_GPIO_PORT(MX21, 1, 2),
-       DEFINE_IMX_GPIO_PORT(MX21, 2, 3),
-       DEFINE_IMX_GPIO_PORT(MX21, 3, 4),
-       DEFINE_IMX_GPIO_PORT(MX21, 4, 5),
-       DEFINE_IMX_GPIO_PORT(MX21, 5, 6),
-};
-
 void __init mx21_init_irq(void)
 {
        mxc_init_irq(MX21_IO_ADDRESS(MX21_AVIC_BASE_ADDR));
-       mxc_gpio_init(imx21_gpio_ports, ARRAY_SIZE(imx21_gpio_ports));
+}
+
+void __init imx21_soc_init(void)
+{
+       mxc_register_gpio("imx21-gpio", 0, MX21_GPIO1_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
+       mxc_register_gpio("imx21-gpio", 1, MX21_GPIO2_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
+       mxc_register_gpio("imx21-gpio", 2, MX21_GPIO3_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
+       mxc_register_gpio("imx21-gpio", 3, MX21_GPIO4_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
+       mxc_register_gpio("imx21-gpio", 4, MX21_GPIO5_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
+       mxc_register_gpio("imx21-gpio", 5, MX21_GPIO6_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
 }
index 02f7b5c..9a1591c 100644 (file)
@@ -27,7 +27,6 @@
 #include <mach/hardware.h>
 #include <mach/mx25.h>
 #include <mach/iomux-v3.h>
-#include <mach/gpio.h>
 #include <mach/irqs.h>
 
 /*
@@ -57,16 +56,16 @@ void __init imx25_init_early(void)
        mxc_arch_reset_init(MX25_IO_ADDRESS(MX25_WDOG_BASE_ADDR));
 }
 
-static struct mxc_gpio_port imx25_gpio_ports[] = {
-       DEFINE_IMX_GPIO_PORT_IRQ(MX25, 0, 1, MX25_INT_GPIO1),
-       DEFINE_IMX_GPIO_PORT_IRQ(MX25, 1, 2, MX25_INT_GPIO2),
-       DEFINE_IMX_GPIO_PORT_IRQ(MX25, 2, 3, MX25_INT_GPIO3),
-       DEFINE_IMX_GPIO_PORT_IRQ(MX25, 3, 4, MX25_INT_GPIO4),
-};
-
 void __init mx25_init_irq(void)
 {
        mxc_init_irq(MX25_IO_ADDRESS(MX25_AVIC_BASE_ADDR));
-       mxc_gpio_init(imx25_gpio_ports, ARRAY_SIZE(imx25_gpio_ports));
 }
 
+void __init imx25_soc_init(void)
+{
+       /* i.mx25 has the i.mx31 type gpio */
+       mxc_register_gpio("imx31-gpio", 0, MX25_GPIO1_BASE_ADDR, SZ_16K, MX25_INT_GPIO1, 0);
+       mxc_register_gpio("imx31-gpio", 1, MX25_GPIO2_BASE_ADDR, SZ_16K, MX25_INT_GPIO2, 0);
+       mxc_register_gpio("imx31-gpio", 2, MX25_GPIO3_BASE_ADDR, SZ_16K, MX25_INT_GPIO3, 0);
+       mxc_register_gpio("imx31-gpio", 3, MX25_GPIO4_BASE_ADDR, SZ_16K, MX25_INT_GPIO4, 0);
+}
index a6761a3..133b300 100644 (file)
@@ -24,7 +24,6 @@
 #include <mach/common.h>
 #include <asm/pgtable.h>
 #include <asm/mach/map.h>
-#include <mach/gpio.h>
 #include <mach/irqs.h>
 #include <mach/iomux-v1.h>
 
@@ -70,17 +69,18 @@ void __init imx27_init_early(void)
                        MX27_NUM_GPIO_PORT);
 }
 
-static struct mxc_gpio_port imx27_gpio_ports[] = {
-       DEFINE_IMX_GPIO_PORT_IRQ(MX27, 0, 1, MX27_INT_GPIO),
-       DEFINE_IMX_GPIO_PORT(MX27, 1, 2),
-       DEFINE_IMX_GPIO_PORT(MX27, 2, 3),
-       DEFINE_IMX_GPIO_PORT(MX27, 3, 4),
-       DEFINE_IMX_GPIO_PORT(MX27, 4, 5),
-       DEFINE_IMX_GPIO_PORT(MX27, 5, 6),
-};
-
 void __init mx27_init_irq(void)
 {
        mxc_init_irq(MX27_IO_ADDRESS(MX27_AVIC_BASE_ADDR));
-       mxc_gpio_init(imx27_gpio_ports, ARRAY_SIZE(imx27_gpio_ports));
+}
+
+void __init imx27_soc_init(void)
+{
+       /* i.mx27 has the i.mx21 type gpio */
+       mxc_register_gpio("imx21-gpio", 0, MX27_GPIO1_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
+       mxc_register_gpio("imx21-gpio", 1, MX27_GPIO2_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
+       mxc_register_gpio("imx21-gpio", 2, MX27_GPIO3_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
+       mxc_register_gpio("imx21-gpio", 3, MX27_GPIO4_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
+       mxc_register_gpio("imx21-gpio", 4, MX27_GPIO5_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
+       mxc_register_gpio("imx21-gpio", 5, MX27_GPIO6_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
 }
index 86b9b45..6d103c0 100644 (file)
@@ -26,7 +26,6 @@
 #include <mach/common.h>
 #include <mach/hardware.h>
 #include <mach/iomux-v3.h>
-#include <mach/gpio.h>
 #include <mach/irqs.h>
 
 static struct map_desc mx31_io_desc[] __initdata = {
@@ -53,14 +52,14 @@ void __init imx31_init_early(void)
        mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR));
 }
 
-static struct mxc_gpio_port imx31_gpio_ports[] = {
-       DEFINE_IMX_GPIO_PORT_IRQ(MX31, 0, 1, MX31_INT_GPIO1),
-       DEFINE_IMX_GPIO_PORT_IRQ(MX31, 1, 2, MX31_INT_GPIO2),
-       DEFINE_IMX_GPIO_PORT_IRQ(MX31, 2, 3, MX31_INT_GPIO3),
-};
-
 void __init mx31_init_irq(void)
 {
        mxc_init_irq(MX31_IO_ADDRESS(MX31_AVIC_BASE_ADDR));
-       mxc_gpio_init(imx31_gpio_ports, ARRAY_SIZE(imx31_gpio_ports));
+}
+
+void __init imx31_soc_init(void)
+{
+       mxc_register_gpio("imx31-gpio", 0, MX31_GPIO1_BASE_ADDR, SZ_16K, MX31_INT_GPIO1, 0);
+       mxc_register_gpio("imx31-gpio", 1, MX31_GPIO2_BASE_ADDR, SZ_16K, MX31_INT_GPIO2, 0);
+       mxc_register_gpio("imx31-gpio", 2, MX31_GPIO3_BASE_ADDR, SZ_16K, MX31_INT_GPIO3, 0);
 }
index c880e6d..bb068bc 100644 (file)
@@ -27,7 +27,6 @@
 #include <mach/common.h>
 #include <mach/hardware.h>
 #include <mach/iomux-v3.h>
-#include <mach/gpio.h>
 #include <mach/irqs.h>
 
 static struct map_desc mx35_io_desc[] __initdata = {
@@ -50,14 +49,15 @@ void __init imx35_init_early(void)
        mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR));
 }
 
-static struct mxc_gpio_port imx35_gpio_ports[] = {
-       DEFINE_IMX_GPIO_PORT_IRQ(MX35, 0, 1, MX35_INT_GPIO1),
-       DEFINE_IMX_GPIO_PORT_IRQ(MX35, 1, 2, MX35_INT_GPIO2),
-       DEFINE_IMX_GPIO_PORT_IRQ(MX35, 2, 3, MX35_INT_GPIO3),
-};
-
 void __init mx35_init_irq(void)
 {
        mxc_init_irq(MX35_IO_ADDRESS(MX35_AVIC_BASE_ADDR));
-       mxc_gpio_init(imx35_gpio_ports, ARRAY_SIZE(imx35_gpio_ports));
+}
+
+void __init imx35_soc_init(void)
+{
+       /* i.mx35 has the i.mx31 type gpio */
+       mxc_register_gpio("imx31-gpio", 0, MX35_GPIO1_BASE_ADDR, SZ_16K, MX35_INT_GPIO1, 0);
+       mxc_register_gpio("imx31-gpio", 1, MX35_GPIO2_BASE_ADDR, SZ_16K, MX35_INT_GPIO2, 0);
+       mxc_register_gpio("imx31-gpio", 2, MX35_GPIO3_BASE_ADDR, SZ_16K, MX35_INT_GPIO3, 0);
 }
index 4efa02e..add0d42 100644 (file)
@@ -245,6 +245,8 @@ __setup("otg_mode=", eukrea_cpuimx51_otg_mode);
  */
 static void __init eukrea_cpuimx51_init(void)
 {
+       imx51_soc_init();
+
        mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51_pads,
                                        ARRAY_SIZE(eukrea_cpuimx51_pads));
 
index 5ef25a5..ff096d5 100644 (file)
@@ -264,6 +264,8 @@ static struct platform_device *platform_devices[] __initdata = {
 
 static void __init eukrea_cpuimx51sd_init(void)
 {
+       imx51_soc_init();
+
        mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51sd_pads,
                                        ARRAY_SIZE(eukrea_cpuimx51sd_pads));
 
index 11210e1..7de25c6 100644 (file)
@@ -192,6 +192,8 @@ static const struct imxi2c_platform_data i2c_data __initconst = {
  */
 static void __init mx50_rdp_board_init(void)
 {
+       imx50_soc_init();
+
        mxc_iomux_v3_setup_multiple_pads(mx50_rdp_pads,
                                        ARRAY_SIZE(mx50_rdp_pads));
 
index 63dfbea..3112d15 100644 (file)
@@ -135,6 +135,8 @@ static struct spi_board_info mx51_3ds_spi_nor_device[] = {
  */
 static void __init mx51_3ds_init(void)
 {
+       imx51_soc_init();
+
        mxc_iomux_v3_setup_multiple_pads(mx51_3ds_pads,
                                        ARRAY_SIZE(mx51_3ds_pads));
 
index c7b3fab..6021dd0 100644 (file)
@@ -340,6 +340,8 @@ static void __init mx51_babbage_init(void)
        iomux_v3_cfg_t power_key = _MX51_PAD_EIM_A27__GPIO2_21 |
                MUX_PAD_CTRL(PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | PAD_CTL_PUS_100K_UP);
 
+       imx51_soc_init();
+
 #if defined(CONFIG_CPU_FREQ_IMX)
        get_cpu_op = mx51_get_cpu_op;
 #endif
index 6e36231..3be603b 100644 (file)
@@ -236,6 +236,8 @@ late_initcall(mx51_efikamx_power_init);
 
 static void __init mx51_efikamx_init(void)
 {
+       imx51_soc_init();
+
        mxc_iomux_v3_setup_multiple_pads(mx51efikamx_pads,
                                        ARRAY_SIZE(mx51efikamx_pads));
        efika_board_common_init();
index 474fc6e..4b2e522 100644 (file)
@@ -248,6 +248,8 @@ static void __init mx51_efikasb_board_id(void)
 
 static void __init efikasb_board_init(void)
 {
+       imx51_soc_init();
+
        mxc_iomux_v3_setup_multiple_pads(mx51efikasb_pads,
                                        ARRAY_SIZE(mx51efikasb_pads));
        efika_board_common_init();
index f87d571..0d9218a 100644 (file)
@@ -117,6 +117,8 @@ static const struct spi_imx_master mx53_evk_spi_data __initconst = {
 
 static void __init mx53_evk_board_init(void)
 {
+       imx53_soc_init();
+
        mxc_iomux_v3_setup_multiple_pads(mx53_evk_pads,
                                        ARRAY_SIZE(mx53_evk_pads));
        mx53_evk_init_uart();
index 1b947e8..359c3e2 100644 (file)
@@ -227,6 +227,8 @@ static const struct imxi2c_platform_data mx53_loco_i2c_data __initconst = {
 
 static void __init mx53_loco_board_init(void)
 {
+       imx53_soc_init();
+
        mxc_iomux_v3_setup_multiple_pads(mx53_loco_pads,
                                        ARRAY_SIZE(mx53_loco_pads));
        imx53_add_imx_uart(0, NULL);
index 817c089..bc02894 100644 (file)
@@ -113,6 +113,8 @@ static const struct imxi2c_platform_data mx53_smd_i2c_data __initconst = {
 
 static void __init mx53_smd_board_init(void)
 {
+       imx53_soc_init();
+
        mxc_iomux_v3_setup_multiple_pads(mx53_smd_pads,
                                        ARRAY_SIZE(mx53_smd_pads));
        mx53_smd_init_uart();
index 153ada5..371ca8c 100644 (file)
@@ -12,7 +12,6 @@
 
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
-#include <linux/gpio.h>
 #include <mach/hardware.h>
 #include <mach/imx-uart.h>
 #include <mach/irqs.h>
@@ -119,66 +118,3 @@ struct platform_device mxc_usbh2_device = {
                .coherent_dma_mask = DMA_BIT_MASK(32),
        },
 };
-
-static struct mxc_gpio_port mxc_gpio_ports[] = {
-       {
-               .chip.label = "gpio-0",
-               .base = MX51_IO_ADDRESS(MX51_GPIO1_BASE_ADDR),
-               .irq = MX51_MXC_INT_GPIO1_LOW,
-               .irq_high = MX51_MXC_INT_GPIO1_HIGH,
-               .virtual_irq_start = MXC_GPIO_IRQ_START
-       },
-       {
-               .chip.label = "gpio-1",
-               .base = MX51_IO_ADDRESS(MX51_GPIO2_BASE_ADDR),
-               .irq = MX51_MXC_INT_GPIO2_LOW,
-               .irq_high = MX51_MXC_INT_GPIO2_HIGH,
-               .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 1
-       },
-       {
-               .chip.label = "gpio-2",
-               .base = MX51_IO_ADDRESS(MX51_GPIO3_BASE_ADDR),
-               .irq = MX51_MXC_INT_GPIO3_LOW,
-               .irq_high = MX51_MXC_INT_GPIO3_HIGH,
-               .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 2
-       },
-       {
-               .chip.label = "gpio-3",
-               .base = MX51_IO_ADDRESS(MX51_GPIO4_BASE_ADDR),
-               .irq = MX51_MXC_INT_GPIO4_LOW,
-               .irq_high = MX51_MXC_INT_GPIO4_HIGH,
-               .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 3
-       },
-       {
-               .chip.label = "gpio-4",
-               .base = MX53_IO_ADDRESS(MX53_GPIO5_BASE_ADDR),
-               .irq = MX53_INT_GPIO5_LOW,
-               .irq_high = MX53_INT_GPIO5_HIGH,
-               .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 4
-       },
-       {
-               .chip.label = "gpio-5",
-               .base = MX53_IO_ADDRESS(MX53_GPIO6_BASE_ADDR),
-               .irq = MX53_INT_GPIO6_LOW,
-               .irq_high = MX53_INT_GPIO6_HIGH,
-               .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 5
-       },
-       {
-               .chip.label = "gpio-6",
-               .base = MX53_IO_ADDRESS(MX53_GPIO7_BASE_ADDR),
-               .irq = MX53_INT_GPIO7_LOW,
-               .irq_high = MX53_INT_GPIO7_HIGH,
-               .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 6
-       },
-};
-
-int __init imx51_register_gpios(void)
-{
-       return mxc_gpio_init(mxc_gpio_ports, 4);
-}
-
-int __init imx53_register_gpios(void)
-{
-       return mxc_gpio_init(mxc_gpio_ports, ARRAY_SIZE(mxc_gpio_ports));
-}
-
index b9c363b..77e374c 100644 (file)
@@ -26,7 +26,6 @@
 #include <mach/hardware.h>
 #include <mach/common.h>
 #include <mach/iomux-v3.h>
-#include <mach/gpio.h>
 #include <mach/irqs.h>
 
 /*
@@ -56,17 +55,18 @@ void __init imx50_init_early(void)
        mxc_arch_reset_init(MX50_IO_ADDRESS(MX50_WDOG_BASE_ADDR));
 }
 
-static struct mxc_gpio_port imx50_gpio_ports[] = {
-       DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 0, 1, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH),
-       DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 1, 2, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH),
-       DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 2, 3, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH),
-       DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 3, 4, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH),
-       DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 4, 5, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH),
-       DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 5, 6, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH),
-};
-
 void __init mx50_init_irq(void)
 {
        tzic_init_irq(MX50_IO_ADDRESS(MX50_TZIC_BASE_ADDR));
-       mxc_gpio_init(imx50_gpio_ports, ARRAY_SIZE(imx50_gpio_ports));
+}
+
+void __init imx50_soc_init(void)
+{
+       /* i.mx50 has the i.mx31 type gpio */
+       mxc_register_gpio("imx31-gpio", 0, MX50_GPIO1_BASE_ADDR, SZ_16K, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH);
+       mxc_register_gpio("imx31-gpio", 1, MX50_GPIO2_BASE_ADDR, SZ_16K, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH);
+       mxc_register_gpio("imx31-gpio", 2, MX50_GPIO3_BASE_ADDR, SZ_16K, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH);
+       mxc_register_gpio("imx31-gpio", 3, MX50_GPIO4_BASE_ADDR, SZ_16K, MX50_INT_GPIO4_LOW, MX50_INT_GPIO4_HIGH);
+       mxc_register_gpio("imx31-gpio", 4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH);
+       mxc_register_gpio("imx31-gpio", 5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH);
 }
index ff55730..665843d 100644 (file)
@@ -69,8 +69,6 @@ void __init imx53_init_early(void)
        mxc_arch_reset_init(MX53_IO_ADDRESS(MX53_WDOG1_BASE_ADDR));
 }
 
-int imx51_register_gpios(void);
-
 void __init mx51_init_irq(void)
 {
        unsigned long tzic_addr;
@@ -86,11 +84,8 @@ void __init mx51_init_irq(void)
                panic("unable to map TZIC interrupt controller\n");
 
        tzic_init_irq(tzic_virt);
-       imx51_register_gpios();
 }
 
-int imx53_register_gpios(void);
-
 void __init mx53_init_irq(void)
 {
        unsigned long tzic_addr;
@@ -103,5 +98,25 @@ void __init mx53_init_irq(void)
                panic("unable to map TZIC interrupt controller\n");
 
        tzic_init_irq(tzic_virt);
-       imx53_register_gpios();
+}
+
+void __init imx51_soc_init(void)
+{
+       /* i.mx51 has the i.mx31 type gpio */
+       mxc_register_gpio("imx31-gpio", 0, MX51_GPIO1_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO1_LOW, MX51_MXC_INT_GPIO1_HIGH);
+       mxc_register_gpio("imx31-gpio", 1, MX51_GPIO2_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO2_LOW, MX51_MXC_INT_GPIO2_HIGH);
+       mxc_register_gpio("imx31-gpio", 2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO3_LOW, MX51_MXC_INT_GPIO3_HIGH);
+       mxc_register_gpio("imx31-gpio", 3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO4_LOW, MX51_MXC_INT_GPIO4_HIGH);
+}
+
+void __init imx53_soc_init(void)
+{
+       /* i.mx53 has the i.mx31 type gpio */
+       mxc_register_gpio("imx31-gpio", 0, MX53_GPIO1_BASE_ADDR, SZ_16K, MX53_INT_GPIO1_LOW, MX53_INT_GPIO1_HIGH);
+       mxc_register_gpio("imx31-gpio", 1, MX53_GPIO2_BASE_ADDR, SZ_16K, MX53_INT_GPIO2_LOW, MX53_INT_GPIO2_HIGH);
+       mxc_register_gpio("imx31-gpio", 2, MX53_GPIO3_BASE_ADDR, SZ_16K, MX53_INT_GPIO3_LOW, MX53_INT_GPIO3_HIGH);
+       mxc_register_gpio("imx31-gpio", 3, MX53_GPIO4_BASE_ADDR, SZ_16K, MX53_INT_GPIO4_LOW, MX53_INT_GPIO4_HIGH);
+       mxc_register_gpio("imx31-gpio", 4, MX53_GPIO5_BASE_ADDR, SZ_16K, MX53_INT_GPIO5_LOW, MX53_INT_GPIO5_HIGH);
+       mxc_register_gpio("imx31-gpio", 5, MX53_GPIO6_BASE_ADDR, SZ_16K, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH);
+       mxc_register_gpio("imx31-gpio", 6, MX53_GPIO7_BASE_ADDR, SZ_16K, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH);
 }
index 58e8923..6c38262 100644 (file)
@@ -1,5 +1,5 @@
 # Common support
-obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
+obj-y := clock.o devices.o icoll.o iomux.o system.o timer.o
 
 obj-$(CONFIG_MXS_OCOTP) += ocotp.o
 obj-$(CONFIG_PM) += pm.o
index cfdb6b2..fe3e847 100644 (file)
@@ -88,3 +88,14 @@ int __init mxs_add_amba_device(const struct amba_device *dev)
 
        return amba_device_register(adev, &iomem_resource);
 }
+
+struct device mxs_apbh_bus = {
+       .init_name      = "mxs_apbh",
+       .parent         = &platform_bus,
+};
+
+static int __init mxs_device_init(void)
+{
+       return device_register(&mxs_apbh_bus);
+}
+core_initcall(mxs_device_init);
index 324f282..351915c 100644 (file)
@@ -6,4 +6,5 @@ obj-$(CONFIG_MXS_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_I2C) += platform-mxs-i2c.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_MMC) += platform-mxs-mmc.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_PWM) += platform-mxs-pwm.o
+obj-y += platform-gpio-mxs.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_MXSFB) += platform-mxsfb.o
diff --git a/arch/arm/mach-mxs/devices/platform-gpio-mxs.c b/arch/arm/mach-mxs/devices/platform-gpio-mxs.c
new file mode 100644 (file)
index 0000000..ed0885e
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <linux/compiler.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+
+struct platform_device *__init mxs_add_gpio(
+       int id, resource_size_t iobase, int irq)
+{
+       struct resource res[] = {
+               {
+                       .start = iobase,
+                       .end = iobase + SZ_8K - 1,
+                       .flags = IORESOURCE_MEM,
+               }, {
+                       .start = irq,
+                       .end = irq,
+                       .flags = IORESOURCE_IRQ,
+               },
+       };
+
+       return platform_device_register_resndata(&mxs_apbh_bus,
+                       "gpio-mxs", id, res, ARRAY_SIZE(res), NULL, 0);
+}
+
+static int __init mxs_add_mxs_gpio(void)
+{
+       if (cpu_is_mx23()) {
+               mxs_add_gpio(0, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO0);
+               mxs_add_gpio(1, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO1);
+               mxs_add_gpio(2, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO2);
+       }
+
+       if (cpu_is_mx28()) {
+               mxs_add_gpio(0, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO0);
+               mxs_add_gpio(1, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO1);
+               mxs_add_gpio(2, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO2);
+               mxs_add_gpio(3, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO3);
+               mxs_add_gpio(4, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO4);
+       }
+
+       return 0;
+}
+postcore_initcall(mxs_add_mxs_gpio);
diff --git a/arch/arm/mach-mxs/gpio.c b/arch/arm/mach-mxs/gpio.c
deleted file mode 100644 (file)
index 2c950fe..0000000
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
- * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
- *
- * Based on code from Freescale,
- * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * 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.
- * This program is distributed in the hope that 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 Street, Fifth Floor, Boston,
- * MA  02110-1301, USA.
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
-#include <mach/mx23.h>
-#include <mach/mx28.h>
-#include <asm-generic/bug.h>
-
-#include "gpio.h"
-
-static struct mxs_gpio_port *mxs_gpio_ports;
-static int gpio_table_size;
-
-#define PINCTRL_DOUT(n)                ((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10)
-#define PINCTRL_DIN(n)         ((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10)
-#define PINCTRL_DOE(n)         ((cpu_is_mx23() ? 0x0700 : 0x0b00) + (n) * 0x10)
-#define PINCTRL_PIN2IRQ(n)     ((cpu_is_mx23() ? 0x0800 : 0x1000) + (n) * 0x10)
-#define PINCTRL_IRQEN(n)       ((cpu_is_mx23() ? 0x0900 : 0x1100) + (n) * 0x10)
-#define PINCTRL_IRQLEV(n)      ((cpu_is_mx23() ? 0x0a00 : 0x1200) + (n) * 0x10)
-#define PINCTRL_IRQPOL(n)      ((cpu_is_mx23() ? 0x0b00 : 0x1300) + (n) * 0x10)
-#define PINCTRL_IRQSTAT(n)     ((cpu_is_mx23() ? 0x0c00 : 0x1400) + (n) * 0x10)
-
-#define GPIO_INT_FALL_EDGE     0x0
-#define GPIO_INT_LOW_LEV       0x1
-#define GPIO_INT_RISE_EDGE     0x2
-#define GPIO_INT_HIGH_LEV      0x3
-#define GPIO_INT_LEV_MASK      (1 << 0)
-#define GPIO_INT_POL_MASK      (1 << 1)
-
-/* Note: This driver assumes 32 GPIOs are handled in one register */
-
-static void clear_gpio_irqstatus(struct mxs_gpio_port *port, u32 index)
-{
-       __mxs_clrl(1 << index, port->base + PINCTRL_IRQSTAT(port->id));
-}
-
-static void set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
-                               int enable)
-{
-       if (enable) {
-               __mxs_setl(1 << index, port->base + PINCTRL_IRQEN(port->id));
-               __mxs_setl(1 << index, port->base + PINCTRL_PIN2IRQ(port->id));
-       } else {
-               __mxs_clrl(1 << index, port->base + PINCTRL_IRQEN(port->id));
-       }
-}
-
-static void mxs_gpio_ack_irq(struct irq_data *d)
-{
-       u32 gpio = irq_to_gpio(d->irq);
-       clear_gpio_irqstatus(&mxs_gpio_ports[gpio / 32], gpio & 0x1f);
-}
-
-static void mxs_gpio_mask_irq(struct irq_data *d)
-{
-       u32 gpio = irq_to_gpio(d->irq);
-       set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 0);
-}
-
-static void mxs_gpio_unmask_irq(struct irq_data *d)
-{
-       u32 gpio = irq_to_gpio(d->irq);
-       set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 1);
-}
-
-static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset);
-
-static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
-{
-       u32 gpio = irq_to_gpio(d->irq);
-       u32 pin_mask = 1 << (gpio & 31);
-       struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
-       void __iomem *pin_addr;
-       int edge;
-
-       switch (type) {
-       case IRQ_TYPE_EDGE_RISING:
-               edge = GPIO_INT_RISE_EDGE;
-               break;
-       case IRQ_TYPE_EDGE_FALLING:
-               edge = GPIO_INT_FALL_EDGE;
-               break;
-       case IRQ_TYPE_LEVEL_LOW:
-               edge = GPIO_INT_LOW_LEV;
-               break;
-       case IRQ_TYPE_LEVEL_HIGH:
-               edge = GPIO_INT_HIGH_LEV;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       /* set level or edge */
-       pin_addr = port->base + PINCTRL_IRQLEV(port->id);
-       if (edge & GPIO_INT_LEV_MASK)
-               __mxs_setl(pin_mask, pin_addr);
-       else
-               __mxs_clrl(pin_mask, pin_addr);
-
-       /* set polarity */
-       pin_addr = port->base + PINCTRL_IRQPOL(port->id);
-       if (edge & GPIO_INT_POL_MASK)
-               __mxs_setl(pin_mask, pin_addr);
-       else
-               __mxs_clrl(pin_mask, pin_addr);
-
-       clear_gpio_irqstatus(port, gpio & 0x1f);
-
-       return 0;
-}
-
-/* MXS has one interrupt *per* gpio port */
-static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
-{
-       u32 irq_stat;
-       struct mxs_gpio_port *port = (struct mxs_gpio_port *)irq_get_handler_data(irq);
-       u32 gpio_irq_no_base = port->virtual_irq_start;
-
-       desc->irq_data.chip->irq_ack(&desc->irq_data);
-
-       irq_stat = __raw_readl(port->base + PINCTRL_IRQSTAT(port->id)) &
-                       __raw_readl(port->base + PINCTRL_IRQEN(port->id));
-
-       while (irq_stat != 0) {
-               int irqoffset = fls(irq_stat) - 1;
-               generic_handle_irq(gpio_irq_no_base + irqoffset);
-               irq_stat &= ~(1 << irqoffset);
-       }
-}
-
-/*
- * Set interrupt number "irq" in the GPIO as a wake-up source.
- * While system is running, all registered GPIO interrupts need to have
- * wake-up enabled. When system is suspended, only selected GPIO interrupts
- * need to have wake-up enabled.
- * @param  irq          interrupt source number
- * @param  enable       enable as wake-up if equal to non-zero
- * @return       This function returns 0 on success.
- */
-static int mxs_gpio_set_wake_irq(struct irq_data *d, unsigned int enable)
-{
-       u32 gpio = irq_to_gpio(d->irq);
-       u32 gpio_idx = gpio & 0x1f;
-       struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
-
-       if (enable) {
-               if (port->irq_high && (gpio_idx >= 16))
-                       enable_irq_wake(port->irq_high);
-               else
-                       enable_irq_wake(port->irq);
-       } else {
-               if (port->irq_high && (gpio_idx >= 16))
-                       disable_irq_wake(port->irq_high);
-               else
-                       disable_irq_wake(port->irq);
-       }
-
-       return 0;
-}
-
-static struct irq_chip gpio_irq_chip = {
-       .name = "mxs gpio",
-       .irq_ack = mxs_gpio_ack_irq,
-       .irq_mask = mxs_gpio_mask_irq,
-       .irq_unmask = mxs_gpio_unmask_irq,
-       .irq_set_type = mxs_gpio_set_irq_type,
-       .irq_set_wake = mxs_gpio_set_wake_irq,
-};
-
-static void mxs_set_gpio_direction(struct gpio_chip *chip, unsigned offset,
-                               int dir)
-{
-       struct mxs_gpio_port *port =
-               container_of(chip, struct mxs_gpio_port, chip);
-       void __iomem *pin_addr = port->base + PINCTRL_DOE(port->id);
-
-       if (dir)
-               __mxs_setl(1 << offset, pin_addr);
-       else
-               __mxs_clrl(1 << offset, pin_addr);
-}
-
-static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
-       struct mxs_gpio_port *port =
-               container_of(chip, struct mxs_gpio_port, chip);
-
-       return (__raw_readl(port->base + PINCTRL_DIN(port->id)) >> offset) & 1;
-}
-
-static void mxs_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
-{
-       struct mxs_gpio_port *port =
-               container_of(chip, struct mxs_gpio_port, chip);
-       void __iomem *pin_addr = port->base + PINCTRL_DOUT(port->id);
-
-       if (value)
-               __mxs_setl(1 << offset, pin_addr);
-       else
-               __mxs_clrl(1 << offset, pin_addr);
-}
-
-static int mxs_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
-{
-       struct mxs_gpio_port *port =
-               container_of(chip, struct mxs_gpio_port, chip);
-
-       return port->virtual_irq_start + offset;
-}
-
-static int mxs_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
-{
-       mxs_set_gpio_direction(chip, offset, 0);
-       return 0;
-}
-
-static int mxs_gpio_direction_output(struct gpio_chip *chip,
-                                    unsigned offset, int value)
-{
-       mxs_gpio_set(chip, offset, value);
-       mxs_set_gpio_direction(chip, offset, 1);
-       return 0;
-}
-
-int __init mxs_gpio_init(struct mxs_gpio_port *port, int cnt)
-{
-       int i, j;
-
-       /* save for local usage */
-       mxs_gpio_ports = port;
-       gpio_table_size = cnt;
-
-       pr_info("MXS GPIO hardware\n");
-
-       for (i = 0; i < cnt; i++) {
-               /* disable the interrupt and clear the status */
-               __raw_writel(0, port[i].base + PINCTRL_PIN2IRQ(i));
-               __raw_writel(0, port[i].base + PINCTRL_IRQEN(i));
-
-               /* clear address has to be used to clear IRQSTAT bits */
-               __mxs_clrl(~0U, port[i].base + PINCTRL_IRQSTAT(i));
-
-               for (j = port[i].virtual_irq_start;
-                       j < port[i].virtual_irq_start + 32; j++) {
-                       irq_set_chip_and_handler(j, &gpio_irq_chip,
-                                                handle_level_irq);
-                       set_irq_flags(j, IRQF_VALID);
-               }
-
-               /* setup one handler for each entry */
-               irq_set_chained_handler(port[i].irq, mxs_gpio_irq_handler);
-               irq_set_handler_data(port[i].irq, &port[i]);
-
-               /* register gpio chip */
-               port[i].chip.direction_input = mxs_gpio_direction_input;
-               port[i].chip.direction_output = mxs_gpio_direction_output;
-               port[i].chip.get = mxs_gpio_get;
-               port[i].chip.set = mxs_gpio_set;
-               port[i].chip.to_irq = mxs_gpio_to_irq;
-               port[i].chip.base = i * 32;
-               port[i].chip.ngpio = 32;
-
-               /* its a serious configuration bug when it fails */
-               BUG_ON(gpiochip_add(&port[i].chip) < 0);
-       }
-
-       return 0;
-}
-
-#define MX23_GPIO_BASE MX23_IO_ADDRESS(MX23_PINCTRL_BASE_ADDR)
-#define MX28_GPIO_BASE MX28_IO_ADDRESS(MX28_PINCTRL_BASE_ADDR)
-
-#define DEFINE_MXS_GPIO_PORT(_base, _irq, _id)                         \
-       {                                                               \
-               .chip.label = "gpio-" #_id,                             \
-               .id = _id,                                              \
-               .irq = _irq,                                            \
-               .base = _base,                                          \
-               .virtual_irq_start = MXS_GPIO_IRQ_START + (_id) * 32,   \
-       }
-
-#ifdef CONFIG_SOC_IMX23
-static struct mxs_gpio_port mx23_gpio_ports[] = {
-       DEFINE_MXS_GPIO_PORT(MX23_GPIO_BASE, MX23_INT_GPIO0, 0),
-       DEFINE_MXS_GPIO_PORT(MX23_GPIO_BASE, MX23_INT_GPIO1, 1),
-       DEFINE_MXS_GPIO_PORT(MX23_GPIO_BASE, MX23_INT_GPIO2, 2),
-};
-
-int __init mx23_register_gpios(void)
-{
-       return mxs_gpio_init(mx23_gpio_ports, ARRAY_SIZE(mx23_gpio_ports));
-}
-#endif
-
-#ifdef CONFIG_SOC_IMX28
-static struct mxs_gpio_port mx28_gpio_ports[] = {
-       DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO0, 0),
-       DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO1, 1),
-       DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO2, 2),
-       DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO3, 3),
-       DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO4, 4),
-};
-
-int __init mx28_register_gpios(void)
-{
-       return mxs_gpio_init(mx28_gpio_ports, ARRAY_SIZE(mx28_gpio_ports));
-}
-#endif
diff --git a/arch/arm/mach-mxs/gpio.h b/arch/arm/mach-mxs/gpio.h
deleted file mode 100644 (file)
index 005bb06..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
- *
- * 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.
- * This program is distributed in the hope that 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 Street, Fifth Floor, Boston,
- * MA  02110-1301, USA.
- */
-
-#ifndef __MXS_GPIO_H__
-#define __MXS_GPIO_H__
-
-struct mxs_gpio_port {
-       void __iomem *base;
-       int id;
-       int irq;
-       int irq_high;
-       int virtual_irq_start;
-       struct gpio_chip chip;
-};
-
-int mxs_gpio_init(struct mxs_gpio_port*, int);
-
-#endif /* __MXS_GPIO_H__ */
index 7a37469..812d7a8 100644 (file)
@@ -11,6 +11,8 @@
 #include <linux/init.h>
 #include <linux/amba/bus.h>
 
+extern struct device mxs_apbh_bus;
+
 struct platform_device *mxs_add_platform_device_dmamask(
                const char *name, int id,
                const struct resource *res, unsigned int num_resources,
index eacdc6b..56767a5 100644 (file)
@@ -26,7 +26,6 @@
 #include <mach/iomux-mx28.h>
 
 #include "devices-mx28.h"
-#include "gpio.h"
 
 #define MX28EVK_FLEXCAN_SWITCH MXS_GPIO_NR(2, 13)
 #define MX28EVK_FEC_PHY_POWER  MXS_GPIO_NR(2, 15)
index 5148cd6..1b2345a 100644 (file)
@@ -41,5 +41,4 @@ void __init mx23_map_io(void)
 void __init mx23_init_irq(void)
 {
        icoll_init_irq();
-       mx23_register_gpios();
 }
index 7e4cea3..b6e18dd 100644 (file)
@@ -41,5 +41,4 @@ void __init mx28_map_io(void)
 void __init mx28_init_irq(void)
 {
        icoll_init_irq();
-       mx28_register_gpios();
 }
index 364137c..399da4c 100644 (file)
@@ -34,11 +34,22 @@ static struct __initdata resource omap15xx_mpu_gpio_resources[] = {
        },
 };
 
+static struct omap_gpio_reg_offs omap15xx_mpuio_regs = {
+       .revision       = USHRT_MAX,
+       .direction      = OMAP_MPUIO_IO_CNTL,
+       .datain         = OMAP_MPUIO_INPUT_LATCH,
+       .dataout        = OMAP_MPUIO_OUTPUT,
+       .irqstatus      = OMAP_MPUIO_GPIO_INT,
+       .irqenable      = OMAP_MPUIO_GPIO_MASKIT,
+       .irqenable_inv  = true,
+};
+
 static struct __initdata omap_gpio_platform_data omap15xx_mpu_gpio_config = {
        .virtual_irq_start      = IH_MPUIO_BASE,
        .bank_type              = METHOD_MPUIO,
        .bank_width             = 16,
        .bank_stride            = 1,
+       .regs                   = &omap15xx_mpuio_regs,
 };
 
 static struct platform_device omap15xx_mpu_gpio = {
@@ -64,10 +75,21 @@ static struct __initdata resource omap15xx_gpio_resources[] = {
        },
 };
 
+static struct omap_gpio_reg_offs omap15xx_gpio_regs = {
+       .revision       = USHRT_MAX,
+       .direction      = OMAP1510_GPIO_DIR_CONTROL,
+       .datain         = OMAP1510_GPIO_DATA_INPUT,
+       .dataout        = OMAP1510_GPIO_DATA_OUTPUT,
+       .irqstatus      = OMAP1510_GPIO_INT_STATUS,
+       .irqenable      = OMAP1510_GPIO_INT_MASK,
+       .irqenable_inv  = true,
+};
+
 static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = {
        .virtual_irq_start      = IH_GPIO_BASE,
        .bank_type              = METHOD_GPIO_1510,
        .bank_width             = 16,
+       .regs                   = &omap15xx_gpio_regs,
 };
 
 static struct platform_device omap15xx_gpio = {
index 293a246..0f399bd 100644 (file)
@@ -37,11 +37,22 @@ static struct __initdata resource omap16xx_mpu_gpio_resources[] = {
        },
 };
 
+static struct omap_gpio_reg_offs omap16xx_mpuio_regs = {
+       .revision       = USHRT_MAX,
+       .direction      = OMAP_MPUIO_IO_CNTL,
+       .datain         = OMAP_MPUIO_INPUT_LATCH,
+       .dataout        = OMAP_MPUIO_OUTPUT,
+       .irqstatus      = OMAP_MPUIO_GPIO_INT,
+       .irqenable      = OMAP_MPUIO_GPIO_MASKIT,
+       .irqenable_inv  = true,
+};
+
 static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config = {
        .virtual_irq_start      = IH_MPUIO_BASE,
        .bank_type              = METHOD_MPUIO,
        .bank_width             = 16,
        .bank_stride            = 1,
+       .regs                   = &omap16xx_mpuio_regs,
 };
 
 static struct platform_device omap16xx_mpu_gpio = {
@@ -67,10 +78,24 @@ static struct __initdata resource omap16xx_gpio1_resources[] = {
        },
 };
 
+static struct omap_gpio_reg_offs omap16xx_gpio_regs = {
+       .revision       = OMAP1610_GPIO_REVISION,
+       .direction      = OMAP1610_GPIO_DIRECTION,
+       .set_dataout    = OMAP1610_GPIO_SET_DATAOUT,
+       .clr_dataout    = OMAP1610_GPIO_CLEAR_DATAOUT,
+       .datain         = OMAP1610_GPIO_DATAIN,
+       .dataout        = OMAP1610_GPIO_DATAOUT,
+       .irqstatus      = OMAP1610_GPIO_IRQSTATUS1,
+       .irqenable      = OMAP1610_GPIO_IRQENABLE1,
+       .set_irqenable  = OMAP1610_GPIO_SET_IRQENABLE1,
+       .clr_irqenable  = OMAP1610_GPIO_CLEAR_IRQENABLE1,
+};
+
 static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = {
        .virtual_irq_start      = IH_GPIO_BASE,
        .bank_type              = METHOD_GPIO_1610,
        .bank_width             = 16,
+       .regs                   = &omap16xx_gpio_regs,
 };
 
 static struct platform_device omap16xx_gpio1 = {
@@ -100,6 +125,7 @@ static struct __initdata omap_gpio_platform_data omap16xx_gpio2_config = {
        .virtual_irq_start      = IH_GPIO_BASE + 16,
        .bank_type              = METHOD_GPIO_1610,
        .bank_width             = 16,
+       .regs                   = &omap16xx_gpio_regs,
 };
 
 static struct platform_device omap16xx_gpio2 = {
@@ -129,6 +155,7 @@ static struct __initdata omap_gpio_platform_data omap16xx_gpio3_config = {
        .virtual_irq_start      = IH_GPIO_BASE + 32,
        .bank_type              = METHOD_GPIO_1610,
        .bank_width             = 16,
+       .regs                   = &omap16xx_gpio_regs,
 };
 
 static struct platform_device omap16xx_gpio3 = {
@@ -158,6 +185,7 @@ static struct __initdata omap_gpio_platform_data omap16xx_gpio4_config = {
        .virtual_irq_start      = IH_GPIO_BASE + 48,
        .bank_type              = METHOD_GPIO_1610,
        .bank_width             = 16,
+       .regs                   = &omap16xx_gpio_regs,
 };
 
 static struct platform_device omap16xx_gpio4 = {
index c6ad248..5ab63ea 100644 (file)
@@ -39,11 +39,22 @@ static struct __initdata resource omap7xx_mpu_gpio_resources[] = {
        },
 };
 
+static struct omap_gpio_reg_offs omap7xx_mpuio_regs = {
+       .revision       = USHRT_MAX,
+       .direction      = OMAP_MPUIO_IO_CNTL / 2,
+       .datain         = OMAP_MPUIO_INPUT_LATCH / 2,
+       .dataout        = OMAP_MPUIO_OUTPUT / 2,
+       .irqstatus      = OMAP_MPUIO_GPIO_INT / 2,
+       .irqenable      = OMAP_MPUIO_GPIO_MASKIT / 2,
+       .irqenable_inv  = true,
+};
+
 static struct __initdata omap_gpio_platform_data omap7xx_mpu_gpio_config = {
        .virtual_irq_start      = IH_MPUIO_BASE,
        .bank_type              = METHOD_MPUIO,
        .bank_width             = 32,
        .bank_stride            = 2,
+       .regs                   = &omap7xx_mpuio_regs,
 };
 
 static struct platform_device omap7xx_mpu_gpio = {
@@ -69,10 +80,21 @@ static struct __initdata resource omap7xx_gpio1_resources[] = {
        },
 };
 
+static struct omap_gpio_reg_offs omap7xx_gpio_regs = {
+       .revision       = USHRT_MAX,
+       .direction      = OMAP7XX_GPIO_DIR_CONTROL,
+       .datain         = OMAP7XX_GPIO_DATA_INPUT,
+       .dataout        = OMAP7XX_GPIO_DATA_OUTPUT,
+       .irqstatus      = OMAP7XX_GPIO_INT_STATUS,
+       .irqenable      = OMAP7XX_GPIO_INT_MASK,
+       .irqenable_inv  = true,
+};
+
 static struct __initdata omap_gpio_platform_data omap7xx_gpio1_config = {
        .virtual_irq_start      = IH_GPIO_BASE,
        .bank_type              = METHOD_GPIO_7XX,
        .bank_width             = 32,
+       .regs                   = &omap7xx_gpio_regs,
 };
 
 static struct platform_device omap7xx_gpio1 = {
@@ -102,6 +124,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio2_config = {
        .virtual_irq_start      = IH_GPIO_BASE + 32,
        .bank_type              = METHOD_GPIO_7XX,
        .bank_width             = 32,
+       .regs                   = &omap7xx_gpio_regs,
 };
 
 static struct platform_device omap7xx_gpio2 = {
@@ -131,6 +154,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio3_config = {
        .virtual_irq_start      = IH_GPIO_BASE + 64,
        .bank_type              = METHOD_GPIO_7XX,
        .bank_width             = 32,
+       .regs                   = &omap7xx_gpio_regs,
 };
 
 static struct platform_device omap7xx_gpio3 = {
@@ -160,6 +184,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio4_config = {
        .virtual_irq_start      = IH_GPIO_BASE + 96,
        .bank_type              = METHOD_GPIO_7XX,
        .bank_width             = 32,
+       .regs                   = &omap7xx_gpio_regs,
 };
 
 static struct platform_device omap7xx_gpio4 = {
@@ -189,6 +214,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio5_config = {
        .virtual_irq_start      = IH_GPIO_BASE + 128,
        .bank_type              = METHOD_GPIO_7XX,
        .bank_width             = 32,
+       .regs                   = &omap7xx_gpio_regs,
 };
 
 static struct platform_device omap7xx_gpio5 = {
@@ -218,6 +244,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio6_config = {
        .virtual_irq_start      = IH_GPIO_BASE + 160,
        .bank_type              = METHOD_GPIO_7XX,
        .bank_width             = 32,
+       .regs                   = &omap7xx_gpio_regs,
 };
 
 static struct platform_device omap7xx_gpio6 = {
index 9529842..9a46d77 100644 (file)
@@ -61,13 +61,45 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
        pdata->dbck_flag = dev_attr->dbck_flag;
        pdata->virtual_irq_start = IH_GPIO_BASE + 32 * (id - 1);
 
+       pdata->regs = kzalloc(sizeof(struct omap_gpio_reg_offs), GFP_KERNEL);
+       if (!pdata) {
+               pr_err("gpio%d: Memory allocation failed\n", id);
+               return -ENOMEM;
+       }
+
        switch (oh->class->rev) {
        case 0:
        case 1:
                pdata->bank_type = METHOD_GPIO_24XX;
+               pdata->regs->revision = OMAP24XX_GPIO_REVISION;
+               pdata->regs->direction = OMAP24XX_GPIO_OE;
+               pdata->regs->datain = OMAP24XX_GPIO_DATAIN;
+               pdata->regs->dataout = OMAP24XX_GPIO_DATAOUT;
+               pdata->regs->set_dataout = OMAP24XX_GPIO_SETDATAOUT;
+               pdata->regs->clr_dataout = OMAP24XX_GPIO_CLEARDATAOUT;
+               pdata->regs->irqstatus = OMAP24XX_GPIO_IRQSTATUS1;
+               pdata->regs->irqstatus2 = OMAP24XX_GPIO_IRQSTATUS2;
+               pdata->regs->irqenable = OMAP24XX_GPIO_IRQENABLE1;
+               pdata->regs->set_irqenable = OMAP24XX_GPIO_SETIRQENABLE1;
+               pdata->regs->clr_irqenable = OMAP24XX_GPIO_CLEARIRQENABLE1;
+               pdata->regs->debounce = OMAP24XX_GPIO_DEBOUNCE_VAL;
+               pdata->regs->debounce_en = OMAP24XX_GPIO_DEBOUNCE_EN;
                break;
        case 2:
                pdata->bank_type = METHOD_GPIO_44XX;
+               pdata->regs->revision = OMAP4_GPIO_REVISION;
+               pdata->regs->direction = OMAP4_GPIO_OE;
+               pdata->regs->datain = OMAP4_GPIO_DATAIN;
+               pdata->regs->dataout = OMAP4_GPIO_DATAOUT;
+               pdata->regs->set_dataout = OMAP4_GPIO_SETDATAOUT;
+               pdata->regs->clr_dataout = OMAP4_GPIO_CLEARDATAOUT;
+               pdata->regs->irqstatus = OMAP4_GPIO_IRQSTATUS0;
+               pdata->regs->irqstatus2 = OMAP4_GPIO_IRQSTATUS1;
+               pdata->regs->irqenable = OMAP4_GPIO_IRQSTATUSSET0;
+               pdata->regs->set_irqenable = OMAP4_GPIO_IRQSTATUSSET0;
+               pdata->regs->clr_irqenable = OMAP4_GPIO_IRQSTATUSCLR0;
+               pdata->regs->debounce = OMAP4_GPIO_DEBOUNCINGTIME;
+               pdata->regs->debounce_en = OMAP4_GPIO_DEBOUNCENABLE;
                break;
        default:
                WARN(1, "Invalid gpio bank_type\n");
index 823c703..ed58ef9 100644 (file)
@@ -4,7 +4,6 @@ obj-y                                   += io.o
 obj-y                                   += irq.o
 obj-y                                   += clock.o
 obj-y                                   += timer.o
-obj-y                                   += gpio.o
 obj-y                                   += pinmux.o
 obj-y                                   += powergate.o
 obj-y                                  += fuse.o
index a138787..d53c35f 100644 (file)
@@ -3,7 +3,7 @@
 #
 
 # Common support
-obj-y := clock.o gpio.o time.o devices.o cpu.o system.o irq-common.o
+obj-y := clock.o time.o devices.o cpu.o system.o irq-common.o
 
 # MX51 uses the TZIC interrupt controller, older platforms use AVIC
 obj-$(CONFIG_MXC_TZIC) += tzic.o
index eee1b60..fb166b2 100644 (file)
@@ -89,3 +89,14 @@ err:
 
        return pdev;
 }
+
+struct device mxc_aips_bus = {
+       .init_name      = "mxc_aips",
+       .parent         = &platform_bus,
+};
+
+static int __init mxc_device_init(void)
+{
+       return device_register(&mxc_aips_bus);
+}
+core_initcall(mxc_device_init);
index ad2922a..b41bf97 100644 (file)
@@ -2,6 +2,7 @@ obj-$(CONFIG_IMX_HAVE_PLATFORM_FEC) += platform-fec.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_FSL_USB2_UDC) += platform-fsl-usb2-udc.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_GPIO_KEYS) += platform-gpio_keys.o
+obj-y += platform-gpio-mxc.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX21_HCD) += platform-imx21-hcd.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT) += platform-imx2-wdt.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_IMXDI_RTC) += platform-imxdi_rtc.o
diff --git a/arch/arm/plat-mxc/devices/platform-gpio-mxc.c b/arch/arm/plat-mxc/devices/platform-gpio-mxc.c
new file mode 100644 (file)
index 0000000..a7919a2
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2011 Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/devices-common.h>
+
+struct platform_device *__init mxc_register_gpio(char *name, int id,
+       resource_size_t iobase, resource_size_t iosize, int irq, int irq_high)
+{
+       struct resource res[] = {
+               {
+                       .start = iobase,
+                       .end = iobase + iosize - 1,
+                       .flags = IORESOURCE_MEM,
+               }, {
+                       .start = irq,
+                       .end = irq,
+                       .flags = IORESOURCE_IRQ,
+               }, {
+                       .start = irq_high,
+                       .end = irq_high,
+                       .flags = IORESOURCE_IRQ,
+               },
+       };
+
+       return platform_device_register_resndata(&mxc_aips_bus,
+                       name, id, res, ARRAY_SIZE(res), NULL, 0);
+}
diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c
deleted file mode 100644 (file)
index 6cd6d7f..0000000
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
- * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
- *
- * Based on code from Freescale,
- * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * 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.
- * This program is distributed in the hope that 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 Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
-#include <mach/hardware.h>
-#include <asm-generic/bug.h>
-
-static struct mxc_gpio_port *mxc_gpio_ports;
-static int gpio_table_size;
-
-#define cpu_is_mx1_mx2()       (cpu_is_mx1() || cpu_is_mx2())
-
-#define GPIO_DR                (cpu_is_mx1_mx2() ? 0x1c : 0x00)
-#define GPIO_GDIR      (cpu_is_mx1_mx2() ? 0x00 : 0x04)
-#define GPIO_PSR       (cpu_is_mx1_mx2() ? 0x24 : 0x08)
-#define GPIO_ICR1      (cpu_is_mx1_mx2() ? 0x28 : 0x0C)
-#define GPIO_ICR2      (cpu_is_mx1_mx2() ? 0x2C : 0x10)
-#define GPIO_IMR       (cpu_is_mx1_mx2() ? 0x30 : 0x14)
-#define GPIO_ISR       (cpu_is_mx1_mx2() ? 0x34 : 0x18)
-
-#define GPIO_INT_LOW_LEV       (cpu_is_mx1_mx2() ? 0x3 : 0x0)
-#define GPIO_INT_HIGH_LEV      (cpu_is_mx1_mx2() ? 0x2 : 0x1)
-#define GPIO_INT_RISE_EDGE     (cpu_is_mx1_mx2() ? 0x0 : 0x2)
-#define GPIO_INT_FALL_EDGE     (cpu_is_mx1_mx2() ? 0x1 : 0x3)
-#define GPIO_INT_NONE          0x4
-
-/* Note: This driver assumes 32 GPIOs are handled in one register */
-
-static void _clear_gpio_irqstatus(struct mxc_gpio_port *port, u32 index)
-{
-       __raw_writel(1 << index, port->base + GPIO_ISR);
-}
-
-static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index,
-                               int enable)
-{
-       u32 l;
-
-       l = __raw_readl(port->base + GPIO_IMR);
-       l = (l & (~(1 << index))) | (!!enable << index);
-       __raw_writel(l, port->base + GPIO_IMR);
-}
-
-static void gpio_ack_irq(struct irq_data *d)
-{
-       u32 gpio = irq_to_gpio(d->irq);
-       _clear_gpio_irqstatus(&mxc_gpio_ports[gpio / 32], gpio & 0x1f);
-}
-
-static void gpio_mask_irq(struct irq_data *d)
-{
-       u32 gpio = irq_to_gpio(d->irq);
-       _set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 0);
-}
-
-static void gpio_unmask_irq(struct irq_data *d)
-{
-       u32 gpio = irq_to_gpio(d->irq);
-       _set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 1);
-}
-
-static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset);
-
-static int gpio_set_irq_type(struct irq_data *d, u32 type)
-{
-       u32 gpio = irq_to_gpio(d->irq);
-       struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32];
-       u32 bit, val;
-       int edge;
-       void __iomem *reg = port->base;
-
-       port->both_edges &= ~(1 << (gpio & 31));
-       switch (type) {
-       case IRQ_TYPE_EDGE_RISING:
-               edge = GPIO_INT_RISE_EDGE;
-               break;
-       case IRQ_TYPE_EDGE_FALLING:
-               edge = GPIO_INT_FALL_EDGE;
-               break;
-       case IRQ_TYPE_EDGE_BOTH:
-               val = mxc_gpio_get(&port->chip, gpio & 31);
-               if (val) {
-                       edge = GPIO_INT_LOW_LEV;
-                       pr_debug("mxc: set GPIO %d to low trigger\n", gpio);
-               } else {
-                       edge = GPIO_INT_HIGH_LEV;
-                       pr_debug("mxc: set GPIO %d to high trigger\n", gpio);
-               }
-               port->both_edges |= 1 << (gpio & 31);
-               break;
-       case IRQ_TYPE_LEVEL_LOW:
-               edge = GPIO_INT_LOW_LEV;
-               break;
-       case IRQ_TYPE_LEVEL_HIGH:
-               edge = GPIO_INT_HIGH_LEV;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
-       bit = gpio & 0xf;
-       val = __raw_readl(reg) & ~(0x3 << (bit << 1));
-       __raw_writel(val | (edge << (bit << 1)), reg);
-       _clear_gpio_irqstatus(port, gpio & 0x1f);
-
-       return 0;
-}
-
-static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio)
-{
-       void __iomem *reg = port->base;
-       u32 bit, val;
-       int edge;
-
-       reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
-       bit = gpio & 0xf;
-       val = __raw_readl(reg);
-       edge = (val >> (bit << 1)) & 3;
-       val &= ~(0x3 << (bit << 1));
-       if (edge == GPIO_INT_HIGH_LEV) {
-               edge = GPIO_INT_LOW_LEV;
-               pr_debug("mxc: switch GPIO %d to low trigger\n", gpio);
-       } else if (edge == GPIO_INT_LOW_LEV) {
-               edge = GPIO_INT_HIGH_LEV;
-               pr_debug("mxc: switch GPIO %d to high trigger\n", gpio);
-       } else {
-               pr_err("mxc: invalid configuration for GPIO %d: %x\n",
-                      gpio, edge);
-               return;
-       }
-       __raw_writel(val | (edge << (bit << 1)), reg);
-}
-
-/* handle 32 interrupts in one status register */
-static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat)
-{
-       u32 gpio_irq_no_base = port->virtual_irq_start;
-
-       while (irq_stat != 0) {
-               int irqoffset = fls(irq_stat) - 1;
-
-               if (port->both_edges & (1 << irqoffset))
-                       mxc_flip_edge(port, irqoffset);
-
-               generic_handle_irq(gpio_irq_no_base + irqoffset);
-
-               irq_stat &= ~(1 << irqoffset);
-       }
-}
-
-/* MX1 and MX3 has one interrupt *per* gpio port */
-static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc)
-{
-       u32 irq_stat;
-       struct mxc_gpio_port *port = irq_get_handler_data(irq);
-
-       irq_stat = __raw_readl(port->base + GPIO_ISR) &
-                       __raw_readl(port->base + GPIO_IMR);
-
-       mxc_gpio_irq_handler(port, irq_stat);
-}
-
-/* MX2 has one interrupt *for all* gpio ports */
-static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc)
-{
-       int i;
-       u32 irq_msk, irq_stat;
-       struct mxc_gpio_port *port = irq_get_handler_data(irq);
-
-       /* walk through all interrupt status registers */
-       for (i = 0; i < gpio_table_size; i++) {
-               irq_msk = __raw_readl(port[i].base + GPIO_IMR);
-               if (!irq_msk)
-                       continue;
-
-               irq_stat = __raw_readl(port[i].base + GPIO_ISR) & irq_msk;
-               if (irq_stat)
-                       mxc_gpio_irq_handler(&port[i], irq_stat);
-       }
-}
-
-/*
- * Set interrupt number "irq" in the GPIO as a wake-up source.
- * While system is running, all registered GPIO interrupts need to have
- * wake-up enabled. When system is suspended, only selected GPIO interrupts
- * need to have wake-up enabled.
- * @param  irq          interrupt source number
- * @param  enable       enable as wake-up if equal to non-zero
- * @return       This function returns 0 on success.
- */
-static int gpio_set_wake_irq(struct irq_data *d, u32 enable)
-{
-       u32 gpio = irq_to_gpio(d->irq);
-       u32 gpio_idx = gpio & 0x1F;
-       struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32];
-
-       if (enable) {
-               if (port->irq_high && (gpio_idx >= 16))
-                       enable_irq_wake(port->irq_high);
-               else
-                       enable_irq_wake(port->irq);
-       } else {
-               if (port->irq_high && (gpio_idx >= 16))
-                       disable_irq_wake(port->irq_high);
-               else
-                       disable_irq_wake(port->irq);
-       }
-
-       return 0;
-}
-
-static struct irq_chip gpio_irq_chip = {
-       .name = "GPIO",
-       .irq_ack = gpio_ack_irq,
-       .irq_mask = gpio_mask_irq,
-       .irq_unmask = gpio_unmask_irq,
-       .irq_set_type = gpio_set_irq_type,
-       .irq_set_wake = gpio_set_wake_irq,
-};
-
-static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
-                               int dir)
-{
-       struct mxc_gpio_port *port =
-               container_of(chip, struct mxc_gpio_port, chip);
-       u32 l;
-       unsigned long flags;
-
-       spin_lock_irqsave(&port->lock, flags);
-       l = __raw_readl(port->base + GPIO_GDIR);
-       if (dir)
-               l |= 1 << offset;
-       else
-               l &= ~(1 << offset);
-       __raw_writel(l, port->base + GPIO_GDIR);
-       spin_unlock_irqrestore(&port->lock, flags);
-}
-
-static void mxc_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
-{
-       struct mxc_gpio_port *port =
-               container_of(chip, struct mxc_gpio_port, chip);
-       void __iomem *reg = port->base + GPIO_DR;
-       u32 l;
-       unsigned long flags;
-
-       spin_lock_irqsave(&port->lock, flags);
-       l = (__raw_readl(reg) & (~(1 << offset))) | (!!value << offset);
-       __raw_writel(l, reg);
-       spin_unlock_irqrestore(&port->lock, flags);
-}
-
-static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
-       struct mxc_gpio_port *port =
-               container_of(chip, struct mxc_gpio_port, chip);
-
-       return (__raw_readl(port->base + GPIO_PSR) >> offset) & 1;
-}
-
-static int mxc_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
-{
-       _set_gpio_direction(chip, offset, 0);
-       return 0;
-}
-
-static int mxc_gpio_direction_output(struct gpio_chip *chip,
-                                    unsigned offset, int value)
-{
-       mxc_gpio_set(chip, offset, value);
-       _set_gpio_direction(chip, offset, 1);
-       return 0;
-}
-
-/*
- * This lock class tells lockdep that GPIO irqs are in a different
- * category than their parents, so it won't report false recursion.
- */
-static struct lock_class_key gpio_lock_class;
-
-int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
-{
-       int i, j;
-
-       /* save for local usage */
-       mxc_gpio_ports = port;
-       gpio_table_size = cnt;
-
-       printk(KERN_INFO "MXC GPIO hardware\n");
-
-       for (i = 0; i < cnt; i++) {
-               /* disable the interrupt and clear the status */
-               __raw_writel(0, port[i].base + GPIO_IMR);
-               __raw_writel(~0, port[i].base + GPIO_ISR);
-               for (j = port[i].virtual_irq_start;
-                       j < port[i].virtual_irq_start + 32; j++) {
-                       irq_set_lockdep_class(j, &gpio_lock_class);
-                       irq_set_chip_and_handler(j, &gpio_irq_chip,
-                                                handle_level_irq);
-                       set_irq_flags(j, IRQF_VALID);
-               }
-
-               /* register gpio chip */
-               port[i].chip.direction_input = mxc_gpio_direction_input;
-               port[i].chip.direction_output = mxc_gpio_direction_output;
-               port[i].chip.get = mxc_gpio_get;
-               port[i].chip.set = mxc_gpio_set;
-               port[i].chip.base = i * 32;
-               port[i].chip.ngpio = 32;
-
-               spin_lock_init(&port[i].lock);
-
-               /* its a serious configuration bug when it fails */
-               BUG_ON( gpiochip_add(&port[i].chip) < 0 );
-
-               if (cpu_is_mx1() || cpu_is_mx3() || cpu_is_mx25() || cpu_is_mx51()) {
-                       /* setup one handler for each entry */
-                       irq_set_chained_handler(port[i].irq,
-                                               mx3_gpio_irq_handler);
-                       irq_set_handler_data(port[i].irq, &port[i]);
-                       if (port[i].irq_high) {
-                               /* setup handler for GPIO 16 to 31 */
-                               irq_set_chained_handler(port[i].irq_high,
-                                                       mx3_gpio_irq_handler);
-                               irq_set_handler_data(port[i].irq_high,
-                                                    &port[i]);
-                       }
-               }
-       }
-
-       if (cpu_is_mx2()) {
-               /* setup one handler for all GPIO interrupts */
-               irq_set_chained_handler(port[0].irq, mx2_gpio_irq_handler);
-               irq_set_handler_data(port[0].irq, port);
-       }
-
-       return 0;
-}
index da79918..4e3d978 100644 (file)
@@ -43,6 +43,15 @@ extern void mx35_init_irq(void);
 extern void mx50_init_irq(void);
 extern void mx51_init_irq(void);
 extern void mx53_init_irq(void);
+extern void imx1_soc_init(void);
+extern void imx21_soc_init(void);
+extern void imx25_soc_init(void);
+extern void imx27_soc_init(void);
+extern void imx31_soc_init(void);
+extern void imx35_soc_init(void);
+extern void imx50_soc_init(void);
+extern void imx51_soc_init(void);
+extern void imx53_soc_init(void);
 extern void epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq);
 extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int);
 extern int mx1_clocks_init(unsigned long fref);
@@ -55,7 +64,8 @@ extern int mx51_clocks_init(unsigned long ckil, unsigned long osc,
                        unsigned long ckih1, unsigned long ckih2);
 extern int mx53_clocks_init(unsigned long ckil, unsigned long osc,
                        unsigned long ckih1, unsigned long ckih2);
-extern int mxc_register_gpios(void);
+extern struct platform_device *mxc_register_gpio(char *name, int id,
+       resource_size_t iobase, resource_size_t iosize, int irq, int irq_high);
 extern int mxc_register_device(struct platform_device *pdev, void *data);
 extern void mxc_set_cpu_type(unsigned int type);
 extern void mxc_arch_reset_init(void __iomem *);
index fa84773..03f6266 100644 (file)
@@ -10,6 +10,8 @@
 #include <linux/platform_device.h>
 #include <linux/init.h>
 
+extern struct device mxc_aips_bus;
+
 struct platform_device *imx_add_platform_device_dmamask(
                const char *name, int id,
                const struct resource *res, unsigned int num_resources,
index a2747f1..31c820c 100644 (file)
 #define gpio_to_irq(gpio)      (MXC_GPIO_IRQ_START + (gpio))
 #define irq_to_gpio(irq)       ((irq) - MXC_GPIO_IRQ_START)
 
-struct mxc_gpio_port {
-       void __iomem *base;
-       int irq;
-       int irq_high;
-       int virtual_irq_start;
-       struct gpio_chip chip;
-       u32 both_edges;
-       spinlock_t lock;
-};
-
-#define DEFINE_IMX_GPIO_PORT_IRQ_HIGH(soc, _id, _hwid, _irq, _irq_high)        \
-       {                                                               \
-               .chip.label = "gpio-" #_id,                             \
-               .irq = _irq,                                            \
-               .irq_high = _irq_high,                                  \
-               .base = soc ## _IO_ADDRESS(                             \
-                               soc ## _GPIO ## _hwid ## _BASE_ADDR),   \
-               .virtual_irq_start = MXC_GPIO_IRQ_START + (_id) * 32,   \
-       }
-
-#define DEFINE_IMX_GPIO_PORT_IRQ(soc, _id, _hwid, _irq)                        \
-       DEFINE_IMX_GPIO_PORT_IRQ_HIGH(soc, _id, _hwid, _irq, 0)
-#define DEFINE_IMX_GPIO_PORT(soc, _id, _hwid)                          \
-       DEFINE_IMX_GPIO_PORT_IRQ(soc, _id, _hwid, 0)
-
-int mxc_gpio_init(struct mxc_gpio_port*, int);
-
 #endif
index 35c89bc..00e812b 100644 (file)
@@ -11,6 +11,8 @@
 #ifndef __ASM_ARCH_MXC_IRQS_H__
 #define __ASM_ARCH_MXC_IRQS_H__
 
+#include <asm-generic/gpio.h>
+
 /*
  * SoCs with TZIC interrupt controller have 128 IRQs, those with AVIC have 64
  */
 
 #define MXC_GPIO_IRQ_START     MXC_INTERNAL_IRQS
 
-/* these are ordered by size to support multi-SoC kernels */
-#if defined CONFIG_SOC_IMX53
-#define MXC_GPIO_IRQS          (32 * 7)
-#elif defined CONFIG_ARCH_MX2
-#define MXC_GPIO_IRQS          (32 * 6)
-#elif defined CONFIG_SOC_IMX50
-#define MXC_GPIO_IRQS          (32 * 6)
-#elif defined CONFIG_ARCH_MX1
-#define MXC_GPIO_IRQS          (32 * 4)
-#elif defined CONFIG_ARCH_MX25
-#define MXC_GPIO_IRQS          (32 * 4)
-#elif defined CONFIG_SOC_IMX51
-#define MXC_GPIO_IRQS          (32 * 4)
-#elif defined CONFIG_ARCH_MX3
-#define MXC_GPIO_IRQS          (32 * 3)
-#endif
-
 /*
  * The next 16 interrupts are for board specific purposes.  Since
  * the kernel can only run on one machine at a time, we can re-use
  * these.  If you need more, increase MXC_BOARD_IRQS, but keep it
  * within sensible limits.
  */
-#define MXC_BOARD_IRQ_START    (MXC_INTERNAL_IRQS + MXC_GPIO_IRQS)
+#define MXC_BOARD_IRQ_START    (MXC_INTERNAL_IRQS + ARCH_NR_GPIOS)
 
 #ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
 #define MXC_BOARD_IRQS  80
index ec97e00..91e8de3 100644 (file)
@@ -174,12 +174,32 @@ struct omap_gpio_dev_attr {
        bool dbck_flag;         /* dbck required or not - True for OMAP3&4 */
 };
 
+struct omap_gpio_reg_offs {
+       u16 revision;
+       u16 direction;
+       u16 datain;
+       u16 dataout;
+       u16 set_dataout;
+       u16 clr_dataout;
+       u16 irqstatus;
+       u16 irqstatus2;
+       u16 irqenable;
+       u16 set_irqenable;
+       u16 clr_irqenable;
+       u16 debounce;
+       u16 debounce_en;
+
+       bool irqenable_inv;
+};
+
 struct omap_gpio_platform_data {
        u16 virtual_irq_start;
        int bank_type;
        int bank_width;         /* GPIO bank width */
        int bank_stride;        /* Only needed for omap1 MPUIO */
        bool dbck_flag;         /* dbck required or not - True for OMAP3&4 */
+
+       struct omap_gpio_reg_offs *regs;
 };
 
 /* TODO: Analyze removing gpio_bank_count usage from driver code */
index 47ea1be..90f4496 100644 (file)
@@ -55,14 +55,6 @@ config PPC_MPC5200_BUGFIX
 
          It is safe to say 'Y' here
 
-config PPC_MPC5200_GPIO
-       bool "MPC5200 GPIO support"
-       depends on PPC_MPC52xx
-       select ARCH_REQUIRE_GPIOLIB
-       select GENERIC_GPIO
-       help
-         Enable gpiolib support for mpc5200 based boards
-
 config PPC_MPC5200_LPBFIFO
        tristate "MPC5200 LocalPlus bus FIFO driver"
        depends on PPC_MPC52xx
index 2bc8cd0..4e62486 100644 (file)
@@ -14,5 +14,4 @@ ifeq ($(CONFIG_PPC_LITE5200),y)
        obj-$(CONFIG_PM)        += lite5200_sleep.o lite5200_pm.o
 endif
 
-obj-$(CONFIG_PPC_MPC5200_GPIO) += mpc52xx_gpio.o
 obj-$(CONFIG_PPC_MPC5200_LPBFIFO)      += mpc52xx_lpbfifo.o
index 2967002..3634986 100644 (file)
@@ -63,33 +63,58 @@ config GPIO_SYSFS
          Kernel drivers may also request that a particular GPIO be
          exported to userspace; this can be useful when debugging.
 
+config GPIO_GENERIC
+       tristate
+
 # put drivers in the right section, in alphabetical order
 
+config GPIO_DA9052
+       tristate "Dialog DA9052 GPIO"
+       depends on PMIC_DA9052
+       help
+         Say yes here to enable the GPIO driver for the DA9052 chip.
+
 config GPIO_MAX730X
        tristate
 
 comment "Memory mapped GPIO drivers:"
 
-config GPIO_BASIC_MMIO_CORE
-       tristate
-       help
-         Provides core functionality for basic memory-mapped GPIO controllers.
-
-config GPIO_BASIC_MMIO
-       tristate "Basic memory-mapped GPIO controllers support"
-       select GPIO_BASIC_MMIO_CORE
+config GPIO_GENERIC_PLATFORM
+       tristate "Generic memory-mapped GPIO controller support (MMIO platform device)"
+       select GPIO_GENERIC
        help
-         Say yes here to support basic memory-mapped GPIO controllers.
+         Say yes here to support basic platform_device memory-mapped GPIO controllers.
 
 config GPIO_IT8761E
        tristate "IT8761E GPIO support"
        help
          Say yes here to support GPIO functionality of IT8761E super I/O chip.
 
+config GPIO_EP93XX
+       def_bool y
+       depends on ARCH_EP93XX
+       select GPIO_GENERIC
+
 config GPIO_EXYNOS4
        def_bool y
        depends on CPU_EXYNOS4210
 
+config GPIO_MPC5200
+       def_bool y
+       depends on PPC_MPC52xx
+
+config GPIO_MXC
+       def_bool y
+       depends on ARCH_MXC
+       select GPIO_GENERIC
+       select GENERIC_IRQ_CHIP
+
+config GPIO_MXS
+       def_bool y
+       depends on ARCH_MXS
+       select GPIO_GENERIC
+       select GENERIC_IRQ_CHIP
+
 config GPIO_PLAT_SAMSUNG
        def_bool y
        depends on SAMSUNG_GPIOLIB_4BIT
@@ -137,9 +162,6 @@ config GPIO_SCH
          The Intel Tunnel Creek processor has 5 GPIOs powered by the
          core power rail and 9 from suspend power supply.
 
-         This driver can also be built as a module. If so, the module
-         will be called sch-gpio.
-
 config GPIO_VX855
        tristate "VIA VX855/VX875 GPIO"
        depends on MFD_SUPPORT && PCI
@@ -202,9 +224,6 @@ config GPIO_PCA953X
 
          16 bits:      pca9535, pca9539, pca9555, tca6416
 
-         This driver can also be built as a module.  If so, the module
-         will be called pca953x.
-
 config GPIO_PCA953X_IRQ
        bool "Interrupt controller support for PCA953x"
        depends on GPIO_PCA953X=y
@@ -296,17 +315,12 @@ config GPIO_ADP5520
          This option enables support for on-chip GPIO found
          on Analog Devices ADP5520 PMICs.
 
-         To compile this driver as a module, choose M here: the module will
-         be called adp5520-gpio.
-
 config GPIO_ADP5588
        tristate "ADP5588 I2C GPIO expander"
        depends on I2C
        help
          This option enables support for 18 GPIOs found
          on Analog Devices ADP5588 GPIO Expanders.
-         To compile this driver as a module, choose M here: the module will be
-         called adp5588-gpio.
 
 config GPIO_ADP5588_IRQ
        bool "Interrupt controller support for ADP5588"
@@ -398,10 +412,11 @@ config GPIO_MAX7301
          GPIO driver for Maxim MAX7301 SPI-based GPIO expander.
 
 config GPIO_MCP23S08
-       tristate "Microchip MCP23Sxx I/O expander"
-       depends on SPI_MASTER
+       tristate "Microchip MCP23xxx I/O expander"
+       depends on SPI_MASTER || I2C
        help
-         SPI driver for Microchip MCP23S08/MPC23S17 I/O expanders.
+         SPI/I2C driver for Microchip MCP23S08/MCP23S17/MCP23008/MCP23017
+         I/O expanders.
          This provides a GPIO interface supporting inputs and outputs.
 
 config GPIO_MC33880
@@ -428,9 +443,6 @@ config GPIO_UCB1400
          This enables support for the Philips UCB1400 GPIO pins.
          The UCB1400 is an AC97 audio codec.
 
-         To compile this driver as a module, choose M here: the
-         module will be called ucb1400_gpio.
-
 comment "MODULbus GPIO expanders:"
 
 config GPIO_JANZ_TTL
@@ -441,7 +453,7 @@ config GPIO_JANZ_TTL
          This driver provides support for driving the pins in output
          mode only. Input mode is not supported.
 
-config AB8500_GPIO
+config GPIO_AB8500
        bool "ST-Ericsson AB8500 Mixed Signal Circuit gpio functions"
        depends on AB8500_CORE && BROKEN
        help
index b605f8e..7207112 100644 (file)
@@ -4,47 +4,56 @@ ccflags-$(CONFIG_DEBUG_GPIO)  += -DDEBUG
 
 obj-$(CONFIG_GPIOLIB)          += gpiolib.o
 
-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
+# Device drivers. Generally keep list sorted alphabetically
+obj-$(CONFIG_GPIO_GENERIC)     += gpio-generic.o
+
+obj-$(CONFIG_GPIO_74X164)      += gpio-74x164.o
+obj-$(CONFIG_GPIO_AB8500)      += gpio-ab8500.o
+obj-$(CONFIG_GPIO_ADP5520)     += gpio-adp5520.o
+obj-$(CONFIG_GPIO_ADP5588)     += gpio-adp5588.o
+obj-$(CONFIG_GPIO_BT8XX)       += gpio-bt8xx.o
+obj-$(CONFIG_GPIO_CS5535)      += gpio-cs5535.o
+obj-$(CONFIG_GPIO_DA9052)      += gpio-da9052.o
+obj-$(CONFIG_GPIO_EP93XX)      += gpio-ep93xx.o
 obj-$(CONFIG_GPIO_EXYNOS4)     += gpio-exynos4.o
+obj-$(CONFIG_GPIO_IT8761E)     += gpio-it8761e.o
+obj-$(CONFIG_GPIO_JANZ_TTL)    += gpio-janz-ttl.o
+obj-$(CONFIG_GPIO_LANGWELL)    += gpio-langwell.o
+obj-$(CONFIG_GPIO_MAX730X)     += gpio-max730x.o
+obj-$(CONFIG_GPIO_MAX7300)     += gpio-max7300.o
+obj-$(CONFIG_GPIO_MAX7301)     += gpio-max7301.o
+obj-$(CONFIG_GPIO_MAX732X)     += gpio-max732x.o
+obj-$(CONFIG_GPIO_MC33880)     += gpio-mc33880.o
+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_MXC)         += gpio-mxc.o
+obj-$(CONFIG_GPIO_MXS)         += gpio-mxs.o
+obj-$(CONFIG_PLAT_NOMADIK)     += gpio-nomadik.o
+obj-$(CONFIG_ARCH_OMAP)                += gpio-omap.o
+obj-$(CONFIG_GPIO_PCA953X)     += gpio-pca953x.o
+obj-$(CONFIG_GPIO_PCF857X)     += gpio-pcf857x.o
+obj-$(CONFIG_GPIO_PCH)         += gpio-pch.o
+obj-$(CONFIG_GPIO_PL061)       += gpio-pl061.o
+obj-$(CONFIG_GPIO_RDC321X)     += gpio-rdc321x.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
-obj-$(CONFIG_GPIO_MAX7301)     += max7301.o
-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
-obj-$(CONFIG_GPIO_PL061)       += pl061.o
-obj-$(CONFIG_GPIO_STMPE)       += stmpe-gpio.o
-obj-$(CONFIG_GPIO_TC3589X)     += tc3589x-gpio.o
-obj-$(CONFIG_GPIO_TIMBERDALE)  += timbgpio.o
-obj-$(CONFIG_GPIO_TWL4030)     += twl4030-gpio.o
-obj-$(CONFIG_GPIO_UCB1400)     += ucb1400_gpio.o
-obj-$(CONFIG_GPIO_XILINX)      += xilinx_gpio.o
-obj-$(CONFIG_GPIO_CS5535)      += cs5535-gpio.o
-obj-$(CONFIG_GPIO_BT8XX)       += bt8xxgpio.o
-obj-$(CONFIG_GPIO_IT8761E)     += it8761e_gpio.o
-obj-$(CONFIG_GPIO_VR41XX)      += vr41xx_giu.o
-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_GPIO_SCH)         += gpio-sch.o
+obj-$(CONFIG_GPIO_STMPE)       += gpio-stmpe.o
+obj-$(CONFIG_GPIO_SX150X)      += gpio-sx150x.o
+obj-$(CONFIG_GPIO_TC3589X)     += gpio-tc3589x.o
+obj-$(CONFIG_ARCH_TEGRA)       += gpio-tegra.o
+obj-$(CONFIG_GPIO_TIMBERDALE)  += gpio-timberdale.o
+obj-$(CONFIG_GPIO_TPS65910)    += gpio-tps65910.o
+obj-$(CONFIG_GPIO_TWL4030)     += gpio-twl4030.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
-obj-$(CONFIG_GPIO_VX855)       += vx855_gpio.o
-obj-$(CONFIG_GPIO_ML_IOH)      += ml_ioh_gpio.o
-obj-$(CONFIG_AB8500_GPIO)       += ab8500-gpio.o
-obj-$(CONFIG_GPIO_TPS65910)    += tps65910-gpio.o
+obj-$(CONFIG_GPIO_UCB1400)     += gpio-ucb1400.o
+obj-$(CONFIG_GPIO_VR41XX)      += gpio-vr41xx.o
+obj-$(CONFIG_GPIO_VX855)       += gpio-vx855.o
+obj-$(CONFIG_GPIO_WM831X)      += gpio-wm831x.o
+obj-$(CONFIG_GPIO_WM8350)      += gpio-wm8350.o
+obj-$(CONFIG_GPIO_WM8994)      += gpio-wm8994.o
+obj-$(CONFIG_GPIO_XILINX)      += gpio-xilinx.o
similarity index 88%
rename from drivers/gpio/74x164.c
rename to drivers/gpio/gpio-74x164.c
index 84e0702..ff525c0 100644 (file)
@@ -16,9 +16,6 @@
 #include <linux/gpio.h>
 #include <linux/slab.h>
 
-#define GEN_74X164_GPIO_COUNT  8
-
-
 struct gen_74x164_chip {
        struct spi_device       *spi;
        struct gpio_chip        gpio_chip;
@@ -26,9 +23,7 @@ struct gen_74x164_chip {
        u8                      port_config;
 };
 
-static void gen_74x164_set_value(struct gpio_chip *, unsigned, int);
-
-static struct gen_74x164_chip *gpio_to_chip(struct gpio_chip *gc)
+static struct gen_74x164_chip *gpio_to_74x164_chip(struct gpio_chip *gc)
 {
        return container_of(gc, struct gen_74x164_chip, gpio_chip);
 }
@@ -39,16 +34,9 @@ static int __gen_74x164_write_config(struct gen_74x164_chip *chip)
                         &chip->port_config, sizeof(chip->port_config));
 }
 
-static int gen_74x164_direction_output(struct gpio_chip *gc,
-               unsigned offset, int val)
-{
-       gen_74x164_set_value(gc, offset, val);
-       return 0;
-}
-
 static int gen_74x164_get_value(struct gpio_chip *gc, unsigned offset)
 {
-       struct gen_74x164_chip *chip = gpio_to_chip(gc);
+       struct gen_74x164_chip *chip = gpio_to_74x164_chip(gc);
        int ret;
 
        mutex_lock(&chip->lock);
@@ -61,7 +49,7 @@ static int gen_74x164_get_value(struct gpio_chip *gc, unsigned offset)
 static void gen_74x164_set_value(struct gpio_chip *gc,
                unsigned offset, int val)
 {
-       struct gen_74x164_chip *chip = gpio_to_chip(gc);
+       struct gen_74x164_chip *chip = gpio_to_74x164_chip(gc);
 
        mutex_lock(&chip->lock);
        if (val)
@@ -73,6 +61,13 @@ static void gen_74x164_set_value(struct gpio_chip *gc,
        mutex_unlock(&chip->lock);
 }
 
+static int gen_74x164_direction_output(struct gpio_chip *gc,
+               unsigned offset, int val)
+{
+       gen_74x164_set_value(gc, offset, val);
+       return 0;
+}
+
 static int __devinit gen_74x164_probe(struct spi_device *spi)
 {
        struct gen_74x164_chip *chip;
@@ -104,12 +99,12 @@ static int __devinit gen_74x164_probe(struct spi_device *spi)
 
        chip->spi = spi;
 
-       chip->gpio_chip.label = GEN_74X164_DRIVER_NAME,
-               chip->gpio_chip.direction_output = gen_74x164_direction_output;
+       chip->gpio_chip.label = spi->modalias;
+       chip->gpio_chip.direction_output = gen_74x164_direction_output;
        chip->gpio_chip.get = gen_74x164_get_value;
        chip->gpio_chip.set = gen_74x164_set_value;
        chip->gpio_chip.base = pdata->base;
-       chip->gpio_chip.ngpio = GEN_74X164_GPIO_COUNT;
+       chip->gpio_chip.ngpio = 8;
        chip->gpio_chip.can_sleep = 1;
        chip->gpio_chip.dev = &spi->dev;
        chip->gpio_chip.owner = THIS_MODULE;
@@ -157,7 +152,7 @@ static int __devexit gen_74x164_remove(struct spi_device *spi)
 
 static struct spi_driver gen_74x164_driver = {
        .driver = {
-               .name           = GEN_74X164_DRIVER_NAME,
+               .name           = "74x164",
                .owner          = THIS_MODULE,
        },
        .probe          = gen_74x164_probe,
diff --git a/drivers/gpio/gpio-da9052.c b/drivers/gpio/gpio-da9052.c
new file mode 100644 (file)
index 0000000..038f5eb
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ * GPIO Driver for Dialog DA9052 PMICs.
+ *
+ * Copyright(c) 2011 Dialog Semiconductor Ltd.
+ *
+ * Author: David Dajun Chen <dchen@diasemi.com>
+ *
+ *  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.
+ *
+ */
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/syscalls.h>
+#include <linux/seq_file.h>
+
+#include <linux/mfd/da9052/da9052.h>
+#include <linux/mfd/da9052/reg.h>
+#include <linux/mfd/da9052/pdata.h>
+#include <linux/mfd/da9052/gpio.h>
+
+#define DA9052_INPUT                           1
+#define DA9052_OUTPUT_OPENDRAIN                2
+#define DA9052_OUTPUT_PUSHPULL                 3
+
+#define DA9052_SUPPLY_VDD_IO1                  0
+
+#define DA9052_DEBOUNCING_OFF                  0
+#define DA9052_DEBOUNCING_ON                   1
+
+#define DA9052_OUTPUT_LOWLEVEL                 0
+
+#define DA9052_ACTIVE_LOW                      0
+#define DA9052_ACTIVE_HIGH                     1
+
+#define DA9052_GPIO_MAX_PORTS_PER_REGISTER     8
+#define DA9052_GPIO_SHIFT_COUNT(no)            (no%8)
+#define DA9052_GPIO_MASK_UPPER_NIBBLE          0xF0
+#define DA9052_GPIO_MASK_LOWER_NIBBLE          0x0F
+#define DA9052_GPIO_NIBBLE_SHIFT               4
+
+struct da9052_gpio {
+       struct da9052 *da9052;
+       struct gpio_chip gp;
+};
+
+static inline struct da9052_gpio *to_da9052_gpio(struct gpio_chip *chip)
+{
+       return container_of(chip, struct da9052_gpio, gp);
+}
+
+static unsigned char da9052_gpio_port_odd(unsigned offset)
+{
+       return offset % 2;
+}
+
+static int da9052_gpio_get(struct gpio_chip *gc, unsigned offset)
+{
+       struct da9052_gpio *gpio = to_da9052_gpio(gc);
+       int da9052_port_direction = 0;
+       int ret;
+
+       ret = da9052_reg_read(gpio->da9052,
+                             DA9052_GPIO_0_1_REG + (offset >> 1));
+       if (ret < 0)
+               return ret;
+
+       if (da9052_gpio_port_odd(offset)) {
+               da9052_port_direction = ret & DA9052_GPIO_ODD_PORT_PIN;
+               da9052_port_direction >>= 4;
+       } else {
+               da9052_port_direction = ret & DA9052_GPIO_EVEN_PORT_PIN;
+       }
+
+       switch (da9052_port_direction) {
+       case DA9052_INPUT:
+               if (offset < DA9052_GPIO_MAX_PORTS_PER_REGISTER)
+                       ret = da9052_reg_read(gpio->da9052,
+                                             DA9052_STATUS_C_REG);
+               else
+                       ret = da9052_reg_read(gpio->da9052,
+                                             DA9052_STATUS_D_REG);
+               if (ret < 0)
+                       return ret;
+               if (ret & (1 << DA9052_GPIO_SHIFT_COUNT(offset)))
+                       return 1;
+               else
+                       return 0;
+       case DA9052_OUTPUT_PUSHPULL:
+               if (da9052_gpio_port_odd(offset))
+                       return ret & DA9052_GPIO_ODD_PORT_MODE;
+               else
+                       return ret & DA9052_GPIO_EVEN_PORT_MODE;
+       default:
+               return -EINVAL;
+       }
+}
+
+static void da9052_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
+{
+       struct da9052_gpio *gpio = to_da9052_gpio(gc);
+       unsigned char register_value = 0;
+       int ret;
+
+       if (da9052_gpio_port_odd(offset)) {
+               if (value) {
+                       register_value = DA9052_GPIO_ODD_PORT_MODE;
+                       ret = da9052_reg_update(gpio->da9052, (offset >> 1) +
+                                               DA9052_GPIO_0_1_REG,
+                                               DA9052_GPIO_ODD_PORT_MODE,
+                                               register_value);
+                       if (ret != 0)
+                               dev_err(gpio->da9052->dev,
+                                       "Failed to updated gpio odd reg,%d",
+                                       ret);
+               }
+       } else {
+               if (value) {
+                       register_value = DA9052_GPIO_EVEN_PORT_MODE;
+                       ret = da9052_reg_update(gpio->da9052, (offset >> 1) +
+                                               DA9052_GPIO_0_1_REG,
+                                               DA9052_GPIO_EVEN_PORT_MODE,
+                                               register_value);
+                       if (ret != 0)
+                               dev_err(gpio->da9052->dev,
+                                       "Failed to updated gpio even reg,%d",
+                                       ret);
+               }
+       }
+}
+
+static int da9052_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
+{
+       struct da9052_gpio *gpio = to_da9052_gpio(gc);
+       unsigned char register_value;
+       int ret;
+
+       /* Format: function - 2 bits type - 1 bit mode - 1 bit */
+       register_value = DA9052_INPUT | DA9052_ACTIVE_LOW << 2 |
+                        DA9052_DEBOUNCING_ON << 3;
+
+       if (da9052_gpio_port_odd(offset))
+               ret = da9052_reg_update(gpio->da9052, (offset >> 1) +
+                                       DA9052_GPIO_0_1_REG,
+                                       DA9052_GPIO_MASK_UPPER_NIBBLE,
+                                       (register_value <<
+                                       DA9052_GPIO_NIBBLE_SHIFT));
+       else
+               ret = da9052_reg_update(gpio->da9052, (offset >> 1) +
+                                       DA9052_GPIO_0_1_REG,
+                                       DA9052_GPIO_MASK_LOWER_NIBBLE,
+                                       register_value);
+
+       return ret;
+}
+
+static int da9052_gpio_direction_output(struct gpio_chip *gc,
+                                       unsigned offset, int value)
+{
+       struct da9052_gpio *gpio = to_da9052_gpio(gc);
+       unsigned char register_value;
+       int ret;
+
+       /* Format: Function - 2 bits Type - 1 bit Mode - 1 bit */
+       register_value = DA9052_OUTPUT_PUSHPULL | DA9052_SUPPLY_VDD_IO1 << 2 |
+                        value << 3;
+
+       if (da9052_gpio_port_odd(offset))
+               ret = da9052_reg_update(gpio->da9052, (offset >> 1) +
+                                       DA9052_GPIO_0_1_REG,
+                                       DA9052_GPIO_MASK_UPPER_NIBBLE,
+                                       (register_value <<
+                                       DA9052_GPIO_NIBBLE_SHIFT));
+       else
+               ret = da9052_reg_update(gpio->da9052, (offset >> 1) +
+                                       DA9052_GPIO_0_1_REG,
+                                       DA9052_GPIO_MASK_LOWER_NIBBLE,
+                                       register_value);
+
+       return ret;
+}
+
+static int da9052_gpio_to_irq(struct gpio_chip *gc, u32 offset)
+{
+       struct da9052_gpio *gpio = to_da9052_gpio(gc);
+       struct da9052 *da9052 = gpio->da9052;
+
+       return da9052->irq_base + DA9052_IRQ_GPI0 + offset;
+}
+
+static struct gpio_chip reference_gp __devinitdata = {
+       .label = "da9052-gpio",
+       .owner = THIS_MODULE,
+       .get = da9052_gpio_get,
+       .set = da9052_gpio_set,
+       .direction_input = da9052_gpio_direction_input,
+       .direction_output = da9052_gpio_direction_output,
+       .to_irq = da9052_gpio_to_irq,
+       .can_sleep = 1;
+       .ngpio = 16;
+       .base = -1;
+};
+
+static int __devinit da9052_gpio_probe(struct platform_device *pdev)
+{
+       struct da9052_gpio *gpio;
+       struct da9052_pdata *pdata;
+       int ret;
+
+       gpio = kzalloc(sizeof(*gpio), GFP_KERNEL);
+       if (gpio == NULL)
+               return -ENOMEM;
+
+       gpio->da9052 = dev_get_drvdata(pdev->dev.parent);
+       pdata = gpio->da9052->dev->platform_data;
+
+       gpio->gp = reference_gp;
+       if (pdata && pdata->gpio_base)
+               gpio->gp.base = pdata->gpio_base;
+
+       ret = gpiochip_add(&gpio->gp);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
+               goto err_mem;
+       }
+
+       platform_set_drvdata(pdev, gpio);
+
+       return 0;
+
+err_mem:
+       kfree(gpio);
+       return ret;
+}
+
+static int __devexit da9052_gpio_remove(struct platform_device *pdev)
+{
+       struct da9052_gpio *gpio = platform_get_drvdata(pdev);
+       int ret;
+
+       ret = gpiochip_remove(&gpio->gp);
+       if (ret == 0)
+               kfree(gpio);
+
+       return ret;
+}
+
+static struct platform_driver da9052_gpio_driver = {
+       .probe = da9052_gpio_probe,
+       .remove = __devexit_p(da9052_gpio_remove),
+       .driver = {
+               .name   = "da9052-gpio",
+               .owner  = THIS_MODULE,
+       },
+};
+
+static int __init da9052_gpio_init(void)
+{
+       return platform_driver_register(&da9052_gpio_driver);
+}
+module_init(da9052_gpio_init);
+
+static void __exit da9052_gpio_exit(void)
+{
+       return platform_driver_unregister(&da9052_gpio_driver);
+}
+module_exit(da9052_gpio_exit);
+
+MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
+MODULE_DESCRIPTION("DA9052 GPIO Device Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:da9052-gpio");
similarity index 69%
rename from arch/arm/mach-ep93xx/gpio.c
rename to drivers/gpio/gpio-ep93xx.c
index 415dce3..3bfd341 100644 (file)
@@ -1,9 +1,8 @@
 /*
- * linux/arch/arm/mach-ep93xx/gpio.c
- *
  * Generic EP93xx GPIO handling
  *
  * Copyright (c) 2008 Ryan Mallon <ryan@bluewatersys.com>
+ * Copyright (c) 2011 H Hartley Sweeten <hsweeten@visionengravers.com>
  *
  * Based on code originally from:
  *  linux/arch/arm/mach-ep93xx/core.c
  *  published by the Free Software Foundation.
  */
 
-#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/init.h>
-#include <linux/module.h>
-#include <linux/seq_file.h>
+#include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
 #include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/basic_mmio_gpio.h>
 
 #include <mach/hardware.h>
 
+struct ep93xx_gpio {
+       void __iomem            *mmio_base;
+       struct bgpio_chip       bgc[8];
+};
+
 /*************************************************************************
  * Interrupt handling for EP93xx on-chip GPIOs
  *************************************************************************/
@@ -225,7 +230,7 @@ static struct irq_chip ep93xx_gpio_irq_chip = {
        .irq_set_type   = ep93xx_gpio_irq_type,
 };
 
-void __init ep93xx_gpio_init_irq(void)
+static void ep93xx_gpio_init_irq(void)
 {
        int gpio_irq;
 
@@ -260,151 +265,141 @@ void __init ep93xx_gpio_init_irq(void)
 /*************************************************************************
  * gpiolib interface for EP93xx on-chip GPIOs
  *************************************************************************/
-struct ep93xx_gpio_chip {
-       struct gpio_chip        chip;
-
-       void __iomem            *data_reg;
-       void __iomem            *data_dir_reg;
+struct ep93xx_gpio_bank {
+       const char      *label;
+       int             data;
+       int             dir;
+       int             base;
+       bool            has_debounce;
 };
 
-#define to_ep93xx_gpio_chip(c) container_of(c, struct ep93xx_gpio_chip, chip)
+#define EP93XX_GPIO_BANK(_label, _data, _dir, _base, _debounce)        \
+       {                                                       \
+               .label          = _label,                       \
+               .data           = _data,                        \
+               .dir            = _dir,                         \
+               .base           = _base,                        \
+               .has_debounce   = _debounce,                    \
+       }
+
+static struct ep93xx_gpio_bank ep93xx_gpio_banks[] = {
+       EP93XX_GPIO_BANK("A", 0x00, 0x10, 0, true),
+       EP93XX_GPIO_BANK("B", 0x04, 0x14, 8, true),
+       EP93XX_GPIO_BANK("C", 0x08, 0x18, 40, false),
+       EP93XX_GPIO_BANK("D", 0x0c, 0x1c, 24, false),
+       EP93XX_GPIO_BANK("E", 0x20, 0x24, 32, false),
+       EP93XX_GPIO_BANK("F", 0x30, 0x34, 16, true),
+       EP93XX_GPIO_BANK("G", 0x38, 0x3c, 48, false),
+       EP93XX_GPIO_BANK("H", 0x40, 0x44, 56, false),
+};
 
-static int ep93xx_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+static int ep93xx_gpio_set_debounce(struct gpio_chip *chip,
+                                   unsigned offset, unsigned debounce)
 {
-       struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip);
-       unsigned long flags;
-       u8 v;
+       int gpio = chip->base + offset;
+       int irq = gpio_to_irq(gpio);
+
+       if (irq < 0)
+               return -EINVAL;
 
-       local_irq_save(flags);
-       v = __raw_readb(ep93xx_chip->data_dir_reg);
-       v &= ~(1 << offset);
-       __raw_writeb(v, ep93xx_chip->data_dir_reg);
-       local_irq_restore(flags);
+       ep93xx_gpio_int_debounce(irq, debounce ? true : false);
 
        return 0;
 }
 
-static int ep93xx_gpio_direction_output(struct gpio_chip *chip,
-                                       unsigned offset, int val)
+static int ep93xx_gpio_add_bank(struct bgpio_chip *bgc, struct device *dev,
+       void __iomem *mmio_base, struct ep93xx_gpio_bank *bank)
 {
-       struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip);
-       unsigned long flags;
-       int line;
-       u8 v;
+       void __iomem *data = mmio_base + bank->data;
+       void __iomem *dir =  mmio_base + bank->dir;
+       int err;
 
-       local_irq_save(flags);
+       err = bgpio_init(bgc, dev, 1, data, NULL, NULL, dir, NULL, false);
+       if (err)
+               return err;
 
-       /* Set the value */
-       v = __raw_readb(ep93xx_chip->data_reg);
-       if (val)
-               v |= (1 << offset);
-       else
-               v &= ~(1 << offset);
-       __raw_writeb(v, ep93xx_chip->data_reg);
-
-       /* Drive as an output */
-       line = chip->base + offset;
-       if (line <= EP93XX_GPIO_LINE_MAX_IRQ) {
-               /* Ports A/B/F */
-               ep93xx_gpio_int_mask(line);
-               ep93xx_gpio_update_int_params(line >> 3);
-       }
+       bgc->gc.label = bank->label;
+       bgc->gc.base = bank->base;
 
-       v = __raw_readb(ep93xx_chip->data_dir_reg);
-       v |= (1 << offset);
-       __raw_writeb(v, ep93xx_chip->data_dir_reg);
+       if (bank->has_debounce)
+               bgc->gc.set_debounce = ep93xx_gpio_set_debounce;
 
-       local_irq_restore(flags);
-
-       return 0;
+       return gpiochip_add(&bgc->gc);
 }
 
-static int ep93xx_gpio_get(struct gpio_chip *chip, unsigned offset)
+static int __devinit ep93xx_gpio_probe(struct platform_device *pdev)
 {
-       struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip);
+       struct ep93xx_gpio *ep93xx_gpio;
+       struct resource *res;
+       void __iomem *mmio;
+       int i;
+       int ret;
 
-       return !!(__raw_readb(ep93xx_chip->data_reg) & (1 << offset));
-}
+       ep93xx_gpio = kzalloc(sizeof(*ep93xx_gpio), GFP_KERNEL);
+       if (!ep93xx_gpio)
+               return -ENOMEM;
 
-static void ep93xx_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
-{
-       struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip);
-       unsigned long flags;
-       u8 v;
-
-       local_irq_save(flags);
-       v = __raw_readb(ep93xx_chip->data_reg);
-       if (val)
-               v |= (1 << offset);
-       else
-               v &= ~(1 << offset);
-       __raw_writeb(v, ep93xx_chip->data_reg);
-       local_irq_restore(flags);
-}
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               ret = -ENXIO;
+               goto exit_free;
+       }
 
-static int ep93xx_gpio_set_debounce(struct gpio_chip *chip,
-                                   unsigned offset, unsigned debounce)
-{
-       int gpio = chip->base + offset;
-       int irq = gpio_to_irq(gpio);
+       if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
+               ret = -EBUSY;
+               goto exit_free;
+       }
 
-       if (irq < 0)
-               return -EINVAL;
+       mmio = ioremap(res->start, resource_size(res));
+       if (!mmio) {
+               ret = -ENXIO;
+               goto exit_release;
+       }
+       ep93xx_gpio->mmio_base = mmio;
 
-       ep93xx_gpio_int_debounce(irq, debounce ? true : false);
+       /* Default all ports to GPIO */
+       ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_KEYS |
+                              EP93XX_SYSCON_DEVCFG_GONK |
+                              EP93XX_SYSCON_DEVCFG_EONIDE |
+                              EP93XX_SYSCON_DEVCFG_GONIDE |
+                              EP93XX_SYSCON_DEVCFG_HONIDE);
 
-       return 0;
-}
+       for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) {
+               struct bgpio_chip *bgc = &ep93xx_gpio->bgc[i];
+               struct ep93xx_gpio_bank *bank = &ep93xx_gpio_banks[i];
 
-#define EP93XX_GPIO_BANK(name, dr, ddr, base_gpio)                     \
-       {                                                               \
-               .chip = {                                               \
-                       .label            = name,                       \
-                       .direction_input  = ep93xx_gpio_direction_input, \
-                       .direction_output = ep93xx_gpio_direction_output, \
-                       .get              = ep93xx_gpio_get,            \
-                       .set              = ep93xx_gpio_set,            \
-                       .base             = base_gpio,                  \
-                       .ngpio            = 8,                          \
-               },                                                      \
-               .data_reg       = EP93XX_GPIO_REG(dr),                  \
-               .data_dir_reg   = EP93XX_GPIO_REG(ddr),                 \
+               if (ep93xx_gpio_add_bank(bgc, &pdev->dev, mmio, bank))
+                       dev_warn(&pdev->dev, "Unable to add gpio bank %s\n",
+                               bank->label);
        }
 
-static struct ep93xx_gpio_chip ep93xx_gpio_banks[] = {
-       EP93XX_GPIO_BANK("A", 0x00, 0x10, 0),
-       EP93XX_GPIO_BANK("B", 0x04, 0x14, 8),
-       EP93XX_GPIO_BANK("C", 0x08, 0x18, 40),
-       EP93XX_GPIO_BANK("D", 0x0c, 0x1c, 24),
-       EP93XX_GPIO_BANK("E", 0x20, 0x24, 32),
-       EP93XX_GPIO_BANK("F", 0x30, 0x34, 16),
-       EP93XX_GPIO_BANK("G", 0x38, 0x3c, 48),
-       EP93XX_GPIO_BANK("H", 0x40, 0x44, 56),
-};
+       ep93xx_gpio_init_irq();
 
-void __init ep93xx_gpio_init(void)
-{
-       int i;
+       return 0;
 
-       /* Set Ports C, D, E, G, and H for GPIO use */
-       ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_KEYS |
-                                EP93XX_SYSCON_DEVCFG_GONK |
-                                EP93XX_SYSCON_DEVCFG_EONIDE |
-                                EP93XX_SYSCON_DEVCFG_GONIDE |
-                                EP93XX_SYSCON_DEVCFG_HONIDE);
+exit_release:
+       release_mem_region(res->start, resource_size(res));
+exit_free:
+       kfree(ep93xx_gpio);
+       dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, ret);
+       return ret;
+}
 
-       for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) {
-               struct gpio_chip *chip = &ep93xx_gpio_banks[i].chip;
-
-               /*
-                * Ports A, B, and F support input debouncing when
-                * used as interrupts.
-                */
-               if (!strcmp(chip->label, "A") ||
-                   !strcmp(chip->label, "B") ||
-                   !strcmp(chip->label, "F"))
-                       chip->set_debounce = ep93xx_gpio_set_debounce;
-
-               gpiochip_add(chip);
-       }
+static struct platform_driver ep93xx_gpio_driver = {
+       .driver         = {
+               .name   = "gpio-ep93xx",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = ep93xx_gpio_probe,
+};
+
+static int __init ep93xx_gpio_init(void)
+{
+       return platform_driver_register(&ep93xx_gpio_driver);
 }
+postcore_initcall(ep93xx_gpio_init);
+
+MODULE_AUTHOR("Ryan Mallon <ryan@bluewatersys.com> "
+               "H Hartley Sweeten <hsweeten@visionengravers.com>");
+MODULE_DESCRIPTION("EP93XX GPIO driver");
+MODULE_LICENSE("GPL");
index 9029835..d24b337 100644 (file)
@@ -1,10 +1,9 @@
-/* linux/arch/arm/mach-exynos4/gpiolib.c
+/*
+ * EXYNOS4 - GPIOlib support
  *
  * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com
  *
- * EXYNOS4 - GPIOlib support
- *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
similarity index 99%
rename from drivers/gpio/basic_mmio_gpio.c
rename to drivers/gpio/gpio-generic.c
index 8152e9f..231714d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Driver for basic memory-mapped GPIO controllers.
+ * Generic driver for memory-mapped GPIO controllers.
  *
  * Copyright 2008 MontaVista Software, Inc.
  * Copyright 2008,2010 Anton Vorontsov <cbouatmailru@gmail.com>
@@ -404,7 +404,7 @@ int __devinit bgpio_init(struct bgpio_chip *bgc,
 }
 EXPORT_SYMBOL_GPL(bgpio_init);
 
-#ifdef CONFIG_GPIO_BASIC_MMIO
+#ifdef CONFIG_GPIO_GENERIC_PLATFORM
 
 static void __iomem *bgpio_map(struct platform_device *pdev,
                               const char *name,
@@ -541,7 +541,7 @@ static void __exit bgpio_platform_exit(void)
 }
 module_exit(bgpio_platform_exit);
 
-#endif /* CONFIG_GPIO_BASIC_MMIO */
+#endif /* CONFIG_GPIO_GENERIC_PLATFORM */
 
 MODULE_DESCRIPTION("Driver for basic memory-mapped GPIO controllers");
 MODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>");
similarity index 98%
rename from drivers/gpio/it8761e_gpio.c
rename to drivers/gpio/gpio-it8761e.c
index 48fc43c..278b813 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  it8761_gpio.c - GPIO interface for IT8761E Super I/O chip
+ *  GPIO interface for IT8761E Super I/O chip
  *
  *  Author: Denis Turischev <denis@compulab.co.il>
  *
similarity index 99%
rename from drivers/gpio/langwell_gpio.c
rename to drivers/gpio/gpio-langwell.c
index 644ba12..d2eb57c 100644 (file)
@@ -1,4 +1,6 @@
-/* langwell_gpio.c Moorestown platform Langwell chip GPIO driver
+/*
+ * Moorestown platform Langwell chip GPIO driver
+ *
  * Copyright (c) 2008 - 2009,  Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify
similarity index 98%
rename from drivers/gpio/max7300.c
rename to drivers/gpio/gpio-max7300.c
index 962f661..a5ca0ab 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * drivers/gpio/max7300.c
- *
  * Copyright (C) 2009 Wolfram Sang, Pengutronix
  *
  * This program is free software; you can redistribute it and/or modify
similarity index 98%
rename from drivers/gpio/max7301.c
rename to drivers/gpio/gpio-max7301.c
index 92a100d..741acfc 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * drivers/gpio/max7301.c
- *
  * Copyright (C) 2006 Juergen Beisert, Pengutronix
  * Copyright (C) 2008 Guennadi Liakhovetski, Pengutronix
  * Copyright (C) 2009 Wolfram Sang, Pengutronix
similarity index 99%
rename from drivers/gpio/max730x.c
rename to drivers/gpio/gpio-max730x.c
index 94ce773..05e2dac 100644 (file)
@@ -1,6 +1,4 @@
 /**
- * drivers/gpio/max7301.c
- *
  * Copyright (C) 2006 Juergen Beisert, Pengutronix
  * Copyright (C) 2008 Guennadi Liakhovetski, Pengutronix
  * Copyright (C) 2009 Wolfram Sang, Pengutronix
similarity index 99%
rename from drivers/gpio/max732x.c
rename to drivers/gpio/gpio-max732x.c
index ad6951e..9504120 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  max732x.c - I2C Port Expander with 8/16 I/O
+ *  MAX732x I2C Port Expander with 8/16 I/O
  *
  *  Copyright (C) 2007 Marvell International Ltd.
  *  Copyright (C) 2008 Jack Ren <jack.ren@marvell.com>
similarity index 98%
rename from drivers/gpio/mc33880.c
rename to drivers/gpio/gpio-mc33880.c
index 4ec7975..b3b4652 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * mc33880.c MC33880 high-side/low-side switch GPIO driver
+ * MC33880 high-side/low-side switch GPIO driver
  * Copyright (c) 2009 Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
similarity index 68%
rename from drivers/gpio/mcp23s08.c
rename to drivers/gpio/gpio-mcp23s08.c
index 40e0760..1ef46e6 100644 (file)
@@ -1,12 +1,12 @@
 /*
- * mcp23s08.c - SPI gpio expander driver
+ * MCP23S08 SPI/GPIO gpio expander driver
  */
 
 #include <linux/kernel.h>
 #include <linux/device.h>
-#include <linux/workqueue.h>
 #include <linux/mutex.h>
 #include <linux/gpio.h>
+#include <linux/i2c.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/mcp23s08.h>
 #include <linux/slab.h>
  */
 #define MCP_TYPE_S08   0
 #define MCP_TYPE_S17   1
+#define MCP_TYPE_008   2
+#define MCP_TYPE_017   3
 
 /* Registers are all 8 bits wide.
  *
  * The mcp23s17 has twice as many bits, and can be configured to work
  * with either 16 bit registers or with two adjacent 8 bit banks.
- *
- * Also, there are I2C versions of both chips.
  */
 #define MCP_IODIR      0x00            /* init/reset:  all ones */
 #define MCP_IPOL       0x01
@@ -51,7 +51,6 @@ struct mcp23s08_ops {
 };
 
 struct mcp23s08 {
-       struct spi_device       *spi;
        u8                      addr;
 
        u16                     cache[11];
@@ -60,9 +59,8 @@ struct mcp23s08 {
 
        struct gpio_chip        chip;
 
-       struct work_struct      work;
-
        const struct mcp23s08_ops       *ops;
+       void                    *data; /* ops specific data */
 };
 
 /* A given spi_device can represent up to eight mcp23sxx chips
@@ -76,6 +74,74 @@ struct mcp23s08_driver_data {
        struct mcp23s08         chip[];
 };
 
+/*----------------------------------------------------------------------*/
+
+#ifdef CONFIG_I2C
+
+static int mcp23008_read(struct mcp23s08 *mcp, unsigned reg)
+{
+       return i2c_smbus_read_byte_data(mcp->data, reg);
+}
+
+static int mcp23008_write(struct mcp23s08 *mcp, unsigned reg, unsigned val)
+{
+       return i2c_smbus_write_byte_data(mcp->data, reg, val);
+}
+
+static int
+mcp23008_read_regs(struct mcp23s08 *mcp, unsigned reg, u16 *vals, unsigned n)
+{
+       while (n--) {
+               int ret = mcp23008_read(mcp, reg++);
+               if (ret < 0)
+                       return ret;
+               *vals++ = ret;
+       }
+
+       return 0;
+}
+
+static int mcp23017_read(struct mcp23s08 *mcp, unsigned reg)
+{
+       return i2c_smbus_read_word_data(mcp->data, reg << 1);
+}
+
+static int mcp23017_write(struct mcp23s08 *mcp, unsigned reg, unsigned val)
+{
+       return i2c_smbus_write_word_data(mcp->data, reg << 1, val);
+}
+
+static int
+mcp23017_read_regs(struct mcp23s08 *mcp, unsigned reg, u16 *vals, unsigned n)
+{
+       while (n--) {
+               int ret = mcp23017_read(mcp, reg++);
+               if (ret < 0)
+                       return ret;
+               *vals++ = ret;
+       }
+
+       return 0;
+}
+
+static const struct mcp23s08_ops mcp23008_ops = {
+       .read           = mcp23008_read,
+       .write          = mcp23008_write,
+       .read_regs      = mcp23008_read_regs,
+};
+
+static const struct mcp23s08_ops mcp23017_ops = {
+       .read           = mcp23017_read,
+       .write          = mcp23017_write,
+       .read_regs      = mcp23017_read_regs,
+};
+
+#endif /* CONFIG_I2C */
+
+/*----------------------------------------------------------------------*/
+
+#ifdef CONFIG_SPI_MASTER
+
 static int mcp23s08_read(struct mcp23s08 *mcp, unsigned reg)
 {
        u8      tx[2], rx[1];
@@ -83,7 +149,7 @@ static int mcp23s08_read(struct mcp23s08 *mcp, unsigned reg)
 
        tx[0] = mcp->addr | 0x01;
        tx[1] = reg;
-       status = spi_write_then_read(mcp->spi, tx, sizeof tx, rx, sizeof rx);
+       status = spi_write_then_read(mcp->data, tx, sizeof tx, rx, sizeof rx);
        return (status < 0) ? status : rx[0];
 }
 
@@ -94,7 +160,7 @@ static int mcp23s08_write(struct mcp23s08 *mcp, unsigned reg, unsigned val)
        tx[0] = mcp->addr;
        tx[1] = reg;
        tx[2] = val;
-       return spi_write_then_read(mcp->spi, tx, sizeof tx, NULL, 0);
+       return spi_write_then_read(mcp->data, tx, sizeof tx, NULL, 0);
 }
 
 static int
@@ -109,7 +175,7 @@ mcp23s08_read_regs(struct mcp23s08 *mcp, unsigned reg, u16 *vals, unsigned n)
        tx[1] = reg;
 
        tmp = (u8 *)vals;
-       status = spi_write_then_read(mcp->spi, tx, sizeof tx, tmp, n);
+       status = spi_write_then_read(mcp->data, tx, sizeof tx, tmp, n);
        if (status >= 0) {
                while (n--)
                        vals[n] = tmp[n]; /* expand to 16bit */
@@ -124,7 +190,7 @@ static int mcp23s17_read(struct mcp23s08 *mcp, unsigned reg)
 
        tx[0] = mcp->addr | 0x01;
        tx[1] = reg << 1;
-       status = spi_write_then_read(mcp->spi, tx, sizeof tx, rx, sizeof rx);
+       status = spi_write_then_read(mcp->data, tx, sizeof tx, rx, sizeof rx);
        return (status < 0) ? status : (rx[0] | (rx[1] << 8));
 }
 
@@ -136,7 +202,7 @@ static int mcp23s17_write(struct mcp23s08 *mcp, unsigned reg, unsigned val)
        tx[1] = reg << 1;
        tx[2] = val;
        tx[3] = val >> 8;
-       return spi_write_then_read(mcp->spi, tx, sizeof tx, NULL, 0);
+       return spi_write_then_read(mcp->data, tx, sizeof tx, NULL, 0);
 }
 
 static int
@@ -150,7 +216,7 @@ mcp23s17_read_regs(struct mcp23s08 *mcp, unsigned reg, u16 *vals, unsigned n)
        tx[0] = mcp->addr | 0x01;
        tx[1] = reg << 1;
 
-       status = spi_write_then_read(mcp->spi, tx, sizeof tx,
+       status = spi_write_then_read(mcp->data, tx, sizeof tx,
                                     (u8 *)vals, n * 2);
        if (status >= 0) {
                while (n--)
@@ -172,6 +238,7 @@ static const struct mcp23s08_ops mcp23s17_ops = {
        .read_regs      = mcp23s17_read_regs,
 };
 
+#endif /* CONFIG_SPI_MASTER */
 
 /*----------------------------------------------------------------------*/
 
@@ -299,17 +366,16 @@ done:
 
 /*----------------------------------------------------------------------*/
 
-static int mcp23s08_probe_one(struct spi_device *spi, unsigned addr,
+static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
+                             void *data, unsigned addr,
                              unsigned type, unsigned base, unsigned pullups)
 {
-       struct mcp23s08_driver_data     *data = spi_get_drvdata(spi);
-       struct mcp23s08                 *mcp = data->mcp[addr];
-       int                             status;
+       int status;
 
        mutex_init(&mcp->lock);
 
-       mcp->spi = spi;
-       mcp->addr = 0x40 | (addr << 1);
+       mcp->data = data;
+       mcp->addr = addr;
 
        mcp->chip.direction_input = mcp23s08_direction_input;
        mcp->chip.get = mcp23s08_get;
@@ -317,18 +383,43 @@ static int mcp23s08_probe_one(struct spi_device *spi, unsigned addr,
        mcp->chip.set = mcp23s08_set;
        mcp->chip.dbg_show = mcp23s08_dbg_show;
 
-       if (type == MCP_TYPE_S17) {
+       switch (type) {
+#ifdef CONFIG_SPI_MASTER
+       case MCP_TYPE_S08:
+               mcp->ops = &mcp23s08_ops;
+               mcp->chip.ngpio = 8;
+               mcp->chip.label = "mcp23s08";
+               break;
+
+       case MCP_TYPE_S17:
                mcp->ops = &mcp23s17_ops;
                mcp->chip.ngpio = 16;
                mcp->chip.label = "mcp23s17";
-       } else {
-               mcp->ops = &mcp23s08_ops;
+               break;
+#endif /* CONFIG_SPI_MASTER */
+
+#ifdef CONFIG_I2C
+       case MCP_TYPE_008:
+               mcp->ops = &mcp23008_ops;
                mcp->chip.ngpio = 8;
-               mcp->chip.label = "mcp23s08";
+               mcp->chip.label = "mcp23008";
+               break;
+
+       case MCP_TYPE_017:
+               mcp->ops = &mcp23017_ops;
+               mcp->chip.ngpio = 16;
+               mcp->chip.label = "mcp23017";
+               break;
+#endif /* CONFIG_I2C */
+
+       default:
+               dev_err(dev, "invalid device type (%d)\n", type);
+               return -EINVAL;
        }
+
        mcp->chip.base = base;
        mcp->chip.can_sleep = 1;
-       mcp->chip.dev = &spi->dev;
+       mcp->chip.dev = dev;
        mcp->chip.owner = THIS_MODULE;
 
        /* verify MCP_IOCON.SEQOP = 0, so sequential reads work,
@@ -374,11 +465,98 @@ static int mcp23s08_probe_one(struct spi_device *spi, unsigned addr,
        status = gpiochip_add(&mcp->chip);
 fail:
        if (status < 0)
-               dev_dbg(&spi->dev, "can't setup chip %d, --> %d\n",
-                               addr, status);
+               dev_dbg(dev, "can't setup chip %d, --> %d\n",
+                       addr, status);
        return status;
 }
 
+/*----------------------------------------------------------------------*/
+
+#ifdef CONFIG_I2C
+
+static int __devinit mcp230xx_probe(struct i2c_client *client,
+                                   const struct i2c_device_id *id)
+{
+       struct mcp23s08_platform_data *pdata;
+       struct mcp23s08 *mcp;
+       int status;
+
+       pdata = client->dev.platform_data;
+       if (!pdata || !gpio_is_valid(pdata->base)) {
+               dev_dbg(&client->dev, "invalid or missing platform data\n");
+               return -EINVAL;
+       }
+
+       mcp = kzalloc(sizeof *mcp, GFP_KERNEL);
+       if (!mcp)
+               return -ENOMEM;
+
+       status = mcp23s08_probe_one(mcp, &client->dev, client, client->addr,
+                                   id->driver_data, pdata->base,
+                                   pdata->chip[0].pullups);
+       if (status)
+               goto fail;
+
+       i2c_set_clientdata(client, mcp);
+
+       return 0;
+
+fail:
+       kfree(mcp);
+
+       return status;
+}
+
+static int __devexit mcp230xx_remove(struct i2c_client *client)
+{
+       struct mcp23s08 *mcp = i2c_get_clientdata(client);
+       int status;
+
+       status = gpiochip_remove(&mcp->chip);
+       if (status == 0)
+               kfree(mcp);
+
+       return status;
+}
+
+static const struct i2c_device_id mcp230xx_id[] = {
+       { "mcp23008", MCP_TYPE_008 },
+       { "mcp23017", MCP_TYPE_017 },
+       { },
+};
+MODULE_DEVICE_TABLE(i2c, mcp230xx_id);
+
+static struct i2c_driver mcp230xx_driver = {
+       .driver = {
+               .name   = "mcp230xx",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = mcp230xx_probe,
+       .remove         = __devexit_p(mcp230xx_remove),
+       .id_table       = mcp230xx_id,
+};
+
+static int __init mcp23s08_i2c_init(void)
+{
+       return i2c_add_driver(&mcp230xx_driver);
+}
+
+static void mcp23s08_i2c_exit(void)
+{
+       i2c_del_driver(&mcp230xx_driver);
+}
+
+#else
+
+static int __init mcp23s08_i2c_init(void) { return 0; }
+static void mcp23s08_i2c_exit(void) { }
+
+#endif /* CONFIG_I2C */
+
+/*----------------------------------------------------------------------*/
+
+#ifdef CONFIG_SPI_MASTER
+
 static int mcp23s08_probe(struct spi_device *spi)
 {
        struct mcp23s08_platform_data   *pdata;
@@ -421,7 +599,8 @@ static int mcp23s08_probe(struct spi_device *spi)
                        continue;
                chips--;
                data->mcp[addr] = &data->chip[chips];
-               status = mcp23s08_probe_one(spi, addr, type, base,
+               status = mcp23s08_probe_one(data->mcp[addr], &spi->dev, spi,
+                                           0x40 | (addr << 1), type, base,
                                            pdata->chip[addr].pullups);
                if (status < 0)
                        goto fail;
@@ -435,14 +614,6 @@ static int mcp23s08_probe(struct spi_device *spi)
         * handled here...
         */
 
-       if (pdata->setup) {
-               status = pdata->setup(spi,
-                               pdata->base, data->ngpio,
-                               pdata->context);
-               if (status < 0)
-                       dev_dbg(&spi->dev, "setup --> %d\n", status);
-       }
-
        return 0;
 
 fail:
@@ -462,20 +633,9 @@ fail:
 static int mcp23s08_remove(struct spi_device *spi)
 {
        struct mcp23s08_driver_data     *data = spi_get_drvdata(spi);
-       struct mcp23s08_platform_data   *pdata = spi->dev.platform_data;
        unsigned                        addr;
        int                             status = 0;
 
-       if (pdata->teardown) {
-               status = pdata->teardown(spi,
-                               pdata->base, data->ngpio,
-                               pdata->context);
-               if (status < 0) {
-                       dev_err(&spi->dev, "%s --> %d\n", "teardown", status);
-                       return status;
-               }
-       }
-
        for (addr = 0; addr < ARRAY_SIZE(data->mcp); addr++) {
                int tmp;
 
@@ -510,20 +670,53 @@ static struct spi_driver mcp23s08_driver = {
        },
 };
 
+static int __init mcp23s08_spi_init(void)
+{
+       return spi_register_driver(&mcp23s08_driver);
+}
+
+static void mcp23s08_spi_exit(void)
+{
+       spi_unregister_driver(&mcp23s08_driver);
+}
+
+#else
+
+static int __init mcp23s08_spi_init(void) { return 0; }
+static void mcp23s08_spi_exit(void) { }
+
+#endif /* CONFIG_SPI_MASTER */
+
 /*----------------------------------------------------------------------*/
 
 static int __init mcp23s08_init(void)
 {
-       return spi_register_driver(&mcp23s08_driver);
+       int ret;
+
+       ret = mcp23s08_spi_init();
+       if (ret)
+               goto spi_fail;
+
+       ret = mcp23s08_i2c_init();
+       if (ret)
+               goto i2c_fail;
+
+       return 0;
+
+ i2c_fail:
+       mcp23s08_spi_exit();
+ spi_fail:
+       return ret;
 }
-/* register after spi postcore initcall and before
+/* register after spi/i2c postcore initcall and before
  * subsys initcalls that may rely on these GPIOs
  */
 subsys_initcall(mcp23s08_init);
 
 static void __exit mcp23s08_exit(void)
 {
-       spi_unregister_driver(&mcp23s08_driver);
+       mcp23s08_spi_exit();
+       mcp23s08_i2c_exit();
 }
 module_exit(mcp23s08_exit);
 
similarity index 99%
rename from drivers/gpio/ml_ioh_gpio.c
rename to drivers/gpio/gpio-ml-ioh.c
index 1bc621a..a9016f5 100644 (file)
@@ -233,7 +233,7 @@ static int __devinit ioh_gpio_probe(struct pci_dev *pdev,
        return 0;
 
 err_gpiochip_add:
-       for (; i != 0; i--) {
+       while (--i >= 0) {
                chip--;
                ret = gpiochip_remove(&chip->gpio);
                if (ret)
similarity index 98%
rename from arch/powerpc/platforms/52xx/mpc52xx_gpio.c
rename to drivers/gpio/gpio-mpc5200.c
index 1757d1d..52d3ed2 100644 (file)
@@ -184,15 +184,13 @@ static int mpc52xx_gpiochip_remove(struct platform_device *ofdev)
 }
 
 static const struct of_device_id mpc52xx_wkup_gpiochip_match[] = {
-       {
-               .compatible = "fsl,mpc5200-gpio-wkup",
-       },
+       { .compatible = "fsl,mpc5200-gpio-wkup", },
        {}
 };
 
 static struct platform_driver mpc52xx_wkup_gpiochip_driver = {
        .driver = {
-               .name = "gpio_wkup",
+               .name = "mpc5200-gpio-wkup",
                .owner = THIS_MODULE,
                .of_match_table = mpc52xx_wkup_gpiochip_match,
        },
@@ -341,15 +339,13 @@ static int __devinit mpc52xx_simple_gpiochip_probe(struct platform_device *ofdev
 }
 
 static const struct of_device_id mpc52xx_simple_gpiochip_match[] = {
-       {
-               .compatible = "fsl,mpc5200-gpio",
-       },
+       { .compatible = "fsl,mpc5200-gpio", },
        {}
 };
 
 static struct platform_driver mpc52xx_simple_gpiochip_driver = {
        .driver = {
-               .name = "gpio",
+               .name = "mpc5200-gpio",
                .owner = THIS_MODULE,
                .of_match_table = mpc52xx_simple_gpiochip_match,
        },
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
new file mode 100644 (file)
index 0000000..4340aca
--- /dev/null
@@ -0,0 +1,460 @@
+/*
+ * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * Based on code from Freescale,
+ * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * 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.
+ * This program is distributed in the hope that 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 Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/basic_mmio_gpio.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <asm-generic/bug.h>
+
+enum mxc_gpio_hwtype {
+       IMX1_GPIO,      /* runs on i.mx1 */
+       IMX21_GPIO,     /* runs on i.mx21 and i.mx27 */
+       IMX31_GPIO,     /* runs on all other i.mx */
+};
+
+/* device type dependent stuff */
+struct mxc_gpio_hwdata {
+       unsigned dr_reg;
+       unsigned gdir_reg;
+       unsigned psr_reg;
+       unsigned icr1_reg;
+       unsigned icr2_reg;
+       unsigned imr_reg;
+       unsigned isr_reg;
+       unsigned low_level;
+       unsigned high_level;
+       unsigned rise_edge;
+       unsigned fall_edge;
+};
+
+struct mxc_gpio_port {
+       struct list_head node;
+       void __iomem *base;
+       int irq;
+       int irq_high;
+       int virtual_irq_start;
+       struct bgpio_chip bgc;
+       u32 both_edges;
+};
+
+static struct mxc_gpio_hwdata imx1_imx21_gpio_hwdata = {
+       .dr_reg         = 0x1c,
+       .gdir_reg       = 0x00,
+       .psr_reg        = 0x24,
+       .icr1_reg       = 0x28,
+       .icr2_reg       = 0x2c,
+       .imr_reg        = 0x30,
+       .isr_reg        = 0x34,
+       .low_level      = 0x03,
+       .high_level     = 0x02,
+       .rise_edge      = 0x00,
+       .fall_edge      = 0x01,
+};
+
+static struct mxc_gpio_hwdata imx31_gpio_hwdata = {
+       .dr_reg         = 0x00,
+       .gdir_reg       = 0x04,
+       .psr_reg        = 0x08,
+       .icr1_reg       = 0x0c,
+       .icr2_reg       = 0x10,
+       .imr_reg        = 0x14,
+       .isr_reg        = 0x18,
+       .low_level      = 0x00,
+       .high_level     = 0x01,
+       .rise_edge      = 0x02,
+       .fall_edge      = 0x03,
+};
+
+static enum mxc_gpio_hwtype mxc_gpio_hwtype;
+static struct mxc_gpio_hwdata *mxc_gpio_hwdata;
+
+#define GPIO_DR                        (mxc_gpio_hwdata->dr_reg)
+#define GPIO_GDIR              (mxc_gpio_hwdata->gdir_reg)
+#define GPIO_PSR               (mxc_gpio_hwdata->psr_reg)
+#define GPIO_ICR1              (mxc_gpio_hwdata->icr1_reg)
+#define GPIO_ICR2              (mxc_gpio_hwdata->icr2_reg)
+#define GPIO_IMR               (mxc_gpio_hwdata->imr_reg)
+#define GPIO_ISR               (mxc_gpio_hwdata->isr_reg)
+
+#define GPIO_INT_LOW_LEV       (mxc_gpio_hwdata->low_level)
+#define GPIO_INT_HIGH_LEV      (mxc_gpio_hwdata->high_level)
+#define GPIO_INT_RISE_EDGE     (mxc_gpio_hwdata->rise_edge)
+#define GPIO_INT_FALL_EDGE     (mxc_gpio_hwdata->fall_edge)
+#define GPIO_INT_NONE          0x4
+
+static struct platform_device_id mxc_gpio_devtype[] = {
+       {
+               .name = "imx1-gpio",
+               .driver_data = IMX1_GPIO,
+       }, {
+               .name = "imx21-gpio",
+               .driver_data = IMX21_GPIO,
+       }, {
+               .name = "imx31-gpio",
+               .driver_data = IMX31_GPIO,
+       }, {
+               /* sentinel */
+       }
+};
+
+static const struct of_device_id mxc_gpio_dt_ids[] = {
+       { .compatible = "fsl,imx1-gpio", .data = &mxc_gpio_devtype[IMX1_GPIO], },
+       { .compatible = "fsl,imx21-gpio", .data = &mxc_gpio_devtype[IMX21_GPIO], },
+       { .compatible = "fsl,imx31-gpio", .data = &mxc_gpio_devtype[IMX31_GPIO], },
+       { /* sentinel */ }
+};
+
+/*
+ * MX2 has one interrupt *for all* gpio ports. The list is used
+ * to save the references to all ports, so that mx2_gpio_irq_handler
+ * can walk through all interrupt status registers.
+ */
+static LIST_HEAD(mxc_gpio_ports);
+
+/* Note: This driver assumes 32 GPIOs are handled in one register */
+
+static int gpio_set_irq_type(struct irq_data *d, u32 type)
+{
+       u32 gpio = irq_to_gpio(d->irq);
+       struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+       struct mxc_gpio_port *port = gc->private;
+       u32 bit, val;
+       int edge;
+       void __iomem *reg = port->base;
+
+       port->both_edges &= ~(1 << (gpio & 31));
+       switch (type) {
+       case IRQ_TYPE_EDGE_RISING:
+               edge = GPIO_INT_RISE_EDGE;
+               break;
+       case IRQ_TYPE_EDGE_FALLING:
+               edge = GPIO_INT_FALL_EDGE;
+               break;
+       case IRQ_TYPE_EDGE_BOTH:
+               val = gpio_get_value(gpio);
+               if (val) {
+                       edge = GPIO_INT_LOW_LEV;
+                       pr_debug("mxc: set GPIO %d to low trigger\n", gpio);
+               } else {
+                       edge = GPIO_INT_HIGH_LEV;
+                       pr_debug("mxc: set GPIO %d to high trigger\n", gpio);
+               }
+               port->both_edges |= 1 << (gpio & 31);
+               break;
+       case IRQ_TYPE_LEVEL_LOW:
+               edge = GPIO_INT_LOW_LEV;
+               break;
+       case IRQ_TYPE_LEVEL_HIGH:
+               edge = GPIO_INT_HIGH_LEV;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
+       bit = gpio & 0xf;
+       val = readl(reg) & ~(0x3 << (bit << 1));
+       writel(val | (edge << (bit << 1)), reg);
+       writel(1 << (gpio & 0x1f), port->base + GPIO_ISR);
+
+       return 0;
+}
+
+static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio)
+{
+       void __iomem *reg = port->base;
+       u32 bit, val;
+       int edge;
+
+       reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
+       bit = gpio & 0xf;
+       val = readl(reg);
+       edge = (val >> (bit << 1)) & 3;
+       val &= ~(0x3 << (bit << 1));
+       if (edge == GPIO_INT_HIGH_LEV) {
+               edge = GPIO_INT_LOW_LEV;
+               pr_debug("mxc: switch GPIO %d to low trigger\n", gpio);
+       } else if (edge == GPIO_INT_LOW_LEV) {
+               edge = GPIO_INT_HIGH_LEV;
+               pr_debug("mxc: switch GPIO %d to high trigger\n", gpio);
+       } else {
+               pr_err("mxc: invalid configuration for GPIO %d: %x\n",
+                      gpio, edge);
+               return;
+       }
+       writel(val | (edge << (bit << 1)), reg);
+}
+
+/* handle 32 interrupts in one status register */
+static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat)
+{
+       u32 gpio_irq_no_base = port->virtual_irq_start;
+
+       while (irq_stat != 0) {
+               int irqoffset = fls(irq_stat) - 1;
+
+               if (port->both_edges & (1 << irqoffset))
+                       mxc_flip_edge(port, irqoffset);
+
+               generic_handle_irq(gpio_irq_no_base + irqoffset);
+
+               irq_stat &= ~(1 << irqoffset);
+       }
+}
+
+/* MX1 and MX3 has one interrupt *per* gpio port */
+static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+       u32 irq_stat;
+       struct mxc_gpio_port *port = irq_get_handler_data(irq);
+
+       irq_stat = readl(port->base + GPIO_ISR) & readl(port->base + GPIO_IMR);
+
+       mxc_gpio_irq_handler(port, irq_stat);
+}
+
+/* MX2 has one interrupt *for all* gpio ports */
+static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+       u32 irq_msk, irq_stat;
+       struct mxc_gpio_port *port;
+
+       /* walk through all interrupt status registers */
+       list_for_each_entry(port, &mxc_gpio_ports, node) {
+               irq_msk = readl(port->base + GPIO_IMR);
+               if (!irq_msk)
+                       continue;
+
+               irq_stat = readl(port->base + GPIO_ISR) & irq_msk;
+               if (irq_stat)
+                       mxc_gpio_irq_handler(port, irq_stat);
+       }
+}
+
+/*
+ * Set interrupt number "irq" in the GPIO as a wake-up source.
+ * While system is running, all registered GPIO interrupts need to have
+ * wake-up enabled. When system is suspended, only selected GPIO interrupts
+ * need to have wake-up enabled.
+ * @param  irq          interrupt source number
+ * @param  enable       enable as wake-up if equal to non-zero
+ * @return       This function returns 0 on success.
+ */
+static int gpio_set_wake_irq(struct irq_data *d, u32 enable)
+{
+       u32 gpio = irq_to_gpio(d->irq);
+       u32 gpio_idx = gpio & 0x1F;
+       struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+       struct mxc_gpio_port *port = gc->private;
+
+       if (enable) {
+               if (port->irq_high && (gpio_idx >= 16))
+                       enable_irq_wake(port->irq_high);
+               else
+                       enable_irq_wake(port->irq);
+       } else {
+               if (port->irq_high && (gpio_idx >= 16))
+                       disable_irq_wake(port->irq_high);
+               else
+                       disable_irq_wake(port->irq);
+       }
+
+       return 0;
+}
+
+static void __init mxc_gpio_init_gc(struct mxc_gpio_port *port)
+{
+       struct irq_chip_generic *gc;
+       struct irq_chip_type *ct;
+
+       gc = irq_alloc_generic_chip("gpio-mxc", 1, port->virtual_irq_start,
+                                   port->base, handle_level_irq);
+       gc->private = port;
+
+       ct = gc->chip_types;
+       ct->chip.irq_ack = irq_gc_ack_set_bit;
+       ct->chip.irq_mask = irq_gc_mask_clr_bit;
+       ct->chip.irq_unmask = irq_gc_mask_set_bit;
+       ct->chip.irq_set_type = gpio_set_irq_type;
+       ct->chip.irq_set_wake = gpio_set_wake_irq;
+       ct->regs.ack = GPIO_ISR;
+       ct->regs.mask = GPIO_IMR;
+
+       irq_setup_generic_chip(gc, IRQ_MSK(32), IRQ_GC_INIT_NESTED_LOCK,
+                              IRQ_NOREQUEST, 0);
+}
+
+static void __devinit mxc_gpio_get_hw(struct platform_device *pdev)
+{
+       const struct of_device_id *of_id =
+                       of_match_device(mxc_gpio_dt_ids, &pdev->dev);
+       enum mxc_gpio_hwtype hwtype;
+
+       if (of_id)
+               pdev->id_entry = of_id->data;
+       hwtype = pdev->id_entry->driver_data;
+
+       if (mxc_gpio_hwtype) {
+               /*
+                * The driver works with a reasonable presupposition,
+                * that is all gpio ports must be the same type when
+                * running on one soc.
+                */
+               BUG_ON(mxc_gpio_hwtype != hwtype);
+               return;
+       }
+
+       if (hwtype == IMX31_GPIO)
+               mxc_gpio_hwdata = &imx31_gpio_hwdata;
+       else
+               mxc_gpio_hwdata = &imx1_imx21_gpio_hwdata;
+
+       mxc_gpio_hwtype = hwtype;
+}
+
+static int __devinit mxc_gpio_probe(struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+       struct mxc_gpio_port *port;
+       struct resource *iores;
+       int err;
+
+       mxc_gpio_get_hw(pdev);
+
+       port = kzalloc(sizeof(struct mxc_gpio_port), GFP_KERNEL);
+       if (!port)
+               return -ENOMEM;
+
+       iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!iores) {
+               err = -ENODEV;
+               goto out_kfree;
+       }
+
+       if (!request_mem_region(iores->start, resource_size(iores),
+                               pdev->name)) {
+               err = -EBUSY;
+               goto out_kfree;
+       }
+
+       port->base = ioremap(iores->start, resource_size(iores));
+       if (!port->base) {
+               err = -ENOMEM;
+               goto out_release_mem;
+       }
+
+       port->irq_high = platform_get_irq(pdev, 1);
+       port->irq = platform_get_irq(pdev, 0);
+       if (port->irq < 0) {
+               err = -EINVAL;
+               goto out_iounmap;
+       }
+
+       /* disable the interrupt and clear the status */
+       writel(0, port->base + GPIO_IMR);
+       writel(~0, port->base + GPIO_ISR);
+
+       if (mxc_gpio_hwtype == IMX21_GPIO) {
+               /* setup one handler for all GPIO interrupts */
+               if (pdev->id == 0)
+                       irq_set_chained_handler(port->irq,
+                                               mx2_gpio_irq_handler);
+       } else {
+               /* setup one handler for each entry */
+               irq_set_chained_handler(port->irq, mx3_gpio_irq_handler);
+               irq_set_handler_data(port->irq, port);
+               if (port->irq_high > 0) {
+                       /* setup handler for GPIO 16 to 31 */
+                       irq_set_chained_handler(port->irq_high,
+                                               mx3_gpio_irq_handler);
+                       irq_set_handler_data(port->irq_high, port);
+               }
+       }
+
+       err = bgpio_init(&port->bgc, &pdev->dev, 4,
+                        port->base + GPIO_PSR,
+                        port->base + GPIO_DR, NULL,
+                        port->base + GPIO_GDIR, NULL, false);
+       if (err)
+               goto out_iounmap;
+
+       port->bgc.gc.base = pdev->id * 32;
+       port->bgc.dir = port->bgc.read_reg(port->bgc.reg_dir);
+       port->bgc.data = port->bgc.read_reg(port->bgc.reg_set);
+
+       err = gpiochip_add(&port->bgc.gc);
+       if (err)
+               goto out_bgpio_remove;
+
+       /*
+        * In dt case, we use gpio number range dynamically
+        * allocated by gpio core.
+        */
+       port->virtual_irq_start = MXC_GPIO_IRQ_START + (np ? port->bgc.gc.base :
+                                                            pdev->id * 32);
+
+       /* gpio-mxc can be a generic irq chip */
+       mxc_gpio_init_gc(port);
+
+       list_add_tail(&port->node, &mxc_gpio_ports);
+
+       return 0;
+
+out_bgpio_remove:
+       bgpio_remove(&port->bgc);
+out_iounmap:
+       iounmap(port->base);
+out_release_mem:
+       release_mem_region(iores->start, resource_size(iores));
+out_kfree:
+       kfree(port);
+       dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, err);
+       return err;
+}
+
+static struct platform_driver mxc_gpio_driver = {
+       .driver         = {
+               .name   = "gpio-mxc",
+               .owner  = THIS_MODULE,
+               .of_match_table = mxc_gpio_dt_ids,
+       },
+       .probe          = mxc_gpio_probe,
+       .id_table       = mxc_gpio_devtype,
+};
+
+static int __init gpio_mxc_init(void)
+{
+       return platform_driver_register(&mxc_gpio_driver);
+}
+postcore_initcall(gpio_mxc_init);
+
+MODULE_AUTHOR("Freescale Semiconductor, "
+             "Daniel Mack <danielncaiaq.de>, "
+             "Juergen Beisert <kernel@pengutronix.de>");
+MODULE_DESCRIPTION("Freescale MXC GPIO");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c
new file mode 100644 (file)
index 0000000..af55a85
--- /dev/null
@@ -0,0 +1,289 @@
+/*
+ * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * Based on code from Freescale,
+ * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * 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.
+ * This program is distributed in the hope that 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 Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/basic_mmio_gpio.h>
+#include <mach/mxs.h>
+
+#define MXS_SET                0x4
+#define MXS_CLR                0x8
+
+#define PINCTRL_DOUT(n)                ((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10)
+#define PINCTRL_DIN(n)         ((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10)
+#define PINCTRL_DOE(n)         ((cpu_is_mx23() ? 0x0700 : 0x0b00) + (n) * 0x10)
+#define PINCTRL_PIN2IRQ(n)     ((cpu_is_mx23() ? 0x0800 : 0x1000) + (n) * 0x10)
+#define PINCTRL_IRQEN(n)       ((cpu_is_mx23() ? 0x0900 : 0x1100) + (n) * 0x10)
+#define PINCTRL_IRQLEV(n)      ((cpu_is_mx23() ? 0x0a00 : 0x1200) + (n) * 0x10)
+#define PINCTRL_IRQPOL(n)      ((cpu_is_mx23() ? 0x0b00 : 0x1300) + (n) * 0x10)
+#define PINCTRL_IRQSTAT(n)     ((cpu_is_mx23() ? 0x0c00 : 0x1400) + (n) * 0x10)
+
+#define GPIO_INT_FALL_EDGE     0x0
+#define GPIO_INT_LOW_LEV       0x1
+#define GPIO_INT_RISE_EDGE     0x2
+#define GPIO_INT_HIGH_LEV      0x3
+#define GPIO_INT_LEV_MASK      (1 << 0)
+#define GPIO_INT_POL_MASK      (1 << 1)
+
+struct mxs_gpio_port {
+       void __iomem *base;
+       int id;
+       int irq;
+       int virtual_irq_start;
+       struct bgpio_chip bgc;
+};
+
+/* Note: This driver assumes 32 GPIOs are handled in one register */
+
+static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
+{
+       u32 gpio = irq_to_gpio(d->irq);
+       u32 pin_mask = 1 << (gpio & 31);
+       struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+       struct mxs_gpio_port *port = gc->private;
+       void __iomem *pin_addr;
+       int edge;
+
+       switch (type) {
+       case IRQ_TYPE_EDGE_RISING:
+               edge = GPIO_INT_RISE_EDGE;
+               break;
+       case IRQ_TYPE_EDGE_FALLING:
+               edge = GPIO_INT_FALL_EDGE;
+               break;
+       case IRQ_TYPE_LEVEL_LOW:
+               edge = GPIO_INT_LOW_LEV;
+               break;
+       case IRQ_TYPE_LEVEL_HIGH:
+               edge = GPIO_INT_HIGH_LEV;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* set level or edge */
+       pin_addr = port->base + PINCTRL_IRQLEV(port->id);
+       if (edge & GPIO_INT_LEV_MASK)
+               writel(pin_mask, pin_addr + MXS_SET);
+       else
+               writel(pin_mask, pin_addr + MXS_CLR);
+
+       /* set polarity */
+       pin_addr = port->base + PINCTRL_IRQPOL(port->id);
+       if (edge & GPIO_INT_POL_MASK)
+               writel(pin_mask, pin_addr + MXS_SET);
+       else
+               writel(pin_mask, pin_addr + MXS_CLR);
+
+       writel(1 << (gpio & 0x1f),
+              port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR);
+
+       return 0;
+}
+
+/* MXS has one interrupt *per* gpio port */
+static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+       u32 irq_stat;
+       struct mxs_gpio_port *port = irq_get_handler_data(irq);
+       u32 gpio_irq_no_base = port->virtual_irq_start;
+
+       desc->irq_data.chip->irq_ack(&desc->irq_data);
+
+       irq_stat = readl(port->base + PINCTRL_IRQSTAT(port->id)) &
+                       readl(port->base + PINCTRL_IRQEN(port->id));
+
+       while (irq_stat != 0) {
+               int irqoffset = fls(irq_stat) - 1;
+               generic_handle_irq(gpio_irq_no_base + irqoffset);
+               irq_stat &= ~(1 << irqoffset);
+       }
+}
+
+/*
+ * Set interrupt number "irq" in the GPIO as a wake-up source.
+ * While system is running, all registered GPIO interrupts need to have
+ * wake-up enabled. When system is suspended, only selected GPIO interrupts
+ * need to have wake-up enabled.
+ * @param  irq          interrupt source number
+ * @param  enable       enable as wake-up if equal to non-zero
+ * @return       This function returns 0 on success.
+ */
+static int mxs_gpio_set_wake_irq(struct irq_data *d, unsigned int enable)
+{
+       struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+       struct mxs_gpio_port *port = gc->private;
+
+       if (enable)
+               enable_irq_wake(port->irq);
+       else
+               disable_irq_wake(port->irq);
+
+       return 0;
+}
+
+static void __init mxs_gpio_init_gc(struct mxs_gpio_port *port)
+{
+       struct irq_chip_generic *gc;
+       struct irq_chip_type *ct;
+
+       gc = irq_alloc_generic_chip("gpio-mxs", 1, port->virtual_irq_start,
+                                   port->base, handle_level_irq);
+       gc->private = port;
+
+       ct = gc->chip_types;
+       ct->chip.irq_ack = irq_gc_ack_set_bit;
+       ct->chip.irq_mask = irq_gc_mask_clr_bit;
+       ct->chip.irq_unmask = irq_gc_mask_set_bit;
+       ct->chip.irq_set_type = mxs_gpio_set_irq_type;
+       ct->chip.irq_set_wake = mxs_gpio_set_wake_irq;
+       ct->regs.ack = PINCTRL_IRQSTAT(port->id) + MXS_CLR;
+       ct->regs.mask = PINCTRL_IRQEN(port->id);
+
+       irq_setup_generic_chip(gc, IRQ_MSK(32), 0, IRQ_NOREQUEST, 0);
+}
+
+static int mxs_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
+{
+       struct bgpio_chip *bgc = to_bgpio_chip(gc);
+       struct mxs_gpio_port *port =
+               container_of(bgc, struct mxs_gpio_port, bgc);
+
+       return port->virtual_irq_start + offset;
+}
+
+static int __devinit mxs_gpio_probe(struct platform_device *pdev)
+{
+       static void __iomem *base;
+       struct mxs_gpio_port *port;
+       struct resource *iores = NULL;
+       int err;
+
+       port = kzalloc(sizeof(struct mxs_gpio_port), GFP_KERNEL);
+       if (!port)
+               return -ENOMEM;
+
+       port->id = pdev->id;
+       port->virtual_irq_start = MXS_GPIO_IRQ_START + port->id * 32;
+
+       /*
+        * map memory region only once, as all the gpio ports
+        * share the same one
+        */
+       if (!base) {
+               iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+               if (!iores) {
+                       err = -ENODEV;
+                       goto out_kfree;
+               }
+
+               if (!request_mem_region(iores->start, resource_size(iores),
+                                       pdev->name)) {
+                       err = -EBUSY;
+                       goto out_kfree;
+               }
+
+               base = ioremap(iores->start, resource_size(iores));
+               if (!base) {
+                       err = -ENOMEM;
+                       goto out_release_mem;
+               }
+       }
+       port->base = base;
+
+       port->irq = platform_get_irq(pdev, 0);
+       if (port->irq < 0) {
+               err = -EINVAL;
+               goto out_iounmap;
+       }
+
+       /*
+        * select the pin interrupt functionality but initially
+        * disable the interrupts
+        */
+       writel(~0U, port->base + PINCTRL_PIN2IRQ(port->id));
+       writel(0, port->base + PINCTRL_IRQEN(port->id));
+
+       /* clear address has to be used to clear IRQSTAT bits */
+       writel(~0U, port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR);
+
+       /* gpio-mxs can be a generic irq chip */
+       mxs_gpio_init_gc(port);
+
+       /* setup one handler for each entry */
+       irq_set_chained_handler(port->irq, mxs_gpio_irq_handler);
+       irq_set_handler_data(port->irq, port);
+
+       err = bgpio_init(&port->bgc, &pdev->dev, 4,
+                        port->base + PINCTRL_DIN(port->id),
+                        port->base + PINCTRL_DOUT(port->id), NULL,
+                        port->base + PINCTRL_DOE(port->id), NULL, false);
+       if (err)
+               goto out_iounmap;
+
+       port->bgc.gc.to_irq = mxs_gpio_to_irq;
+       port->bgc.gc.base = port->id * 32;
+
+       err = gpiochip_add(&port->bgc.gc);
+       if (err)
+               goto out_bgpio_remove;
+
+       return 0;
+
+out_bgpio_remove:
+       bgpio_remove(&port->bgc);
+out_iounmap:
+       if (iores)
+               iounmap(port->base);
+out_release_mem:
+       if (iores)
+               release_mem_region(iores->start, resource_size(iores));
+out_kfree:
+       kfree(port);
+       dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, err);
+       return err;
+}
+
+static struct platform_driver mxs_gpio_driver = {
+       .driver         = {
+               .name   = "gpio-mxs",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = mxs_gpio_probe,
+};
+
+static int __init mxs_gpio_init(void)
+{
+       return platform_driver_register(&mxs_gpio_driver);
+}
+postcore_initcall(mxs_gpio_init);
+
+MODULE_AUTHOR("Freescale Semiconductor, "
+             "Daniel Mack <danielncaiaq.de>, "
+             "Juergen Beisert <kernel@pengutronix.de>");
+MODULE_DESCRIPTION("Freescale MXS GPIO");
+MODULE_LICENSE("GPL");
index 35bebde..0599854 100644 (file)
@@ -54,6 +54,11 @@ struct gpio_bank {
        struct device *dev;
        bool dbck_flag;
        int stride;
+       u32 width;
+
+       void (*set_dataout)(struct gpio_bank *bank, int gpio, int enable);
+
+       struct omap_gpio_reg_offs *regs;
 };
 
 #ifdef CONFIG_ARCH_OMAP3
@@ -79,121 +84,18 @@ static struct omap3_gpio_regs gpio_context[OMAP34XX_NR_GPIOS];
  */
 static struct gpio_bank *gpio_bank;
 
-static int bank_width;
-
 /* TODO: Analyze removing gpio_bank_count usage from driver code */
 int gpio_bank_count;
 
-static inline struct gpio_bank *get_gpio_bank(int gpio)
-{
-       if (cpu_is_omap15xx()) {
-               if (OMAP_GPIO_IS_MPUIO(gpio))
-                       return &gpio_bank[0];
-               return &gpio_bank[1];
-       }
-       if (cpu_is_omap16xx()) {
-               if (OMAP_GPIO_IS_MPUIO(gpio))
-                       return &gpio_bank[0];
-               return &gpio_bank[1 + (gpio >> 4)];
-       }
-       if (cpu_is_omap7xx()) {
-               if (OMAP_GPIO_IS_MPUIO(gpio))
-                       return &gpio_bank[0];
-               return &gpio_bank[1 + (gpio >> 5)];
-       }
-       if (cpu_is_omap24xx())
-               return &gpio_bank[gpio >> 5];
-       if (cpu_is_omap34xx() || cpu_is_omap44xx())
-               return &gpio_bank[gpio >> 5];
-       BUG();
-       return NULL;
-}
-
-static inline int get_gpio_index(int gpio)
-{
-       if (cpu_is_omap7xx())
-               return gpio & 0x1f;
-       if (cpu_is_omap24xx())
-               return gpio & 0x1f;
-       if (cpu_is_omap34xx() || cpu_is_omap44xx())
-               return gpio & 0x1f;
-       return gpio & 0x0f;
-}
-
-static inline int gpio_valid(int gpio)
-{
-       if (gpio < 0)
-               return -1;
-       if (cpu_class_is_omap1() && OMAP_GPIO_IS_MPUIO(gpio)) {
-               if (gpio >= OMAP_MAX_GPIO_LINES + 16)
-                       return -1;
-               return 0;
-       }
-       if (cpu_is_omap15xx() && gpio < 16)
-               return 0;
-       if ((cpu_is_omap16xx()) && gpio < 64)
-               return 0;
-       if (cpu_is_omap7xx() && gpio < 192)
-               return 0;
-       if (cpu_is_omap2420() && gpio < 128)
-               return 0;
-       if (cpu_is_omap2430() && gpio < 160)
-               return 0;
-       if ((cpu_is_omap34xx() || cpu_is_omap44xx()) && gpio < 192)
-               return 0;
-       return -1;
-}
-
-static int check_gpio(int gpio)
-{
-       if (unlikely(gpio_valid(gpio) < 0)) {
-               printk(KERN_ERR "omap-gpio: invalid GPIO %d\n", gpio);
-               dump_stack();
-               return -1;
-       }
-       return 0;
-}
+#define GPIO_INDEX(bank, gpio) (gpio % bank->width)
+#define GPIO_BIT(bank, gpio) (1 << GPIO_INDEX(bank, gpio))
 
 static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
 {
        void __iomem *reg = bank->base;
        u32 l;
 
-       switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP1
-       case METHOD_MPUIO:
-               reg += OMAP_MPUIO_IO_CNTL / bank->stride;
-               break;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-       case METHOD_GPIO_1510:
-               reg += OMAP1510_GPIO_DIR_CONTROL;
-               break;
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-       case METHOD_GPIO_1610:
-               reg += OMAP1610_GPIO_DIRECTION;
-               break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-       case METHOD_GPIO_7XX:
-               reg += OMAP7XX_GPIO_DIR_CONTROL;
-               break;
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-       case METHOD_GPIO_24XX:
-               reg += OMAP24XX_GPIO_OE;
-               break;
-#endif
-#if defined(CONFIG_ARCH_OMAP4)
-       case METHOD_GPIO_44XX:
-               reg += OMAP4_GPIO_OE;
-               break;
-#endif
-       default:
-               WARN_ON(1);
-               return;
-       }
+       reg += bank->regs->direction;
        l = __raw_readl(reg);
        if (is_input)
                l |= 1 << gpio;
@@ -202,165 +104,48 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
        __raw_writel(l, reg);
 }
 
-static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
+
+/* set data out value using dedicate set/clear register */
+static void _set_gpio_dataout_reg(struct gpio_bank *bank, int gpio, int enable)
 {
        void __iomem *reg = bank->base;
-       u32 l = 0;
+       u32 l = GPIO_BIT(bank, gpio);
+
+       if (enable)
+               reg += bank->regs->set_dataout;
+       else
+               reg += bank->regs->clr_dataout;
 
-       switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP1
-       case METHOD_MPUIO:
-               reg += OMAP_MPUIO_OUTPUT / bank->stride;
-               l = __raw_readl(reg);
-               if (enable)
-                       l |= 1 << gpio;
-               else
-                       l &= ~(1 << gpio);
-               break;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-       case METHOD_GPIO_1510:
-               reg += OMAP1510_GPIO_DATA_OUTPUT;
-               l = __raw_readl(reg);
-               if (enable)
-                       l |= 1 << gpio;
-               else
-                       l &= ~(1 << gpio);
-               break;
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-       case METHOD_GPIO_1610:
-               if (enable)
-                       reg += OMAP1610_GPIO_SET_DATAOUT;
-               else
-                       reg += OMAP1610_GPIO_CLEAR_DATAOUT;
-               l = 1 << gpio;
-               break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-       case METHOD_GPIO_7XX:
-               reg += OMAP7XX_GPIO_DATA_OUTPUT;
-               l = __raw_readl(reg);
-               if (enable)
-                       l |= 1 << gpio;
-               else
-                       l &= ~(1 << gpio);
-               break;
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-       case METHOD_GPIO_24XX:
-               if (enable)
-                       reg += OMAP24XX_GPIO_SETDATAOUT;
-               else
-                       reg += OMAP24XX_GPIO_CLEARDATAOUT;
-               l = 1 << gpio;
-               break;
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-       case METHOD_GPIO_44XX:
-               if (enable)
-                       reg += OMAP4_GPIO_SETDATAOUT;
-               else
-                       reg += OMAP4_GPIO_CLEARDATAOUT;
-               l = 1 << gpio;
-               break;
-#endif
-       default:
-               WARN_ON(1);
-               return;
-       }
        __raw_writel(l, reg);
 }
 
-static int _get_gpio_datain(struct gpio_bank *bank, int gpio)
+/* set data out value using mask register */
+static void _set_gpio_dataout_mask(struct gpio_bank *bank, int gpio, int enable)
 {
-       void __iomem *reg;
+       void __iomem *reg = bank->base + bank->regs->dataout;
+       u32 gpio_bit = GPIO_BIT(bank, gpio);
+       u32 l;
 
-       if (check_gpio(gpio) < 0)
-               return -EINVAL;
-       reg = bank->base;
-       switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP1
-       case METHOD_MPUIO:
-               reg += OMAP_MPUIO_INPUT_LATCH / bank->stride;
-               break;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-       case METHOD_GPIO_1510:
-               reg += OMAP1510_GPIO_DATA_INPUT;
-               break;
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-       case METHOD_GPIO_1610:
-               reg += OMAP1610_GPIO_DATAIN;
-               break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-       case METHOD_GPIO_7XX:
-               reg += OMAP7XX_GPIO_DATA_INPUT;
-               break;
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-       case METHOD_GPIO_24XX:
-               reg += OMAP24XX_GPIO_DATAIN;
-               break;
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-       case METHOD_GPIO_44XX:
-               reg += OMAP4_GPIO_DATAIN;
-               break;
-#endif
-       default:
-               return -EINVAL;
-       }
-       return (__raw_readl(reg)
-                       & (1 << get_gpio_index(gpio))) != 0;
+       l = __raw_readl(reg);
+       if (enable)
+               l |= gpio_bit;
+       else
+               l &= ~gpio_bit;
+       __raw_writel(l, reg);
 }
 
-static int _get_gpio_dataout(struct gpio_bank *bank, int gpio)
+static int _get_gpio_datain(struct gpio_bank *bank, int gpio)
 {
-       void __iomem *reg;
+       void __iomem *reg = bank->base + bank->regs->datain;
 
-       if (check_gpio(gpio) < 0)
-               return -EINVAL;
-       reg = bank->base;
+       return (__raw_readl(reg) & GPIO_BIT(bank, gpio)) != 0;
+}
 
-       switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP1
-       case METHOD_MPUIO:
-               reg += OMAP_MPUIO_OUTPUT / bank->stride;
-               break;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-       case METHOD_GPIO_1510:
-               reg += OMAP1510_GPIO_DATA_OUTPUT;
-               break;
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-       case METHOD_GPIO_1610:
-               reg += OMAP1610_GPIO_DATAOUT;
-               break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-       case METHOD_GPIO_7XX:
-               reg += OMAP7XX_GPIO_DATA_OUTPUT;
-               break;
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-       case METHOD_GPIO_24XX:
-               reg += OMAP24XX_GPIO_DATAOUT;
-               break;
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-       case METHOD_GPIO_44XX:
-               reg += OMAP4_GPIO_DATAOUT;
-               break;
-#endif
-       default:
-               return -EINVAL;
-       }
+static int _get_gpio_dataout(struct gpio_bank *bank, int gpio)
+{
+       void __iomem *reg = bank->base + bank->regs->dataout;
 
-       return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0;
+       return (__raw_readl(reg) & GPIO_BIT(bank, gpio)) != 0;
 }
 
 #define MOD_REG_BIT(reg, bit_mask, set)        \
@@ -383,7 +168,7 @@ do {        \
 static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
                unsigned debounce)
 {
-       void __iomem            *reg = bank->base;
+       void __iomem            *reg;
        u32                     val;
        u32                     l;
 
@@ -397,21 +182,12 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
        else
                debounce = (debounce / 0x1f) - 1;
 
-       l = 1 << get_gpio_index(gpio);
-
-       if (bank->method == METHOD_GPIO_44XX)
-               reg += OMAP4_GPIO_DEBOUNCINGTIME;
-       else
-               reg += OMAP24XX_GPIO_DEBOUNCE_VAL;
+       l = GPIO_BIT(bank, gpio);
 
+       reg = bank->base + bank->regs->debounce;
        __raw_writel(debounce, reg);
 
-       reg = bank->base;
-       if (bank->method == METHOD_GPIO_44XX)
-               reg += OMAP4_GPIO_DEBOUNCENABLE;
-       else
-               reg += OMAP24XX_GPIO_DEBOUNCE_EN;
-
+       reg = bank->base + bank->regs->debounce_en;
        val = __raw_readl(reg);
 
        if (debounce) {
@@ -629,9 +405,6 @@ static int gpio_irq_type(struct irq_data *d, unsigned type)
        else
                gpio = d->irq - IH_GPIO_BASE;
 
-       if (check_gpio(gpio) < 0)
-               return -EINVAL;
-
        if (type & ~IRQ_TYPE_SENSE_MASK)
                return -EINVAL;
 
@@ -642,7 +415,7 @@ static int gpio_irq_type(struct irq_data *d, unsigned type)
 
        bank = irq_data_get_irq_chip_data(d);
        spin_lock_irqsave(&bank->lock, flags);
-       retval = _set_gpio_triggering(bank, get_gpio_index(gpio), type);
+       retval = _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), type);
        spin_unlock_irqrestore(&bank->lock, flags);
 
        if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
@@ -657,195 +430,81 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
 {
        void __iomem *reg = bank->base;
 
-       switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP1
-       case METHOD_MPUIO:
-               /* MPUIO irqstatus is reset by reading the status register,
-                * so do nothing here */
-               return;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-       case METHOD_GPIO_1510:
-               reg += OMAP1510_GPIO_INT_STATUS;
-               break;
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-       case METHOD_GPIO_1610:
-               reg += OMAP1610_GPIO_IRQSTATUS1;
-               break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-       case METHOD_GPIO_7XX:
-               reg += OMAP7XX_GPIO_INT_STATUS;
-               break;
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-       case METHOD_GPIO_24XX:
-               reg += OMAP24XX_GPIO_IRQSTATUS1;
-               break;
-#endif
-#if defined(CONFIG_ARCH_OMAP4)
-       case METHOD_GPIO_44XX:
-               reg += OMAP4_GPIO_IRQSTATUS0;
-               break;
-#endif
-       default:
-               WARN_ON(1);
-               return;
-       }
+       reg += bank->regs->irqstatus;
        __raw_writel(gpio_mask, reg);
 
        /* Workaround for clearing DSP GPIO interrupts to allow retention */
-       if (cpu_is_omap24xx() || cpu_is_omap34xx())
-               reg = bank->base + OMAP24XX_GPIO_IRQSTATUS2;
-       else if (cpu_is_omap44xx())
-               reg = bank->base + OMAP4_GPIO_IRQSTATUS1;
-
-       if (cpu_is_omap24xx() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
+       if (bank->regs->irqstatus2) {
+               reg = bank->base + bank->regs->irqstatus2;
                __raw_writel(gpio_mask, reg);
+       }
 
        /* Flush posted write for the irq status to avoid spurious interrupts */
        __raw_readl(reg);
-       }
 }
 
 static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio)
 {
-       _clear_gpio_irqbank(bank, 1 << get_gpio_index(gpio));
+       _clear_gpio_irqbank(bank, GPIO_BIT(bank, gpio));
 }
 
 static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank)
 {
        void __iomem *reg = bank->base;
-       int inv = 0;
        u32 l;
-       u32 mask;
-
-       switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP1
-       case METHOD_MPUIO:
-               reg += OMAP_MPUIO_GPIO_MASKIT / bank->stride;
-               mask = 0xffff;
-               inv = 1;
-               break;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-       case METHOD_GPIO_1510:
-               reg += OMAP1510_GPIO_INT_MASK;
-               mask = 0xffff;
-               inv = 1;
-               break;
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-       case METHOD_GPIO_1610:
-               reg += OMAP1610_GPIO_IRQENABLE1;
-               mask = 0xffff;
-               break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-       case METHOD_GPIO_7XX:
-               reg += OMAP7XX_GPIO_INT_MASK;
-               mask = 0xffffffff;
-               inv = 1;
-               break;
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-       case METHOD_GPIO_24XX:
-               reg += OMAP24XX_GPIO_IRQENABLE1;
-               mask = 0xffffffff;
-               break;
-#endif
-#if defined(CONFIG_ARCH_OMAP4)
-       case METHOD_GPIO_44XX:
-               reg += OMAP4_GPIO_IRQSTATUSSET0;
-               mask = 0xffffffff;
-               break;
-#endif
-       default:
-               WARN_ON(1);
-               return 0;
-       }
+       u32 mask = (1 << bank->width) - 1;
 
+       reg += bank->regs->irqenable;
        l = __raw_readl(reg);
-       if (inv)
+       if (bank->regs->irqenable_inv)
                l = ~l;
        l &= mask;
        return l;
 }
 
-static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable)
+static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
 {
        void __iomem *reg = bank->base;
        u32 l;
 
-       switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP1
-       case METHOD_MPUIO:
-               reg += OMAP_MPUIO_GPIO_MASKIT / bank->stride;
-               l = __raw_readl(reg);
-               if (enable)
-                       l &= ~(gpio_mask);
-               else
-                       l |= gpio_mask;
-               break;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-       case METHOD_GPIO_1510:
-               reg += OMAP1510_GPIO_INT_MASK;
+       if (bank->regs->set_irqenable) {
+               reg += bank->regs->set_irqenable;
+               l = gpio_mask;
+       } else {
+               reg += bank->regs->irqenable;
                l = __raw_readl(reg);
-               if (enable)
-                       l &= ~(gpio_mask);
+               if (bank->regs->irqenable_inv)
+                       l &= ~gpio_mask;
                else
                        l |= gpio_mask;
-               break;
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-       case METHOD_GPIO_1610:
-               if (enable)
-                       reg += OMAP1610_GPIO_SET_IRQENABLE1;
-               else
-                       reg += OMAP1610_GPIO_CLEAR_IRQENABLE1;
+       }
+
+       __raw_writel(l, reg);
+}
+
+static void _disable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
+{
+       void __iomem *reg = bank->base;
+       u32 l;
+
+       if (bank->regs->clr_irqenable) {
+               reg += bank->regs->clr_irqenable;
                l = gpio_mask;
-               break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-       case METHOD_GPIO_7XX:
-               reg += OMAP7XX_GPIO_INT_MASK;
+       } else {
+               reg += bank->regs->irqenable;
                l = __raw_readl(reg);
-               if (enable)
-                       l &= ~(gpio_mask);
-               else
+               if (bank->regs->irqenable_inv)
                        l |= gpio_mask;
-               break;
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-       case METHOD_GPIO_24XX:
-               if (enable)
-                       reg += OMAP24XX_GPIO_SETIRQENABLE1;
-               else
-                       reg += OMAP24XX_GPIO_CLEARIRQENABLE1;
-               l = gpio_mask;
-               break;
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-       case METHOD_GPIO_44XX:
-               if (enable)
-                       reg += OMAP4_GPIO_IRQSTATUSSET0;
                else
-                       reg += OMAP4_GPIO_IRQSTATUSCLR0;
-               l = gpio_mask;
-               break;
-#endif
-       default:
-               WARN_ON(1);
-               return;
+                       l &= ~gpio_mask;
        }
+
        __raw_writel(l, reg);
 }
 
 static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable)
 {
-       _enable_gpio_irqbank(bank, 1 << get_gpio_index(gpio), enable);
+       _enable_gpio_irqbank(bank, GPIO_BIT(bank, gpio));
 }
 
 /*
@@ -858,50 +517,32 @@ static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int ena
  */
 static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
 {
-       unsigned long uninitialized_var(flags);
+       u32 gpio_bit = GPIO_BIT(bank, gpio);
+       unsigned long flags;
 
-       switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP16XX
-       case METHOD_MPUIO:
-       case METHOD_GPIO_1610:
-               spin_lock_irqsave(&bank->lock, flags);
-               if (enable)
-                       bank->suspend_wakeup |= (1 << gpio);
-               else
-                       bank->suspend_wakeup &= ~(1 << gpio);
-               spin_unlock_irqrestore(&bank->lock, flags);
-               return 0;
-#endif
-#ifdef CONFIG_ARCH_OMAP2PLUS
-       case METHOD_GPIO_24XX:
-       case METHOD_GPIO_44XX:
-               if (bank->non_wakeup_gpios & (1 << gpio)) {
-                       printk(KERN_ERR "Unable to modify wakeup on "
-                                       "non-wakeup GPIO%d\n",
-                                       (bank - gpio_bank) * 32 + gpio);
-                       return -EINVAL;
-               }
-               spin_lock_irqsave(&bank->lock, flags);
-               if (enable)
-                       bank->suspend_wakeup |= (1 << gpio);
-               else
-                       bank->suspend_wakeup &= ~(1 << gpio);
-               spin_unlock_irqrestore(&bank->lock, flags);
-               return 0;
-#endif
-       default:
-               printk(KERN_ERR "Can't enable GPIO wakeup for method %i\n",
-                      bank->method);
+       if (bank->non_wakeup_gpios & gpio_bit) {
+               dev_err(bank->dev, 
+                       "Unable to modify wakeup on non-wakeup GPIO%d\n", gpio);
                return -EINVAL;
        }
+
+       spin_lock_irqsave(&bank->lock, flags);
+       if (enable)
+               bank->suspend_wakeup |= gpio_bit;
+       else
+               bank->suspend_wakeup &= ~gpio_bit;
+
+       spin_unlock_irqrestore(&bank->lock, flags);
+
+       return 0;
 }
 
 static void _reset_gpio(struct gpio_bank *bank, int gpio)
 {
-       _set_gpio_direction(bank, get_gpio_index(gpio), 1);
+       _set_gpio_direction(bank, GPIO_INDEX(bank, gpio), 1);
        _set_gpio_irqenable(bank, gpio, 0);
        _clear_gpio_irqstatus(bank, gpio);
-       _set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE);
+       _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), IRQ_TYPE_NONE);
 }
 
 /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */
@@ -911,10 +552,8 @@ static int gpio_wake_enable(struct irq_data *d, unsigned int enable)
        struct gpio_bank *bank;
        int retval;
 
-       if (check_gpio(gpio) < 0)
-               return -ENODEV;
        bank = irq_data_get_irq_chip_data(d);
-       retval = _set_gpio_wakeup(bank, get_gpio_index(gpio), enable);
+       retval = _set_gpio_wakeup(bank, gpio, enable);
 
        return retval;
 }
@@ -1030,31 +669,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
        chained_irq_enter(chip, desc);
 
        bank = irq_get_handler_data(irq);
-#ifdef CONFIG_ARCH_OMAP1
-       if (bank->method == METHOD_MPUIO)
-               isr_reg = bank->base +
-                               OMAP_MPUIO_GPIO_INT / bank->stride;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-       if (bank->method == METHOD_GPIO_1510)
-               isr_reg = bank->base + OMAP1510_GPIO_INT_STATUS;
-#endif
-#if defined(CONFIG_ARCH_OMAP16XX)
-       if (bank->method == METHOD_GPIO_1610)
-               isr_reg = bank->base + OMAP1610_GPIO_IRQSTATUS1;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-       if (bank->method == METHOD_GPIO_7XX)
-               isr_reg = bank->base + OMAP7XX_GPIO_INT_STATUS;
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-       if (bank->method == METHOD_GPIO_24XX)
-               isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1;
-#endif
-#if defined(CONFIG_ARCH_OMAP4)
-       if (bank->method == METHOD_GPIO_44XX)
-               isr_reg = bank->base + OMAP4_GPIO_IRQSTATUS0;
-#endif
+       isr_reg = bank->base + bank->regs->irqstatus;
 
        if (WARN_ON(!isr_reg))
                goto exit;
@@ -1076,9 +691,9 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
                /* clear edge sensitive interrupts before handler(s) are
                called so that we don't miss any interrupt occurred while
                executing them */
-               _enable_gpio_irqbank(bank, isr_saved & ~level_mask, 0);
+               _disable_gpio_irqbank(bank, isr_saved & ~level_mask);
                _clear_gpio_irqbank(bank, isr_saved & ~level_mask);
-               _enable_gpio_irqbank(bank, isr_saved & ~level_mask, 1);
+               _enable_gpio_irqbank(bank, isr_saved & ~level_mask);
 
                /* if there is only edge sensitive GPIO pin interrupts
                configured, we could unmask GPIO bank interrupt immediately */
@@ -1094,7 +709,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 
                gpio_irq = bank->virtual_irq_start;
                for (; isr != 0; isr >>= 1, gpio_irq++) {
-                       gpio_index = get_gpio_index(irq_to_gpio(gpio_irq));
+                       gpio_index = GPIO_INDEX(bank, irq_to_gpio(gpio_irq));
 
                        if (!(isr & 1))
                                continue;
@@ -1150,7 +765,7 @@ static void gpio_mask_irq(struct irq_data *d)
 
        spin_lock_irqsave(&bank->lock, flags);
        _set_gpio_irqenable(bank, gpio, 0);
-       _set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE);
+       _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), IRQ_TYPE_NONE);
        spin_unlock_irqrestore(&bank->lock, flags);
 }
 
@@ -1158,13 +773,13 @@ static void gpio_unmask_irq(struct irq_data *d)
 {
        unsigned int gpio = d->irq - IH_GPIO_BASE;
        struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
-       unsigned int irq_mask = 1 << get_gpio_index(gpio);
+       unsigned int irq_mask = GPIO_BIT(bank, gpio);
        u32 trigger = irqd_get_trigger_type(d);
        unsigned long flags;
 
        spin_lock_irqsave(&bank->lock, flags);
        if (trigger)
-               _set_gpio_triggering(bank, get_gpio_index(gpio), trigger);
+               _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), trigger);
 
        /* For level-triggered GPIOs, the clearing must be done after
         * the HW source is cleared, thus after the handler has run */
@@ -1191,45 +806,8 @@ static struct irq_chip gpio_irq_chip = {
 
 #ifdef CONFIG_ARCH_OMAP1
 
-/* MPUIO uses the always-on 32k clock */
-
-static void mpuio_ack_irq(struct irq_data *d)
-{
-       /* The ISR is reset automatically, so do nothing here. */
-}
-
-static void mpuio_mask_irq(struct irq_data *d)
-{
-       unsigned int gpio = OMAP_MPUIO(d->irq - IH_MPUIO_BASE);
-       struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
-
-       _set_gpio_irqenable(bank, gpio, 0);
-}
-
-static void mpuio_unmask_irq(struct irq_data *d)
-{
-       unsigned int gpio = OMAP_MPUIO(d->irq - IH_MPUIO_BASE);
-       struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
-
-       _set_gpio_irqenable(bank, gpio, 1);
-}
-
-static struct irq_chip mpuio_irq_chip = {
-       .name           = "MPUIO",
-       .irq_ack        = mpuio_ack_irq,
-       .irq_mask       = mpuio_mask_irq,
-       .irq_unmask     = mpuio_unmask_irq,
-       .irq_set_type   = gpio_irq_type,
-#ifdef CONFIG_ARCH_OMAP16XX
-       /* REVISIT: assuming only 16xx supports MPUIO wake events */
-       .irq_set_wake   = gpio_wake_enable,
-#endif
-};
-
-
 #define bank_is_mpuio(bank)    ((bank)->method == METHOD_MPUIO)
 
-
 #ifdef CONFIG_ARCH_OMAP16XX
 
 #include <linux/platform_device.h>
@@ -1289,7 +867,7 @@ static struct platform_device omap_mpuio_device = {
 
 static inline void mpuio_init(void)
 {
-       struct gpio_bank *bank = get_gpio_bank(OMAP_MPUIO(0));
+       struct gpio_bank *bank = &gpio_bank[0];
        platform_set_drvdata(&omap_mpuio_device, bank);
 
        if (platform_driver_register(&omap_mpuio_driver) == 0)
@@ -1302,8 +880,6 @@ static inline void mpuio_init(void) {}
 
 #else
 
-extern struct irq_chip mpuio_irq_chip;
-
 #define bank_is_mpuio(bank)    0
 static inline void mpuio_init(void) {}
 
@@ -1329,31 +905,8 @@ static int gpio_input(struct gpio_chip *chip, unsigned offset)
 
 static int gpio_is_input(struct gpio_bank *bank, int mask)
 {
-       void __iomem *reg = bank->base;
+       void __iomem *reg = bank->base + bank->regs->direction;
 
-       switch (bank->method) {
-       case METHOD_MPUIO:
-               reg += OMAP_MPUIO_IO_CNTL / bank->stride;
-               break;
-       case METHOD_GPIO_1510:
-               reg += OMAP1510_GPIO_DIR_CONTROL;
-               break;
-       case METHOD_GPIO_1610:
-               reg += OMAP1610_GPIO_DIRECTION;
-               break;
-       case METHOD_GPIO_7XX:
-               reg += OMAP7XX_GPIO_DIR_CONTROL;
-               break;
-       case METHOD_GPIO_24XX:
-               reg += OMAP24XX_GPIO_OE;
-               break;
-       case METHOD_GPIO_44XX:
-               reg += OMAP4_GPIO_OE;
-               break;
-       default:
-               WARN_ONCE(1, "gpio_is_input: incorrect OMAP GPIO method");
-               return -EINVAL;
-       }
        return __raw_readl(reg) & mask;
 }
 
@@ -1365,9 +918,9 @@ static int gpio_get(struct gpio_chip *chip, unsigned offset)
        u32 mask;
 
        gpio = chip->base + offset;
-       bank = get_gpio_bank(gpio);
+       bank = container_of(chip, struct gpio_bank, chip);
        reg = bank->base;
-       mask = 1 << get_gpio_index(gpio);
+       mask = GPIO_BIT(bank, gpio);
 
        if (gpio_is_input(bank, mask))
                return _get_gpio_datain(bank, gpio);
@@ -1382,7 +935,7 @@ static int gpio_output(struct gpio_chip *chip, unsigned offset, int value)
 
        bank = container_of(chip, struct gpio_bank, chip);
        spin_lock_irqsave(&bank->lock, flags);
-       _set_gpio_dataout(bank, offset, value);
+       bank->set_dataout(bank, offset, value);
        _set_gpio_direction(bank, offset, 0);
        spin_unlock_irqrestore(&bank->lock, flags);
        return 0;
@@ -1416,7 +969,7 @@ static void gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 
        bank = container_of(chip, struct gpio_bank, chip);
        spin_lock_irqsave(&bank->lock, flags);
-       _set_gpio_dataout(bank, offset, value);
+       bank->set_dataout(bank, offset, value);
        spin_unlock_irqrestore(&bank->lock, flags);
 }
 
@@ -1432,19 +985,17 @@ static int gpio_2irq(struct gpio_chip *chip, unsigned offset)
 
 static void __init omap_gpio_show_rev(struct gpio_bank *bank)
 {
+       static bool called;
        u32 rev;
 
-       if (cpu_is_omap16xx() && !(bank->method != METHOD_MPUIO))
-               rev = __raw_readw(bank->base + OMAP1610_GPIO_REVISION);
-       else if (cpu_is_omap24xx() || cpu_is_omap34xx())
-               rev = __raw_readl(bank->base + OMAP24XX_GPIO_REVISION);
-       else if (cpu_is_omap44xx())
-               rev = __raw_readl(bank->base + OMAP4_GPIO_REVISION);
-       else
+       if (called || bank->regs->revision == USHRT_MAX)
                return;
 
-       printk(KERN_INFO "OMAP GPIO hardware version %d.%d\n",
+       rev = __raw_readw(bank->base + bank->regs->revision);
+       pr_info("OMAP GPIO hardware version %d.%d\n",
                (rev >> 4) & 0x0f, rev & 0x0f);
+
+       called = true;
 }
 
 /* This lock class tells lockdep that GPIO irqs are in a different
@@ -1526,6 +1077,30 @@ static void omap_gpio_mod_init(struct gpio_bank *bank, int id)
        }
 }
 
+static __init void
+omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start,
+                   unsigned int num)
+{
+       struct irq_chip_generic *gc;
+       struct irq_chip_type *ct;
+
+       gc = irq_alloc_generic_chip("MPUIO", 1, irq_start, bank->base,
+                                   handle_simple_irq);
+       ct = gc->chip_types;
+
+       /* NOTE: No ack required, reading IRQ status clears it. */
+       ct->chip.irq_mask = irq_gc_mask_set_bit;
+       ct->chip.irq_unmask = irq_gc_mask_clr_bit;
+       ct->chip.irq_set_type = gpio_irq_type;
+       /* REVISIT: assuming only 16xx supports MPUIO wake events */
+       if (cpu_is_omap16xx())
+               ct->chip.irq_set_wake = gpio_wake_enable,
+
+       ct->regs.mask = OMAP_MPUIO_GPIO_INT / bank->stride;
+       irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
+                              IRQ_NOREQUEST | IRQ_NOPROBE, 0);
+}
+
 static void __devinit omap_gpio_chip_init(struct gpio_bank *bank)
 {
        int j;
@@ -1553,22 +1128,23 @@ static void __devinit omap_gpio_chip_init(struct gpio_bank *bank)
        } else {
                bank->chip.label = "gpio";
                bank->chip.base = gpio;
-               gpio += bank_width;
+               gpio += bank->width;
        }
-       bank->chip.ngpio = bank_width;
+       bank->chip.ngpio = bank->width;
 
        gpiochip_add(&bank->chip);
 
        for (j = bank->virtual_irq_start;
-                    j < bank->virtual_irq_start + bank_width; j++) {
+                    j < bank->virtual_irq_start + bank->width; j++) {
                irq_set_lockdep_class(j, &gpio_lock_class);
                irq_set_chip_data(j, bank);
-               if (bank_is_mpuio(bank))
-                       irq_set_chip(j, &mpuio_irq_chip);
-               else
+               if (bank_is_mpuio(bank)) {
+                       omap_mpuio_alloc_gc(bank, j, bank->width);
+               } else {
                        irq_set_chip(j, &gpio_irq_chip);
-               irq_set_handler(j, handle_simple_irq);
-               set_irq_flags(j, IRQF_VALID);
+                       irq_set_handler(j, handle_simple_irq);
+                       set_irq_flags(j, IRQF_VALID);
+               }
        }
        irq_set_chained_handler(bank->irq, gpio_irq_handler);
        irq_set_handler_data(bank->irq, bank);
@@ -1610,7 +1186,14 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
        bank->dev = &pdev->dev;
        bank->dbck_flag = pdata->dbck_flag;
        bank->stride = pdata->bank_stride;
-       bank_width = pdata->bank_width;
+       bank->width = pdata->bank_width;
+
+       bank->regs = pdata->regs;
+
+       if (bank->regs->set_dataout && bank->regs->clr_dataout)
+               bank->set_dataout = _set_gpio_dataout_reg;
+       else
+               bank->set_dataout = _set_gpio_dataout_mask;
 
        spin_lock_init(&bank->lock);
 
similarity index 89%
rename from drivers/gpio/pca953x.c
rename to drivers/gpio/gpio-pca953x.c
index 0451d7a..c43b8ff 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  pca953x.c - 4/8/16 bit I/O ports
+ *  PCA953x 4/8/16 bit I/O ports
  *
  *  Copyright (C) 2005 Ben Gardner <bgardner@wabtec.com>
  *  Copyright (C) 2007 Marvell International Ltd.
@@ -21,7 +21,6 @@
 #include <linux/slab.h>
 #ifdef CONFIG_OF_GPIO
 #include <linux/of_platform.h>
-#include <linux/of_gpio.h>
 #endif
 
 #define PCA953X_INPUT          0
@@ -85,7 +84,6 @@ struct pca953x_chip {
 #endif
 
        struct i2c_client *client;
-       struct pca953x_platform_data *dyn_pdata;
        struct gpio_chip gpio_chip;
        const char *const *names;
        int     chip_type;
@@ -437,7 +435,7 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid)
 
        do {
                level = __ffs(pending);
-               generic_handle_irq(level + chip->irq_base);
+               handle_nested_irq(level + chip->irq_base);
 
                pending &= ~(1 << level);
        } while (pending);
@@ -446,13 +444,13 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid)
 }
 
 static int pca953x_irq_setup(struct pca953x_chip *chip,
-                            const struct i2c_device_id *id)
+                            const struct i2c_device_id *id,
+                            int irq_base)
 {
        struct i2c_client *client = chip->client;
-       struct pca953x_platform_data *pdata = client->dev.platform_data;
        int ret, offset = 0;
 
-       if (pdata->irq_base != -1
+       if (irq_base != -1
                        && (id->driver_data & PCA_INT)) {
                int lvl;
 
@@ -474,15 +472,19 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
                 * this purpose.
                 */
                chip->irq_stat &= chip->reg_direction;
-               chip->irq_base = pdata->irq_base;
                mutex_init(&chip->irq_lock);
 
+               chip->irq_base = irq_alloc_descs(-1, irq_base, chip->gpio_chip.ngpio, -1);
+               if (chip->irq_base < 0)
+                       goto out_failed;
+
                for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) {
                        int irq = lvl + chip->irq_base;
 
+                       irq_clear_status_flags(irq, IRQ_NOREQUEST);
                        irq_set_chip_data(irq, chip);
-                       irq_set_chip_and_handler(irq, &pca953x_irq_chip,
-                                                handle_simple_irq);
+                       irq_set_chip(irq, &pca953x_irq_chip);
+                       irq_set_nested_thread(irq, true);
 #ifdef CONFIG_ARM
                        set_irq_flags(irq, IRQF_VALID);
 #else
@@ -493,8 +495,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
                ret = request_threaded_irq(client->irq,
                                           NULL,
                                           pca953x_irq_handler,
-                                          IRQF_TRIGGER_RISING |
-                                          IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+                                          IRQF_TRIGGER_LOW | IRQF_ONESHOT,
                                           dev_name(&client->dev), chip);
                if (ret) {
                        dev_err(&client->dev, "failed to request irq %d\n",
@@ -514,17 +515,19 @@ out_failed:
 
 static void pca953x_irq_teardown(struct pca953x_chip *chip)
 {
-       if (chip->irq_base != -1)
+       if (chip->irq_base != -1) {
+               irq_free_descs(chip->irq_base, chip->gpio_chip.ngpio);
                free_irq(chip->client->irq, chip);
+       }
 }
 #else /* CONFIG_GPIO_PCA953X_IRQ */
 static int pca953x_irq_setup(struct pca953x_chip *chip,
-                            const struct i2c_device_id *id)
+                            const struct i2c_device_id *id,
+                            int irq_base)
 {
        struct i2c_client *client = chip->client;
-       struct pca953x_platform_data *pdata = client->dev.platform_data;
 
-       if (pdata->irq_base != -1 && (id->driver_data & PCA_INT))
+       if (irq_base != -1 && (id->driver_data & PCA_INT))
                dev_warn(&client->dev, "interrupt support not compiled in\n");
 
        return 0;
@@ -541,46 +544,39 @@ static void pca953x_irq_teardown(struct pca953x_chip *chip)
 #ifdef CONFIG_OF_GPIO
 /*
  * Translate OpenFirmware node properties into platform_data
+ * WARNING: This is DEPRECATED and will be removed eventually!
  */
-static struct pca953x_platform_data *
-pca953x_get_alt_pdata(struct i2c_client *client)
+void
+pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert)
 {
-       struct pca953x_platform_data *pdata;
        struct device_node *node;
        const __be32 *val;
        int size;
 
        node = client->dev.of_node;
        if (node == NULL)
-               return NULL;
-
-       pdata = kzalloc(sizeof(struct pca953x_platform_data), GFP_KERNEL);
-       if (pdata == NULL) {
-               dev_err(&client->dev, "Unable to allocate platform_data\n");
-               return NULL;
-       }
+               return;
 
-       pdata->gpio_base = -1;
+       *gpio_base = -1;
        val = of_get_property(node, "linux,gpio-base", &size);
+       WARN(val, "%s: device-tree property 'linux,gpio-base' is deprecated!", __func__);
        if (val) {
                if (size != sizeof(*val))
                        dev_warn(&client->dev, "%s: wrong linux,gpio-base\n",
                                 node->full_name);
                else
-                       pdata->gpio_base = be32_to_cpup(val);
+                       *gpio_base = be32_to_cpup(val);
        }
 
        val = of_get_property(node, "polarity", NULL);
+       WARN(val, "%s: device-tree property 'polarity' is deprecated!", __func__);
        if (val)
-               pdata->invert = *val;
-
-       return pdata;
+               *invert = *val;
 }
 #else
-static struct pca953x_platform_data *
-pca953x_get_alt_pdata(struct i2c_client *client)
+void
+pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert)
 {
-       return NULL;
 }
 #endif
 
@@ -642,6 +638,7 @@ static int __devinit pca953x_probe(struct i2c_client *client,
 {
        struct pca953x_platform_data *pdata;
        struct pca953x_chip *chip;
+       int irq_base=0, invert=0;
        int ret = 0;
 
        chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL);
@@ -649,26 +646,22 @@ static int __devinit pca953x_probe(struct i2c_client *client,
                return -ENOMEM;
 
        pdata = client->dev.platform_data;
-       if (pdata == NULL) {
-               pdata = pca953x_get_alt_pdata(client);
-               /*
-                * Unlike normal platform_data, this is allocated
-                * dynamically and must be freed in the driver
-                */
-               chip->dyn_pdata = pdata;
-       }
-
-       if (pdata == NULL) {
-               dev_dbg(&client->dev, "no platform data\n");
-               ret = -EINVAL;
-               goto out_failed;
+       if (pdata) {
+               irq_base = pdata->irq_base;
+               chip->gpio_start = pdata->gpio_base;
+               invert = pdata->invert;
+               chip->names = pdata->names;
+       } else {
+               pca953x_get_alt_pdata(client, &chip->gpio_start, &invert);
+#ifdef CONFIG_OF_GPIO
+               /* If I2C node has no interrupts property, disable GPIO interrupts */
+               if (of_find_property(client->dev.of_node, "interrupts", NULL) == NULL)
+                       irq_base = -1;
+#endif
        }
 
        chip->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);
@@ -679,13 +672,13 @@ static int __devinit pca953x_probe(struct i2c_client *client,
        pca953x_setup_gpio(chip, id->driver_data & PCA_GPIO_MASK);
 
        if (chip->chip_type == PCA953X_TYPE)
-               device_pca953x_init(chip, pdata->invert);
+               device_pca953x_init(chip, invert);
        else if (chip->chip_type == PCA957X_TYPE)
-               device_pca957x_init(chip, pdata->invert);
+               device_pca957x_init(chip, invert);
        else
                goto out_failed;
 
-       ret = pca953x_irq_setup(chip, id);
+       ret = pca953x_irq_setup(chip, id, irq_base);
        if (ret)
                goto out_failed;
 
@@ -693,7 +686,7 @@ static int __devinit pca953x_probe(struct i2c_client *client,
        if (ret)
                goto out_failed_irq;
 
-       if (pdata->setup) {
+       if (pdata && pdata->setup) {
                ret = pdata->setup(client, chip->gpio_chip.base,
                                chip->gpio_chip.ngpio, pdata->context);
                if (ret < 0)
@@ -706,7 +699,6 @@ static int __devinit pca953x_probe(struct i2c_client *client,
 out_failed_irq:
        pca953x_irq_teardown(chip);
 out_failed:
-       kfree(chip->dyn_pdata);
        kfree(chip);
        return ret;
 }
@@ -717,7 +709,7 @@ static int pca953x_remove(struct i2c_client *client)
        struct pca953x_chip *chip = i2c_get_clientdata(client);
        int ret = 0;
 
-       if (pdata->teardown) {
+       if (pdata && pdata->teardown) {
                ret = pdata->teardown(client, chip->gpio_chip.base,
                                chip->gpio_chip.ngpio, pdata->context);
                if (ret < 0) {
@@ -735,7 +727,6 @@ static int pca953x_remove(struct i2c_client *client)
        }
 
        pca953x_irq_teardown(chip);
-       kfree(chip->dyn_pdata);
        kfree(chip);
        return 0;
 }
similarity index 99%
rename from drivers/gpio/pcf857x.c
rename to drivers/gpio/gpio-pcf857x.c
index 879b473..7369fdd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * pcf857x - driver for pcf857x, pca857x, and pca967x I2C GPIO expanders
+ * Driver for pcf857x, pca857x, and pca967x I2C GPIO expanders
  *
  * Copyright (C) 2007 David Brownell
  *
similarity index 99%
rename from drivers/gpio/pl061.c
rename to drivers/gpio/gpio-pl061.c
index 6fcb28c..2c5a18f 100644 (file)
@@ -1,7 +1,5 @@
 /*
- *  linux/drivers/gpio/pl061.c
- *
- *  Copyright (C) 2008, 2009 Provigent Ltd.
+ * Copyright (C) 2008, 2009 Provigent Ltd.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
index ea37c04..ef67f19 100644 (file)
@@ -1,5 +1,4 @@
-/* arch/arm/plat-samsung/gpiolib.c
- *
+/*
  * Copyright 2008 Openmoko, Inc.
  * Copyright 2008 Simtec Electronics
  *      Ben Dooks <ben@simtec.co.uk>
index 2842394..7f87b0c 100644 (file)
@@ -1,4 +1,5 @@
-/* linux/arch/arm/mach-s5pc100/gpiolib.c
+/*
+ * S5PC100 - GPIOlib support
  *
  * Copyright (c) 2010 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com
@@ -6,8 +7,6 @@
  *  Copyright 2009 Samsung Electronics Co
  *  Kyungmin Park <kyungmin.park@samsung.com>
  *
- * S5PC100 - GPIOlib support
- *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
index 1ba20a7..eb12f16 100644 (file)
@@ -1,10 +1,9 @@
-/* linux/arch/arm/mach-s5pv210/gpiolib.c
+/*
+ * S5PV210 - GPIOlib support
  *
  * Copyright (c) 2010 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com/
  *
- * S5PV210 - GPIOlib support
- *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
similarity index 99%
rename from drivers/gpio/sch_gpio.c
rename to drivers/gpio/gpio-sch.c
index 5606042..1635158 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  sch_gpio.c - GPIO interface for Intel Poulsbo SCH
+ * GPIO interface for Intel Poulsbo SCH
  *
  *  Copyright (c) 2010 CompuLab Ltd
  *  Author: Denis Turischev <denis@compulab.co.il>
similarity index 97%
rename from arch/arm/mach-tegra/gpio.c
rename to drivers/gpio/gpio-tegra.c
index 919d638..747eb40 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/of.h>
 
 #include <asm/mach/irq.h>
 
@@ -340,6 +341,15 @@ static int __init tegra_gpio_init(void)
                }
        }
 
+#ifdef CONFIG_OF_GPIO
+       /*
+        * This isn't ideal, but it gets things hooked up until this
+        * driver is converted into a platform_device
+        */
+       tegra_gpio_chip.of_node = of_find_compatible_node(NULL, NULL,
+                                               "nvidia,tegra20-gpio");
+#endif /* CONFIG_OF_GPIO */
+
        gpiochip_add(&tegra_gpio_chip);
 
        for (i = INT_GPIO_BASE; i < (INT_GPIO_BASE + TEGRA_NR_GPIOS); i++) {
similarity index 99%
rename from drivers/gpio/timbgpio.c
rename to drivers/gpio/gpio-timberdale.c
index 0265872..c593bd4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * timbgpio.c timberdale FPGA GPIO driver
+ * Timberdale FPGA GPIO driver
  * Copyright (c) 2009 Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
similarity index 98%
rename from drivers/gpio/tps65910-gpio.c
rename to drivers/gpio/gpio-tps65910.c
index 15097ca..b9c1c29 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * tps65910-gpio.c  --  TI TPS6591x
+ * TI TPS6591x GPIO driver
  *
  * Copyright 2010 Texas Instruments Inc.
  *
similarity index 99%
rename from drivers/gpio/twl4030-gpio.c
rename to drivers/gpio/gpio-twl4030.c
index 57635ac..b8b4f22 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * twl4030_gpio.c -- access to GPIOs on TWL4030/TPS659x0 chips
+ * Access to GPIOs on TWL4030/TPS659x0 chips
  *
  * Copyright (C) 2006-2007 Texas Instruments, Inc.
  * Copyright (C) 2006 MontaVista Software, Inc.
index d927901..fd2dfee 100644 (file)
@@ -1,11 +1,8 @@
 /*
- *
- * arch/arm/mach-u300/gpio.c
- *
+ * U300 GPIO module.
  *
  * Copyright (C) 2007-2009 ST-Ericsson AB
  * License terms: GNU General Public License (GPL) version 2
- * U300 GPIO module.
  * This can driver either of the two basic GPIO cores
  * available in the U300 platforms:
  * COH 901 335   - Used in DB3150 (U300 1.0) and DB3200 (U330 1.0)
similarity index 99%
rename from drivers/gpio/vr41xx_giu.c
rename to drivers/gpio/gpio-vr41xx.c
index a365be0..98723cb 100644 (file)
@@ -518,7 +518,7 @@ static int __devinit giu_probe(struct platform_device *pdev)
        if (!res)
                return -EBUSY;
 
-       giu_base = ioremap(res->start, res->end - res->start + 1);
+       giu_base = ioremap(res->start, resource_size(res));
        if (!giu_base)
                return -ENOMEM;
 
similarity index 99%
rename from drivers/gpio/wm831x-gpio.c
rename to drivers/gpio/gpio-wm831x.c
index 2bcfb0b..deb949e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * wm831x-gpio.c  --  gpiolib support for Wolfson WM831x PMICs
+ * gpiolib support for Wolfson WM831x PMICs
  *
  * Copyright 2009 Wolfson Microelectronics PLC.
  *
similarity index 98%
rename from drivers/gpio/wm8350-gpiolib.c
rename to drivers/gpio/gpio-wm8350.c
index 3599992..a06af51 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * wm835x-gpiolib.c  --  gpiolib support for Wolfson WM835x PMICs
+ * gpiolib support for Wolfson WM835x PMICs
  *
  * Copyright 2009 Wolfson Microelectronics PLC.
  *
similarity index 99%
rename from drivers/gpio/wm8994-gpio.c
rename to drivers/gpio/gpio-wm8994.c
index c822baa..96198f3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * wm8994-gpio.c  --  gpiolib support for Wolfson WM8994
+ * gpiolib support for Wolfson WM8994
  *
  * Copyright 2009 Wolfson Microelectronics PLC.
  *
index 713d43b..6c21c29 100644 (file)
@@ -92,7 +92,7 @@ config LEDS_NET48XX
 config LEDS_NET5501
        tristate "LED Support for Soekris net5501 series Error LED"
        depends on LEDS_TRIGGERS
-       depends on X86 && LEDS_GPIO_PLATFORM && GPIO_CS5535
+       depends on X86 && GPIO_CS5535
        select LEDS_TRIGGER_DEFAULT_ON
        default n
        help
@@ -182,23 +182,6 @@ config LEDS_GPIO
          defined as platform devices and/or OpenFirmware platform devices.
          The code to use these bindings can be selected below.
 
-config LEDS_GPIO_PLATFORM
-       bool "Platform device bindings for GPIO LEDs"
-       depends on LEDS_GPIO
-       default y
-       help
-         Let the leds-gpio driver drive LEDs which have been defined as
-         platform devices.  If you don't know what this means, say yes.
-
-config LEDS_GPIO_OF
-       bool "OpenFirmware platform device bindings for GPIO LEDs"
-       depends on LEDS_GPIO && OF_DEVICE
-       default y
-       help
-         Let the leds-gpio driver drive LEDs which have been defined as
-         of_platform devices.  For instance, LEDs which are listed in a "dts"
-         file.
-
 config LEDS_LP3944
        tristate "LED Support for N.S. LP3944 (Fun Light) I2C chip"
        depends on LEDS_CLASS
index b0480c8..3d8bc32 100644 (file)
@@ -165,7 +165,7 @@ static inline int sizeof_gpio_leds_priv(int num_leds)
 }
 
 /* Code to create from OpenFirmware platform devices */
-#ifdef CONFIG_LEDS_GPIO_OF
+#ifdef CONFIG_OF_GPIO
 static struct gpio_leds_priv * __devinit gpio_leds_create_of(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node, *child;
@@ -223,13 +223,13 @@ static const struct of_device_id of_gpio_leds_match[] = {
        { .compatible = "gpio-leds", },
        {},
 };
-#else
+#else /* CONFIG_OF_GPIO */
 static struct gpio_leds_priv * __devinit gpio_leds_create_of(struct platform_device *pdev)
 {
        return NULL;
 }
 #define of_gpio_leds_match NULL
-#endif
+#endif /* CONFIG_OF_GPIO */
 
 
 static int __devinit gpio_led_probe(struct platform_device *pdev)
index 9059603..3007662 100644 (file)
@@ -21,8 +21,9 @@
 #include <linux/slab.h>
 
 /**
- * of_get_gpio_flags - Get a GPIO number and flags to use with GPIO API
+ * of_get_named_gpio_flags() - Get a GPIO number and flags to use with GPIO API
  * @np:                device node to get GPIO from
+ * @propname:  property name containing gpio specifier(s)
  * @index:     index of the GPIO
  * @flags:     a flags pointer to fill in
  *
@@ -30,8 +31,8 @@
  * value on the error condition. If @flags is not NULL the function also fills
  * in flags for the GPIO.
  */
-int of_get_gpio_flags(struct device_node *np, int index,
-                     enum of_gpio_flags *flags)
+int of_get_named_gpio_flags(struct device_node *np, const char *propname,
+                           int index, enum of_gpio_flags *flags)
 {
        int ret;
        struct device_node *gpio_np;
@@ -40,7 +41,7 @@ int of_get_gpio_flags(struct device_node *np, int index,
        const void *gpio_spec;
        const __be32 *gpio_cells;
 
-       ret = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", index,
+       ret = of_parse_phandles_with_args(np, propname, "#gpio-cells", index,
                                          &gpio_np, &gpio_spec);
        if (ret) {
                pr_debug("%s: can't parse gpios property\n", __func__);
@@ -79,7 +80,7 @@ err0:
        pr_debug("%s exited with status %d\n", __func__, ret);
        return ret;
 }
-EXPORT_SYMBOL(of_get_gpio_flags);
+EXPORT_SYMBOL(of_get_named_gpio_flags);
 
 /**
  * of_gpio_count - Count GPIOs for a device
index 6598c04..aec8025 100644 (file)
@@ -46,8 +46,9 @@ static inline struct of_mm_gpio_chip *to_of_mm_gpio_chip(struct gpio_chip *gc)
        return container_of(gc, struct of_mm_gpio_chip, gc);
 }
 
-extern int of_get_gpio_flags(struct device_node *np, int index,
-                            enum of_gpio_flags *flags);
+extern int of_get_named_gpio_flags(struct device_node *np,
+               const char *list_name, int index, enum of_gpio_flags *flags);
+
 extern unsigned int of_gpio_count(struct device_node *np);
 
 extern int of_mm_gpiochip_add(struct device_node *np,
@@ -60,8 +61,8 @@ extern struct gpio_chip *of_node_to_gpiochip(struct device_node *np);
 #else /* CONFIG_OF_GPIO */
 
 /* Drivers may not strictly depend on the GPIO support, so let them link. */
-static inline int of_get_gpio_flags(struct device_node *np, int index,
-                                   enum of_gpio_flags *flags)
+static inline int of_get_named_gpio_flags(struct device_node *np,
+               const char *list_name, int index, enum of_gpio_flags *flags)
 {
        return -ENOSYS;
 }
@@ -77,7 +78,38 @@ static inline void of_gpiochip_remove(struct gpio_chip *gc) { }
 #endif /* CONFIG_OF_GPIO */
 
 /**
- * of_get_gpio - Get a GPIO number to use with GPIO API
+ * of_get_gpio_flags() - Get a GPIO number and flags to use with GPIO API
+ * @np:                device node to get GPIO from
+ * @index:     index of the GPIO
+ * @flags:     a flags pointer to fill in
+ *
+ * Returns GPIO number to use with Linux generic GPIO API, or one of the errno
+ * value on the error condition. If @flags is not NULL the function also fills
+ * in flags for the GPIO.
+ */
+static inline int of_get_gpio_flags(struct device_node *np, int index,
+                     enum of_gpio_flags *flags)
+{
+       return of_get_named_gpio_flags(np, "gpios", index, flags);
+}
+
+/**
+ * of_get_named_gpio() - Get a GPIO number to use with GPIO API
+ * @np:                device node to get GPIO from
+ * @propname:  Name of property containing gpio specifier(s)
+ * @index:     index of the GPIO
+ *
+ * Returns GPIO number to use with Linux generic GPIO API, or one of the errno
+ * value on the error condition.
+ */
+static inline int of_get_named_gpio(struct device_node *np,
+                                   const char *propname, int index)
+{
+       return of_get_named_gpio_flags(np, propname, index, NULL);
+}
+
+/**
+ * of_get_gpio() - Get a GPIO number to use with GPIO API
  * @np:                device node to get GPIO from
  * @index:     index of the GPIO
  *
index d85c52f..0aa6acc 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef LINUX_SPI_74X164_H
 #define LINUX_SPI_74X164_H
 
-#define GEN_74X164_DRIVER_NAME "74x164"
-
 struct gen_74x164_chip_platform_data {
        /* number assigned to the first GPIO */
        unsigned        base;
index c42cff8..2d676d5 100644 (file)
@@ -22,13 +22,4 @@ struct mcp23s08_platform_data {
         * base to base+15 (or base+31 for s17 variant).
         */
        unsigned        base;
-
-       void            *context;       /* param to setup/teardown */
-
-       int             (*setup)(struct spi_device *spi,
-                                       int gpio, unsigned ngpio,
-                                       void *context);
-       int             (*teardown)(struct spi_device *spi,
-                                       int gpio, unsigned ngpio,
-                                       void *context);
 };