diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-26 13:56:38 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-26 13:56:38 -0700 |
commit | f948ad0787de7b393c325803014fd7d5f1b501b1 (patch) | |
tree | d5ac20ec61151809b8e365a137099a3f93562692 | |
parent | 608adca52305e4d14ca5978f9c62698ca45d3f42 (diff) | |
parent | 4fbb0022cba37eef4a263183fdb7dbee89b299f2 (diff) |
Merge tag 'gpio-for-v3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio
Pull GPIO changes from Linus Walleij:
- New driver for AMD-8111 southbridge GPIOs
- New driver for Wolfson Micro Arizona devices
- Propagate device tree parse errors
- Probe deferral finalizations - all expected calls to GPIO will now
hopefully request deferral where apropriate
- Misc updates to TCA6424, WM8994, LPC32xx, PCF857x, Samsung MXC, OMAP
and PCA953X drivers.
Fix up gpio_idx conflicts in drivers/gpio/gpio-mxc.c
* tag 'gpio-for-v3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio:
gpio: of_get_named_gpio_flags() return -EPROBE_DEFER if GPIO not yet available
gpiolib: Defer failed gpio requests by default
MAINTAINERS: add entry OMAP GPIO driver
gpio/pca953x: increase variables size to support 24 bit of data
GPIO: PCA953X: Increase size of invert variable to support 24 bit
gpio/omap: move bank->dbck initialization to omap_gpio_mod_init()
gpio/mxc: use the edge_sel feature if available
gpio: propagate of_parse_phandle_with_args errors
gpio: samsung: add flags specifier to device-tree binding
gpiolib: Add support for Wolfson Microelectronics Arizona class devices
gpio: gpio-lpc32xx: Add gpio_to_irq mapping
gpio: pcf857x: share 8/16 bit access functions
gpio: LPC32xx: Driver cleanup
MAINTAINERS: Add Wolfson gpiolib drivers to the Wolfson entry
gpiolib: wm8994: Convert to devm_kzalloc()
gpiolib: wm8994: Use irq_domain mappings for gpios
gpio: add a driver for GPIO pins found on AMD-8111 south bridge chips
gpio/tca6424: merge I2C transactions, remove cast
gpio/of: fix a typo of comment message
-rw-r--r-- | Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt | 2 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/gpio/gpio-samsung.txt | 9 | ||||
-rw-r--r-- | MAINTAINERS | 8 | ||||
-rw-r--r-- | arch/arm/boot/dts/imx51.dtsi | 8 | ||||
-rw-r--r-- | arch/arm/boot/dts/imx53.dtsi | 14 | ||||
-rw-r--r-- | arch/arm/boot/dts/imx6q.dtsi | 14 | ||||
-rw-r--r-- | arch/arm/mach-imx/mm-imx25.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-imx/mm-imx3.c | 7 | ||||
-rw-r--r-- | arch/arm/mach-imx/mm-imx5.c | 40 | ||||
-rw-r--r-- | drivers/gpio/Kconfig | 18 | ||||
-rw-r--r-- | drivers/gpio/Makefile | 2 | ||||
-rw-r--r-- | drivers/gpio/gpio-amd8111.c | 246 | ||||
-rw-r--r-- | drivers/gpio/gpio-arizona.c | 163 | ||||
-rw-r--r-- | drivers/gpio/gpio-lpc32xx.c | 74 | ||||
-rw-r--r-- | drivers/gpio/gpio-mxc.c | 71 | ||||
-rw-r--r-- | drivers/gpio/gpio-omap.c | 10 | ||||
-rw-r--r-- | drivers/gpio/gpio-pca953x.c | 67 | ||||
-rw-r--r-- | drivers/gpio/gpio-pcf857x.c | 93 | ||||
-rw-r--r-- | drivers/gpio/gpio-samsung.c | 5 | ||||
-rw-r--r-- | drivers/gpio/gpio-wm8994.c | 17 | ||||
-rw-r--r-- | drivers/gpio/gpiolib-of.c | 9 | ||||
-rw-r--r-- | drivers/gpio/gpiolib.c | 2 | ||||
-rw-r--r-- | include/linux/i2c/pca953x.h | 2 |
23 files changed, 700 insertions, 191 deletions
diff --git a/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt b/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt index 4f3929713ae..dbd22e0df21 100644 --- a/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt +++ b/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt @@ -22,7 +22,7 @@ Required properties: Example: gpio0: gpio@73f84000 { - compatible = "fsl,imx51-gpio", "fsl,imx31-gpio"; + compatible = "fsl,imx51-gpio", "fsl,imx35-gpio"; reg = <0x73f84000 0x4000>; interrupts = <50 51>; gpio-controller; diff --git a/Documentation/devicetree/bindings/gpio/gpio-samsung.txt b/Documentation/devicetree/bindings/gpio/gpio-samsung.txt index 8f50fe5e6c4..5375625e8cd 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-samsung.txt +++ b/Documentation/devicetree/bindings/gpio/gpio-samsung.txt @@ -11,14 +11,15 @@ Required properties: <[phandle of the gpio controller node] [pin number within the gpio controller] [mux function] - [pull up/down] + [flags and pull up/down] [drive strength]> Values for gpio specifier: - Pin number: is a value between 0 to 7. - - Pull Up/Down: 0 - Pull Up/Down Disabled. - 1 - Pull Down Enabled. - 3 - Pull Up Enabled. + - Flags and Pull Up/Down: 0 - Pull Up/Down Disabled. + 1 - Pull Down Enabled. + 3 - Pull Up Enabled. + Bit 16 (0x00010000) - Input is active low. - Drive Strength: 0 - 1x, 1 - 3x, 2 - 2x, diff --git a/MAINTAINERS b/MAINTAINERS index 429e72cc13f..5b41de49a32 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4961,6 +4961,13 @@ S: Maintained F: drivers/usb/*/*omap* F: arch/arm/*omap*/usb* +OMAP GPIO DRIVER +M: Santosh Shilimkar <santosh.shilimkar@ti.com> +M: Kevin Hilman <khilman@ti.com> +L: linux-omap@vger.kernel.org +S: Maintained +F: drivers/gpio/gpio-omap.c + OMFS FILESYSTEM M: Bob Copeland <me@bobcopeland.com> L: linux-karma-devel@lists.sourceforge.net @@ -7615,6 +7622,7 @@ F: Documentation/hwmon/wm83?? F: arch/arm/mach-s3c64xx/mach-crag6410* F: drivers/clk/clk-wm83*.c F: drivers/leds/leds-wm83*.c +F: drivers/gpio/gpio-*wm*.c F: drivers/hwmon/wm83??-hwmon.c F: drivers/input/misc/wm831x-on.c F: drivers/input/touchscreen/wm831x-ts.c diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi index 922adefdd29..53cbaa3d4f9 100644 --- a/arch/arm/boot/dts/imx51.dtsi +++ b/arch/arm/boot/dts/imx51.dtsi @@ -127,7 +127,7 @@ }; gpio1: gpio@73f84000 { - compatible = "fsl,imx51-gpio", "fsl,imx31-gpio"; + compatible = "fsl,imx51-gpio", "fsl,imx35-gpio"; reg = <0x73f84000 0x4000>; interrupts = <50 51>; gpio-controller; @@ -137,7 +137,7 @@ }; gpio2: gpio@73f88000 { - compatible = "fsl,imx51-gpio", "fsl,imx31-gpio"; + compatible = "fsl,imx51-gpio", "fsl,imx35-gpio"; reg = <0x73f88000 0x4000>; interrupts = <52 53>; gpio-controller; @@ -147,7 +147,7 @@ }; gpio3: gpio@73f8c000 { - compatible = "fsl,imx51-gpio", "fsl,imx31-gpio"; + compatible = "fsl,imx51-gpio", "fsl,imx35-gpio"; reg = <0x73f8c000 0x4000>; interrupts = <54 55>; gpio-controller; @@ -157,7 +157,7 @@ }; gpio4: gpio@73f90000 { - compatible = "fsl,imx51-gpio", "fsl,imx31-gpio"; + compatible = "fsl,imx51-gpio", "fsl,imx35-gpio"; reg = <0x73f90000 0x4000>; interrupts = <56 57>; gpio-controller; diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi index 4e735edc78e..fc79cdc4b4e 100644 --- a/arch/arm/boot/dts/imx53.dtsi +++ b/arch/arm/boot/dts/imx53.dtsi @@ -129,7 +129,7 @@ }; gpio1: gpio@53f84000 { - compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; + compatible = "fsl,imx53-gpio", "fsl,imx35-gpio"; reg = <0x53f84000 0x4000>; interrupts = <50 51>; gpio-controller; @@ -139,7 +139,7 @@ }; gpio2: gpio@53f88000 { - compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; + compatible = "fsl,imx53-gpio", "fsl,imx35-gpio"; reg = <0x53f88000 0x4000>; interrupts = <52 53>; gpio-controller; @@ -149,7 +149,7 @@ }; gpio3: gpio@53f8c000 { - compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; + compatible = "fsl,imx53-gpio", "fsl,imx35-gpio"; reg = <0x53f8c000 0x4000>; interrupts = <54 55>; gpio-controller; @@ -159,7 +159,7 @@ }; gpio4: gpio@53f90000 { - compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; + compatible = "fsl,imx53-gpio", "fsl,imx35-gpio"; reg = <0x53f90000 0x4000>; interrupts = <56 57>; gpio-controller; @@ -197,7 +197,7 @@ }; gpio5: gpio@53fdc000 { - compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; + compatible = "fsl,imx53-gpio", "fsl,imx35-gpio"; reg = <0x53fdc000 0x4000>; interrupts = <103 104>; gpio-controller; @@ -207,7 +207,7 @@ }; gpio6: gpio@53fe0000 { - compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; + compatible = "fsl,imx53-gpio", "fsl,imx35-gpio"; reg = <0x53fe0000 0x4000>; interrupts = <105 106>; gpio-controller; @@ -217,7 +217,7 @@ }; gpio7: gpio@53fe4000 { - compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; + compatible = "fsl,imx53-gpio", "fsl,imx35-gpio"; reg = <0x53fe4000 0x4000>; interrupts = <107 108>; gpio-controller; diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index c25d4958481..3d3c64b014e 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi @@ -277,7 +277,7 @@ }; gpio1: gpio@0209c000 { - compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; + compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; reg = <0x0209c000 0x4000>; interrupts = <0 66 0x04 0 67 0x04>; gpio-controller; @@ -287,7 +287,7 @@ }; gpio2: gpio@020a0000 { - compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; + compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; reg = <0x020a0000 0x4000>; interrupts = <0 68 0x04 0 69 0x04>; gpio-controller; @@ -297,7 +297,7 @@ }; gpio3: gpio@020a4000 { - compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; + compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; reg = <0x020a4000 0x4000>; interrupts = <0 70 0x04 0 71 0x04>; gpio-controller; @@ -307,7 +307,7 @@ }; gpio4: gpio@020a8000 { - compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; + compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; reg = <0x020a8000 0x4000>; interrupts = <0 72 0x04 0 73 0x04>; gpio-controller; @@ -317,7 +317,7 @@ }; gpio5: gpio@020ac000 { - compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; + compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; reg = <0x020ac000 0x4000>; interrupts = <0 74 0x04 0 75 0x04>; gpio-controller; @@ -327,7 +327,7 @@ }; gpio6: gpio@020b0000 { - compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; + compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; reg = <0x020b0000 0x4000>; interrupts = <0 76 0x04 0 77 0x04>; gpio-controller; @@ -337,7 +337,7 @@ }; gpio7: gpio@020b4000 { - compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; + compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; reg = <0x020b4000 0x4000>; interrupts = <0 78 0x04 0 79 0x04>; gpio-controller; diff --git a/arch/arm/mach-imx/mm-imx25.c b/arch/arm/mach-imx/mm-imx25.c index 388928fdb11..f3f5c6542ab 100644 --- a/arch/arm/mach-imx/mm-imx25.c +++ b/arch/arm/mach-imx/mm-imx25.c @@ -89,11 +89,11 @@ static const struct resource imx25_audmux_res[] __initconst = { void __init imx25_soc_init(void) { - /* i.mx25 has the i.mx31 type gpio */ - mxc_register_gpio("imx31-gpio", 0, MX25_GPIO1_BASE_ADDR, SZ_16K, MX25_INT_GPIO1, 0); - mxc_register_gpio("imx31-gpio", 1, MX25_GPIO2_BASE_ADDR, SZ_16K, MX25_INT_GPIO2, 0); - mxc_register_gpio("imx31-gpio", 2, MX25_GPIO3_BASE_ADDR, SZ_16K, MX25_INT_GPIO3, 0); - mxc_register_gpio("imx31-gpio", 3, MX25_GPIO4_BASE_ADDR, SZ_16K, MX25_INT_GPIO4, 0); + /* i.mx25 has the i.mx35 type gpio */ + mxc_register_gpio("imx35-gpio", 0, MX25_GPIO1_BASE_ADDR, SZ_16K, MX25_INT_GPIO1, 0); + mxc_register_gpio("imx35-gpio", 1, MX25_GPIO2_BASE_ADDR, SZ_16K, MX25_INT_GPIO2, 0); + mxc_register_gpio("imx35-gpio", 2, MX25_GPIO3_BASE_ADDR, SZ_16K, MX25_INT_GPIO3, 0); + mxc_register_gpio("imx35-gpio", 3, MX25_GPIO4_BASE_ADDR, SZ_16K, MX25_INT_GPIO4, 0); pinctrl_provide_dummies(); /* i.mx25 has the i.mx35 type sdma */ diff --git a/arch/arm/mach-imx/mm-imx3.c b/arch/arm/mach-imx/mm-imx3.c index fe96105109b..9d2c843bde0 100644 --- a/arch/arm/mach-imx/mm-imx3.c +++ b/arch/arm/mach-imx/mm-imx3.c @@ -272,10 +272,9 @@ void __init imx35_soc_init(void) imx3_init_l2x0(); - /* 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); + mxc_register_gpio("imx35-gpio", 0, MX35_GPIO1_BASE_ADDR, SZ_16K, MX35_INT_GPIO1, 0); + mxc_register_gpio("imx35-gpio", 1, MX35_GPIO2_BASE_ADDR, SZ_16K, MX35_INT_GPIO2, 0); + mxc_register_gpio("imx35-gpio", 2, MX35_GPIO3_BASE_ADDR, SZ_16K, MX35_INT_GPIO3, 0); pinctrl_provide_dummies(); if (to_version == 1) { diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c index f19d604e1b2..52d8f534be1 100644 --- a/arch/arm/mach-imx/mm-imx5.c +++ b/arch/arm/mach-imx/mm-imx5.c @@ -161,13 +161,13 @@ static const struct resource imx53_audmux_res[] __initconst = { void __init imx50_soc_init(void) { - /* i.mx50 has the i.mx31 type gpio */ - mxc_register_gpio("imx31-gpio", 0, MX50_GPIO1_BASE_ADDR, SZ_16K, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH); - mxc_register_gpio("imx31-gpio", 1, MX50_GPIO2_BASE_ADDR, SZ_16K, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH); - mxc_register_gpio("imx31-gpio", 2, MX50_GPIO3_BASE_ADDR, SZ_16K, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH); - mxc_register_gpio("imx31-gpio", 3, MX50_GPIO4_BASE_ADDR, SZ_16K, MX50_INT_GPIO4_LOW, MX50_INT_GPIO4_HIGH); - mxc_register_gpio("imx31-gpio", 4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH); - mxc_register_gpio("imx31-gpio", 5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH); + /* i.mx50 has the i.mx35 type gpio */ + mxc_register_gpio("imx35-gpio", 0, MX50_GPIO1_BASE_ADDR, SZ_16K, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH); + mxc_register_gpio("imx35-gpio", 1, MX50_GPIO2_BASE_ADDR, SZ_16K, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH); + mxc_register_gpio("imx35-gpio", 2, MX50_GPIO3_BASE_ADDR, SZ_16K, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH); + mxc_register_gpio("imx35-gpio", 3, MX50_GPIO4_BASE_ADDR, SZ_16K, MX50_INT_GPIO4_LOW, MX50_INT_GPIO4_HIGH); + mxc_register_gpio("imx35-gpio", 4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH); + mxc_register_gpio("imx35-gpio", 5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH); /* i.mx50 has the i.mx31 type audmux */ platform_device_register_simple("imx31-audmux", 0, imx50_audmux_res, @@ -176,11 +176,11 @@ void __init imx50_soc_init(void) void __init imx51_soc_init(void) { - /* i.mx51 has the i.mx31 type gpio */ - mxc_register_gpio("imx31-gpio", 0, MX51_GPIO1_BASE_ADDR, SZ_16K, MX51_INT_GPIO1_LOW, MX51_INT_GPIO1_HIGH); - mxc_register_gpio("imx31-gpio", 1, MX51_GPIO2_BASE_ADDR, SZ_16K, MX51_INT_GPIO2_LOW, MX51_INT_GPIO2_HIGH); - mxc_register_gpio("imx31-gpio", 2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_INT_GPIO3_LOW, MX51_INT_GPIO3_HIGH); - mxc_register_gpio("imx31-gpio", 3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_INT_GPIO4_LOW, MX51_INT_GPIO4_HIGH); + /* i.mx51 has the i.mx35 type gpio */ + mxc_register_gpio("imx35-gpio", 0, MX51_GPIO1_BASE_ADDR, SZ_16K, MX51_INT_GPIO1_LOW, MX51_INT_GPIO1_HIGH); + mxc_register_gpio("imx35-gpio", 1, MX51_GPIO2_BASE_ADDR, SZ_16K, MX51_INT_GPIO2_LOW, MX51_INT_GPIO2_HIGH); + mxc_register_gpio("imx35-gpio", 2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_INT_GPIO3_LOW, MX51_INT_GPIO3_HIGH); + mxc_register_gpio("imx35-gpio", 3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_INT_GPIO4_LOW, MX51_INT_GPIO4_HIGH); pinctrl_provide_dummies(); @@ -198,14 +198,14 @@ void __init imx51_soc_init(void) void __init imx53_soc_init(void) { - /* i.mx53 has the i.mx31 type gpio */ - mxc_register_gpio("imx31-gpio", 0, MX53_GPIO1_BASE_ADDR, SZ_16K, MX53_INT_GPIO1_LOW, MX53_INT_GPIO1_HIGH); - mxc_register_gpio("imx31-gpio", 1, MX53_GPIO2_BASE_ADDR, SZ_16K, MX53_INT_GPIO2_LOW, MX53_INT_GPIO2_HIGH); - mxc_register_gpio("imx31-gpio", 2, MX53_GPIO3_BASE_ADDR, SZ_16K, MX53_INT_GPIO3_LOW, MX53_INT_GPIO3_HIGH); - mxc_register_gpio("imx31-gpio", 3, MX53_GPIO4_BASE_ADDR, SZ_16K, MX53_INT_GPIO4_LOW, MX53_INT_GPIO4_HIGH); - mxc_register_gpio("imx31-gpio", 4, MX53_GPIO5_BASE_ADDR, SZ_16K, MX53_INT_GPIO5_LOW, MX53_INT_GPIO5_HIGH); - mxc_register_gpio("imx31-gpio", 5, MX53_GPIO6_BASE_ADDR, SZ_16K, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH); - mxc_register_gpio("imx31-gpio", 6, MX53_GPIO7_BASE_ADDR, SZ_16K, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH); + /* i.mx53 has the i.mx35 type gpio */ + mxc_register_gpio("imx35-gpio", 0, MX53_GPIO1_BASE_ADDR, SZ_16K, MX53_INT_GPIO1_LOW, MX53_INT_GPIO1_HIGH); + mxc_register_gpio("imx35-gpio", 1, MX53_GPIO2_BASE_ADDR, SZ_16K, MX53_INT_GPIO2_LOW, MX53_INT_GPIO2_HIGH); + mxc_register_gpio("imx35-gpio", 2, MX53_GPIO3_BASE_ADDR, SZ_16K, MX53_INT_GPIO3_LOW, MX53_INT_GPIO3_HIGH); + mxc_register_gpio("imx35-gpio", 3, MX53_GPIO4_BASE_ADDR, SZ_16K, MX53_INT_GPIO4_LOW, MX53_INT_GPIO4_HIGH); + mxc_register_gpio("imx35-gpio", 4, MX53_GPIO5_BASE_ADDR, SZ_16K, MX53_INT_GPIO5_LOW, MX53_INT_GPIO5_HIGH); + mxc_register_gpio("imx35-gpio", 5, MX53_GPIO6_BASE_ADDR, SZ_16K, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH); + mxc_register_gpio("imx35-gpio", 6, MX53_GPIO7_BASE_ADDR, SZ_16K, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH); pinctrl_provide_dummies(); /* i.mx53 has the i.mx35 type sdma */ diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 542f0c04b69..502b5ea43f4 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -253,6 +253,12 @@ config GPIO_GE_FPGA comment "I2C GPIO expanders:" +config GPIO_ARIZONA + tristate "Wolfson Microelectronics Arizona class devices" + depends on MFD_ARIZONA + help + Support for GPIOs on Wolfson Arizona class devices. + config GPIO_MAX7300 tristate "Maxim MAX7300 GPIO expander" depends on I2C @@ -466,6 +472,18 @@ config GPIO_BT8XX If unsure, say N. +config GPIO_AMD8111 + tristate "AMD 8111 GPIO driver" + depends on PCI + help + The AMD 8111 south bridge contains 32 GPIO pins which can be used. + + Note, that usually system firmware/ACPI handles GPIO pins on their + own and users might easily break their systems with uncarefull usage + of this driver! + + If unsure, say N + config GPIO_LANGWELL bool "Intel Langwell/Penwell GPIO support" depends on PCI && X86 diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 0f55662002c..d37048105a8 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -12,6 +12,8 @@ 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_AMD8111) += gpio-amd8111.o +obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o diff --git a/drivers/gpio/gpio-amd8111.c b/drivers/gpio/gpio-amd8111.c new file mode 100644 index 00000000000..710fafcdd1b --- /dev/null +++ b/drivers/gpio/gpio-amd8111.c @@ -0,0 +1,246 @@ +/* + * GPIO driver for AMD 8111 south bridges + * + * Copyright (c) 2012 Dmitry Eremin-Solenikov + * + * Based on the AMD RNG driver: + * Copyright 2005 (c) MontaVista Software, Inc. + * with the majority of the code coming from: + * + * Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG) + * (c) Copyright 2003 Red Hat Inc <jgarzik@redhat.com> + * + * derived from + * + * Hardware driver for the AMD 768 Random Number Generator (RNG) + * (c) Copyright 2001 Red Hat Inc + * + * derived from + * + * Hardware driver for Intel i810 Random Number Generator (RNG) + * Copyright 2000,2001 Jeff Garzik <jgarzik@pobox.com> + * Copyright 2000,2001 Philipp Rumpf <prumpf@mandrakesoft.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/gpio.h> +#include <linux/pci.h> +#include <linux/spinlock.h> + +#define PMBASE_OFFSET 0xb0 +#define PMBASE_SIZE 0x30 + +#define AMD_REG_GPIO(i) (0x10 + (i)) + +#define AMD_GPIO_LTCH_STS 0x40 /* Latch status, w1 */ +#define AMD_GPIO_RTIN 0x20 /* Real Time in, ro */ +#define AMD_GPIO_DEBOUNCE 0x10 /* Debounce, rw */ +#define AMD_GPIO_MODE_MASK 0x0c /* Pin Mode Select, rw */ +#define AMD_GPIO_MODE_IN 0x00 +#define AMD_GPIO_MODE_OUT 0x04 +/* Enable alternative (e.g. clkout, IRQ, etc) function of the pin */ +#define AMD_GPIO_MODE_ALTFN 0x08 /* Or 0x09 */ +#define AMD_GPIO_X_MASK 0x03 /* In/Out specific, rw */ +#define AMD_GPIO_X_IN_ACTIVEHI 0x01 /* Active High */ +#define AMD_GPIO_X_IN_LATCH 0x02 /* Latched version is selected */ +#define AMD_GPIO_X_OUT_LOW 0x00 +#define AMD_GPIO_X_OUT_HI 0x01 +#define AMD_GPIO_X_OUT_CLK0 0x02 +#define AMD_GPIO_X_OUT_CLK1 0x03 + +/* + * Data for PCI driver interface + * + * This data only exists for exporting the supported + * PCI ids via MODULE_DEVICE_TABLE. We do not actually + * register a pci_driver, because someone else might one day + * want to register another driver on the same PCI id. + */ +static DEFINE_PCI_DEVICE_TABLE(pci_tbl) = { + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_SMBUS), 0 }, + { 0, }, /* terminate list */ +}; +MODULE_DEVICE_TABLE(pci, pci_tbl); + +struct amd_gpio { + struct gpio_chip chip; + u32 pmbase; + void __iomem *pm; + struct pci_dev *pdev; + spinlock_t lock; /* guards hw registers and orig table */ + u8 orig[32]; +}; + +#define to_agp(chip) container_of(chip, struct amd_gpio, chip) + +static int amd_gpio_request(struct gpio_chip *chip, unsigned offset) +{ + struct amd_gpio *agp = to_agp(chip); + + agp->orig[offset] = ioread8(agp->pm + AMD_REG_GPIO(offset)) & + (AMD_GPIO_DEBOUNCE | AMD_GPIO_MODE_MASK | AMD_GPIO_X_MASK); + + dev_dbg(&agp->pdev->dev, "Requested gpio %d, data %x\n", offset, agp->orig[offset]); + + return 0; +} + +static void amd_gpio_free(struct gpio_chip *chip, unsigned offset) +{ + struct amd_gpio *agp = to_agp(chip); + + dev_dbg(&agp->pdev->dev, "Freed gpio %d, data %x\n", offset, agp->orig[offset]); + + iowrite8(agp->orig[offset], agp->pm + AMD_REG_GPIO(offset)); +} + +static void amd_gpio_set(struct gpio_chip *chip, unsigned offset, int value) +{ + struct amd_gpio *agp = to_agp(chip); + u8 temp; + unsigned long flags; + + spin_lock_irqsave(&agp->lock, flags); + temp = ioread8(agp->pm + AMD_REG_GPIO(offset)); + temp = (temp & AMD_GPIO_DEBOUNCE) | AMD_GPIO_MODE_OUT | (value ? AMD_GPIO_X_OUT_HI : AMD_GPIO_X_OUT_LOW); + iowrite8(temp, agp->pm + AMD_REG_GPIO(offset)); + spin_unlock_irqrestore(&agp->lock, flags); + + dev_dbg(&agp->pdev->dev, "Setting gpio %d, value %d, reg=%02x\n", offset, !!value, temp); +} + +static int amd_gpio_get(struct gpio_chip *chip, unsigned offset) +{ + struct amd_gpio *agp = to_agp(chip); + u8 temp; + + temp = ioread8(agp->pm + AMD_REG_GPIO(offset)); + + dev_dbg(&agp->pdev->dev, "Getting gpio %d, reg=%02x\n", offset, temp); + + return (temp & AMD_GPIO_RTIN) ? 1 : 0; +} + +static int amd_gpio_dirout(struct gpio_chip *chip, unsigned offset, int value) +{ + struct amd_gpio *agp = to_agp(chip); + u8 temp; + unsigned long flags; + + spin_lock_irqsave(&agp->lock, flags); + temp = ioread8(agp->pm + AMD_REG_GPIO(offset)); + temp = (temp & AMD_GPIO_DEBOUNCE) | AMD_GPIO_MODE_OUT | (value ? AMD_GPIO_X_OUT_HI : AMD_GPIO_X_OUT_LOW); + iowrite8(temp, agp->pm + AMD_REG_GPIO(offset)); + spin_unlock_irqrestore(&agp->lock, flags); + + dev_dbg(&agp->pdev->dev, "Dirout gpio %d, value %d, reg=%02x\n", offset, !!value, temp); + + return 0; +} + +static int amd_gpio_dirin(struct gpio_chip *chip, unsigned offset) +{ + struct amd_gpio *agp = to_agp(chip); + u8 temp; + unsigned long flags; + + spin_lock_irqsave(&agp->lock, flags); + temp = ioread8(agp->pm + AMD_REG_GPIO(offset)); + temp = (temp & AMD_GPIO_DEBOUNCE) | AMD_GPIO_MODE_IN; + iowrite8(temp, agp->pm + AMD_REG_GPIO(offset)); + spin_unlock_irqrestore(&agp->lock, flags); + + dev_dbg(&agp->pdev->dev, "Dirin gpio %d, reg=%02x\n", offset, temp); + + return 0; +} + +static struct amd_gpio gp = { + .chip = { + .label = "AMD GPIO", + .owner = THIS_MODULE, + .base = -1, + .ngpio = 32, + .request = amd_gpio_request, + .free = amd_gpio_free, + .set = amd_gpio_set, + .get = amd_gpio_get, + .direction_output = amd_gpio_dirout, + .direction_input = amd_gpio_dirin, + }, +}; + +static int __init amd_gpio_init(void) +{ + int err = -ENODEV; + struct pci_dev *pdev = NULL; + const struct pci_device_id *ent; + + + /* We look for our device - AMD South Bridge + * I don't know about a system with two such bridges, + * so we can assume that there is max. one device. + * + * We can't use plain pci_driver mechanism, + * as the device is really a multiple function device, + * main driver that binds to the pci_device is an smbus + * driver and have to find & bind to the device this way. + */ + for_each_pci_dev(pdev) { + ent = pci_match_id(pci_tbl, pdev); + if (ent) + goto found; + } + /* Device not found. */ + goto out; + +found: + err = pci_read_config_dword(pdev, 0x58, &gp.pmbase); + if (err) + goto out; + err = -EIO; + gp.pmbase &= 0x0000FF00; + if (gp.pmbase == 0) + goto out; + if (!request_region(gp.pmbase + PMBASE_OFFSET, PMBASE_SIZE, "AMD GPIO")) { + dev_err(&pdev->dev, "AMD GPIO region 0x%x already in use!\n", + gp.pmbase + PMBASE_OFFSET); + err = -EBUSY; + goto out; + } + gp.pm = ioport_map(gp.pmbase + PMBASE_OFFSET, PMBASE_SIZE); + gp.pdev = pdev; + gp.chip.dev = &pdev->dev; + + spin_lock_init(&gp.lock); + + printk(KERN_INFO "AMD-8111 GPIO detected\n"); + err = gpiochip_add(&gp.chip); + if (err) { + printk(KERN_ERR "GPIO registering failed (%d)\n", + err); + release_region(gp.pmbase + PMBASE_OFFSET, PMBASE_SIZE); + goto out; + } +out: + return err; +} + +static void __exit amd_gpio_exit(void) +{ + int err = gpiochip_remove(&gp.chip); + WARN_ON(err); + ioport_unmap(gp.pm); + release_region(gp.pmbase + PMBASE_OFFSET, PMBASE_SIZE); +} + +module_init(amd_gpio_init); +module_exit(amd_gpio_exit); + +MODULE_AUTHOR("The Linux Kernel team"); +MODULE_DESCRIPTION("GPIO driver for AMD chipsets"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpio/gpio-arizona.c b/drivers/gpio/gpio-arizona.c new file mode 100644 index 00000000000..8740d2eb06f --- /dev/null +++ b/drivers/gpio/gpio-arizona.c @@ -0,0 +1,163 @@ +/* + * gpiolib support for Wolfson Arizona class devices + * + * Copyright 2012 Wolfson Microelectronics PLC. + * + * Author: Mark Brown <broonie@opensource.wolfsonmicro.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/kernel.h> +#include <linux/slab.h> +#include <linux/module.h> +#include <linux/gpio.h> +#include <linux/platform_device.h> +#include <linux/seq_file.h> + +#include <linux/mfd/arizona/core.h> +#include <linux/mfd/arizona/pdata.h> +#include <linux/mfd/arizona/registers.h> + +struct arizona_gpio { + struct arizona *arizona; + struct gpio_chip gpio_chip; +}; + +static inline struct arizona_gpio *to_arizona_gpio(struct gpio_chip *chip) +{ + return container_of(chip, struct arizona_gpio, gpio_chip); +} + +static int arizona_gpio_direction_in(struct gpio_chip *chip, unsigned offset) +{ + struct arizona_gpio *arizona_gpio = to_arizona_gpio(chip); + struct arizona *arizona = arizona_gpio->arizona; + + return regmap_update_bits(arizona->regmap, ARIZONA_GPIO1_CTRL + offset, + ARIZONA_GPN_DIR, ARIZONA_GPN_DIR); +} + +static int arizona_gpio_get(struct gpio_chip *chip, unsigned offset) +{ + struct arizona_gpio *arizona_gpio = to_arizona_gpio(chip); + struct arizona *arizona = arizona_gpio->arizona; + unsigned int val; + int ret; + + ret = regmap_read(arizona->regmap, ARIZONA_GPIO1_CTRL + offset, &val); + if (ret < 0) + return ret; + + if (val & ARIZONA_GPN_LVL) + return 1; + else + return 0; +} + +static int arizona_gpio_direction_out(struct gpio_chip *chip, + unsigned offset, int value) +{ + struct arizona_gpio *arizona_gpio = to_arizona_gpio(chip); + struct arizona *arizona = arizona_gpio->arizona; + + if (value) + value = ARIZONA_GPN_LVL; + + return regmap_update_bits(arizona->regmap, ARIZONA_GPIO1_CTRL + offset, + ARIZONA_GPN_DIR | ARIZONA_GPN_LVL, value); +} + +static void arizona_gpio_set(struct gpio_chip *chip, unsigned offset, int value) +{ + struct arizona_gpio *arizona_gpio = to_arizona_gpio(chip); + struct arizona *arizona = arizona_gpio->arizona; + + if (value) + value = ARIZONA_GPN_LVL; + + regmap_update_bits(arizona->regmap, ARIZONA_GPIO1_CTRL + offset, + ARIZONA_GPN_LVL, value); +} + +static struct gpio_chip template_chip = { + .label = "arizona", + .owner = THIS_MODULE, + .direction_input = arizona_gpio_direction_in, + .get = arizona_gpio_get, + .direction_output = arizona_gpio_direction_out, + .set = arizona_gpio_set, + .can_sleep = 1, +}; + +static int __devinit arizona_gpio_probe(struct platform_device *pdev) +{ + struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); + struct arizona_pdata *pdata = arizona->dev->platform_data; + struct arizona_gpio *arizona_gpio; + int ret; + + arizona_gpio = devm_kzalloc(&pdev->dev, sizeof(*arizona_gpio), + GFP_KERNEL); + if (arizona_gpio == NULL) + return -ENOMEM; + + arizona_gpio->arizona = arizona; + arizona_gpio->gpio_chip = template_chip; + arizona_gpio->gpio_chip.dev = &pdev->dev; + + switch (arizona->type) { + case WM5102: + case WM5110: + arizona_gpio->gpio_chip.ngpio = 5; + break; + default: + dev_err(&pdev->dev, "Unknown chip variant %d\n", + arizona->type); + return -EINVAL; + } + + if (pdata && pdata->gpio_base) + arizona_gpio->gpio_chip.base = pdata->gpio_base; + else + arizona_gpio->gpio_chip.base = -1; + + ret = gpiochip_add(&arizona_gpio->gpio_chip); + if (ret < 0) { + dev_err(&pdev->dev, "Could not register gpiochip, %d\n", + ret); + goto err; + } + + platform_set_drvdata(pdev, arizona_gpio); + + return ret; + +err: + return ret; +} + +static int __devexit arizona_gpio_remove(struct platform_device *pdev) +{ + struct arizona_gpio *arizona_gpio = platform_get_drvdata(pdev); + + return gpiochip_remove(&arizona_gpio->gpio_chip); +} + +static struct platform_driver arizona_gpio_driver = { + .driver.name = "arizona-gpio", + .driver.owner = THIS_MODULE, + .probe = arizona_gpio_probe, + .remove = __devexit_p(arizona_gpio_remove), +}; + +module_platform_driver(arizona_gpio_driver); + +MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); +MODULE_DESCRIPTION("GPIO interface for Arizona devices"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:arizona-gpio"); diff --git a/drivers/gpio/gpio |