aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2011-07-17 22:45:41 +0200
committerArnd Bergmann <arnd@arndb.de>2011-07-17 22:51:35 +0200
commit382bc10fbe827191218d4eecfaca0995b085dbfd (patch)
treefc335b59f754a5e4571937499c7296f06f27aba2
parentea3e643bbf03735f2109c2d18bee6263c2c71498 (diff)
parent752ad5e82dfd83851e44a2b9da8761994cd7e61c (diff)
Merge branch 'depends/gpio' into for-next
Conflicts: 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/mm.c
-rw-r--r--Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt22
-rw-r--r--Documentation/devicetree/bindings/gpio/gpio.txt46
-rw-r--r--Documentation/devicetree/bindings/gpio/gpio_nvidia.txt8
-rw-r--r--arch/arm/mach-ep93xx/Makefile2
-rw-r--r--arch/arm/mach-ep93xx/core.c27
-rw-r--r--arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h1
-rw-r--r--arch/arm/mach-imx/mm-imx1.c8
-rw-r--r--arch/arm/mach-imx/mm-imx21.c12
-rw-r--r--arch/arm/mach-imx/mm-imx25.c9
-rw-r--r--arch/arm/mach-imx/mm-imx27.c13
-rw-r--r--arch/arm/mach-imx/mm-imx31.c6
-rw-r--r--arch/arm/mach-imx/mm-imx35.c7
-rw-r--r--arch/arm/mach-mx5/mm-mx50.c13
-rw-r--r--arch/arm/mach-mx5/mm.c24
-rw-r--r--arch/arm/mach-omap1/gpio15xx.c22
-rw-r--r--arch/arm/mach-omap1/gpio16xx.c28
-rw-r--r--arch/arm/mach-omap1/gpio7xx.c27
-rw-r--r--arch/arm/mach-omap2/gpio.c32
-rw-r--r--arch/arm/mach-tegra/Makefile1
-rw-r--r--arch/arm/plat-mxc/devices/platform-gpio-mxc.c4
-rw-r--r--arch/arm/plat-mxc/include/mach/common.h2
-rw-r--r--arch/arm/plat-mxc/include/mach/irqs.h21
-rw-r--r--arch/arm/plat-omap/include/plat/gpio.h20
-rw-r--r--arch/powerpc/platforms/52xx/Kconfig8
-rw-r--r--arch/powerpc/platforms/52xx/Makefile1
-rw-r--r--drivers/gpio/Kconfig63
-rw-r--r--drivers/gpio/Makefile85
-rw-r--r--drivers/gpio/gpio-74x164.c (renamed from drivers/gpio/74x164.c)33
-rw-r--r--drivers/gpio/gpio-ab8500.c (renamed from drivers/gpio/ab8500-gpio.c)0
-rw-r--r--drivers/gpio/gpio-adp5520.c (renamed from drivers/gpio/adp5520-gpio.c)0
-rw-r--r--drivers/gpio/gpio-adp5588.c (renamed from drivers/gpio/adp5588-gpio.c)0
-rw-r--r--drivers/gpio/gpio-bt8xx.c (renamed from drivers/gpio/bt8xxgpio.c)0
-rw-r--r--drivers/gpio/gpio-cs5535.c (renamed from drivers/gpio/cs5535-gpio.c)0
-rw-r--r--drivers/gpio/gpio-da9052.c277
-rw-r--r--drivers/gpio/gpio-ep93xx.c (renamed from arch/arm/mach-ep93xx/gpio.c)243
-rw-r--r--drivers/gpio/gpio-exynos4.c5
-rw-r--r--drivers/gpio/gpio-generic.c (renamed from drivers/gpio/basic_mmio_gpio.c)6
-rw-r--r--drivers/gpio/gpio-it8761e.c (renamed from drivers/gpio/it8761e_gpio.c)2
-rw-r--r--drivers/gpio/gpio-janz-ttl.c (renamed from drivers/gpio/janz-ttl.c)0
-rw-r--r--drivers/gpio/gpio-langwell.c (renamed from drivers/gpio/langwell_gpio.c)4
-rw-r--r--drivers/gpio/gpio-max7300.c (renamed from drivers/gpio/max7300.c)2
-rw-r--r--drivers/gpio/gpio-max7301.c (renamed from drivers/gpio/max7301.c)2
-rw-r--r--drivers/gpio/gpio-max730x.c (renamed from drivers/gpio/max730x.c)2
-rw-r--r--drivers/gpio/gpio-max732x.c (renamed from drivers/gpio/max732x.c)2
-rw-r--r--drivers/gpio/gpio-mc33880.c (renamed from drivers/gpio/mc33880.c)2
-rw-r--r--drivers/gpio/gpio-mcp23s08.c (renamed from drivers/gpio/mcp23s08.c)291
-rw-r--r--drivers/gpio/gpio-ml-ioh.c (renamed from drivers/gpio/ml_ioh_gpio.c)2
-rw-r--r--drivers/gpio/gpio-mpc5200.c (renamed from arch/powerpc/platforms/52xx/mpc52xx_gpio.c)12
-rw-r--r--drivers/gpio/gpio-mxc.c245
-rw-r--r--drivers/gpio/gpio-mxs.c189
-rw-r--r--drivers/gpio/gpio-omap.c723
-rw-r--r--drivers/gpio/gpio-pca953x.c (renamed from drivers/gpio/pca953x.c)105
-rw-r--r--drivers/gpio/gpio-pcf857x.c (renamed from drivers/gpio/pcf857x.c)2
-rw-r--r--drivers/gpio/gpio-pch.c (renamed from drivers/gpio/pch_gpio.c)0
-rw-r--r--drivers/gpio/gpio-pl061.c (renamed from drivers/gpio/pl061.c)4
-rw-r--r--drivers/gpio/gpio-plat-samsung.c3
-rw-r--r--drivers/gpio/gpio-rdc321x.c (renamed from drivers/gpio/rdc321x-gpio.c)0
-rw-r--r--drivers/gpio/gpio-s5pc100.c5
-rw-r--r--drivers/gpio/gpio-s5pv210.c5
-rw-r--r--drivers/gpio/gpio-sch.c (renamed from drivers/gpio/sch_gpio.c)2
-rw-r--r--drivers/gpio/gpio-stmpe.c (renamed from drivers/gpio/stmpe-gpio.c)0
-rw-r--r--drivers/gpio/gpio-sx150x.c (renamed from drivers/gpio/sx150x.c)0
-rw-r--r--drivers/gpio/gpio-tc3589x.c (renamed from drivers/gpio/tc3589x-gpio.c)0
-rw-r--r--drivers/gpio/gpio-tegra.c (renamed from arch/arm/mach-tegra/gpio.c)10
-rw-r--r--drivers/gpio/gpio-timberdale.c (renamed from drivers/gpio/timbgpio.c)2
-rw-r--r--drivers/gpio/gpio-tps65910.c (renamed from drivers/gpio/tps65910-gpio.c)2
-rw-r--r--drivers/gpio/gpio-twl4030.c (renamed from drivers/gpio/twl4030-gpio.c)2
-rw-r--r--drivers/gpio/gpio-u300.c5
-rw-r--r--drivers/gpio/gpio-ucb1400.c (renamed from drivers/gpio/ucb1400_gpio.c)0
-rw-r--r--drivers/gpio/gpio-vr41xx.c (renamed from drivers/gpio/vr41xx_giu.c)2
-rw-r--r--drivers/gpio/gpio-vx855.c (renamed from drivers/gpio/vx855_gpio.c)0
-rw-r--r--drivers/gpio/gpio-wm831x.c (renamed from drivers/gpio/wm831x-gpio.c)2
-rw-r--r--drivers/gpio/gpio-wm8350.c (renamed from drivers/gpio/wm8350-gpiolib.c)2
-rw-r--r--drivers/gpio/gpio-wm8994.c (renamed from drivers/gpio/wm8994-gpio.c)2
-rw-r--r--drivers/gpio/gpio-xilinx.c (renamed from drivers/gpio/xilinx_gpio.c)0
-rw-r--r--drivers/leds/Kconfig19
-rw-r--r--drivers/leds/leds-gpio.c6
-rw-r--r--drivers/of/gpio.c11
-rw-r--r--include/linux/of_gpio.h42
-rw-r--r--include/linux/spi/74x164.h2
-rw-r--r--include/linux/spi/mcp23s08.h9
81 files changed, 1511 insertions, 1287 deletions
diff --git a/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt b/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt
new file mode 100644
index 00000000000..4363ae4b3c1
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt
@@ -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>;
+};
diff --git a/Documentation/devicetree/bindings/gpio/gpio.txt b/Documentation/devicetree/bindings/gpio/gpio.txt
index edaa84d288a..4e16ba4feab 100644
--- a/Documentation/devicetree/bindings/gpio/gpio.txt
+++ b/Documentation/devicetree/bindings/gpio/gpio.txt
@@ -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
index 00000000000..eb4b530d64e
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio_nvidia.txt
@@ -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.
diff --git a/arch/arm/mach-ep93xx/Makefile b/arch/arm/mach-ep93xx/Makefile
index 33ee2c863d1..6b7c41d155d 100644
--- a/arch/arm/mach-ep93xx/Makefile
+++ b/arch/arm/mach-ep93xx/Makefile
@@ -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- :=
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 6659a0d137a..c488e4bd61e 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -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);
diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
index 9ac4d105509..c4a7b84ef06 100644
--- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
+++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
@@ -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)
diff --git a/arch/arm/mach-imx/mm-imx1.c b/arch/arm/mach-imx/mm-imx1.c
index f2a6566e22e..2bded591d5c 100644
--- a/arch/arm/mach-imx/mm-imx1.c
+++ b/arch/arm/mach-imx/mm-imx1.c
@@ -50,12 +50,12 @@ void __init mx1_init_irq(void)
void __init imx1_soc_init(void)
{
- mxc_register_gpio(0, MX1_GPIO1_BASE_ADDR, SZ_256,
+ mxc_register_gpio("imx1-gpio", 0, MX1_GPIO1_BASE_ADDR, SZ_256,
MX1_GPIO_INT_PORTA, 0);
- mxc_register_gpio(1, MX1_GPIO2_BASE_ADDR, SZ_256,
+ mxc_register_gpio("imx1-gpio", 1, MX1_GPIO2_BASE_ADDR, SZ_256,
MX1_GPIO_INT_PORTB, 0);
- mxc_register_gpio(2, MX1_GPIO3_BASE_ADDR, SZ_256,
+ mxc_register_gpio("imx1-gpio", 2, MX1_GPIO3_BASE_ADDR, SZ_256,
MX1_GPIO_INT_PORTC, 0);
- mxc_register_gpio(3, MX1_GPIO4_BASE_ADDR, SZ_256,
+ mxc_register_gpio("imx1-gpio", 3, MX1_GPIO4_BASE_ADDR, SZ_256,
MX1_GPIO_INT_PORTD, 0);
}
diff --git a/arch/arm/mach-imx/mm-imx21.c b/arch/arm/mach-imx/mm-imx21.c
index 4f32a8a9aee..3f05dfebacc 100644
--- a/arch/arm/mach-imx/mm-imx21.c
+++ b/arch/arm/mach-imx/mm-imx21.c
@@ -77,12 +77,12 @@ void __init mx21_init_irq(void)
void __init imx21_soc_init(void)
{
- mxc_register_gpio(0, MX21_GPIO1_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
- mxc_register_gpio(1, MX21_GPIO2_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
- mxc_register_gpio(2, MX21_GPIO3_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
- mxc_register_gpio(3, MX21_GPIO4_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
- mxc_register_gpio(4, MX21_GPIO5_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
- mxc_register_gpio(5, MX21_GPIO6_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
+ 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);
imx_add_imx_dma();
}
diff --git a/arch/arm/mach-imx/mm-imx25.c b/arch/arm/mach-imx/mm-imx25.c
index 1e0c95651c2..8bf02916465 100644
--- a/arch/arm/mach-imx/mm-imx25.c
+++ b/arch/arm/mach-imx/mm-imx25.c
@@ -86,10 +86,11 @@ static struct sdma_platform_data imx25_sdma_pdata __initdata = {
void __init imx25_soc_init(void)
{
- mxc_register_gpio(0, MX25_GPIO1_BASE_ADDR, SZ_16K, MX25_INT_GPIO1, 0);
- mxc_register_gpio(1, MX25_GPIO2_BASE_ADDR, SZ_16K, MX25_INT_GPIO2, 0);
- mxc_register_gpio(2, MX25_GPIO3_BASE_ADDR, SZ_16K, MX25_INT_GPIO3, 0);
- mxc_register_gpio(3, MX25_GPIO4_BASE_ADDR, SZ_16K, MX25_INT_GPIO4, 0);
+ /* 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);
imx_add_imx_sdma(MX25_SDMA_BASE_ADDR, MX25_INT_SDMA, &imx25_sdma_pdata);
}
diff --git a/arch/arm/mach-imx/mm-imx27.c b/arch/arm/mach-imx/mm-imx27.c
index 944e02d3ccc..96dd1f5ea7b 100644
--- a/arch/arm/mach-imx/mm-imx27.c
+++ b/arch/arm/mach-imx/mm-imx27.c
@@ -77,12 +77,13 @@ void __init mx27_init_irq(void)
void __init imx27_soc_init(void)
{
- mxc_register_gpio(0, MX27_GPIO1_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
- mxc_register_gpio(1, MX27_GPIO2_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
- mxc_register_gpio(2, MX27_GPIO3_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
- mxc_register_gpio(3, MX27_GPIO4_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
- mxc_register_gpio(4, MX27_GPIO5_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
- mxc_register_gpio(5, MX27_GPIO6_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
+ /* 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);
imx_add_imx_dma();
}
diff --git a/arch/arm/mach-imx/mm-imx31.c b/arch/arm/mach-imx/mm-imx31.c
index a1ff96f249d..61bff38cb95 100644
--- a/arch/arm/mach-imx/mm-imx31.c
+++ b/arch/arm/mach-imx/mm-imx31.c
@@ -78,9 +78,9 @@ void __init imx31_soc_init(void)
{
int to_version = mx31_revision() >> 4;
- mxc_register_gpio(0, MX31_GPIO1_BASE_ADDR, SZ_16K, MX31_INT_GPIO1, 0);
- mxc_register_gpio(1, MX31_GPIO2_BASE_ADDR, SZ_16K, MX31_INT_GPIO2, 0);
- mxc_register_gpio(2, MX31_GPIO3_BASE_ADDR, SZ_16K, MX31_INT_GPIO3, 0);
+ 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);
if (to_version == 1) {
strncpy(imx31_sdma_pdata.fw_name, "sdma-imx31-to1.bin",
diff --git a/arch/arm/mach-imx/mm-imx35.c b/arch/arm/mach-imx/mm-imx35.c
index da530ca48ae..98769ae3437 100644
--- a/arch/arm/mach-imx/mm-imx35.c
+++ b/arch/arm/mach-imx/mm-imx35.c
@@ -95,9 +95,10 @@ void __init imx35_soc_init(void)
{
int to_version = mx35_revision() >> 4;
- mxc_register_gpio(0, MX35_GPIO1_BASE_ADDR, SZ_16K, MX35_INT_GPIO1, 0);
- mxc_register_gpio(1, MX35_GPIO2_BASE_ADDR, SZ_16K, MX35_INT_GPIO2, 0);
- mxc_register_gpio(2, MX35_GPIO3_BASE_ADDR, SZ_16K, MX35_INT_GPIO3, 0);
+ /* 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);
if (to_version == 1) {
strncpy(imx35_sdma_pdata.fw_name, "sdma-imx35-to1.bin",
diff --git a/arch/arm/mach-mx5/mm-mx50.c b/arch/arm/mach-mx5/mm-mx50.c
index 28c3f60f734..77e374c726f 100644
--- a/arch/arm/mach-mx5/mm-mx50.c
+++ b/arch/arm/mach-mx5/mm-mx50.c
@@ -62,10 +62,11 @@ void __init mx50_init_irq(void)
void __init imx50_soc_init(void)
{
- mxc_register_gpio(0, MX50_GPIO1_BASE_ADDR, SZ_16K, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH);
- mxc_register_gpio(1, MX50_GPIO2_BASE_ADDR, SZ_16K, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH);
- mxc_register_gpio(2, MX50_GPIO3_BASE_ADDR, SZ_16K, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH);
- mxc_register_gpio(3, MX50_GPIO4_BASE_ADDR, SZ_16K, MX50_INT_GPIO4_LOW, MX50_INT_GPIO4_HIGH);
- mxc_register_gpio(4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH);
- mxc_register_gpio(5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH);
+ /* 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);
}
diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-mx5/mm.c
index 1b7059f1ac7..ef8aec9319b 100644
--- a/arch/arm/mach-mx5/mm.c
+++ b/arch/arm/mach-mx5/mm.c
@@ -142,23 +142,25 @@ static struct sdma_platform_data imx53_sdma_pdata __initdata = {
void __init imx51_soc_init(void)
{
- mxc_register_gpio(0, MX51_GPIO1_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO1_LOW, MX51_MXC_INT_GPIO1_HIGH);
- mxc_register_gpio(1, MX51_GPIO2_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO2_LOW, MX51_MXC_INT_GPIO2_HIGH);
- mxc_register_gpio(2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO3_LOW, MX51_MXC_INT_GPIO3_HIGH);
- mxc_register_gpio(3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO4_LOW, MX51_MXC_INT_GPIO4_HIGH);
+ /* 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);
imx_add_imx_sdma(MX51_SDMA_BASE_ADDR, MX51_INT_SDMA, &imx51_sdma_pdata);
}
void __init imx53_soc_init(void)
{
- mxc_register_gpio(0, MX53_GPIO1_BASE_ADDR, SZ_16K, MX53_INT_GPIO1_LOW, MX53_INT_GPIO1_HIGH);
- mxc_register_gpio(1, MX53_GPIO2_BASE_ADDR, SZ_16K, MX53_INT_GPIO2_LOW, MX53_INT_GPIO2_HIGH);
- mxc_register_gpio(2, MX53_GPIO3_BASE_ADDR, SZ_16K, MX53_INT_GPIO3_LOW, MX53_INT_GPIO3_HIGH);
- mxc_register_gpio(3, MX53_GPIO4_BASE_ADDR, SZ_16K, MX53_INT_GPIO4_LOW, MX53_INT_GPIO4_HIGH);
- mxc_register_gpio(4, MX53_GPIO5_BASE_ADDR, SZ_16K, MX53_INT_GPIO5_LOW, MX53_INT_GPIO5_HIGH);
- mxc_register_gpio(5, MX53_GPIO6_BASE_ADDR, SZ_16K, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH);
- mxc_register_gpio(6, MX53_GPIO7_BASE_ADDR, SZ_16K, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH);
+ /* 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);
imx_add_imx_sdma(MX53_SDMA_BASE_ADDR, MX53_INT_SDMA, &imx53_sdma_pdata);
}
diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c
index 364137c2042..399da4ce017 100644
--- a/arch/arm/mach-omap1/gpio15xx.c
+++ b/arch/arm/mach-omap1/gpio15xx.c
@@ -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 = {
diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c
index 293a246e282..0f399bd0e70 100644
--- a/arch/arm/mach-omap1/gpio16xx.c
+++ b/arch/arm/mach-omap1/gpio16xx.c
@@ -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 = {
diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c
index c6ad248d63a..5ab63eab0ff 100644
--- a/arch/arm/mach-omap1/gpio7xx.c
+++ b/arch/arm/mach-omap1/gpio7xx.c
@@ -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 = {
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index 9529842ae05..9a46d7773a4 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -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");
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 823c703e573..ed58ef9019b 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -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
diff --git a/arch/arm/plat-mxc/devices/platform-gpio-mxc.c b/arch/arm/plat-mxc/devices/platform-gpio-mxc.c
index cf1b7fdfa20..a7919a24103 100644
--- a/arch/arm/plat-mxc/devices/platform-gpio-mxc.c
+++ b/arch/arm/plat-mxc/devices/platform-gpio-mxc.c
@@ -8,7 +8,7 @@
*/
#include <mach/devices-common.h>
-struct platform_device *__init mxc_register_gpio(int id,
+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[] = {
@@ -28,5 +28,5 @@ struct platform_device *__init mxc_register_gpio(int id,
};
return platform_device_register_resndata(&mxc_aips_bus,
- "gpio-mxc", id, res, ARRAY_SIZE(res), NULL, 0);
+ name, id, res, ARRAY_SIZE(res), NULL, 0);
}
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index 91fa2632aa5..4e3d97890d6 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -64,7 +64,7 @@ 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 struct platform_device *mxc_register_gpio(int id,
+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);
diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h
index 35c89bcdf75..00e812bbd81 100644
--- a/arch/arm/plat-mxc/include/mach/irqs.h
+++ b/arch/arm/plat-mxc/include/mach/irqs.h
@@ -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
*/
@@ -22,30 +24,13 @@
#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
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index ec97e00cb58..91e8de3db08 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -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 */
diff --git a/arch/powerpc/platforms/52xx/Kconfig b/arch/powerpc/platforms/52xx/Kconfig
index 47ea1be1481..90f4496017e 100644
--- a/arch/powerpc/platforms/52xx/Kconfig
+++ b/arch/powerpc/platforms/52xx/Kconfig
@@ -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
diff --git a/arch/powerpc/platforms/52xx/Makefile b/arch/powerpc/platforms/52xx/Makefile
index 2bc8cd0c5cf..4e62486791e 100644
--- a/arch/powerpc/platforms/52xx/Makefile
+++ b/arch/powerpc/platforms/52xx/Makefile
@@ -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
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 5e6fc222bb2..363498697c2 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -63,41 +63,57 @@ 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_MXS
+config GPIO_MPC5200
def_bool y
- depends on ARCH_MXS
+ depends on PPC_MPC52xx
config GPIO_MXC
def_bool y
depends on ARCH_MXC
- select GPIO_BASIC_MMIO_CORE
+ 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
@@ -146,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
@@ -211,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
@@ -305,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"
@@ -407,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
@@ -437,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
@@ -450,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
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 9c37339a57a..72071125139 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -4,49 +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
diff --git a/drivers/gpio/74x164.c b/drivers/gpio/gpio-74x164.c
index 84e07021983..ff525c0958d 100644
--- a/drivers/gpio/74x164.c
+++ b/drivers/gpio/gpio-74x164.c
@@ -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/ab8500-gpio.c b/drivers/gpio/gpio-ab8500.c
index 970053c89ff..970053c89ff 100644
--- a/drivers/gpio/ab8500-gpio.c
+++ b/drivers/gpio/gpio-ab8500.c
diff --git a/drivers/gpio/adp5520-gpio.c b/drivers/gpio/gpio-adp5520.c
index 9f278153700..9f278153700 100644
--- a/drivers/gpio/adp5520-gpio.c
+++ b/drivers/gpio/gpio-adp5520.c
diff --git a/drivers/gpio/adp5588-gpio.c b/drivers/gpio/gpio-adp5588.c
index 3525ad91877..3525ad91877 100644
--- a/drivers/gpio/adp5588-gpio.c
+++ b/drivers/gpio/gpio-adp5588.c
diff --git a/drivers/gpio/bt8xxgpio.c b/drivers/gpio/gpio-bt8xx.c
index aa4f09ad3ce..aa4f09ad3ce 100644
--- a/drivers/gpio/bt8xxgpio.c
+++ b/drivers/gpio/gpio-bt8xx.c
diff --git a/drivers/gpio/cs5535-gpio.c b/drivers/gpio/gpio-cs5535.c
index 6e16cba56ad..6e16cba56ad 100644
--- a/drivers/gpio/cs5535-gpio.c
+++ b/drivers/gpio/gpio-cs5535.c
diff --git a/drivers/gpio/gpio-da9052.c b/drivers/gpio/gpio-da9052.c
new file mode 100644
index 00000000000..038f5eb8b13
--- /dev/null
+++ b/drivers/gpio/gpio-da9052.c
@@ -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");
diff --git a/arch/arm/mach-ep93xx/gpio.c b/drivers/gpio/gpio-ep93xx.c
index 415dce37b88..3bfd3417ab1 100644
--- a/arch/arm/mach-ep93xx/gpio.c
+++ b/drivers/gpio/gpio-ep93xx.c
@@ -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
@@ -13,17 +12,23 @@
* 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");
diff --git a/drivers/gpio/gpio-exynos4.c b/drivers/gpio/gpio-exynos4.c
index 9029835112e..d24b337cf1a 100644
--- a/drivers/gpio/gpio-exynos4.c
+++ b/drivers/gpio/gpio-exynos4.c
@@ -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.
diff --git a/drivers/gpio/basic_mmio_gpio.c b/drivers/gpio/gpio-generic.c
index 8152e9f516b..231714def4d 100644
--- a/drivers/gpio/basic_mmio_gpio.c
+++ b/drivers/gpio/gpio-generic.c
@@ -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>");
diff --git a/drivers/gpio/it8761e_gpio.c b/drivers/gpio/gpio-it8761e.c
index 48fc43c4bdd..278b8131701 100644
--- a/drivers/gpio/it8761e_gpio.c
+++ b/drivers/gpio/gpio-it8761e.c
@@ -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>
*
diff --git a/drivers/gpio/janz-ttl.c b/drivers/gpio/gpio-janz-ttl.c
index 813ac077e5d..813ac077e5d 100644
--- a/drivers/gpio/janz-ttl.c
+++ b/drivers/gpio/gpio-janz-ttl.c
diff --git a/drivers/gpio/langwell_gpio.c b/drivers/gpio/gpio-langwell.c
index 644ba1255d3..d2eb57c60e0 100644
--- a/drivers/gpio/langwell_gpio.c
+++ b/drivers/gpio/gpio-langwell.c
@@ -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
diff --git a/drivers/gpio/max7300.c b/drivers/gpio/gpio-max7300.c
index 962f661c18c..a5ca0ab1b37 100644
--- a/drivers/gpio/max7300.c
+++ b/drivers/gpio/gpio-max7300.c
@@ -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
diff --git a/drivers/gpio/max7301.c b/drivers/gpio/gpio-max7301.c
index 92a100ddef6..741acfcbe76 100644
--- a/drivers/gpio/max7301.c
+++ b/drivers/gpio/gpio-max7301.c
@@ -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
diff --git a/drivers/gpio/max730x.c b/drivers/gpio/gpio-max730x.c
index 94ce773f95f..05e2dac60b3 100644
--- a/drivers/gpio/max730x.c
+++ b/drivers/gpio/gpio-max730x.c
@@ -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
diff --git a/drivers/gpio/max732x.c b/drivers/gpio/gpio-max732x.c
index ad6951edc16..9504120812a 100644
--- a/drivers/gpio/max732x.c
+++ b/drivers/gpio/gpio-max732x.c
@@ -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>
diff --git a/drivers/gpio/mc33880.c b/drivers/gpio/gpio-mc33880.c
index 4ec797593bd..b3b4652e89e 100644
--- a/drivers/gpio/mc33880.c
+++ b/drivers/gpio/gpio-mc33880.c
@@ -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
diff --git a/drivers/gpio/mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c
index 40e076083ec..1ef46e6c2a2 100644
--- a/drivers/gpio/mcp23s08.c
+++ b/drivers/gpio/gpio-mcp23s08.c
@@ -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>
@@ -17,13 +17,13 @@
*/
#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);
diff --git a/drivers/gpio/ml_ioh_gpio.c b/drivers/gpio/gpio-ml-ioh.c
index 1bc621ac353..a9016f56ed7 100644
--- a/drivers/gpio/ml_ioh_gpio.c
+++ b/drivers/gpio/gpio-ml-ioh.c
@@ -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)
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c b/drivers/gpio/gpio-mpc5200.c
index 1757d1db4b5..52d3ed20810 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c
+++ b/drivers/gpio/gpio-mpc5200.c
@@ -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
index b351952893b..89fda58db90 100644
--- a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -27,9 +27,31 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/basic_mmio_gpio.h>
-#include <mach/hardware.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;
@@ -40,6 +62,73 @@ struct mxc_gpio_port {
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
@@ -47,64 +136,13 @@ struct mxc_gpio_port {
*/
static LIST_HEAD(mxc_gpio_ports);
-#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)
-{
- writel(1 << index, port->base + GPIO_ISR);
-}
-
-static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index,
- int enable)
-{
- u32 l;
-
- l = readl(port->base + GPIO_IMR);
- l = (l & (~(1 << index))) | (!!enable << index);
- writel(l, port->base + GPIO_IMR);
-}
-
-static void gpio_ack_irq(struct irq_data *d)
-{
- struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d);
- u32 gpio = irq_to_gpio(d->irq);
- _clear_gpio_irqstatus(port, gpio & 0x1f);
-}
-
-static void gpio_mask_irq(struct irq_data *d)
-{
- struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d);
- u32 gpio = irq_to_gpio(d->irq);
- _set_gpio_irqenable(port, gpio & 0x1f, 0);
-}
-
-static void gpio_unmask_irq(struct irq_data *d)
-{
- struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d);
- u32 gpio = irq_to_gpio(d->irq);
- _set_gpio_irqenable(port, gpio & 0x1f, 1);
-}
-
static int gpio_set_irq_type(struct irq_data *d, u32 type)
{
u32 gpio = irq_to_gpio(d->irq);
- struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d);
+ 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;
@@ -118,7 +156,7 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
edge = GPIO_INT_FALL_EDGE;
break;
case IRQ_TYPE_EDGE_BOTH:
- val = gpio_get_value(gpio & 31);
+ val = gpio_get_value(gpio);
if (val) {
edge = GPIO_INT_LOW_LEV;
pr_debug("mxc: set GPIO %d to low trigger\n", gpio);
@@ -142,7 +180,7 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
bit = gpio & 0xf;
val = readl(reg) & ~(0x3 << (bit << 1));
writel(val | (edge << (bit << 1)), reg);
- _clear_gpio_irqstatus(port, gpio & 0x1f);
+ writel(1 << (gpio & 0x1f), port->base + GPIO_ISR);
return 0;
}
@@ -231,7 +269,8 @@ 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 = irq_data_get_irq_chip_data(d);
+ 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))
@@ -248,33 +287,69 @@ static int gpio_set_wake_irq(struct irq_data *d, u32 enable)
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 __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,
+ 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);
+}
-/*
- * 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;
+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, i;
+ int err;
+
+ mxc_gpio_get_hw(pdev);
port = kzalloc(sizeof(struct mxc_gpio_port), GFP_KERNEL);
if (!port)
return -ENOMEM;
- port->virtual_irq_start = MXC_GPIO_IRQ_START + pdev->id * 32;
-
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!iores) {
err = -ENODEV;
@@ -304,15 +379,7 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev)
writel(0, port->base + GPIO_IMR);
writel(~0, port->base + GPIO_ISR);
- for (i = port->virtual_irq_start;
- i < port->virtual_irq_start + 32; i++) {
- irq_set_lockdep_class(i, &gpio_lock_class);
- irq_set_chip_and_handler(i, &gpio_irq_chip, handle_level_irq);
- set_irq_flags(i, IRQF_VALID);
- irq_set_chip_data(i, port);
- }
-
- if (cpu_is_mx2()) {
+ if (mxc_gpio_hwtype == IMX21_GPIO) {
/* setup one handler for all GPIO interrupts */
if (pdev->id == 0)
irq_set_chained_handler(port->irq,
@@ -337,11 +404,23 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev)
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;
@@ -362,8 +441,10 @@ 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)
diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c
index a28761428bb..d8cafba8c82 100644
--- a/drivers/gpio/gpio-mxs.c
+++ b/drivers/gpio/gpio-mxs.c
@@ -27,6 +27,7 @@
#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
@@ -52,60 +53,18 @@ struct mxs_gpio_port {
void __iomem *base;
int id;
int irq;
- int irq_high;
int virtual_irq_start;
- struct gpio_chip chip;
+ struct bgpio_chip bgc;
};
/* Note: This driver assumes 32 GPIOs are handled in one register */
-static void clear_gpio_irqstatus(struct mxs_gpio_port *port, u32 index)
-{
- writel(1 << index, port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR);
-}
-
-static void set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
- int enable)
-{
- if (enable) {
- writel(1 << index,
- port->base + PINCTRL_IRQEN(port->id) + MXS_SET);
- writel(1 << index,
- port->base + PINCTRL_PIN2IRQ(port->id) + MXS_SET);
- } else {
- writel(1 << index,
- port->base + PINCTRL_IRQEN(port->id) + MXS_CLR);
- }
-}
-
-static void mxs_gpio_ack_irq(struct irq_data *d)
-{
- struct mxs_gpio_port *port = irq_data_get_irq_chip_data(d);
- u32 gpio = irq_to_gpio(d->irq);
- clear_gpio_irqstatus(port, gpio & 0x1f);
-}
-
-static void mxs_gpio_mask_irq(struct irq_data *d)
-{
- struct mxs_gpio_port *port = irq_data_get_irq_chip_data(d);
- u32 gpio = irq_to_gpio(d->irq);
- set_gpio_irqenable(port, gpio & 0x1f, 0);
-}
-
-static void mxs_gpio_unmask_irq(struct irq_data *d)
-{
- struct mxs_gpio_port *port = irq_data_get_irq_chip_data(d);
- u32 gpio = irq_to_gpio(d->irq);
- set_gpio_irqenable(port, 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 = irq_data_get_irq_chip_data(d);
+ 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;
@@ -140,7 +99,8 @@ static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
else
writel(pin_mask, pin_addr + MXS_CLR);
- clear_gpio_irqstatus(port, gpio & 0x1f);
+ writel(1 << (gpio & 0x1f),
+ port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR);
return 0;
}
@@ -175,95 +135,53 @@ static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
*/
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 = irq_data_get_irq_chip_data(d);
-
- 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,
-};
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct mxs_gpio_port *port = gc->private;
-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)
- writel(1 << offset, pin_addr + MXS_SET);
+ if (enable)
+ enable_irq_wake(port->irq);
else
- writel(1 << offset, pin_addr + MXS_CLR);
-}
-
-static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
- struct mxs_gpio_port *port =
- container_of(chip, struct mxs_gpio_port, chip);
+ disable_irq_wake(port->irq);
- return (readl(port->base + PINCTRL_DIN(port->id)) >> offset) & 1;
+ return 0;
}
-static void mxs_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+static void __init mxs_gpio_init_gc(struct mxs_gpio_port *port)
{
- 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)
- writel(1 << offset, pin_addr + MXS_SET);
- else
- writel(1 << offset, pin_addr + MXS_CLR);
+ 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,
+ 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 *chip, unsigned offset)
+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(chip, struct mxs_gpio_port, chip);
+ container_of(bgc, struct mxs_gpio_port, bgc);
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;
-}
-
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, i;
+ int err;
port = kzalloc(sizeof(struct mxs_gpio_port), GFP_KERNEL);
if (!port)
@@ -303,40 +221,41 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev)
goto out_iounmap;
}
- /* disable the interrupt and clear the status */
- writel(0, port->base + PINCTRL_PIN2IRQ(port->id));
+ /*
+ * 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);
- for (i = port->virtual_irq_start;
- i < port->virtual_irq_start + 32; i++) {
- irq_set_chip_and_handler(i, &gpio_irq_chip,
- handle_level_irq);
- set_irq_flags(i, IRQF_VALID);
- irq_set_chip_data(i, port);
- }
+ /* 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);
- /* register gpio chip */
- port->chip.direction_input = mxs_gpio_direction_input;
- port->chip.direction_output = mxs_gpio_direction_output;
- port->chip.get = mxs_gpio_get;
- port->chip.set = mxs_gpio_set;
- port->chip.to_irq = mxs_gpio_to_irq;
- port->chip.base = port->id * 32;
- port->chip.ngpio = 32;
-
- err = gpiochip_add(&port->chip);
+ 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);
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 35bebde23e8..0599854e221 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -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);
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/gpio-pca953x.c
index 0451d7ac94a..c43b8ff626a 100644
--- a/drivers/gpio/pca953x.c
+++ b/drivers/gpio/gpio-pca953x.c
@@ -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;
}
diff --git a/drivers/gpio/pcf857x.c b/drivers/gpio/gpio-pcf857x.c
index 879b473aab5..7369fdda92b 100644
--- a/drivers/gpio/pcf857x.c
+++ b/drivers/gpio/gpio-pcf857x.c
@@ -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
*
diff --git a/drivers/gpio/pch_gpio.c b/drivers/gpio/gpio-pch.c
index 36919e77c49..36919e77c49 100644
--- a/drivers/gpio/pch_gpio.c
+++ b/drivers/gpio/gpio-pch.c
diff --git a/drivers/gpio/pl061.c b/drivers/gpio/gpio-pl061.c
index 6fcb28cdd86..2c5a18f32bf 100644
--- a/drivers/gpio/pl061.c
+++ b/drivers/gpio/gpio-pl061.c
@@ -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
diff --git a/drivers/gpio/gpio-plat-samsung.c b/drivers/gpio/gpio-plat-samsung.c
index ea37c046178..ef67f1952a7 100644
--- a/drivers/gpio/gpio-plat-samsung.c
+++ b/drivers/gpio/gpio-plat-samsung.c
@@ -1,5 +1,4 @@
-/* arch/arm/plat-samsung/gpiolib.c
- *
+/*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
diff --git a/drivers/gpio/rdc321x-gpio.c b/drivers/gpio/gpio-rdc321x.c
index 2762698e020..2762698e020 100644
--- a/drivers/gpio/rdc321x-gpio.c
+++ b/drivers/gpio/gpio-rdc321x.c
diff --git a/drivers/gpio/gpio-s5pc100.c b/drivers/gpio/gpio-s5pc100.c
index 2842394b28b..7f87b0c76e0 100644
--- a/drivers/gpio/gpio-s5pc100.c
+++ b/drivers/gpio/gpio-s5pc100.c
@@ -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.
diff --git a/drivers/gpio/gpio-s5pv210.c b/drivers/gpio/gpio-s5pv210.c
index 1ba20a703e0..eb12f1602de 100644
--- a/drivers/gpio/gpio-s5pv210.c
+++ b/drivers/gpio/gpio-s5pv210.c
@@ -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.
diff --git a/drivers/gpio/sch_gpio.c b/drivers/gpio/gpio-sch.c
index 56060421cdf..16351584549 100644
--- a/drivers/gpio/sch_gpio.c
+++ b/drivers/gpio/gpio-sch.c
@@ -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>
diff --git a/drivers/gpio/stmpe-gpio.c b/drivers/gpio/gpio-stmpe.c
index 4c980b57332..4c980b57332 100644
--- a/drivers/gpio/stmpe-gpio.c
+++ b/drivers/gpio/gpio-stmpe.c
diff --git a/drivers/gpio/sx150x.c b/drivers/gpio/gpio-sx150x.c
index a4f73534394..a4f73534394 100644
--- a/drivers/gpio/sx150x.c
+++ b/drivers/gpio/gpio-sx150x.c
diff --git a/drivers/gpio/tc3589x-gpio.c b/drivers/gpio/gpio-tc3589x.c
index 2a82e8999a4..2a82e8999a4 100644
--- a/drivers/gpio/tc3589x-gpio.c
+++ b/drivers/gpio/gpio-tc3589x.c
diff --git a/arch/arm/mach-tegra/gpio.c b/drivers/gpio/gpio-tegra.c
index 919d6383773..747eb40e8af 100644
--- a/arch/arm/mach-tegra/gpio.c
+++ b/drivers/gpio/gpio-tegra.c
@@ -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++) {
diff --git a/drivers/gpio/timbgpio.c b/drivers/gpio/gpio-timberdale.c
index 0265872e57d..c593bd46bfb 100644
--- a/drivers/gpio/timbgpio.c
+++ b/drivers/gpio/gpio-timberdale.c
@@ -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
diff --git a/drivers/gpio/tps65910-gpio.c b/drivers/gpio/gpio-tps65910.c
index 15097ca616d..b9c1c297669 100644
--- a/drivers/gpio/tps65910-gpio.c
+++ b/drivers/gpio/gpio-tps65910.c
@@ -1,5 +1,5 @@
/*
- * tps65910-gpio.c -- TI TPS6591x
+ * TI TPS6591x GPIO driver
*
* Copyright 2010 Texas Instruments Inc.
*
diff --git a/drivers/gpio/twl4030-gpio.c b/drivers/gpio/gpio-twl4030.c
index 57635ac35a7..b8b4f228757 100644
--- a/drivers/gpio/twl4030-gpio.c
+++ b/drivers/gpio/gpio-twl4030.c
@@ -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.
diff --git a/drivers/gpio/gpio-u300.c b/drivers/gpio/gpio-u300.c
index d92790140fe..fd2dfeeefdf 100644
--- a/drivers/gpio/gpio-u300.c
+++ b/drivers/gpio/gpio-u300.c
@@ -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)
diff --git a/drivers/gpio/ucb1400_gpio.c b/drivers/gpio/gpio-ucb1400.c
index 50e6bd1392c..50e6bd1392c 100644
--- a/drivers/gpio/ucb1400_gpio.c
+++ b/drivers/gpio/gpio-ucb1400.c
diff --git a/drivers/gpio/vr41xx_giu.c b/drivers/gpio/gpio-vr41xx.c
index a365be040b3..98723cb9ac6 100644
--- a/drivers/gpio/vr41xx_giu.c
+++ b/drivers/gpio/gpio-vr41xx.c
@@ -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;
diff --git a/drivers/gpio/vx855_gpio.c b/drivers/gpio/gpio-vx855.c
index ef5aabd8b8b..ef5aabd8b8b 100644
--- a/drivers/gpio/vx855_gpio.c
+++ b/drivers/gpio/gpio-vx855.c
diff --git a/drivers/gpio/wm831x-gpio.c b/drivers/gpio/gpio-wm831x.c
index 309644cf4d9..31a9ed7bba8 100644
--- a/drivers/gpio/wm831x-gpio.c
+++ b/drivers/gpio/gpio-wm831x.c
@@ -1,5 +1,5 @@
/*
- * wm831x-gpio.c -- gpiolib support for Wolfson WM831x PMICs
+ * gpiolib support for Wolfson WM831x PMICs
*
* Copyright 2009 Wolfson Microelectronics PLC.
*
diff --git a/drivers/gpio/wm8350-gpiolib.c b/drivers/gpio/gpio-wm8350.c
index 359999290f5..a06af515483 100644
--- a/drivers/gpio/wm8350-gpiolib.c
+++ b/drivers/gpio/gpio-wm8350.c
@@ -1,5 +1,5 @@
/*
- * wm835x-gpiolib.c -- gpiolib support for Wolfson WM835x PMICs
+ * gpiolib support for Wolfson WM835x PMICs
*
* Copyright 2009 Wolfson Microelectronics PLC.
*
diff --git a/drivers/gpio/wm8994-gpio.c b/drivers/gpio/gpio-wm8994.c
index c822baacd8f..96198f3fab7 100644
--- a/drivers/gpio/wm8994-gpio.c
+++ b/drivers/gpio/gpio-wm8994.c
@@ -1,5 +1,5 @@
/*
- * wm8994-gpio.c -- gpiolib support for Wolfson WM8994
+ * gpiolib support for Wolfson WM8994
*
* Copyright 2009 Wolfson Microelectronics PLC.
*
diff --git a/drivers/gpio/xilinx_gpio.c b/drivers/gpio/gpio-xilinx.c
index 846fbd5e31b..846fbd5e31b 100644
--- a/drivers/gpio/xilinx_gpio.c
+++ b/drivers/gpio/gpio-xilinx.c
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 713d43b4e56..6c21c2986ca 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -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
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index b0480c8fbcb..3d8bc327a68 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -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)
diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c
index 905960338fb..3007662ac61 100644
--- a/drivers/of/gpio.c
+++ b/drivers/of/gpio.c
@@ -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
diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h
index 6598c04dab0..aec8025c786 100644
--- a/include/linux/of_gpio.h
+++ b/include/linux/of_gpio.h
@@ -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
*
diff --git a/include/linux/spi/74x164.h b/include/linux/spi/74x164.h
index d85c52f294a..0aa6acc7331 100644
--- a/include/linux/spi/74x164.h
+++ b/include/linux/spi/74x164.h
@@ -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;
diff --git a/include/linux/spi/mcp23s08.h b/include/linux/spi/mcp23s08.h
index c42cff8ca19..2d676d5aaa8 100644
--- a/include/linux/spi/mcp23s08.h
+++ b/include/linux/spi/mcp23s08.h
@@ -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);
};