diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-26 16:56:38 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-26 16:56:38 -0400 |
| 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 4f3929713ae4..dbd22e0df21e 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: | |||
| 22 | Example: | 22 | Example: |
| 23 | 23 | ||
| 24 | gpio0: gpio@73f84000 { | 24 | gpio0: gpio@73f84000 { |
| 25 | compatible = "fsl,imx51-gpio", "fsl,imx31-gpio"; | 25 | compatible = "fsl,imx51-gpio", "fsl,imx35-gpio"; |
| 26 | reg = <0x73f84000 0x4000>; | 26 | reg = <0x73f84000 0x4000>; |
| 27 | interrupts = <50 51>; | 27 | interrupts = <50 51>; |
| 28 | gpio-controller; | 28 | gpio-controller; |
diff --git a/Documentation/devicetree/bindings/gpio/gpio-samsung.txt b/Documentation/devicetree/bindings/gpio/gpio-samsung.txt index 8f50fe5e6c42..5375625e8cd2 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-samsung.txt +++ b/Documentation/devicetree/bindings/gpio/gpio-samsung.txt | |||
| @@ -11,14 +11,15 @@ Required properties: | |||
| 11 | <[phandle of the gpio controller node] | 11 | <[phandle of the gpio controller node] |
| 12 | [pin number within the gpio controller] | 12 | [pin number within the gpio controller] |
| 13 | [mux function] | 13 | [mux function] |
| 14 | [pull up/down] | 14 | [flags and pull up/down] |
| 15 | [drive strength]> | 15 | [drive strength]> |
| 16 | 16 | ||
| 17 | Values for gpio specifier: | 17 | Values for gpio specifier: |
| 18 | - Pin number: is a value between 0 to 7. | 18 | - Pin number: is a value between 0 to 7. |
| 19 | - Pull Up/Down: 0 - Pull Up/Down Disabled. | 19 | - Flags and Pull Up/Down: 0 - Pull Up/Down Disabled. |
| 20 | 1 - Pull Down Enabled. | 20 | 1 - Pull Down Enabled. |
| 21 | 3 - Pull Up Enabled. | 21 | 3 - Pull Up Enabled. |
| 22 | Bit 16 (0x00010000) - Input is active low. | ||
| 22 | - Drive Strength: 0 - 1x, | 23 | - Drive Strength: 0 - 1x, |
| 23 | 1 - 3x, | 24 | 1 - 3x, |
| 24 | 2 - 2x, | 25 | 2 - 2x, |
diff --git a/MAINTAINERS b/MAINTAINERS index 429e72cc13fc..5b41de49a324 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -4961,6 +4961,13 @@ S: Maintained | |||
| 4961 | F: drivers/usb/*/*omap* | 4961 | F: drivers/usb/*/*omap* |
| 4962 | F: arch/arm/*omap*/usb* | 4962 | F: arch/arm/*omap*/usb* |
| 4963 | 4963 | ||
| 4964 | OMAP GPIO DRIVER | ||
| 4965 | M: Santosh Shilimkar <santosh.shilimkar@ti.com> | ||
| 4966 | M: Kevin Hilman <khilman@ti.com> | ||
| 4967 | L: linux-omap@vger.kernel.org | ||
| 4968 | S: Maintained | ||
| 4969 | F: drivers/gpio/gpio-omap.c | ||
| 4970 | |||
| 4964 | OMFS FILESYSTEM | 4971 | OMFS FILESYSTEM |
| 4965 | M: Bob Copeland <me@bobcopeland.com> | 4972 | M: Bob Copeland <me@bobcopeland.com> |
| 4966 | L: linux-karma-devel@lists.sourceforge.net | 4973 | L: linux-karma-devel@lists.sourceforge.net |
| @@ -7615,6 +7622,7 @@ F: Documentation/hwmon/wm83?? | |||
| 7615 | F: arch/arm/mach-s3c64xx/mach-crag6410* | 7622 | F: arch/arm/mach-s3c64xx/mach-crag6410* |
| 7616 | F: drivers/clk/clk-wm83*.c | 7623 | F: drivers/clk/clk-wm83*.c |
| 7617 | F: drivers/leds/leds-wm83*.c | 7624 | F: drivers/leds/leds-wm83*.c |
| 7625 | F: drivers/gpio/gpio-*wm*.c | ||
| 7618 | F: drivers/hwmon/wm83??-hwmon.c | 7626 | F: drivers/hwmon/wm83??-hwmon.c |
| 7619 | F: drivers/input/misc/wm831x-on.c | 7627 | F: drivers/input/misc/wm831x-on.c |
| 7620 | F: drivers/input/touchscreen/wm831x-ts.c | 7628 | F: drivers/input/touchscreen/wm831x-ts.c |
diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi index 922adefdd291..53cbaa3d4f90 100644 --- a/arch/arm/boot/dts/imx51.dtsi +++ b/arch/arm/boot/dts/imx51.dtsi | |||
| @@ -127,7 +127,7 @@ | |||
| 127 | }; | 127 | }; |
| 128 | 128 | ||
| 129 | gpio1: gpio@73f84000 { | 129 | gpio1: gpio@73f84000 { |
| 130 | compatible = "fsl,imx51-gpio", "fsl,imx31-gpio"; | 130 | compatible = "fsl,imx51-gpio", "fsl,imx35-gpio"; |
| 131 | reg = <0x73f84000 0x4000>; | 131 | reg = <0x73f84000 0x4000>; |
| 132 | interrupts = <50 51>; | 132 | interrupts = <50 51>; |
| 133 | gpio-controller; | 133 | gpio-controller; |
| @@ -137,7 +137,7 @@ | |||
| 137 | }; | 137 | }; |
| 138 | 138 | ||
| 139 | gpio2: gpio@73f88000 { | 139 | gpio2: gpio@73f88000 { |
| 140 | compatible = "fsl,imx51-gpio", "fsl,imx31-gpio"; | 140 | compatible = "fsl,imx51-gpio", "fsl,imx35-gpio"; |
| 141 | reg = <0x73f88000 0x4000>; | 141 | reg = <0x73f88000 0x4000>; |
| 142 | interrupts = <52 53>; | 142 | interrupts = <52 53>; |
| 143 | gpio-controller; | 143 | gpio-controller; |
| @@ -147,7 +147,7 @@ | |||
| 147 | }; | 147 | }; |
| 148 | 148 | ||
| 149 | gpio3: gpio@73f8c000 { | 149 | gpio3: gpio@73f8c000 { |
| 150 | compatible = "fsl,imx51-gpio", "fsl,imx31-gpio"; | 150 | compatible = "fsl,imx51-gpio", "fsl,imx35-gpio"; |
| 151 | reg = <0x73f8c000 0x4000>; | 151 | reg = <0x73f8c000 0x4000>; |
| 152 | interrupts = <54 55>; | 152 | interrupts = <54 55>; |
| 153 | gpio-controller; | 153 | gpio-controller; |
| @@ -157,7 +157,7 @@ | |||
| 157 | }; | 157 | }; |
| 158 | 158 | ||
| 159 | gpio4: gpio@73f90000 { | 159 | gpio4: gpio@73f90000 { |
| 160 | compatible = "fsl,imx51-gpio", "fsl,imx31-gpio"; | 160 | compatible = "fsl,imx51-gpio", "fsl,imx35-gpio"; |
| 161 | reg = <0x73f90000 0x4000>; | 161 | reg = <0x73f90000 0x4000>; |
| 162 | interrupts = <56 57>; | 162 | interrupts = <56 57>; |
| 163 | gpio-controller; | 163 | gpio-controller; |
diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi index 4e735edc78ed..fc79cdc4b4e6 100644 --- a/arch/arm/boot/dts/imx53.dtsi +++ b/arch/arm/boot/dts/imx53.dtsi | |||
| @@ -129,7 +129,7 @@ | |||
| 129 | }; | 129 | }; |
| 130 | 130 | ||
| 131 | gpio1: gpio@53f84000 { | 131 | gpio1: gpio@53f84000 { |
| 132 | compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; | 132 | compatible = "fsl,imx53-gpio", "fsl,imx35-gpio"; |
| 133 | reg = <0x53f84000 0x4000>; | 133 | reg = <0x53f84000 0x4000>; |
| 134 | interrupts = <50 51>; | 134 | interrupts = <50 51>; |
| 135 | gpio-controller; | 135 | gpio-controller; |
| @@ -139,7 +139,7 @@ | |||
| 139 | }; | 139 | }; |
| 140 | 140 | ||
| 141 | gpio2: gpio@53f88000 { | 141 | gpio2: gpio@53f88000 { |
| 142 | compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; | 142 | compatible = "fsl,imx53-gpio", "fsl,imx35-gpio"; |
| 143 | reg = <0x53f88000 0x4000>; | 143 | reg = <0x53f88000 0x4000>; |
| 144 | interrupts = <52 53>; | 144 | interrupts = <52 53>; |
| 145 | gpio-controller; | 145 | gpio-controller; |
| @@ -149,7 +149,7 @@ | |||
| 149 | }; | 149 | }; |
| 150 | 150 | ||
| 151 | gpio3: gpio@53f8c000 { | 151 | gpio3: gpio@53f8c000 { |
| 152 | compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; | 152 | compatible = "fsl,imx53-gpio", "fsl,imx35-gpio"; |
| 153 | reg = <0x53f8c000 0x4000>; | 153 | reg = <0x53f8c000 0x4000>; |
| 154 | interrupts = <54 55>; | 154 | interrupts = <54 55>; |
| 155 | gpio-controller; | 155 | gpio-controller; |
| @@ -159,7 +159,7 @@ | |||
| 159 | }; | 159 | }; |
| 160 | 160 | ||
| 161 | gpio4: gpio@53f90000 { | 161 | gpio4: gpio@53f90000 { |
| 162 | compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; | 162 | compatible = "fsl,imx53-gpio", "fsl,imx35-gpio"; |
| 163 | reg = <0x53f90000 0x4000>; | 163 | reg = <0x53f90000 0x4000>; |
| 164 | interrupts = <56 57>; | 164 | interrupts = <56 57>; |
| 165 | gpio-controller; | 165 | gpio-controller; |
| @@ -197,7 +197,7 @@ | |||
| 197 | }; | 197 | }; |
| 198 | 198 | ||
| 199 | gpio5: gpio@53fdc000 { | 199 | gpio5: gpio@53fdc000 { |
| 200 | compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; | 200 | compatible = "fsl,imx53-gpio", "fsl,imx35-gpio"; |
| 201 | reg = <0x53fdc000 0x4000>; | 201 | reg = <0x53fdc000 0x4000>; |
| 202 | interrupts = <103 104>; | 202 | interrupts = <103 104>; |
| 203 | gpio-controller; | 203 | gpio-controller; |
| @@ -207,7 +207,7 @@ | |||
| 207 | }; | 207 | }; |
| 208 | 208 | ||
| 209 | gpio6: gpio@53fe0000 { | 209 | gpio6: gpio@53fe0000 { |
| 210 | compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; | 210 | compatible = "fsl,imx53-gpio", "fsl,imx35-gpio"; |
| 211 | reg = <0x53fe0000 0x4000>; | 211 | reg = <0x53fe0000 0x4000>; |
| 212 | interrupts = <105 106>; | 212 | interrupts = <105 106>; |
| 213 | gpio-controller; | 213 | gpio-controller; |
| @@ -217,7 +217,7 @@ | |||
| 217 | }; | 217 | }; |
| 218 | 218 | ||
| 219 | gpio7: gpio@53fe4000 { | 219 | gpio7: gpio@53fe4000 { |
| 220 | compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; | 220 | compatible = "fsl,imx53-gpio", "fsl,imx35-gpio"; |
| 221 | reg = <0x53fe4000 0x4000>; | 221 | reg = <0x53fe4000 0x4000>; |
| 222 | interrupts = <107 108>; | 222 | interrupts = <107 108>; |
| 223 | gpio-controller; | 223 | gpio-controller; |
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index c25d49584814..3d3c64b014e6 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi | |||
| @@ -277,7 +277,7 @@ | |||
| 277 | }; | 277 | }; |
| 278 | 278 | ||
| 279 | gpio1: gpio@0209c000 { | 279 | gpio1: gpio@0209c000 { |
| 280 | compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; | 280 | compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; |
| 281 | reg = <0x0209c000 0x4000>; | 281 | reg = <0x0209c000 0x4000>; |
| 282 | interrupts = <0 66 0x04 0 67 0x04>; | 282 | interrupts = <0 66 0x04 0 67 0x04>; |
| 283 | gpio-controller; | 283 | gpio-controller; |
| @@ -287,7 +287,7 @@ | |||
| 287 | }; | 287 | }; |
| 288 | 288 | ||
| 289 | gpio2: gpio@020a0000 { | 289 | gpio2: gpio@020a0000 { |
| 290 | compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; | 290 | compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; |
| 291 | reg = <0x020a0000 0x4000>; | 291 | reg = <0x020a0000 0x4000>; |
| 292 | interrupts = <0 68 0x04 0 69 0x04>; | 292 | interrupts = <0 68 0x04 0 69 0x04>; |
| 293 | gpio-controller; | 293 | gpio-controller; |
| @@ -297,7 +297,7 @@ | |||
| 297 | }; | 297 | }; |
| 298 | 298 | ||
| 299 | gpio3: gpio@020a4000 { | 299 | gpio3: gpio@020a4000 { |
| 300 | compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; | 300 | compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; |
| 301 | reg = <0x020a4000 0x4000>; | 301 | reg = <0x020a4000 0x4000>; |
| 302 | interrupts = <0 70 0x04 0 71 0x04>; | 302 | interrupts = <0 70 0x04 0 71 0x04>; |
| 303 | gpio-controller; | 303 | gpio-controller; |
| @@ -307,7 +307,7 @@ | |||
| 307 | }; | 307 | }; |
| 308 | 308 | ||
| 309 | gpio4: gpio@020a8000 { | 309 | gpio4: gpio@020a8000 { |
| 310 | compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; | 310 | compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; |
| 311 | reg = <0x020a8000 0x4000>; | 311 | reg = <0x020a8000 0x4000>; |
| 312 | interrupts = <0 72 0x04 0 73 0x04>; | 312 | interrupts = <0 72 0x04 0 73 0x04>; |
| 313 | gpio-controller; | 313 | gpio-controller; |
| @@ -317,7 +317,7 @@ | |||
| 317 | }; | 317 | }; |
| 318 | 318 | ||
| 319 | gpio5: gpio@020ac000 { | 319 | gpio5: gpio@020ac000 { |
| 320 | compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; | 320 | compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; |
| 321 | reg = <0x020ac000 0x4000>; | 321 | reg = <0x020ac000 0x4000>; |
| 322 | interrupts = <0 74 0x04 0 75 0x04>; | 322 | interrupts = <0 74 0x04 0 75 0x04>; |
| 323 | gpio-controller; | 323 | gpio-controller; |
| @@ -327,7 +327,7 @@ | |||
| 327 | }; | 327 | }; |
| 328 | 328 | ||
| 329 | gpio6: gpio@020b0000 { | 329 | gpio6: gpio@020b0000 { |
| 330 | compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; | 330 | compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; |
| 331 | reg = <0x020b0000 0x4000>; | 331 | reg = <0x020b0000 0x4000>; |
| 332 | interrupts = <0 76 0x04 0 77 0x04>; | 332 | interrupts = <0 76 0x04 0 77 0x04>; |
| 333 | gpio-controller; | 333 | gpio-controller; |
| @@ -337,7 +337,7 @@ | |||
| 337 | }; | 337 | }; |
| 338 | 338 | ||
| 339 | gpio7: gpio@020b4000 { | 339 | gpio7: gpio@020b4000 { |
| 340 | compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; | 340 | compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; |
| 341 | reg = <0x020b4000 0x4000>; | 341 | reg = <0x020b4000 0x4000>; |
| 342 | interrupts = <0 78 0x04 0 79 0x04>; | 342 | interrupts = <0 78 0x04 0 79 0x04>; |
| 343 | gpio-controller; | 343 | gpio-controller; |
diff --git a/arch/arm/mach-imx/mm-imx25.c b/arch/arm/mach-imx/mm-imx25.c index 388928fdb11a..f3f5c6542ab4 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 = { | |||
| 89 | 89 | ||
| 90 | void __init imx25_soc_init(void) | 90 | void __init imx25_soc_init(void) |
| 91 | { | 91 | { |
| 92 | /* i.mx25 has the i.mx31 type gpio */ | 92 | /* i.mx25 has the i.mx35 type gpio */ |
| 93 | mxc_register_gpio("imx31-gpio", 0, MX25_GPIO1_BASE_ADDR, SZ_16K, MX25_INT_GPIO1, 0); | 93 | mxc_register_gpio("imx35-gpio", 0, MX25_GPIO1_BASE_ADDR, SZ_16K, MX25_INT_GPIO1, 0); |
| 94 | mxc_register_gpio("imx31-gpio", 1, MX25_GPIO2_BASE_ADDR, SZ_16K, MX25_INT_GPIO2, 0); | 94 | mxc_register_gpio("imx35-gpio", 1, MX25_GPIO2_BASE_ADDR, SZ_16K, MX25_INT_GPIO2, 0); |
| 95 | mxc_register_gpio("imx31-gpio", 2, MX25_GPIO3_BASE_ADDR, SZ_16K, MX25_INT_GPIO3, 0); | 95 | mxc_register_gpio("imx35-gpio", 2, MX25_GPIO3_BASE_ADDR, SZ_16K, MX25_INT_GPIO3, 0); |
| 96 | mxc_register_gpio("imx31-gpio", 3, MX25_GPIO4_BASE_ADDR, SZ_16K, MX25_INT_GPIO4, 0); | 96 | mxc_register_gpio("imx35-gpio", 3, MX25_GPIO4_BASE_ADDR, SZ_16K, MX25_INT_GPIO4, 0); |
| 97 | 97 | ||
| 98 | pinctrl_provide_dummies(); | 98 | pinctrl_provide_dummies(); |
| 99 | /* i.mx25 has the i.mx35 type sdma */ | 99 | /* 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 fe96105109b3..9d2c843bde02 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) | |||
| 272 | 272 | ||
| 273 | imx3_init_l2x0(); | 273 | imx3_init_l2x0(); |
| 274 | 274 | ||
| 275 | /* i.mx35 has the i.mx31 type gpio */ | 275 | mxc_register_gpio("imx35-gpio", 0, MX35_GPIO1_BASE_ADDR, SZ_16K, MX35_INT_GPIO1, 0); |
| 276 | mxc_register_gpio("imx31-gpio", 0, MX35_GPIO1_BASE_ADDR, SZ_16K, MX35_INT_GPIO1, 0); | 276 | mxc_register_gpio("imx35-gpio", 1, MX35_GPIO2_BASE_ADDR, SZ_16K, MX35_INT_GPIO2, 0); |
| 277 | mxc_register_gpio("imx31-gpio", 1, MX35_GPIO2_BASE_ADDR, SZ_16K, MX35_INT_GPIO2, 0); | 277 | mxc_register_gpio("imx35-gpio", 2, MX35_GPIO3_BASE_ADDR, SZ_16K, MX35_INT_GPIO3, 0); |
| 278 | mxc_register_gpio("imx31-gpio", 2, MX35_GPIO3_BASE_ADDR, SZ_16K, MX35_INT_GPIO3, 0); | ||
| 279 | 278 | ||
| 280 | pinctrl_provide_dummies(); | 279 | pinctrl_provide_dummies(); |
| 281 | if (to_version == 1) { | 280 | if (to_version == 1) { |
diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c index f19d604e1b2a..52d8f534be10 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 = { | |||
| 161 | 161 | ||
| 162 | void __init imx50_soc_init(void) | 162 | void __init imx50_soc_init(void) |
| 163 | { | 163 | { |
| 164 | /* i.mx50 has the i.mx31 type gpio */ | 164 | /* i.mx50 has the i.mx35 type gpio */ |
| 165 | mxc_register_gpio("imx31-gpio", 0, MX50_GPIO1_BASE_ADDR, SZ_16K, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH); | 165 | mxc_register_gpio("imx35-gpio", 0, MX50_GPIO1_BASE_ADDR, SZ_16K, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH); |
| 166 | mxc_register_gpio("imx31-gpio", 1, MX50_GPIO2_BASE_ADDR, SZ_16K, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH); | 166 | mxc_register_gpio("imx35-gpio", 1, MX50_GPIO2_BASE_ADDR, SZ_16K, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH); |
| 167 | mxc_register_gpio("imx31-gpio", 2, MX50_GPIO3_BASE_ADDR, SZ_16K, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH); | 167 | mxc_register_gpio("imx35-gpio", 2, MX50_GPIO3_BASE_ADDR, SZ_16K, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH); |
| 168 | mxc_register_gpio("imx31-gpio", 3, MX50_GPIO4_BASE_ADDR, SZ_16K, MX50_INT_GPIO4_LOW, MX50_INT_GPIO4_HIGH); | 168 | mxc_register_gpio("imx35-gpio", 3, MX50_GPIO4_BASE_ADDR, SZ_16K, MX50_INT_GPIO4_LOW, MX50_INT_GPIO4_HIGH); |
| 169 | mxc_register_gpio("imx31-gpio", 4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH); | 169 | mxc_register_gpio("imx35-gpio", 4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH); |
| 170 | mxc_register_gpio("imx31-gpio", 5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH); | 170 | mxc_register_gpio("imx35-gpio", 5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH); |
| 171 | 171 | ||
| 172 | /* i.mx50 has the i.mx31 type audmux */ | 172 | /* i.mx50 has the i.mx31 type audmux */ |
| 173 | platform_device_register_simple("imx31-audmux", 0, imx50_audmux_res, | 173 | platform_device_register_simple("imx31-audmux", 0, imx50_audmux_res, |
| @@ -176,11 +176,11 @@ void __init imx50_soc_init(void) | |||
| 176 | 176 | ||
| 177 | void __init imx51_soc_init(void) | 177 | void __init imx51_soc_init(void) |
| 178 | { | 178 | { |
| 179 | /* i.mx51 has the i.mx31 type gpio */ | 179 | /* i.mx51 has the i.mx35 type gpio */ |
| 180 | mxc_register_gpio("imx31-gpio", 0, MX51_GPIO1_BASE_ADDR, SZ_16K, MX51_INT_GPIO1_LOW, MX51_INT_GPIO1_HIGH); | 180 | mxc_register_gpio("imx35-gpio", 0, MX51_GPIO1_BASE_ADDR, SZ_16K, MX51_INT_GPIO1_LOW, MX51_INT_GPIO1_HIGH); |
| 181 | mxc_register_gpio("imx31-gpio", 1, MX51_GPIO2_BASE_ADDR, SZ_16K, MX51_INT_GPIO2_LOW, MX51_INT_GPIO2_HIGH); | 181 | mxc_register_gpio("imx35-gpio", 1, MX51_GPIO2_BASE_ADDR, SZ_16K, MX51_INT_GPIO2_LOW, MX51_INT_GPIO2_HIGH); |
| 182 | mxc_register_gpio("imx31-gpio", 2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_INT_GPIO3_LOW, MX51_INT_GPIO3_HIGH); | 182 | mxc_register_gpio("imx35-gpio", 2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_INT_GPIO3_LOW, MX51_INT_GPIO3_HIGH); |
| 183 | mxc_register_gpio("imx31-gpio", 3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_INT_GPIO4_LOW, MX51_INT_GPIO4_HIGH); | 183 | mxc_register_gpio("imx35-gpio", 3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_INT_GPIO4_LOW, MX51_INT_GPIO4_HIGH); |
| 184 | 184 | ||
| 185 | pinctrl_provide_dummies(); | 185 | pinctrl_provide_dummies(); |
| 186 | 186 | ||
| @@ -198,14 +198,14 @@ void __init imx51_soc_init(void) | |||
| 198 | 198 | ||
| 199 | void __init imx53_soc_init(void) | 199 | void __init imx53_soc_init(void) |
| 200 | { | 200 | { |
| 201 | /* i.mx53 has the i.mx31 type gpio */ | 201 | /* i.mx53 has the i.mx35 type gpio */ |
| 202 | mxc_register_gpio("imx31-gpio", 0, MX53_GPIO1_BASE_ADDR, SZ_16K, MX53_INT_GPIO1_LOW, MX53_INT_GPIO1_HIGH); | 202 | mxc_register_gpio("imx35-gpio", 0, MX53_GPIO1_BASE_ADDR, SZ_16K, MX53_INT_GPIO1_LOW, MX53_INT_GPIO1_HIGH); |
| 203 | mxc_register_gpio("imx31-gpio", 1, MX53_GPIO2_BASE_ADDR, SZ_16K, MX53_INT_GPIO2_LOW, MX53_INT_GPIO2_HIGH); | 203 | mxc_register_gpio("imx35-gpio", 1, MX53_GPIO2_BASE_ADDR, SZ_16K, MX53_INT_GPIO2_LOW, MX53_INT_GPIO2_HIGH); |
| 204 | mxc_register_gpio("imx31-gpio", 2, MX53_GPIO3_BASE_ADDR, SZ_16K, MX53_INT_GPIO3_LOW, MX53_INT_GPIO3_HIGH); | 204 | mxc_register_gpio("imx35-gpio", 2, MX53_GPIO3_BASE_ADDR, SZ_16K, MX53_INT_GPIO3_LOW, MX53_INT_GPIO3_HIGH); |
| 205 | mxc_register_gpio("imx31-gpio", 3, MX53_GPIO4_BASE_ADDR, SZ_16K, MX53_INT_GPIO4_LOW, MX53_INT_GPIO4_HIGH); | 205 | mxc_register_gpio("imx35-gpio", 3, MX53_GPIO4_BASE_ADDR, SZ_16K, MX53_INT_GPIO4_LOW, MX53_INT_GPIO4_HIGH); |
| 206 | mxc_register_gpio("imx31-gpio", 4, MX53_GPIO5_BASE_ADDR, SZ_16K, MX53_INT_GPIO5_LOW, MX53_INT_GPIO5_HIGH); | 206 | mxc_register_gpio("imx35-gpio", 4, MX53_GPIO5_BASE_ADDR, SZ_16K, MX53_INT_GPIO5_LOW, MX53_INT_GPIO5_HIGH); |
| 207 | mxc_register_gpio("imx31-gpio", 5, MX53_GPIO6_BASE_ADDR, SZ_16K, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH); | 207 | mxc_register_gpio("imx35-gpio", 5, MX53_GPIO6_BASE_ADDR, SZ_16K, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH); |
| 208 | mxc_register_gpio("imx31-gpio", 6, MX53_GPIO7_BASE_ADDR, SZ_16K, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH); | 208 | mxc_register_gpio("imx35-gpio", 6, MX53_GPIO7_BASE_ADDR, SZ_16K, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH); |
| 209 | 209 | ||
| 210 | pinctrl_provide_dummies(); | 210 | pinctrl_provide_dummies(); |
| 211 | /* i.mx53 has the i.mx35 type sdma */ | 211 | /* i.mx53 has the i.mx35 type sdma */ |
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 542f0c04b695..502b5ea43f4f 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
| @@ -253,6 +253,12 @@ config GPIO_GE_FPGA | |||
| 253 | 253 | ||
| 254 | comment "I2C GPIO expanders:" | 254 | comment "I2C GPIO expanders:" |
| 255 | 255 | ||
| 256 | config GPIO_ARIZONA | ||
| 257 | tristate "Wolfson Microelectronics Arizona class devices" | ||
| 258 | depends on MFD_ARIZONA | ||
| 259 | help | ||
| 260 | Support for GPIOs on Wolfson Arizona class devices. | ||
| 261 | |||
| 256 | config GPIO_MAX7300 | 262 | config GPIO_MAX7300 |
| 257 | tristate "Maxim MAX7300 GPIO expander" | 263 | tristate "Maxim MAX7300 GPIO expander" |
| 258 | depends on I2C | 264 | depends on I2C |
| @@ -466,6 +472,18 @@ config GPIO_BT8XX | |||
| 466 | 472 | ||
| 467 | If unsure, say N. | 473 | If unsure, say N. |
| 468 | 474 | ||
| 475 | config GPIO_AMD8111 | ||
| 476 | tristate "AMD 8111 GPIO driver" | ||
| 477 | depends on PCI | ||
| 478 | help | ||
| 479 | The AMD 8111 south bridge contains 32 GPIO pins which can be used. | ||
| 480 | |||
| 481 | Note, that usually system firmware/ACPI handles GPIO pins on their | ||
| 482 | own and users might easily break their systems with uncarefull usage | ||
| 483 | of this driver! | ||
| 484 | |||
| 485 | If unsure, say N | ||
| 486 | |||
| 469 | config GPIO_LANGWELL | 487 | config GPIO_LANGWELL |
| 470 | bool "Intel Langwell/Penwell GPIO support" | 488 | bool "Intel Langwell/Penwell GPIO support" |
| 471 | depends on PCI && X86 | 489 | depends on PCI && X86 |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 0f55662002c3..d37048105a87 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
| @@ -12,6 +12,8 @@ obj-$(CONFIG_GPIO_74X164) += gpio-74x164.o | |||
| 12 | obj-$(CONFIG_GPIO_AB8500) += gpio-ab8500.o | 12 | obj-$(CONFIG_GPIO_AB8500) += gpio-ab8500.o |
| 13 | obj-$(CONFIG_GPIO_ADP5520) += gpio-adp5520.o | 13 | obj-$(CONFIG_GPIO_ADP5520) += gpio-adp5520.o |
| 14 | obj-$(CONFIG_GPIO_ADP5588) += gpio-adp5588.o | 14 | obj-$(CONFIG_GPIO_ADP5588) += gpio-adp5588.o |
| 15 | obj-$(CONFIG_GPIO_AMD8111) += gpio-amd8111.o | ||
| 16 | obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o | ||
| 15 | obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o | 17 | obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o |
| 16 | obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o | 18 | obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o |
| 17 | obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o | 19 | 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 000000000000..710fafcdd1b1 --- /dev/null +++ b/drivers/gpio/gpio-amd8111.c | |||
| @@ -0,0 +1,246 @@ | |||
| 1 | /* | ||
| 2 | * GPIO driver for AMD 8111 south bridges | ||
| 3 | * | ||
| 4 | * Copyright (c) 2012 Dmitry Eremin-Solenikov | ||
| 5 | * | ||
| 6 | * Based on the AMD RNG driver: | ||
| 7 | * Copyright 2005 (c) MontaVista Software, Inc. | ||
| 8 | * with the majority of the code coming from: | ||
| 9 | * | ||
| 10 | * Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG) | ||
| 11 | * (c) Copyright 2003 Red Hat Inc <jgarzik@redhat.com> | ||
| 12 | * | ||
| 13 | * derived from | ||
| 14 | * | ||
| 15 | * Hardware driver for the AMD 768 Random Number Generator (RNG) | ||
| 16 | * (c) Copyright 2001 Red Hat Inc | ||
| 17 | * | ||
| 18 | * derived from | ||
| 19 | * | ||
| 20 | * Hardware driver for Intel i810 Random Number Generator (RNG) | ||
| 21 | * Copyright 2000,2001 Jeff Garzik <jgarzik@pobox.com> | ||
| 22 | * Copyright 2000,2001 Philipp Rumpf <prumpf@mandrakesoft.com> | ||
| 23 | * | ||
| 24 | * This file is licensed under the terms of the GNU General Public | ||
| 25 | * License version 2. This program is licensed "as is" without any | ||
| 26 | * warranty of any kind, whether express or implied. | ||
| 27 | */ | ||
| 28 | #include <linux/module.h> | ||
| 29 | #include <linux/kernel.h> | ||
| 30 | #include <linux/gpio.h> | ||
| 31 | #include <linux/pci.h> | ||
| 32 | #include <linux/spinlock.h> | ||
| 33 | |||
| 34 | #define PMBASE_OFFSET 0xb0 | ||
| 35 | #define PMBASE_SIZE 0x30 | ||
| 36 | |||
| 37 | #define AMD_REG_GPIO(i) (0x10 + (i)) | ||
| 38 | |||
| 39 | #define AMD_GPIO_LTCH_STS 0x40 /* Latch status, w1 */ | ||
| 40 | #define AMD_GPIO_RTIN 0x20 /* Real Time in, ro */ | ||
| 41 | #define AMD_GPIO_DEBOUNCE 0x10 /* Debounce, rw */ | ||
| 42 | #define AMD_GPIO_MODE_MASK 0x0c /* Pin Mode Select, rw */ | ||
| 43 | #define AMD_GPIO_MODE_IN 0x00 | ||
| 44 | #define AMD_GPIO_MODE_OUT 0x04 | ||
| 45 | /* Enable alternative (e.g. clkout, IRQ, etc) function of the pin */ | ||
| 46 | #define AMD_GPIO_MODE_ALTFN 0x08 /* Or 0x09 */ | ||
| 47 | #define AMD_GPIO_X_MASK 0x03 /* In/Out specific, rw */ | ||
| 48 | #define AMD_GPIO_X_IN_ACTIVEHI 0x01 /* Active High */ | ||
| 49 | #define AMD_GPIO_X_IN_LATCH 0x02 /* Latched version is selected */ | ||
| 50 | #define AMD_GPIO_X_OUT_LOW 0x00 | ||
| 51 | #define AMD_GPIO_X_OUT_HI 0x01 | ||
| 52 | #define AMD_GPIO_X_OUT_CLK0 0x02 | ||
| 53 | #define AMD_GPIO_X_OUT_CLK1 0x03 | ||
| 54 | |||
| 55 | /* | ||
| 56 | * Data for PCI driver interface | ||
| 57 | * | ||
| 58 | * This data only exists for exporting the supported | ||
| 59 | * PCI ids via MODULE_DEVICE_TABLE. We do not actually | ||
| 60 | * register a pci_driver, because someone else might one day | ||
| 61 | * want to register another driver on the same PCI id. | ||
| 62 | */ | ||
| 63 | static DEFINE_PCI_DEVICE_TABLE(pci_tbl) = { | ||
| 64 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_SMBUS), 0 }, | ||
| 65 | { 0, }, /* terminate list */ | ||
| 66 | }; | ||
| 67 | MODULE_DEVICE_TABLE(pci, pci_tbl); | ||
| 68 | |||
| 69 | struct amd_gpio { | ||
| 70 | struct gpio_chip chip; | ||
| 71 | u32 pmbase; | ||
| 72 | void __iomem *pm; | ||
| 73 | struct pci_dev *pdev; | ||
| 74 | spinlock_t lock; /* guards hw registers and orig table */ | ||
| 75 | u8 orig[32]; | ||
| 76 | }; | ||
| 77 | |||
| 78 | #define to_agp(chip) container_of(chip, struct amd_gpio, chip) | ||
| 79 | |||
| 80 | static int amd_gpio_request(struct gpio_chip *chip, unsigned offset) | ||
| 81 | { | ||
| 82 | struct amd_gpio *agp = to_agp(chip); | ||
| 83 | |||
| 84 | agp->orig[offset] = ioread8(agp->pm + AMD_REG_GPIO(offset)) & | ||
| 85 | (AMD_GPIO_DEBOUNCE | AMD_GPIO_MODE_MASK | AMD_GPIO_X_MASK); | ||
| 86 | |||
| 87 | dev_dbg(&agp->pdev->dev, "Requested gpio %d, data %x\n", offset, agp->orig[offset]); | ||
| 88 | |||
| 89 | return 0; | ||
| 90 | } | ||
| 91 | |||
| 92 | static void amd_gpio_free(struct gpio_chip *chip, unsigned offset) | ||
| 93 | { | ||
| 94 | struct amd_gpio *agp = to_agp(chip); | ||
| 95 | |||
| 96 | dev_dbg(&agp->pdev->dev, "Freed gpio %d, data %x\n", offset, agp->orig[offset]); | ||
| 97 | |||
| 98 | iowrite8(agp->orig[offset], agp->pm + AMD_REG_GPIO(offset)); | ||
| 99 | } | ||
| 100 | |||
| 101 | static void amd_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
| 102 | { | ||
| 103 | struct amd_gpio *agp = to_agp(chip); | ||
| 104 | u8 temp; | ||
| 105 | unsigned long flags; | ||
| 106 | |||
| 107 | spin_lock_irqsave(&agp->lock, flags); | ||
| 108 | temp = ioread8(agp->pm + AMD_REG_GPIO(offset)); | ||
| 109 | temp = (temp & AMD_GPIO_DEBOUNCE) | AMD_GPIO_MODE_OUT | (value ? AMD_GPIO_X_OUT_HI : AMD_GPIO_X_OUT_LOW); | ||
| 110 | iowrite8(temp, agp->pm + AMD_REG_GPIO(offset)); | ||
| 111 | spin_unlock_irqrestore(&agp->lock, flags); | ||
| 112 | |||
| 113 | dev_dbg(&agp->pdev->dev, "Setting gpio %d, value %d, reg=%02x\n", offset, !!value, temp); | ||
| 114 | } | ||
| 115 | |||
| 116 | static int amd_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
| 117 | { | ||
| 118 | struct amd_gpio *agp = to_agp(chip); | ||
| 119 | u8 temp; | ||
| 120 | |||
| 121 | temp = ioread8(agp->pm + AMD_REG_GPIO(offset)); | ||
| 122 | |||
| 123 | dev_dbg(&agp->pdev->dev, "Getting gpio %d, reg=%02x\n", offset, temp); | ||
| 124 | |||
| 125 | return (temp & AMD_GPIO_RTIN) ? 1 : 0; | ||
| 126 | } | ||
| 127 | |||
| 128 | static int amd_gpio_dirout(struct gpio_chip *chip, unsigned offset, int value) | ||
| 129 | { | ||
| 130 | struct amd_gpio *agp = to_agp(chip); | ||
| 131 | u8 temp; | ||
| 132 | unsigned long flags; | ||
| 133 | |||
| 134 | spin_lock_irqsave(&agp->lock, flags); | ||
| 135 | temp = ioread8(agp->pm + AMD_REG_GPIO(offset)); | ||
| 136 | temp = (temp & AMD_GPIO_DEBOUNCE) | AMD_GPIO_MODE_OUT | (value ? AMD_GPIO_X_OUT_HI : AMD_GPIO_X_OUT_LOW); | ||
| 137 | iowrite8(temp, agp->pm + AMD_REG_GPIO(offset)); | ||
| 138 | spin_unlock_irqrestore(&agp->lock, flags); | ||
| 139 | |||
| 140 | dev_dbg(&agp->pdev->dev, "Dirout gpio %d, value %d, reg=%02x\n", offset, !!value, temp); | ||
| 141 | |||
| 142 | return 0; | ||
| 143 | } | ||
| 144 | |||
| 145 | static int amd_gpio_dirin(struct gpio_chip *chip, unsigned offset) | ||
| 146 | { | ||
| 147 | struct amd_gpio *agp = to_agp(chip); | ||
| 148 | u8 temp; | ||
| 149 | unsigned long flags; | ||
| 150 | |||
| 151 | spin_lock_irqsave(&agp->lock, flags); | ||
| 152 | temp = ioread8(agp->pm + AMD_REG_GPIO(offset)); | ||
| 153 | temp = (temp & AMD_GPIO_DEBOUNCE) | AMD_GPIO_MODE_IN; | ||
| 154 | iowrite8(temp, agp->pm + AMD_REG_GPIO(offset)); | ||
| 155 | spin_unlock_irqrestore(&agp->lock, flags); | ||
| 156 | |||
| 157 | dev_dbg(&agp->pdev->dev, "Dirin gpio %d, reg=%02x\n", offset, temp); | ||
| 158 | |||
| 159 | return 0; | ||
| 160 | } | ||
| 161 | |||
| 162 | static struct amd_gpio gp = { | ||
| 163 | .chip = { | ||
| 164 | .label = "AMD GPIO", | ||
| 165 | .owner = THIS_MODULE, | ||
| 166 | .base = -1, | ||
| 167 | .ngpio = 32, | ||
| 168 | .request = amd_gpio_request, | ||
| 169 | .free = amd_gpio_free, | ||
| 170 | .set = amd_gpio_set, | ||
| 171 | .get = amd_gpio_get, | ||
| 172 | .direction_output = amd_gpio_dirout, | ||
| 173 | .direction_input = amd_gpio_dirin, | ||
| 174 | }, | ||
| 175 | }; | ||
| 176 | |||
| 177 | static int __init amd_gpio_init(void) | ||
| 178 | { | ||
| 179 | int err = -ENODEV; | ||
| 180 | struct pci_dev *pdev = NULL; | ||
| 181 | const struct pci_device_id *ent; | ||
| 182 | |||
| 183 | |||
| 184 | /* We look for our device - AMD South Bridge | ||
| 185 | * I don't know about a system with two such bridges, | ||
| 186 | * so we can assume that there is max. one device. | ||
| 187 | * | ||
| 188 | * We can't use plain pci_driver mechanism, | ||
| 189 | * as the device is really a multiple function device, | ||
| 190 | * main driver that binds to the pci_device is an smbus | ||
| 191 | * driver and have to find & bind to the device this way. | ||
| 192 | */ | ||
| 193 | for_each_pci_dev(pdev) { | ||
| 194 | ent = pci_match_id(pci_tbl, pdev); | ||
| 195 | if (ent) | ||
| 196 | goto found; | ||
| 197 | } | ||
| 198 | /* Device not found. */ | ||
| 199 | goto out; | ||
| 200 | |||
| 201 | found: | ||
| 202 | err = pci_read_config_dword(pdev, 0x58, &gp.pmbase); | ||
| 203 | if (err) | ||
| 204 | goto out; | ||
| 205 | err = -EIO; | ||
| 206 | gp.pmbase &= 0x0000FF00; | ||
| 207 | if (gp.pmbase == 0) | ||
| 208 | goto out; | ||
| 209 | if (!request_region(gp.pmbase + PMBASE_OFFSET, PMBASE_SIZE, "AMD GPIO")) { | ||
| 210 | dev_err(&pdev->dev, "AMD GPIO region 0x%x already in use!\n", | ||
| 211 | gp.pmbase + PMBASE_OFFSET); | ||
| 212 | err = -EBUSY; | ||
| 213 | goto out; | ||
| 214 | } | ||
| 215 | gp.pm = ioport_map(gp.pmbase + PMBASE_OFFSET, PMBASE_SIZE); | ||
| 216 | gp.pdev = pdev; | ||
| 217 | gp.chip.dev = &pdev->dev; | ||
| 218 | |||
| 219 | spin_lock_init(&gp.lock); | ||
| 220 | |||
| 221 | printk(KERN_INFO "AMD-8111 GPIO detected\n"); | ||
| 222 | err = gpiochip_add(&gp.chip); | ||
| 223 | if (err) { | ||
| 224 | printk(KERN_ERR "GPIO registering failed (%d)\n", | ||
| 225 | err); | ||
| 226 | release_region(gp.pmbase + PMBASE_OFFSET, PMBASE_SIZE); | ||
| 227 | goto out; | ||
| 228 | } | ||
| 229 | out: | ||
| 230 | return err; | ||
| 231 | } | ||
| 232 | |||
| 233 | static void __exit amd_gpio_exit(void) | ||
| 234 | { | ||
| 235 | int err = gpiochip_remove(&gp.chip); | ||
| 236 | WARN_ON(err); | ||
| 237 | ioport_unmap(gp.pm); | ||
| 238 | release_region(gp.pmbase + PMBASE_OFFSET, PMBASE_SIZE); | ||
| 239 | } | ||
| 240 | |||
| 241 | module_init(amd_gpio_init); | ||
| 242 | module_exit(amd_gpio_exit); | ||
| 243 | |||
| 244 | MODULE_AUTHOR("The Linux Kernel team"); | ||
| 245 | MODULE_DESCRIPTION("GPIO driver for AMD chipsets"); | ||
| 246 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/gpio/gpio-arizona.c b/drivers/gpio/gpio-arizona.c new file mode 100644 index 000000000000..8740d2eb06f8 --- /dev/null +++ b/drivers/gpio/gpio-arizona.c | |||
| @@ -0,0 +1,163 @@ | |||
| 1 | /* | ||
| 2 | * gpiolib support for Wolfson Arizona class devices | ||
| 3 | * | ||
| 4 | * Copyright 2012 Wolfson Microelectronics PLC. | ||
| 5 | * | ||
| 6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the | ||
| 10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 11 | * option) any later version. | ||
| 12 | * | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/slab.h> | ||
| 17 | #include <linux/module.h> | ||
| 18 | #include <linux/gpio.h> | ||
| 19 | #include <linux/platform_device.h> | ||
| 20 | #include <linux/seq_file.h> | ||
| 21 | |||
| 22 | #include <linux/mfd/arizona/core.h> | ||
| 23 | #include <linux/mfd/arizona/pdata.h> | ||
| 24 | #include <linux/mfd/arizona/registers.h> | ||
| 25 | |||
| 26 | struct arizona_gpio { | ||
| 27 | struct arizona *arizona; | ||
| 28 | struct gpio_chip gpio_chip; | ||
| 29 | }; | ||
| 30 | |||
| 31 | static inline struct arizona_gpio *to_arizona_gpio(struct gpio_chip *chip) | ||
| 32 | { | ||
| 33 | return container_of(chip, struct arizona_gpio, gpio_chip); | ||
| 34 | } | ||
| 35 | |||
| 36 | static int arizona_gpio_direction_in(struct gpio_chip *chip, unsigned offset) | ||
| 37 | { | ||
| 38 | struct arizona_gpio *arizona_gpio = to_arizona_gpio(chip); | ||
| 39 | struct arizona *arizona = arizona_gpio->arizona; | ||
| 40 | |||
| 41 | return regmap_update_bits(arizona->regmap, ARIZONA_GPIO1_CTRL + offset, | ||
| 42 | ARIZONA_GPN_DIR, ARIZONA_GPN_DIR); | ||
| 43 | } | ||
| 44 | |||
| 45 | static int arizona_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
| 46 | { | ||
| 47 | struct arizona_gpio *arizona_gpio = to_arizona_gpio(chip); | ||
| 48 | struct arizona *arizona = arizona_gpio->arizona; | ||
| 49 | unsigned int val; | ||
| 50 | int ret; | ||
| 51 | |||
| 52 | ret = regmap_read(arizona->regmap, ARIZONA_GPIO1_CTRL + offset, &val); | ||
| 53 | if (ret < 0) | ||
| 54 | return ret; | ||
| 55 | |||
| 56 | if (val & ARIZONA_GPN_LVL) | ||
| 57 | return 1; | ||
| 58 | else | ||
| 59 | return 0; | ||
| 60 | } | ||
| 61 | |||
| 62 | static int arizona_gpio_direction_out(struct gpio_chip *chip, | ||
| 63 | unsigned offset, int value) | ||
| 64 | { | ||
| 65 | struct arizona_gpio *arizona_gpio = to_arizona_gpio(chip); | ||
| 66 | struct arizona *arizona = arizona_gpio->arizona; | ||
| 67 | |||
| 68 | if (value) | ||
| 69 | value = ARIZONA_GPN_LVL; | ||
| 70 | |||
| 71 | return regmap_update_bits(arizona->regmap, ARIZONA_GPIO1_CTRL + offset, | ||
| 72 | ARIZONA_GPN_DIR | ARIZONA_GPN_LVL, value); | ||
| 73 | } | ||
| 74 | |||
| 75 | static void arizona_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
| 76 | { | ||
| 77 | struct arizona_gpio *arizona_gpio = to_arizona_gpio(chip); | ||
| 78 | struct arizona *arizona = arizona_gpio->arizona; | ||
| 79 | |||
| 80 | if (value) | ||
| 81 | value = ARIZONA_GPN_LVL; | ||
| 82 | |||
| 83 | regmap_update_bits(arizona->regmap, ARIZONA_GPIO1_CTRL + offset, | ||
| 84 | ARIZONA_GPN_LVL, value); | ||
| 85 | } | ||
| 86 | |||
| 87 | static struct gpio_chip template_chip = { | ||
| 88 | .label = "arizona", | ||
| 89 | .owner = THIS_MODULE, | ||
| 90 | .direction_input = arizona_gpio_direction_in, | ||
| 91 | .get = arizona_gpio_get, | ||
| 92 | .direction_output = arizona_gpio_direction_out, | ||
| 93 | .set = arizona_gpio_set, | ||
| 94 | .can_sleep = 1, | ||
| 95 | }; | ||
| 96 | |||
| 97 | static int __devinit arizona_gpio_probe(struct platform_device *pdev) | ||
| 98 | { | ||
| 99 | struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); | ||
| 100 | struct arizona_pdata *pdata = arizona->dev->platform_data; | ||
| 101 | struct arizona_gpio *arizona_gpio; | ||
| 102 | int ret; | ||
| 103 | |||
| 104 | arizona_gpio = devm_kzalloc(&pdev->dev, sizeof(*arizona_gpio), | ||
| 105 | GFP_KERNEL); | ||
| 106 | if (arizona_gpio == NULL) | ||
| 107 | return -ENOMEM; | ||
| 108 | |||
| 109 | arizona_gpio->arizona = arizona; | ||
| 110 | arizona_gpio->gpio_chip = template_chip; | ||
| 111 | arizona_gpio->gpio_chip.dev = &pdev->dev; | ||
| 112 | |||
| 113 | switch (arizona->type) { | ||
| 114 | case WM5102: | ||
| 115 | case WM5110: | ||
| 116 | arizona_gpio->gpio_chip.ngpio = 5; | ||
| 117 | break; | ||
| 118 | default: | ||
| 119 | dev_err(&pdev->dev, "Unknown chip variant %d\n", | ||
| 120 | arizona->type); | ||
| 121 | return -EINVAL; | ||
| 122 | } | ||
| 123 | |||
| 124 | if (pdata && pdata->gpio_base) | ||
| 125 | arizona_gpio->gpio_chip.base = pdata->gpio_base; | ||
| 126 | else | ||
| 127 | arizona_gpio->gpio_chip.base = -1; | ||
| 128 | |||
| 129 | ret = gpiochip_add(&arizona_gpio->gpio_chip); | ||
| 130 | if (ret < 0) { | ||
| 131 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", | ||
| 132 | ret); | ||
| 133 | goto err; | ||
| 134 | } | ||
| 135 | |||
| 136 | platform_set_drvdata(pdev, arizona_gpio); | ||
| 137 | |||
| 138 | return ret; | ||
| 139 | |||
| 140 | err: | ||
| 141 | return ret; | ||
| 142 | } | ||
| 143 | |||
| 144 | static int __devexit arizona_gpio_remove(struct platform_device *pdev) | ||
| 145 | { | ||
| 146 | struct arizona_gpio *arizona_gpio = platform_get_drvdata(pdev); | ||
| 147 | |||
| 148 | return gpiochip_remove(&arizona_gpio->gpio_chip); | ||
| 149 | } | ||
| 150 | |||
| 151 | static struct platform_driver arizona_gpio_driver = { | ||
| 152 | .driver.name = "arizona-gpio", | ||
| 153 | .driver.owner = THIS_MODULE, | ||
| 154 | .probe = arizona_gpio_probe, | ||
| 155 | .remove = __devexit_p(arizona_gpio_remove), | ||
| 156 | }; | ||
| 157 | |||
| 158 | module_platform_driver(arizona_gpio_driver); | ||
| 159 | |||
| 160 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | ||
| 161 | MODULE_DESCRIPTION("GPIO interface for Arizona devices"); | ||
| 162 | MODULE_LICENSE("GPL"); | ||
| 163 | MODULE_ALIAS("platform:arizona-gpio"); | ||
diff --git a/drivers/gpio/gpio-lpc32xx.c b/drivers/gpio/gpio-lpc32xx.c index c2199beca98a..8a420f13905e 100644 --- a/drivers/gpio/gpio-lpc32xx.c +++ b/drivers/gpio/gpio-lpc32xx.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * arch/arm/mach-lpc32xx/gpiolib.c | 2 | * GPIO driver for LPC32xx SoC |
| 3 | * | 3 | * |
| 4 | * Author: Kevin Wells <kevin.wells@nxp.com> | 4 | * Author: Kevin Wells <kevin.wells@nxp.com> |
| 5 | * | 5 | * |
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <mach/hardware.h> | 28 | #include <mach/hardware.h> |
| 29 | #include <mach/platform.h> | 29 | #include <mach/platform.h> |
| 30 | #include <mach/gpio-lpc32xx.h> | 30 | #include <mach/gpio-lpc32xx.h> |
| 31 | #include <mach/irqs.h> | ||
| 31 | 32 | ||
| 32 | #define LPC32XX_GPIO_P3_INP_STATE _GPREG(0x000) | 33 | #define LPC32XX_GPIO_P3_INP_STATE _GPREG(0x000) |
| 33 | #define LPC32XX_GPIO_P3_OUTP_SET _GPREG(0x004) | 34 | #define LPC32XX_GPIO_P3_OUTP_SET _GPREG(0x004) |
| @@ -367,6 +368,66 @@ static int lpc32xx_gpio_request(struct gpio_chip *chip, unsigned pin) | |||
| 367 | return -EINVAL; | 368 | return -EINVAL; |
| 368 | } | 369 | } |
| 369 | 370 | ||
| 371 | static int lpc32xx_gpio_to_irq_p01(struct gpio_chip *chip, unsigned offset) | ||
| 372 | { | ||
| 373 | return IRQ_LPC32XX_P0_P1_IRQ; | ||
| 374 | } | ||
| 375 | |||
| 376 | static const char lpc32xx_gpio_to_irq_gpio_p3_table[] = { | ||
| 377 | IRQ_LPC32XX_GPIO_00, | ||
| 378 | IRQ_LPC32XX_GPIO_01, | ||
| 379 | IRQ_LPC32XX_GPIO_02, | ||
| 380 | IRQ_LPC32XX_GPIO_03, | ||
| 381 | IRQ_LPC32XX_GPIO_04, | ||
| 382 | IRQ_LPC32XX_GPIO_05, | ||
| 383 | }; | ||
| 384 | |||
| 385 | static int lpc32xx_gpio_to_irq_gpio_p3(struct gpio_chip *chip, unsigned offset) | ||
| 386 | { | ||
| 387 | if (offset < ARRAY_SIZE(lpc32xx_gpio_to_irq_gpio_p3_table)) | ||
| 388 | return lpc32xx_gpio_to_irq_gpio_p3_table[offset]; | ||
| 389 | return -ENXIO; | ||
| 390 | } | ||
| 391 | |||
| 392 | static const char lpc32xx_gpio_to_irq_gpi_p3_table[] = { | ||
| 393 | IRQ_LPC32XX_GPI_00, | ||
| 394 | IRQ_LPC32XX_GPI_01, | ||
| 395 | IRQ_LPC32XX_GPI_02, | ||
| 396 | IRQ_LPC32XX_GPI_03, | ||
| 397 | IRQ_LPC32XX_GPI_04, | ||
| 398 | IRQ_LPC32XX_GPI_05, | ||
| 399 | IRQ_LPC32XX_GPI_06, | ||
| 400 | IRQ_LPC32XX_GPI_07, | ||
| 401 | IRQ_LPC32XX_GPI_08, | ||
| 402 | IRQ_LPC32XX_GPI_09, | ||
| 403 | -ENXIO, /* 10 */ | ||
| 404 | -ENXIO, /* 11 */ | ||
| 405 | -ENXIO, /* 12 */ | ||
| 406 | -ENXIO, /* 13 */ | ||
| 407 | -ENXIO, /* 14 */ | ||
| 408 | -ENXIO, /* 15 */ | ||
| 409 | -ENXIO, /* 16 */ | ||
| 410 | -ENXIO, /* 17 */ | ||
| 411 | -ENXIO, /* 18 */ | ||
| 412 | IRQ_LPC32XX_GPI_19, | ||
| 413 | -ENXIO, /* 20 */ | ||
| 414 | -ENXIO, /* 21 */ | ||
| 415 | -ENXIO, /* 22 */ | ||
| 416 | -ENXIO, /* 23 */ | ||
| 417 | -ENXIO, /* 24 */ | ||
| 418 | -ENXIO, /* 25 */ | ||
| 419 | -ENXIO, /* 26 */ | ||
| 420 | -ENXIO, /* 27 */ | ||
| 421 | IRQ_LPC32XX_GPI_28, | ||
| 422 | }; | ||
| 423 | |||
| 424 | static int lpc32xx_gpio_to_irq_gpi_p3(struct gpio_chip *chip, unsigned offset) | ||
| 425 | { | ||
| 426 | if (offset < ARRAY_SIZE(lpc32xx_gpio_to_irq_gpi_p3_table)) | ||
| 427 | return lpc32xx_gpio_to_irq_gpi_p3_table[offset]; | ||
| 428 | return -ENXIO; | ||
| 429 | } | ||
| 430 | |||
| 370 | static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = { | 431 | static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = { |
| 371 | { | 432 | { |
| 372 | .chip = { | 433 | .chip = { |
| @@ -376,6 +437,7 @@ static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = { | |||
| 376 | .direction_output = lpc32xx_gpio_dir_output_p012, | 437 | .direction_output = lpc32xx_gpio_dir_output_p012, |
| 377 | .set = lpc32xx_gpio_set_value_p012, | 438 | .set = lpc32xx_gpio_set_value_p012, |
| 378 | .request = lpc32xx_gpio_request, | 439 | .request = lpc32xx_gpio_request, |
| 440 | .to_irq = lpc32xx_gpio_to_irq_p01, | ||
| 379 | .base = LPC32XX_GPIO_P0_GRP, | 441 | .base = LPC32XX_GPIO_P0_GRP, |
| 380 | .ngpio = LPC32XX_GPIO_P0_MAX, | 442 | .ngpio = LPC32XX_GPIO_P0_MAX, |
| 381 | .names = gpio_p0_names, | 443 | .names = gpio_p0_names, |
| @@ -391,6 +453,7 @@ static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = { | |||
| 391 | .direction_output = lpc32xx_gpio_dir_output_p012, | 453 | .direction_output = lpc32xx_gpio_dir_output_p012, |
| 392 | .set = lpc32xx_gpio_set_value_p012, | 454 | .set = lpc32xx_gpio_set_value_p012, |
| 393 | .request = lpc32xx_gpio_request, | 455 | .request = lpc32xx_gpio_request, |
| 456 | .to_irq = lpc32xx_gpio_to_irq_p01, | ||
| 394 | .base = LPC32XX_GPIO_P1_GRP, | 457 | .base = LPC32XX_GPIO_P1_GRP, |
| 395 | .ngpio = LPC32XX_GPIO_P1_MAX, | 458 | .ngpio = LPC32XX_GPIO_P1_MAX, |
| 396 | .names = gpio_p1_names, | 459 | .names = gpio_p1_names, |
| @@ -421,6 +484,7 @@ static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = { | |||
| 421 | .direction_output = lpc32xx_gpio_dir_output_p3, | 484 | .direction_output = lpc32xx_gpio_dir_output_p3, |
| 422 | .set = lpc32xx_gpio_set_value_p3, | 485 | .set = lpc32xx_gpio_set_value_p3, |
| 423 | .request = lpc32xx_gpio_request, | 486 | .request = lpc32xx_gpio_request, |
| 487 | .to_irq = lpc32xx_gpio_to_irq_gpio_p3, | ||
| 424 | .base = LPC32XX_GPIO_P3_GRP, | 488 | .base = LPC32XX_GPIO_P3_GRP, |
| 425 | .ngpio = LPC32XX_GPIO_P3_MAX, | 489 | .ngpio = LPC32XX_GPIO_P3_MAX, |
| 426 | .names = gpio_p3_names, | 490 | .names = gpio_p3_names, |
| @@ -434,6 +498,7 @@ static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = { | |||
| 434 | .direction_input = lpc32xx_gpio_dir_in_always, | 498 | .direction_input = lpc32xx_gpio_dir_in_always, |
| 435 | .get = lpc32xx_gpi_get_value, | 499 | .get = lpc32xx_gpi_get_value, |
| 436 | .request = lpc32xx_gpio_request, | 500 | .request = lpc32xx_gpio_request, |
| 501 | .to_irq = lpc32xx_gpio_to_irq_gpi_p3, | ||
| 437 | .base = LPC32XX_GPI_P3_GRP, | 502 | .base = LPC32XX_GPI_P3_GRP, |
| 438 | .ngpio = LPC32XX_GPI_P3_MAX, | 503 | .ngpio = LPC32XX_GPI_P3_MAX, |
| 439 | .names = gpi_p3_names, | 504 | .names = gpi_p3_names, |
| @@ -457,13 +522,6 @@ static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = { | |||
| 457 | }, | 522 | }, |
| 458 | }; | 523 | }; |
| 459 | 524 | ||
| 460 | /* Empty now, can be removed later when mach-lpc32xx is finally switched over | ||
| 461 | * to DT support | ||
| 462 | */ | ||
| 463 | void __init lpc32xx_gpio_init(void) | ||
| 464 | { | ||
| 465 | } | ||
| 466 | |||
| 467 | static int lpc32xx_of_xlate(struct gpio_chip *gc, | 525 | static int lpc32xx_of_xlate(struct gpio_chip *gc, |
| 468 | const struct of_phandle_args *gpiospec, u32 *flags) | 526 | const struct of_phandle_args *gpiospec, u32 *flags) |
| 469 | { | 527 | { |
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c index 04691d3abe60..4db460b6ecf7 100644 --- a/drivers/gpio/gpio-mxc.c +++ b/drivers/gpio/gpio-mxc.c | |||
| @@ -37,7 +37,8 @@ | |||
| 37 | enum mxc_gpio_hwtype { | 37 | enum mxc_gpio_hwtype { |
| 38 | IMX1_GPIO, /* runs on i.mx1 */ | 38 | IMX1_GPIO, /* runs on i.mx1 */ |
| 39 | IMX21_GPIO, /* runs on i.mx21 and i.mx27 */ | 39 | IMX21_GPIO, /* runs on i.mx21 and i.mx27 */ |
| 40 | IMX31_GPIO, /* runs on all other i.mx */ | 40 | IMX31_GPIO, /* runs on i.mx31 */ |
| 41 | IMX35_GPIO, /* runs on all other i.mx */ | ||
| 41 | }; | 42 | }; |
| 42 | 43 | ||
| 43 | /* device type dependent stuff */ | 44 | /* device type dependent stuff */ |
| @@ -49,6 +50,7 @@ struct mxc_gpio_hwdata { | |||
| 49 | unsigned icr2_reg; | 50 | unsigned icr2_reg; |
| 50 | unsigned imr_reg; | 51 | unsigned imr_reg; |
| 51 | unsigned isr_reg; | 52 | unsigned isr_reg; |
| 53 | int edge_sel_reg; | ||
| 52 | unsigned low_level; | 54 | unsigned low_level; |
| 53 | unsigned high_level; | 55 | unsigned high_level; |
| 54 | unsigned rise_edge; | 56 | unsigned rise_edge; |
| @@ -73,6 +75,7 @@ static struct mxc_gpio_hwdata imx1_imx21_gpio_hwdata = { | |||
| 73 | .icr2_reg = 0x2c, | 75 | .icr2_reg = 0x2c, |
| 74 | .imr_reg = 0x30, | 76 | .imr_reg = 0x30, |
| 75 | .isr_reg = 0x34, | 77 | .isr_reg = 0x34, |
| 78 | .edge_sel_reg = -EINVAL, | ||
| 76 | .low_level = 0x03, | 79 | .low_level = 0x03, |
| 77 | .high_level = 0x02, | 80 | .high_level = 0x02, |
| 78 | .rise_edge = 0x00, | 81 | .rise_edge = 0x00, |
| @@ -87,6 +90,22 @@ static struct mxc_gpio_hwdata imx31_gpio_hwdata = { | |||
| 87 | .icr2_reg = 0x10, | 90 | .icr2_reg = 0x10, |
| 88 | .imr_reg = 0x14, | 91 | .imr_reg = 0x14, |
| 89 | .isr_reg = 0x18, | 92 | .isr_reg = 0x18, |
| 93 | .edge_sel_reg = -EINVAL, | ||
| 94 | .low_level = 0x00, | ||
| 95 | .high_level = 0x01, | ||
| 96 | .rise_edge = 0x02, | ||
| 97 | .fall_edge = 0x03, | ||
| 98 | }; | ||
| 99 | |||
| 100 | static struct mxc_gpio_hwdata imx35_gpio_hwdata = { | ||
| 101 | .dr_reg = 0x00, | ||
| 102 | .gdir_reg = 0x04, | ||
| 103 | .psr_reg = 0x08, | ||
| 104 | .icr1_reg = 0x0c, | ||
| 105 | .icr2_reg = 0x10, | ||
| 106 | .imr_reg = 0x14, | ||
| 107 | .isr_reg = 0x18, | ||
| 108 | .edge_sel_reg = 0x1c, | ||
| 90 | .low_level = 0x00, | 109 | .low_level = 0x00, |
| 91 | .high_level = 0x01, | 110 | .high_level = 0x01, |
| 92 | .rise_edge = 0x02, | 111 | .rise_edge = 0x02, |
| @@ -103,12 +122,13 @@ static struct mxc_gpio_hwdata *mxc_gpio_hwdata; | |||
| 103 | #define GPIO_ICR2 (mxc_gpio_hwdata->icr2_reg) | 122 | #define GPIO_ICR2 (mxc_gpio_hwdata->icr2_reg) |
| 104 | #define GPIO_IMR (mxc_gpio_hwdata->imr_reg) | 123 | #define GPIO_IMR (mxc_gpio_hwdata->imr_reg) |
| 105 | #define GPIO_ISR (mxc_gpio_hwdata->isr_reg) | 124 | #define GPIO_ISR (mxc_gpio_hwdata->isr_reg) |
| 125 | #define GPIO_EDGE_SEL (mxc_gpio_hwdata->edge_sel_reg) | ||
| 106 | 126 | ||
| 107 | #define GPIO_INT_LOW_LEV (mxc_gpio_hwdata->low_level) | 127 | #define GPIO_INT_LOW_LEV (mxc_gpio_hwdata->low_level) |
| 108 | #define GPIO_INT_HIGH_LEV (mxc_gpio_hwdata->high_level) | 128 | #define GPIO_INT_HIGH_LEV (mxc_gpio_hwdata->high_level) |
| 109 | #define GPIO_INT_RISE_EDGE (mxc_gpio_hwdata->rise_edge) | 129 | #define GPIO_INT_RISE_EDGE (mxc_gpio_hwdata->rise_edge) |
| 110 | #define GPIO_INT_FALL_EDGE (mxc_gpio_hwdata->fall_edge) | 130 | #define GPIO_INT_FALL_EDGE (mxc_gpio_hwdata->fall_edge) |
| 111 | #define GPIO_INT_NONE 0x4 | 131 | #define GPIO_INT_BOTH_EDGES 0x4 |
| 112 | 132 | ||
| 113 | static struct platform_device_id mxc_gpio_devtype[] = { | 133 | static struct platform_device_id mxc_gpio_devtype[] = { |
| 114 | { | 134 | { |
| @@ -121,6 +141,9 @@ static struct platform_device_id mxc_gpio_devtype[] = { | |||
| 121 | .name = "imx31-gpio", | 141 | .name = "imx31-gpio", |
| 122 | .driver_data = IMX31_GPIO, | 142 | .driver_data = IMX31_GPIO, |
| 123 | }, { | 143 | }, { |
| 144 | .name = "imx35-gpio", | ||
| 145 | .driver_data = IMX35_GPIO, | ||
| 146 | }, { | ||
| 124 | /* sentinel */ | 147 | /* sentinel */ |
| 125 | } | 148 | } |
| 126 | }; | 149 | }; |
| @@ -129,6 +152,7 @@ static const struct of_device_id mxc_gpio_dt_ids[] = { | |||
| 129 | { .compatible = "fsl,imx1-gpio", .data = &mxc_gpio_devtype[IMX1_GPIO], }, | 152 | { .compatible = "fsl,imx1-gpio", .data = &mxc_gpio_devtype[IMX1_GPIO], }, |
| 130 | { .compatible = "fsl,imx21-gpio", .data = &mxc_gpio_devtype[IMX21_GPIO], }, | 153 | { .compatible = "fsl,imx21-gpio", .data = &mxc_gpio_devtype[IMX21_GPIO], }, |
| 131 | { .compatible = "fsl,imx31-gpio", .data = &mxc_gpio_devtype[IMX31_GPIO], }, | 154 | { .compatible = "fsl,imx31-gpio", .data = &mxc_gpio_devtype[IMX31_GPIO], }, |
| 155 | { .compatible = "fsl,imx35-gpio", .data = &mxc_gpio_devtype[IMX35_GPIO], }, | ||
| 132 | { /* sentinel */ } | 156 | { /* sentinel */ } |
| 133 | }; | 157 | }; |
| 134 | 158 | ||
| @@ -160,15 +184,19 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type) | |||
| 160 | edge = GPIO_INT_FALL_EDGE; | 184 | edge = GPIO_INT_FALL_EDGE; |
| 161 | break; | 185 | break; |
| 162 | case IRQ_TYPE_EDGE_BOTH: | 186 | case IRQ_TYPE_EDGE_BOTH: |
| 163 | val = gpio_get_value(gpio); | 187 | if (GPIO_EDGE_SEL >= 0) { |
| 164 | if (val) { | 188 | edge = GPIO_INT_BOTH_EDGES; |
| 165 | edge = GPIO_INT_LOW_LEV; | ||
| 166 | pr_debug("mxc: set GPIO %d to low trigger\n", gpio); | ||
| 167 | } else { | 189 | } else { |
| 168 | edge = GPIO_INT_HIGH_LEV; | 190 | val = gpio_get_value(gpio); |
| 169 | pr_debug("mxc: set GPIO %d to high trigger\n", gpio); | 191 | if (val) { |
| 192 | edge = GPIO_INT_LOW_LEV; | ||
| 193 | pr_debug("mxc: set GPIO %d to low trigger\n", gpio); | ||
| 194 | } else { | ||
| 195 | edge = GPIO_INT_HIGH_LEV; | ||
| 196 | pr_debug("mxc: set GPIO %d to high trigger\n", gpio); | ||
| 197 | } | ||
| 198 | port->both_edges |= 1 << gpio_idx; | ||
| 170 | } | 199 | } |
| 171 | port->both_edges |= 1 << gpio_idx; | ||
| 172 | break; | 200 | break; |
| 173 | case IRQ_TYPE_LEVEL_LOW: | 201 | case IRQ_TYPE_LEVEL_LOW: |
| 174 | edge = GPIO_INT_LOW_LEV; | 202 | edge = GPIO_INT_LOW_LEV; |
| @@ -180,10 +208,23 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type) | |||
| 180 | return -EINVAL; | 208 | return -EINVAL; |
| 181 | } | 209 | } |
| 182 | 210 | ||
| 183 | reg += GPIO_ICR1 + ((gpio_idx & 0x10) >> 2); /* ICR1 or ICR2 */ | 211 | if (GPIO_EDGE_SEL >= 0) { |
| 184 | bit = gpio_idx & 0xf; | 212 | val = readl(port->base + GPIO_EDGE_SEL); |
| 185 | val = readl(reg) & ~(0x3 << (bit << 1)); | 213 | if (edge == GPIO_INT_BOTH_EDGES) |
| 186 | writel(val | (edge << (bit << 1)), reg); | 214 | writel(val | (1 << gpio_idx), |
| 215 | port->base + GPIO_EDGE_SEL); | ||
| 216 | else | ||
| 217 | writel(val & ~(1 << gpio_idx), | ||
| 218 | port->base + GPIO_EDGE_SEL); | ||
| 219 | } | ||
| 220 | |||
| 221 | if (edge != GPIO_INT_BOTH_EDGES) { | ||
| 222 | reg += GPIO_ICR1 + ((gpio_idx & 0x10) >> 2); /* lower or upper register */ | ||
| 223 | bit = gpio_idx & 0xf; | ||
| 224 | val = readl(reg) & ~(0x3 << (bit << 1)); | ||
| 225 | writel(val | (edge << (bit << 1)), reg); | ||
| 226 | } | ||
| 227 | |||
| 187 | writel(1 << gpio_idx, port->base + GPIO_ISR); | 228 | writel(1 << gpio_idx, port->base + GPIO_ISR); |
| 188 | 229 | ||
| 189 | return 0; | 230 | return 0; |
| @@ -335,7 +376,9 @@ static void __devinit mxc_gpio_get_hw(struct platform_device *pdev) | |||
| 335 | return; | 376 | return; |
| 336 | } | 377 | } |
| 337 | 378 | ||
| 338 | if (hwtype == IMX31_GPIO) | 379 | if (hwtype == IMX35_GPIO) |
| 380 | mxc_gpio_hwdata = &imx35_gpio_hwdata; | ||
| 381 | else if (hwtype == IMX31_GPIO) | ||
| 339 | mxc_gpio_hwdata = &imx31_gpio_hwdata; | 382 | mxc_gpio_hwdata = &imx31_gpio_hwdata; |
| 340 | else | 383 | else |
| 341 | mxc_gpio_hwdata = &imx1_imx21_gpio_hwdata; | 384 | mxc_gpio_hwdata = &imx1_imx21_gpio_hwdata; |
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 4fbc208c32cf..e6efd77668f0 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c | |||
| @@ -899,12 +899,6 @@ static int gpio_debounce(struct gpio_chip *chip, unsigned offset, | |||
| 899 | 899 | ||
| 900 | bank = container_of(chip, struct gpio_bank, chip); | 900 | bank = container_of(chip, struct gpio_bank, chip); |
| 901 | 901 | ||
| 902 | if (!bank->dbck) { | ||
| 903 | bank->dbck = clk_get(bank->dev, "dbclk"); | ||
| 904 | if (IS_ERR(bank->dbck)) | ||
| 905 | dev_err(bank->dev, "Could not get gpio dbck\n"); | ||
| 906 | } | ||
| 907 | |||
| 908 | spin_lock_irqsave(&bank->lock, flags); | 902 | spin_lock_irqsave(&bank->lock, flags); |
| 909 | _set_gpio_debounce(bank, offset, debounce); | 903 | _set_gpio_debounce(bank, offset, debounce); |
| 910 | spin_unlock_irqrestore(&bank->lock, flags); | 904 | spin_unlock_irqrestore(&bank->lock, flags); |
| @@ -976,6 +970,10 @@ static void omap_gpio_mod_init(struct gpio_bank *bank) | |||
| 976 | /* Initialize interface clk ungated, module enabled */ | 970 | /* Initialize interface clk ungated, module enabled */ |
| 977 | if (bank->regs->ctrl) | 971 | if (bank->regs->ctrl) |
| 978 | __raw_writel(0, base + bank->regs->ctrl); | 972 | __raw_writel(0, base + bank->regs->ctrl); |
| 973 | |||
| 974 | bank->dbck = clk_get(bank->dev, "dbclk"); | ||
| 975 | if (IS_ERR(bank->dbck)) | ||
| 976 | dev_err(bank->dev, "Could not get gpio dbck\n"); | ||
| 979 | } | 977 | } |
| 980 | 978 | ||
| 981 | static __devinit void | 979 | static __devinit void |
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 1c313c710be3..9c693ae17956 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c | |||
| @@ -78,10 +78,10 @@ struct pca953x_chip { | |||
| 78 | 78 | ||
| 79 | #ifdef CONFIG_GPIO_PCA953X_IRQ | 79 | #ifdef CONFIG_GPIO_PCA953X_IRQ |
| 80 | struct mutex irq_lock; | 80 | struct mutex irq_lock; |
| 81 | uint16_t irq_mask; | 81 | u32 irq_mask; |
| 82 | uint16_t irq_stat; | 82 | u32 irq_stat; |
| 83 | uint16_t irq_trig_raise; | 83 | u32 irq_trig_raise; |
| 84 | uint16_t irq_trig_fall; | 84 | u32 irq_trig_fall; |
| 85 | int irq_base; | 85 | int irq_base; |
| 86 | #endif | 86 | #endif |
| 87 | 87 | ||
| @@ -98,12 +98,11 @@ static int pca953x_write_reg(struct pca953x_chip *chip, int reg, u32 val) | |||
| 98 | if (chip->gpio_chip.ngpio <= 8) | 98 | if (chip->gpio_chip.ngpio <= 8) |
| 99 | ret = i2c_smbus_write_byte_data(chip->client, reg, val); | 99 | ret = i2c_smbus_write_byte_data(chip->client, reg, val); |
| 100 | else if (chip->gpio_chip.ngpio == 24) { | 100 | else if (chip->gpio_chip.ngpio == 24) { |
| 101 | ret = i2c_smbus_write_word_data(chip->client, | 101 | cpu_to_le32s(&val); |
| 102 | ret = i2c_smbus_write_i2c_block_data(chip->client, | ||
| 102 | (reg << 2) | REG_ADDR_AI, | 103 | (reg << 2) | REG_ADDR_AI, |
| 103 | val & 0xffff); | 104 | 3, |
| 104 | ret = i2c_smbus_write_byte_data(chip->client, | 105 | (u8 *) &val); |
| 105 | (reg << 2) + 2, | ||
| 106 | (val & 0xff0000) >> 16); | ||
| 107 | } | 106 | } |
| 108 | else { | 107 | else { |
| 109 | switch (chip->chip_type) { | 108 | switch (chip->chip_type) { |
| @@ -135,22 +134,27 @@ static int pca953x_read_reg(struct pca953x_chip *chip, int reg, u32 *val) | |||
| 135 | { | 134 | { |
| 136 | int ret; | 135 | int ret; |
| 137 | 136 | ||
| 138 | if (chip->gpio_chip.ngpio <= 8) | 137 | if (chip->gpio_chip.ngpio <= 8) { |
| 139 | ret = i2c_smbus_read_byte_data(chip->client, reg); | 138 | ret = i2c_smbus_read_byte_data(chip->client, reg); |
| 140 | else if (chip->gpio_chip.ngpio == 24) { | 139 | *val = ret; |
| 141 | ret = i2c_smbus_read_word_data(chip->client, reg << 2); | ||
| 142 | ret |= (i2c_smbus_read_byte_data(chip->client, | ||
| 143 | (reg << 2) + 2)<<16); | ||
| 144 | } | 140 | } |
| 145 | else | 141 | else if (chip->gpio_chip.ngpio == 24) { |
| 142 | *val = 0; | ||
| 143 | ret = i2c_smbus_read_i2c_block_data(chip->client, | ||
| 144 | (reg << 2) | REG_ADDR_AI, | ||
| 145 | 3, | ||
| 146 | (u8 *) val); | ||
| 147 | le32_to_cpus(val); | ||
| 148 | } else { | ||
| 146 | ret = i2c_smbus_read_word_data(chip->client, reg << 1); | 149 | ret = i2c_smbus_read_word_data(chip->client, reg << 1); |
| 150 | *val = ret; | ||
| 151 | } | ||
| 147 | 152 | ||
| 148 | if (ret < 0) { | 153 | if (ret < 0) { |
| 149 | dev_err(&chip->client->dev, "failed reading register\n"); | 154 | dev_err(&chip->client->dev, "failed reading register\n"); |
| 150 | return ret; | 155 | return ret; |
| 151 | } | 156 | } |
| 152 | 157 | ||
| 153 | *val = (u32)ret; | ||
| 154 | return 0; | 158 | return 0; |
| 155 | } | 159 | } |
| 156 | 160 | ||
| @@ -349,8 +353,8 @@ static void pca953x_irq_bus_lock(struct irq_data *d) | |||
| 349 | static void pca953x_irq_bus_sync_unlock(struct irq_data *d) | 353 | static void pca953x_irq_bus_sync_unlock(struct irq_data *d) |
| 350 | { | 354 | { |
| 351 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); | 355 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); |
| 352 | uint16_t new_irqs; | 356 | u32 new_irqs; |
| 353 | uint16_t level; | 357 | u32 level; |
| 354 | 358 | ||
| 355 | /* Look for any newly setup interrupt */ | 359 | /* Look for any newly setup interrupt */ |
| 356 | new_irqs = chip->irq_trig_fall | chip->irq_trig_raise; | 360 | new_irqs = chip->irq_trig_fall | chip->irq_trig_raise; |
| @@ -368,8 +372,8 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d) | |||
| 368 | static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) | 372 | static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) |
| 369 | { | 373 | { |
| 370 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); | 374 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); |
| 371 | uint16_t level = d->irq - chip->irq_base; | 375 | u32 level = d->irq - chip->irq_base; |
| 372 | uint16_t mask = 1 << level; | 376 | u32 mask = 1 << level; |
| 373 | 377 | ||
| 374 | if (!(type & IRQ_TYPE_EDGE_BOTH)) { | 378 | if (!(type & IRQ_TYPE_EDGE_BOTH)) { |
| 375 | dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", | 379 | dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", |
| @@ -399,12 +403,12 @@ static struct irq_chip pca953x_irq_chip = { | |||
| 399 | .irq_set_type = pca953x_irq_set_type, | 403 | .irq_set_type = pca953x_irq_set_type, |
| 400 | }; | 404 | }; |
| 401 | 405 | ||
| 402 | static uint16_t pca953x_irq_pending(struct pca953x_chip *chip) | 406 | static u32 pca953x_irq_pending(struct pca953x_chip *chip) |
| 403 | { | 407 | { |
| 404 | u32 cur_stat; | 408 | u32 cur_stat; |
| 405 | uint16_t old_stat; | 409 | u32 old_stat; |
| 406 | uint16_t pending; | 410 | u32 pending; |
| 407 | uint16_t trigger; | 411 | u32 trigger; |
| 408 | int ret, offset = 0; | 412 | int ret, offset = 0; |
| 409 | 413 | ||
| 410 | switch (chip->chip_type) { | 414 | switch (chip->chip_type) { |
| @@ -440,8 +444,8 @@ static uint16_t pca953x_irq_pending(struct pca953x_chip *chip) | |||
| 440 | static irqreturn_t pca953x_irq_handler(int irq, void *devid) | 444 | static irqreturn_t pca953x_irq_handler(int irq, void *devid) |
| 441 | { | 445 | { |
| 442 | struct pca953x_chip *chip = devid; | 446 | struct pca953x_chip *chip = devid; |
| 443 | uint16_t pending; | 447 | u32 pending; |
| 444 | uint16_t level; | 448 | u32 level; |
| 445 | 449 | ||
| 446 | pending = pca953x_irq_pending(chip); | 450 | pending = pca953x_irq_pending(chip); |
| 447 | 451 | ||
| @@ -564,7 +568,7 @@ static void pca953x_irq_teardown(struct pca953x_chip *chip) | |||
| 564 | * WARNING: This is DEPRECATED and will be removed eventually! | 568 | * WARNING: This is DEPRECATED and will be removed eventually! |
| 565 | */ | 569 | */ |
| 566 | static void | 570 | static void |
| 567 | pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert) | 571 | pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, u32 *invert) |
| 568 | { | 572 | { |
| 569 | struct device_node *node; | 573 | struct device_node *node; |
| 570 | const __be32 *val; | 574 | const __be32 *val; |
| @@ -592,13 +596,13 @@ pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert) | |||
| 592 | } | 596 | } |
| 593 | #else | 597 | #else |
| 594 | static void | 598 | static void |
| 595 | pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert) | 599 | pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, u32 *invert) |
| 596 | { | 600 | { |
| 597 | *gpio_base = -1; | 601 | *gpio_base = -1; |
| 598 | } | 602 | } |
| 599 | #endif | 603 | #endif |
| 600 | 604 | ||
| 601 | static int __devinit device_pca953x_init(struct pca953x_chip *chip, int invert) | 605 | static int __devinit device_pca953x_init(struct pca953x_chip *chip, u32 invert) |
| 602 | { | 606 | { |
| 603 | int ret; | 607 | int ret; |
| 604 | 608 | ||
| @@ -617,7 +621,7 @@ out: | |||
| 617 | return ret; | 621 | return ret; |
| 618 | } | 622 | } |
| 619 | 623 | ||
| 620 | static int __devinit device_pca957x_init(struct pca953x_chip *chip, int invert) | 624 | static int __devinit device_pca957x_init(struct pca953x_chip *chip, u32 invert) |
| 621 | { | 625 | { |
| 622 | int ret; | 626 | int ret; |
| 623 | u32 val = 0; | 627 | u32 val = 0; |
| @@ -653,8 +657,9 @@ static int __devinit pca953x_probe(struct i2c_client *client, | |||
| 653 | { | 657 | { |
| 654 | struct pca953x_platform_data *pdata; | 658 | struct pca953x_platform_data *pdata; |
| 655 | struct pca953x_chip *chip; | 659 | struct pca953x_chip *chip; |
| 656 | int irq_base=0, invert=0; | 660 | int irq_base = 0; |
| 657 | int ret; | 661 | int ret; |
| 662 | u32 invert = 0; | ||
| 658 | 663 | ||
| 659 | chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); | 664 | chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); |
| 660 | if (chip == NULL) | 665 | if (chip == NULL) |
diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/gpio-pcf857x.c index 2d1de9e7e9bd..076e236d0da7 100644 --- a/drivers/gpio/gpio-pcf857x.c +++ b/drivers/gpio/gpio-pcf857x.c | |||
| @@ -61,61 +61,28 @@ struct pcf857x { | |||
| 61 | struct i2c_client *client; | 61 | struct i2c_client *client; |
| 62 | struct mutex lock; /* protect 'out' */ | 62 | struct mutex lock; /* protect 'out' */ |
| 63 | unsigned out; /* software latch */ | 63 | unsigned out; /* software latch */ |
| 64 | |||
| 65 | int (*write)(struct i2c_client *client, unsigned data); | ||
| 66 | int (*read)(struct i2c_client *client); | ||
| 64 | }; | 67 | }; |
| 65 | 68 | ||
| 66 | /*-------------------------------------------------------------------------*/ | 69 | /*-------------------------------------------------------------------------*/ |
| 67 | 70 | ||
| 68 | /* Talk to 8-bit I/O expander */ | 71 | /* Talk to 8-bit I/O expander */ |
| 69 | 72 | ||
| 70 | static int pcf857x_input8(struct gpio_chip *chip, unsigned offset) | 73 | static int i2c_write_le8(struct i2c_client *client, unsigned data) |
| 71 | { | ||
| 72 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); | ||
| 73 | int status; | ||
| 74 | |||
| 75 | mutex_lock(&gpio->lock); | ||
| 76 | gpio->out |= (1 << offset); | ||
| 77 | status = i2c_smbus_write_byte(gpio->client, gpio->out); | ||
| 78 | mutex_unlock(&gpio->lock); | ||
| 79 | |||
| 80 | return status; | ||
| 81 | } | ||
| 82 | |||
| 83 | static int pcf857x_get8(struct gpio_chip *chip, unsigned offset) | ||
| 84 | { | ||
| 85 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); | ||
| 86 | s32 value; | ||
| 87 | |||
| 88 | value = i2c_smbus_read_byte(gpio->client); | ||
| 89 | return (value < 0) ? 0 : (value & (1 << offset)); | ||
| 90 | } | ||
| 91 | |||
| 92 | static int pcf857x_output8(struct gpio_chip *chip, unsigned offset, int value) | ||
| 93 | { | 74 | { |
| 94 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); | 75 | return i2c_smbus_write_byte(client, data); |
| 95 | unsigned bit = 1 << offset; | ||
| 96 | int status; | ||
| 97 | |||
| 98 | mutex_lock(&gpio->lock); | ||
| 99 | if (value) | ||
| 100 | gpio->out |= bit; | ||
| 101 | else | ||
| 102 | gpio->out &= ~bit; | ||
| 103 | status = i2c_smbus_write_byte(gpio->client, gpio->out); | ||
| 104 | mutex_unlock(&gpio->lock); | ||
| 105 | |||
| 106 | return status; | ||
| 107 | } | 76 | } |
| 108 | 77 | ||
| 109 | static void pcf857x_set8(struct gpio_chip *chip, unsigned offset, int value) | 78 | static int i2c_read_le8(struct i2c_client *client) |
| 110 | { | 79 | { |
| 111 | pcf857x_output8(chip, offset, value); | 80 | return (int)i2c_smbus_read_byte(client); |
| 112 | } | 81 | } |
| 113 | 82 | ||
| 114 | /*-------------------------------------------------------------------------*/ | ||
| 115 | |||
| 116 | /* Talk to 16-bit I/O expander */ | 83 | /* Talk to 16-bit I/O expander */ |
| 117 | 84 | ||
| 118 | static int i2c_write_le16(struct i2c_client *client, u16 word) | 85 | static int i2c_write_le16(struct i2c_client *client, unsigned word) |
| 119 | { | 86 | { |
| 120 | u8 buf[2] = { word & 0xff, word >> 8, }; | 87 | u8 buf[2] = { word & 0xff, word >> 8, }; |
| 121 | int status; | 88 | int status; |
| @@ -135,29 +102,31 @@ static int i2c_read_le16(struct i2c_client *client) | |||
| 135 | return (buf[1] << 8) | buf[0]; | 102 | return (buf[1] << 8) | buf[0]; |
| 136 | } | 103 | } |
| 137 | 104 | ||
| 138 | static int pcf857x_input16(struct gpio_chip *chip, unsigned offset) | 105 | /*-------------------------------------------------------------------------*/ |
| 106 | |||
| 107 | static int pcf857x_input(struct gpio_chip *chip, unsigned offset) | ||
| 139 | { | 108 | { |
| 140 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); | 109 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); |
| 141 | int status; | 110 | int status; |
| 142 | 111 | ||
| 143 | mutex_lock(&gpio->lock); | 112 | mutex_lock(&gpio->lock); |
| 144 | gpio->out |= (1 << offset); | 113 | gpio->out |= (1 << offset); |
| 145 | status = i2c_write_le16(gpio->client, gpio->out); | 114 | status = gpio->write(gpio->client, gpio->out); |
| 146 | mutex_unlock(&gpio->lock); | 115 | mutex_unlock(&gpio->lock); |
| 147 | 116 | ||
| 148 | return status; | 117 | return status; |
| 149 | } | 118 | } |
| 150 | 119 | ||
| 151 | static int pcf857x_get16(struct gpio_chip *chip, unsigned offset) | 120 | static int pcf857x_get(struct gpio_chip *chip, unsigned offset) |
| 152 | { | 121 | { |
| 153 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); | 122 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); |
| 154 | int value; | 123 | int value; |
| 155 | 124 | ||
| 156 | value = i2c_read_le16(gpio->client); | 125 | value = gpio->read(gpio->client); |
| 157 | return (value < 0) ? 0 : (value & (1 << offset)); | 126 | return (value < 0) ? 0 : (value & (1 << offset)); |
| 158 | } | 127 | } |
| 159 | 128 | ||
| 160 | static int pcf857x_output16(struct gpio_chip *chip, unsigned offset, int value) | 129 | static int pcf857x_output(struct gpio_chip *chip, unsigned offset, int value) |
| 161 | { | 130 | { |
| 162 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); | 131 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); |
| 163 | unsigned bit = 1 << offset; | 132 | unsigned bit = 1 << offset; |
| @@ -168,15 +137,15 @@ static int pcf857x_output16(struct gpio_chip *chip, unsigned offset, int value) | |||
| 168 | gpio->out |= bit; | 137 | gpio->out |= bit; |
| 169 | else | 138 | else |
| 170 | gpio->out &= ~bit; | 139 | gpio->out &= ~bit; |
| 171 | status = i2c_write_le16(gpio->client, gpio->out); | 140 | status = gpio->write(gpio->client, gpio->out); |
| 172 | mutex_unlock(&gpio->lock); | 141 | mutex_unlock(&gpio->lock); |
| 173 | 142 | ||
| 174 | return status; | 143 | return status; |
| 175 | } | 144 | } |
| 176 | 145 | ||
| 177 | static void pcf857x_set16(struct gpio_chip *chip, unsigned offset, int value) | 146 | static void pcf857x_set(struct gpio_chip *chip, unsigned offset, int value) |
| 178 | { | 147 | { |
| 179 | pcf857x_output16(chip, offset, value); | 148 | pcf857x_output(chip, offset, value); |
| 180 | } | 149 | } |
| 181 | 150 | ||
| 182 | /*-------------------------------------------------------------------------*/ | 151 | /*-------------------------------------------------------------------------*/ |
| @@ -200,10 +169,15 @@ static int pcf857x_probe(struct i2c_client *client, | |||
| 200 | 169 | ||
| 201 | mutex_init(&gpio->lock); | 170 | mutex_init(&gpio->lock); |
| 202 | 171 | ||
| 203 | gpio->chip.base = pdata ? pdata->gpio_base : -1; | 172 | gpio->chip.base = pdata ? pdata->gpio_base : -1; |
| 204 | gpio->chip.can_sleep = 1; | 173 | gpio->chip.can_sleep = 1; |
| 205 | gpio->chip.dev = &client->dev; | 174 | gpio->chip.dev = &client->dev; |
| 206 | gpio->chip.owner = THIS_MODULE; | 175 | gpio->chip.owner = THIS_MODULE; |
| 176 | gpio->chip.get = pcf857x_get; | ||
| 177 | gpio->chip.set = pcf857x_set; | ||
| 178 | gpio->chip.direction_input = pcf857x_input; | ||
| 179 | gpio->chip.direction_output = pcf857x_output; | ||
| 180 | gpio->chip.ngpio = id->driver_data; | ||
| 207 | 181 | ||
| 208 | /* NOTE: the OnSemi jlc1562b is also largely compatible with | 182 | /* NOTE: the OnSemi jlc1562b is also largely compatible with |
| 209 | * these parts, notably for output. It has a low-resolution | 183 | * these parts, notably for output. It has a low-resolution |
| @@ -216,12 +190,9 @@ static int pcf857x_probe(struct i2c_client *client, | |||
| 216 | * | 190 | * |
| 217 | * NOTE: we don't distinguish here between *4 and *4a parts. | 191 | * NOTE: we don't distinguish here between *4 and *4a parts. |
| 218 | */ | 192 | */ |
| 219 | gpio->chip.ngpio = id->driver_data; | ||
| 220 | if (gpio->chip.ngpio == 8) { | 193 | if (gpio->chip.ngpio == 8) { |
| 221 | gpio->chip.direction_input = pcf857x_input8; | 194 | gpio->write = i2c_write_le8; |
| 222 | gpio->chip.get = pcf857x_get8; | 195 | gpio->read = i2c_read_le8; |
| 223 | gpio->chip.direction_output = pcf857x_output8; | ||
| 224 | gpio->chip.set = pcf857x_set8; | ||
| 225 | 196 | ||
| 226 | if (!i2c_check_functionality(client->adapter, | 197 | if (!i2c_check_functionality(client->adapter, |
| 227 | I2C_FUNC_SMBUS_BYTE)) | 198 | I2C_FUNC_SMBUS_BYTE)) |
| @@ -238,10 +209,8 @@ static int pcf857x_probe(struct i2c_client *client, | |||
| 238 | * NOTE: we don't distinguish here between '75 and '75c parts. | 209 | * NOTE: we don't distinguish here between '75 and '75c parts. |
| 239 | */ | 210 | */ |
| 240 | } else if (gpio->chip.ngpio == 16) { | 211 | } else if (gpio->chip.ngpio == 16) { |
| 241 | gpio->chip.direction_input = pcf857x_input16; | 212 | gpio->write = i2c_write_le16; |
| 242 | gpio->chip.get = pcf857x_get16; | 213 | gpio->read = i2c_read_le16; |
| 243 | gpio->chip.direction_output = pcf857x_output16; | ||
| 244 | gpio->chip.set = pcf857x_set16; | ||
| 245 | 214 | ||
| 246 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) | 215 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) |
| 247 | status = -EIO; | 216 | status = -EIO; |
diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c index b6453d0e44ad..92f7b2bb79d4 100644 --- a/drivers/gpio/gpio-samsung.c +++ b/drivers/gpio/gpio-samsung.c | |||
| @@ -2681,11 +2681,14 @@ static int exynos_gpio_xlate(struct gpio_chip *gc, | |||
| 2681 | 2681 | ||
| 2682 | if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(gpiospec->args[1]))) | 2682 | if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(gpiospec->args[1]))) |
| 2683 | pr_warn("gpio_xlate: failed to set pin function\n"); | 2683 | pr_warn("gpio_xlate: failed to set pin function\n"); |
| 2684 | if (s3c_gpio_setpull(pin, gpiospec->args[2])) | 2684 | if (s3c_gpio_setpull(pin, gpiospec->args[2] & 0xffff)) |
| 2685 | pr_warn("gpio_xlate: failed to set pin pull up/down\n"); | 2685 | pr_warn("gpio_xlate: failed to set pin pull up/down\n"); |
| 2686 | if (s5p_gpio_set_drvstr(pin, gpiospec->args[3])) | 2686 | if (s5p_gpio_set_drvstr(pin, gpiospec->args[3])) |
| 2687 | pr_warn("gpio_xlate: failed to set pin drive strength\n"); | 2687 | pr_warn("gpio_xlate: failed to set pin drive strength\n"); |
| 2688 | 2688 | ||
| 2689 | if (flags) | ||
| 2690 | *flags = gpiospec->args[2] >> 16; | ||
| 2691 | |||
| 2689 | return gpiospec->args[0]; | 2692 | return gpiospec->args[0]; |
| 2690 | } | 2693 | } |
| 2691 | 2694 | ||
diff --git a/drivers/gpio/gpio-wm8994.c b/drivers/gpio/gpio-wm8994.c index aa61ad2fcaaa..1c764e779d80 100644 --- a/drivers/gpio/gpio-wm8994.c +++ b/drivers/gpio/gpio-wm8994.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/mfd/core.h> | 19 | #include <linux/mfd/core.h> |
| 20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
| 21 | #include <linux/seq_file.h> | 21 | #include <linux/seq_file.h> |
| 22 | #include <linux/regmap.h> | ||
| 22 | 23 | ||
| 23 | #include <linux/mfd/wm8994/core.h> | 24 | #include <linux/mfd/wm8994/core.h> |
| 24 | #include <linux/mfd/wm8994/pdata.h> | 25 | #include <linux/mfd/wm8994/pdata.h> |
| @@ -112,10 +113,7 @@ static int wm8994_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | |||
| 112 | struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip); | 113 | struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip); |
| 113 | struct wm8994 *wm8994 = wm8994_gpio->wm8994; | 114 | struct wm8994 *wm8994 = wm8994_gpio->wm8994; |
| 114 | 115 | ||
| 115 | if (!wm8994->irq_base) | 116 | return regmap_irq_get_virq(wm8994->irq_data, offset); |
| 116 | return -EINVAL; | ||
| 117 | |||
| 118 | return wm8994->irq_base + offset; | ||
| 119 | } | 117 | } |
| 120 | 118 | ||
| 121 | 119 | ||
| @@ -254,7 +252,8 @@ static int __devinit wm8994_gpio_probe(struct platform_device *pdev) | |||
| 254 | struct wm8994_gpio *wm8994_gpio; | 252 | struct wm8994_gpio *wm8994_gpio; |
| 255 | int ret; | 253 | int ret; |
| 256 | 254 | ||
| 257 | wm8994_gpio = kzalloc(sizeof(*wm8994_gpio), GFP_KERNEL); | 255 | wm8994_gpio = devm_kzalloc(&pdev->dev, sizeof(*wm8994_gpio), |
| 256 | GFP_KERNEL); | ||
| 258 | if (wm8994_gpio == NULL) | 257 | if (wm8994_gpio == NULL) |
| 259 | return -ENOMEM; | 258 | return -ENOMEM; |
| 260 | 259 | ||
| @@ -279,20 +278,14 @@ static int __devinit wm8994_gpio_probe(struct platform_device *pdev) | |||
| 279 | return ret; | 278 | return ret; |
| 280 | 279 | ||
| 281 | err: | 280 | err: |
| 282 | kfree(wm8994_gpio); | ||
| 283 | return ret; | 281 | return ret; |
| 284 | } | 282 | } |
| 285 | 283 | ||
| 286 | static int __devexit wm8994_gpio_remove(struct platform_device *pdev) | 284 | static int __devexit wm8994_gpio_remove(struct platform_device *pdev) |
| 287 | { | 285 | { |
| 288 | struct wm8994_gpio *wm8994_gpio = platform_get_drvdata(pdev); | 286 | struct wm8994_gpio *wm8994_gpio = platform_get_drvdata(pdev); |
| 289 | int ret; | ||
| 290 | 287 | ||
| 291 | ret = gpiochip_remove(&wm8994_gpio->gpio_chip); | 288 | return gpiochip_remove(&wm8994_gpio->gpio_chip); |
| 292 | if (ret == 0) | ||
| 293 | kfree(wm8994_gpio); | ||
| 294 | |||
| 295 | return ret; | ||
| 296 | } | 289 | } |
| 297 | 290 | ||
| 298 | static struct platform_driver wm8994_gpio_driver = { | 291 | static struct platform_driver wm8994_gpio_driver = { |
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index d18068a9f3ec..a18c4aa68b1e 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c | |||
| @@ -21,7 +21,7 @@ | |||
| 21 | #include <linux/of_gpio.h> | 21 | #include <linux/of_gpio.h> |
| 22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 23 | 23 | ||
| 24 | /* Private data structure for of_gpiochip_is_match */ | 24 | /* Private data structure for of_gpiochip_find_and_xlate */ |
| 25 | struct gg_data { | 25 | struct gg_data { |
| 26 | enum of_gpio_flags *flags; | 26 | enum of_gpio_flags *flags; |
| 27 | struct of_phandle_args gpiospec; | 27 | struct of_phandle_args gpiospec; |
| @@ -62,7 +62,10 @@ static int of_gpiochip_find_and_xlate(struct gpio_chip *gc, void *data) | |||
| 62 | int of_get_named_gpio_flags(struct device_node *np, const char *propname, | 62 | int of_get_named_gpio_flags(struct device_node *np, const char *propname, |
| 63 | int index, enum of_gpio_flags *flags) | 63 | int index, enum of_gpio_flags *flags) |
| 64 | { | 64 | { |
| 65 | struct gg_data gg_data = { .flags = flags, .out_gpio = -ENODEV }; | 65 | /* Return -EPROBE_DEFER to support probe() functions to be called |
| 66 | * later when the GPIO actually becomes available | ||
| 67 | */ | ||
| 68 | struct gg_data gg_data = { .flags = flags, .out_gpio = -EPROBE_DEFER }; | ||
| 66 | int ret; | 69 | int ret; |
| 67 | 70 | ||
| 68 | /* .of_xlate might decide to not fill in the flags, so clear it. */ | 71 | /* .of_xlate might decide to not fill in the flags, so clear it. */ |
| @@ -73,7 +76,7 @@ int of_get_named_gpio_flags(struct device_node *np, const char *propname, | |||
| 73 | &gg_data.gpiospec); | 76 | &gg_data.gpiospec); |
| 74 | if (ret) { | 77 | if (ret) { |
| 75 | pr_debug("%s: can't parse gpios property\n", __func__); | 78 | pr_debug("%s: can't parse gpios property\n", __func__); |
| 76 | return -EINVAL; | 79 | return ret; |
| 77 | } | 80 | } |
| 78 | 81 | ||
| 79 | gpiochip_find(&gg_data, of_gpiochip_find_and_xlate); | 82 | gpiochip_find(&gg_data, of_gpiochip_find_and_xlate); |
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 120b2a0e3167..de0213c9d11c 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
| @@ -1186,7 +1186,7 @@ int gpio_request(unsigned gpio, const char *label) | |||
| 1186 | { | 1186 | { |
| 1187 | struct gpio_desc *desc; | 1187 | struct gpio_desc *desc; |
| 1188 | struct gpio_chip *chip; | 1188 | struct gpio_chip *chip; |
| 1189 | int status = -EINVAL; | 1189 | int status = -EPROBE_DEFER; |
| 1190 | unsigned long flags; | 1190 | unsigned long flags; |
| 1191 | 1191 | ||
| 1192 | spin_lock_irqsave(&gpio_lock, flags); | 1192 | spin_lock_irqsave(&gpio_lock, flags); |
diff --git a/include/linux/i2c/pca953x.h b/include/linux/i2c/pca953x.h index 139ba52667c8..3c98dd4f901f 100644 --- a/include/linux/i2c/pca953x.h +++ b/include/linux/i2c/pca953x.h | |||
| @@ -11,7 +11,7 @@ struct pca953x_platform_data { | |||
| 11 | unsigned gpio_base; | 11 | unsigned gpio_base; |
| 12 | 12 | ||
| 13 | /* initial polarity inversion setting */ | 13 | /* initial polarity inversion setting */ |
| 14 | uint16_t invert; | 14 | u32 invert; |
| 15 | 15 | ||
| 16 | /* interrupt base */ | 16 | /* interrupt base */ |
| 17 | int irq_base; | 17 | int irq_base; |
