Pull GPIO updates from Linus Walleij: "This is the bulk of GPIO changes for kernel v4.6. There is quite a lot of interesting stuff going on. The patches to other subsystems and arch-wide are ACKed as far as possible, though I consider things like per-arch <asm/gpio.h> as essentially a part of the GPIO subsystem so it should not be needed. Core changes: - The gpio_chip is now a *real device*. Until now the gpio chips were just piggybacking the parent device or (gasp) floating in space outside of the device model. We now finally make GPIO chips devices. The gpio_chip will create a gpio_device which contains a struct device, and this gpio_device struct is kept private. Anything that needs to be kept private from the rest of the kernel will gradually be moved over to the gpio_device. - As a result of making the gpio_device a real device, we have added resource management, so devm_gpiochip_add_data() will cut down on overhead and reduce code lines. A huge slew of patches convert almost all drivers in the subsystem to use this. - Building on making the GPIO a real device, we add the first step of a new userspace ABI: the GPIO character device. We take small steps here, so we first add a pure *information* ABI and the tool "lsgpio" that will list all GPIO devices on the system and all lines on these devices. We can now discover GPIOs properly from userspace. We still have not come up with a way to actually *use* GPIOs from userspace. - To encourage people to use the character device for the future, we have it always-enabled when using GPIO. The old sysfs ABI is still opt-in (and can be used in parallel), but is marked as deprecated. We will keep it around for the foreseeable future, but it will not be extended to cover ever more use cases. Cleanup: - Bjorn Helgaas removed a whole slew of per-architecture <asm/gpio.h> includes. This dates back to when GPIO was an opt-in feature and no shared library even existed: just a header file with proper prototypes was provided and all semantics were up to the arch to implement. These patches make the GPIO chip even more a proper device and cleans out leftovers of the old in-kernel API here and there. Still some cruft is left but it's very little now. - There is still some clamping of return values for .get() going on, but we now return sane values in the vast majority of drivers and the errorpath is sanitized. Some patches for powerpc, blackfin and unicore still drop in. - We continue to switch the ARM, MIPS, blackfin, m68k local GPIO implementations to use gpiochip_add_data() and cut down on code lines. - MPC8xxx is converted to use the generic GPIO helpers. - ATH79 is converted to use the generic GPIO helpers. New drivers: - WinSystems WS16C48 - Acces 104-DIO-48E - F81866 (a F7188x variant) - Qoric (a MPC8xxx variant) - TS-4800 - SPI serializers (pisosr): simple 74xx shift registers connected to SPI to obtain a dirt-cheap output-only GPIO expander. - Texas Instruments TPIC2810 - Texas Instruments TPS65218 - Texas Instruments TPS65912 - X-Gene (ARM64) standby GPIO controller" * tag 'gpio-v4.6-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio: (194 commits) Revert "Share upstreaming patches" gpio: mcp23s08: Fix clearing of interrupt. gpiolib: Fix comment referring to gpio_*() in gpiod_*() gpio: pca953x: Fix pca953x_gpio_set_multiple() on 64-bit gpio: xgene: Fix kconfig for standby GIPO contoller gpio: Add generic serializer DT binding gpio: uapi: use 0xB4 as ioctl() major gpio: tps65912: fix bad merge Revert "gpio: lp3943: Drop pin_used and lp3943_gpio_request/lp3943_gpio_free" gpio: omap: drop dev field from gpio_bank structure gpio: mpc8xxx: Slightly update the code for better readability gpio: mpc8xxx: Remove *read_reg and *write_reg from struct mpc8xxx_gpio_chip gpio: mpc8xxx: Fixup setting gpio direction output gpio: mcp23s08: Add support for mcp23s18 dt-bindings: gpio: altera: Fix altr,interrupt-type property gpio: add driver for MEN 16Z127 GPIO controller gpio: lp3943: Drop pin_used and lp3943_gpio_request/lp3943_gpio_free gpio: timberdale: Switch to devm_ioremap_resource() gpio: ts4800: Add IMX51 dependency gpiolib: rewrite gpiodev_add_to_list ...
Unified · Split
| @@ -1,7 +1,7 @@ | |||
| 1 | What: /sys/class/gpio/ | 1 | What: /sys/class/gpio/ |
| 2 | Date: July 2008 | 2 | Date: July 2008 |
| 3 | KernelVersion: 2.6.27 | 3 | KernelVersion: 2.6.27 |
| 4 | Contact: David Brownell <dbrownell@users.sourceforge.net> | 4 | Contact: Linus Walleij <linusw@kernel.org> |
| 5 | Description: | 5 | Description: |
| 6 | 6 | ||
| 7 | As a Kconfig option, individual GPIO signals may be accessed from | 7 | As a Kconfig option, individual GPIO signals may be accessed from |
| @@ -26,3 +26,5 @@ Description: · 18 unmodified lines | |||
| 26 | /label ... (r/o) descriptive, not necessarily unique | 26 | /label ... (r/o) descriptive, not necessarily unique |
| 27 | /ngpio ... (r/o) number of GPIOs; numbered N to N + (ngpio - 1) | 27 | /ngpio ... (r/o) number of GPIOs; numbered N to N + (ngpio - 1) |
| 28 | 28 | ||
| 29 | This ABI is deprecated and will be removed after 2020. It is | ||
| 30 | replaced with the GPIO character device. | ||
| @@ -0,0 +1,26 @@ | |||
| 1 | What: /dev/gpiochip[0-9]+ | ||
| 2 | Date: November 2015 | ||
| 3 | KernelVersion: 4.4 | ||
| 4 | Contact: linux-gpio@vger.kernel.org | ||
| 5 | Description: | ||
| 6 | The character device files /dev/gpiochip* are the interface | ||
| 7 | between GPIO chips and userspace. | ||
| 8 | |||
| 9 | The ioctl(2)-based ABI is defined and documented in | ||
| 10 | [include/uapi]<linux/gpio.h>. | ||
| 11 | |||
| 12 | The following file operations are supported: | ||
| 13 | |||
| 14 | open(2) | ||
| 15 | Currently the only useful flags are O_RDWR. | ||
| 16 | |||
| 17 | ioctl(2) | ||
| 18 | Initiate various actions. | ||
| 19 | See the inline documentation in [include/uapi]<linux/gpio.h> | ||
| 20 | for descriptions of all ioctls. | ||
| 21 | |||
| 22 | close(2) | ||
| 23 | Stops and free up the I/O contexts that was associated | ||
| 24 | with the file descriptor. | ||
| 25 | |||
| 26 | Users: TBD | ||
| @@ -12,7 +12,7 @@ Required properties: · 11 unmodified lines | |||
| 12 | - #interrupt-cells : Should be 1. The interrupt type is fixed in the hardware. | 12 | - #interrupt-cells : Should be 1. The interrupt type is fixed in the hardware. |
| 13 | - The first cell is the GPIO offset number within the GPIO controller. | 13 | - The first cell is the GPIO offset number within the GPIO controller. |
| 14 | - interrupts: Specify the interrupt. | 14 | - interrupts: Specify the interrupt. |
| 15 | - altr,interrupt-trigger: Specifies the interrupt trigger type the GPIO | 15 | - altr,interrupt-type: Specifies the interrupt trigger type the GPIO |
| 16 | hardware is synthesized. This field is required if the Altera GPIO controller | 16 | hardware is synthesized. This field is required if the Altera GPIO controller |
| 17 | used has IRQ enabled as the interrupt type is not software controlled, | 17 | used has IRQ enabled as the interrupt type is not software controlled, |
| 18 | but hardware synthesized. Required if GPIO is used as an interrupt | 18 | but hardware synthesized. Required if GPIO is used as an interrupt |
| @@ -35,7 +35,7 @@ gpio_altr: gpio@0xff200000 { · 16 unmodified lines | |||
| 35 | reg = <0xff200000 0x10>; | 35 | reg = <0xff200000 0x10>; |
| 36 | interrupts = <0 45 4>; | 36 | interrupts = <0 45 4>; |
| 37 | altr,ngpio = <32>; | 37 | altr,ngpio = <32>; |
| 38 | altr,interrupt-trigger = <IRQ_TYPE_EDGE_RISING>; | 38 | altr,interrupt-type = <IRQ_TYPE_EDGE_RISING>; |
| 39 | #gpio-cells = <2>; | 39 | #gpio-cells = <2>; |
| 40 | gpio-controller; | 40 | gpio-controller; |
| 41 | #interrupt-cells = <1>; | 41 | #interrupt-cells = <1>; |
| @@ -10,6 +10,7 @@ Required properties: · 9 unmodified lines | |||
| 10 | 10 | ||
| 11 | - "microchip,mcp23s08" for 8 GPIO SPI version | 11 | - "microchip,mcp23s08" for 8 GPIO SPI version |
| 12 | - "microchip,mcp23s17" for 16 GPIO SPI version | 12 | - "microchip,mcp23s17" for 16 GPIO SPI version |
| 13 | - "microchip,mcp23s18" for 16 GPIO SPI version | ||
| 13 | - "microchip,mcp23008" for 8 GPIO I2C version or | 14 | - "microchip,mcp23008" for 8 GPIO I2C version or |
| 14 | - "microchip,mcp23017" for 16 GPIO I2C version of the chip | 15 | - "microchip,mcp23017" for 16 GPIO I2C version of the chip |
| 15 | NOTE: Do not use the old mcp prefix any more. It is deprecated and will be | 16 | NOTE: Do not use the old mcp prefix any more. It is deprecated and will be |
| @@ -43,9 +44,6 @@ Optional properties: · 27 unmodified lines | |||
| 43 | - first cell is the pin number | 44 | - first cell is the pin number |
| 44 | - second cell is used to specify flags. | 45 | - second cell is used to specify flags. |
| 45 | - interrupt-controller: Marks the device node as a interrupt controller. | 46 | - interrupt-controller: Marks the device node as a interrupt controller. |
| 46 | NOTE: The interrupt functionality is only supported for i2c versions of the | ||
| 47 | chips. The spi chips can also do the interrupts, but this is not supported by | ||
| 48 | the linux driver yet. | ||
| 49 | 47 | ||
| 50 | Optional device specific properties: | 48 | Optional device specific properties: |
| 51 | - microchip,irq-mirror: Sets the mirror flag in the IOCON register. Devices | 49 | - microchip,irq-mirror: Sets the mirror flag in the IOCON register. Devices |
| @@ -0,0 +1,34 @@ | |||
| 1 | Generic Parallel-in/Serial-out Shift Register GPIO Driver | ||
| 2 | |||
| 3 | This binding describes generic parallel-in/serial-out shift register | ||
| 4 | devices that can be used for GPI (General Purpose Input). This includes | ||
| 5 | SN74165 serial-out shift registers and the SN65HVS88x series of | ||
| 6 | industrial serializers. | ||
| 7 | |||
| 8 | Required properties: | ||
| 9 | - compatible : Should be "pisosr-gpio". | ||
| 10 | - gpio-controller : Marks the device node as a GPIO controller. | ||
| 11 | - #gpio-cells : Should be two. For consumer use see gpio.txt. | ||
| 12 | |||
| 13 | Optional properties: | ||
| 14 | - ngpios : Number of used GPIO lines (0..n-1), default is 8. | ||
| 15 | - load-gpios : GPIO pin specifier attached to load enable, this | ||
| 16 | pin is pulsed before reading from the device to | ||
| 17 | load input pin values into the the device. | ||
| 18 | |||
| 19 | For other required and optional properties of SPI slave | ||
| 20 | nodes please refer to ../spi/spi-bus.txt. | ||
| 21 | |||
| 22 | Example: | ||
| 23 | |||
| 24 | gpio@0 { | ||
| 25 | compatible = "ti,sn65hvs882", "pisosr-gpio"; | ||
| 26 | gpio-controller; | ||
| 27 | #gpio-cells = <2>; | ||
| 28 | |||
| 29 | load-gpios = <&gpio2 23 GPIO_ACTIVE_LOW>; | ||
| 30 | |||
| 31 | reg = <0>; | ||
| 32 | spi-max-frequency = <1000000>; | ||
| 33 | spi-cpol; | ||
| 34 | }; | ||
| @@ -0,0 +1,20 @@ | |||
| 1 | * TS-4800 FPGA's GPIO controller bindings | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible: Must be "technologic,ts4800-gpio". | ||
| 5 | - #gpio-cells: Should be two. The first cell is the pin number. | ||
| 6 | - reg: Physical base address of the controller and length | ||
| 7 | of memory mapped region. | ||
| 8 | |||
| 9 | Optional property: | ||
| 10 | - ngpios: See "gpio.txt" | ||
| 11 | |||
| 12 | Example: | ||
| 13 | |||
| 14 | gpio1: gpio { | ||
| 15 | compatible = "technologic,ts4800-gpio"; | ||
| 16 | reg = <0x10020 0x6>; | ||
| 17 | ngpios = <8>; | ||
| 18 | gpio-controller; | ||
| 19 | #gpio-cells = <2>; | ||
| 20 | }; | ||
| @@ -1,10 +1,20 @@ | |||
| 1 | APM X-Gene Standby GPIO controller bindings | 1 | APM X-Gene Standby GPIO controller bindings |
| 2 | 2 | ||
| 3 | This is a gpio controller in the standby domain. | 3 | This is a gpio controller in the standby domain. It also supports interrupt in |
| 4 | 4 | some particular pins which are sourced to its parent interrupt controller | |
| 5 | There are 20 GPIO pins from 0..21. There is no GPIO_DS14 or GPIO_DS15, | 5 | as diagram below: |
| 6 | only GPIO_DS8..GPIO_DS13 support interrupts. The IRQ mapping | 6 | +-----------------+ |
| 7 | is currently 1-to-1 on interrupts 0x28 thru 0x2d. | 7 | | X-Gene standby | |
| 8 | | GPIO controller +------ GPIO_0 | ||
| 9 | +------------+ | | ... | ||
| 10 | | Parent IRQ | EXT_INT_0 | +------ GPIO_8/EXT_INT_0 | ||
| 11 | | controller | (SPI40) | | ... | ||
| 12 | | (GICv2) +--------------+ +------ GPIO_[N+8]/EXT_INT_N | ||
| 13 | | | ... | | | ||
| 14 | | | EXT_INT_N | +------ GPIO_[N+9] | ||
| 15 | | | (SPI[40 + N])| | ... | ||
| 16 | | +--------------+ +------ GPIO_MAX | ||
| 17 | +------------+ +-----------------+ | ||
| 8 | 18 | ||
| 9 | Required properties: | 19 | Required properties: |
| 10 | - compatible: "apm,xgene-gpio-sb" for the X-Gene Standby GPIO controller | 20 | - compatible: "apm,xgene-gpio-sb" for the X-Gene Standby GPIO controller |
| @@ -15,10 +25,18 @@ Required properties: · 4 unmodified lines | |||
| 15 | 0 = active high | 25 | 0 = active high |
| 16 | 1 = active low | 26 | 1 = active low |
| 17 | - gpio-controller: Marks the device node as a GPIO controller. | 27 | - gpio-controller: Marks the device node as a GPIO controller. |
| 18 | - interrupts: Shall contain exactly 6 interrupts. | 28 | - interrupts: The EXT_INT_0 parent interrupt resource must be listed first. |
| 29 | - interrupt-parent: Phandle of the parent interrupt controller. | ||
| 30 | - interrupt-cells: Should be two. | ||
| 31 | - first cell is 0-N coresponding for EXT_INT_0 to EXT_INT_N. | ||
| 32 | - second cell is used to specify flags. | ||
| 33 | - interrupt-controller: Marks the device node as an interrupt controller. | ||
| 34 | - apm,nr-gpios: Optional, specify number of gpios pin. | ||
| 35 | - apm,nr-irqs: Optional, specify number of interrupt pins. | ||
| 36 | - apm,irq-start: Optional, specify lowest gpio pin support interrupt. | ||
| 19 | 37 | ||
| 20 | Example: | 38 | Example: |
| 21 | sbgpio: sbgpio@17001000 { | 39 | sbgpio: gpio@17001000{ |
| 22 | compatible = "apm,xgene-gpio-sb"; | 40 | compatible = "apm,xgene-gpio-sb"; |
| 23 | reg = <0x0 0x17001000 0x0 0x400>; | 41 | reg = <0x0 0x17001000 0x0 0x400>; |
| 24 | #gpio-cells = <2>; | 42 | #gpio-cells = <2>; |
| @@ -29,4 +47,19 @@ Example: · 4 unmodified lines | |||
| 29 | <0x0 0x2b 0x1>, | 47 | <0x0 0x2b 0x1>, |
| 30 | <0x0 0x2c 0x1>, | 48 | <0x0 0x2c 0x1>, |
| 31 | <0x0 0x2d 0x1>; | 49 | <0x0 0x2d 0x1>; |
| 50 | interrupt-parent = <&gic>; | ||
| 51 | #interrupt-cells = <2>; | ||
| 52 | interrupt-controller; | ||
| 53 | apm,nr-gpios = <22>; | ||
| 54 | apm,nr-irqs = <6>; | ||
| 55 | apm,irq-start = <8>; | ||
| 56 | }; | ||
| 57 | |||
| 58 | testuser { | ||
| 59 | compatible = "example,testuser"; | ||
| 60 | /* Use the GPIO_13/EXT_INT_5 line as an active high triggered | ||
| 61 | * level interrupt | ||
| 62 | */ | ||
| 63 | interrupts = <5 4>; | ||
| 64 | interrupt-parent = <&sbgpio>; | ||
| 32 | }; | 65 | }; |
| @@ -0,0 +1,50 @@ | |||
| 1 | * TPS65912 Power Management Integrated Circuit bindings | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible : Should be "ti,tps65912". | ||
| 5 | - reg : Slave address or chip select number (I2C / SPI). | ||
| 6 | - interrupt-parent : The parent interrupt controller. | ||
| 7 | - interrupts : The interrupt line the device is connected to. | ||
| 8 | - interrupt-controller : Marks the device node as an interrupt controller. | ||
| 9 | - #interrupt-cells : The number of cells to describe an IRQ, should be 2. | ||
| 10 | The first cell is the IRQ number. | ||
| 11 | The second cell is the flags, encoded as trigger | ||
| 12 | masks from ../interrupt-controller/interrupts.txt. | ||
| 13 | - gpio-controller : Marks the device node as a GPIO Controller. | ||
| 14 | - #gpio-cells : Should be two. The first cell is the pin number and | ||
| 15 | the second cell is used to specify flags. | ||
| 16 | See ../gpio/gpio.txt for more information. | ||
| 17 | - regulators: : List of child nodes that specify the regulator | ||
| 18 | initialization data. Child nodes must be named | ||
| 19 | after their hardware counterparts: dcdc[1-4] and | ||
| 20 | ldo[1-10]. Each child nodes is defined using the | ||
| 21 | standard binding for regulators. | ||
| 22 | |||
| 23 | Example: | ||
| 24 | |||
| 25 | pmic: tps65912@2d { | ||
| 26 | compatible = "ti,tps65912"; | ||
| 27 | reg = <0x2d>; | ||
| 28 | interrupt-parent = <&gpio1>; | ||
| 29 | interrupts = <28 IRQ_TYPE_LEVEL_LOW>; | ||
| 30 | interrupt-controller; | ||
| 31 | #interrupt-cells = <2>; | ||
| 32 | gpio-controller; | ||
| 33 | #gpio-cells = <2>; | ||
| 34 | |||
| 35 | regulators { | ||
| 36 | dcdc1 { | ||
| 37 | regulator-name = "vdd_core"; | ||
| 38 | regulator-min-microvolt = <912000>; | ||
| 39 | regulator-max-microvolt = <1144000>; | ||
| 40 | regulator-boot-on; | ||
| 41 | regulator-always-on; | ||
| 42 | }; | ||
| 43 | |||
| 44 | ldo1 { | ||
| 45 | regulator-name = "ldo1"; | ||
| 46 | regulator-min-microvolt = <1900000>; | ||
| 47 | regulator-max-microvolt = <1900000>; | ||
| 48 | }; | ||
| 49 | }; | ||
| 50 | }; | ||
| @@ -252,6 +252,11 @@ GPIO · 251 unmodified lines | |||
| 252 | devm_gpiod_get_index_optional() | 252 | devm_gpiod_get_index_optional() |
| 253 | devm_gpiod_get_optional() | 253 | devm_gpiod_get_optional() |
| 254 | devm_gpiod_put() | 254 | devm_gpiod_put() |
| 255 | devm_gpiochip_add_data() | ||
| 256 | devm_gpiochip_remove() | ||
| 257 | devm_gpio_request() | ||
| 258 | devm_gpio_request_one() | ||
| 259 | devm_gpio_free() | ||
| 255 | 260 | ||
| 256 | IIO | 261 | IIO |
| 257 | devm_iio_device_alloc() | 262 | devm_iio_device_alloc() |
| @@ -111,16 +111,13 @@ files that desire to do so need to include the following header: · 110 unmodified lines | |||
| 111 | GPIOs are mapped by the means of tables of lookups, containing instances of the | 111 | GPIOs are mapped by the means of tables of lookups, containing instances of the |
| 112 | gpiod_lookup structure. Two macros are defined to help declaring such mappings: | 112 | gpiod_lookup structure. Two macros are defined to help declaring such mappings: |
| 113 | 113 | ||
| 114 | GPIO_LOOKUP(chip_label, chip_hwnum, dev_id, con_id, flags) | 114 | GPIO_LOOKUP(chip_label, chip_hwnum, con_id, flags) |
| 115 | GPIO_LOOKUP_IDX(chip_label, chip_hwnum, dev_id, con_id, idx, flags) | 115 | GPIO_LOOKUP_IDX(chip_label, chip_hwnum, con_id, idx, flags) |
| 116 | 116 | ||
| 117 | where | 117 | where |
| 118 | 118 | ||
| 119 | - chip_label is the label of the gpiod_chip instance providing the GPIO | 119 | - chip_label is the label of the gpiod_chip instance providing the GPIO |
| 120 | - chip_hwnum is the hardware number of the GPIO within the chip | 120 | - chip_hwnum is the hardware number of the GPIO within the chip |
| 121 | - dev_id is the identifier of the device that will make use of this GPIO. It | ||
| 122 | can be NULL, in which case it will be matched for calls to gpiod_get() | ||
| 123 | with a NULL device. | ||
| 124 | - con_id is the name of the GPIO function from the device point of view. It | 121 | - con_id is the name of the GPIO function from the device point of view. It |
| 125 | can be NULL, in which case it will match any function. | 122 | can be NULL, in which case it will match any function. |
| 126 | - idx is the index of the GPIO within the function. | 123 | - idx is the index of the GPIO within the function. |
| @@ -134,7 +131,9 @@ In the future, these flags might be extended to support more properties. · 7 unmodified lines | |||
| 134 | Note that GPIO_LOOKUP() is just a shortcut to GPIO_LOOKUP_IDX() where idx = 0. | 131 | Note that GPIO_LOOKUP() is just a shortcut to GPIO_LOOKUP_IDX() where idx = 0. |
| 135 | 132 | ||
| 136 | A lookup table can then be defined as follows, with an empty entry defining its | 133 | A lookup table can then be defined as follows, with an empty entry defining its |
| 137 | end: | 134 | end. The 'dev_id' field of the table is the identifier of the device that will |
| 135 | make use of these GPIOs. It can be NULL, in which case it will be matched for | ||
| 136 | calls to gpiod_get() with a NULL device. | ||
| 138 | 137 | ||
| 139 | struct gpiod_lookup_table gpios_table = { | 138 | struct gpiod_lookup_table gpios_table = { |
| 140 | .dev_id = "foo.0", | 139 | .dev_id = "foo.0", |
| @@ -319,6 +319,7 @@ Code Seq#(hex) Include File Comments · 318 unmodified lines | |||
| 319 | <mailto:vgo@ratio.de> | 319 | <mailto:vgo@ratio.de> |
| 320 | 0xB1 00-1F PPPoX <mailto:mostrows@styx.uwaterloo.ca> | 320 | 0xB1 00-1F PPPoX <mailto:mostrows@styx.uwaterloo.ca> |
| 321 | 0xB3 00 linux/mmc/ioctl.h | 321 | 0xB3 00 linux/mmc/ioctl.h |
| 322 | 0xB4 00-0F linux/gpio.h <mailto:linux-gpio@vger.kernel.org> | ||
| 322 | 0xC0 00-0F linux/usb/iowarrior.h | 323 | 0xC0 00-0F linux/usb/iowarrior.h |
| 323 | 0xCA 00-0F uapi/misc/cxl.h | 324 | 0xCA 00-0F uapi/misc/cxl.h |
| 324 | 0xCA 80-8F uapi/scsi/cxlflash_ioctl.h | 325 | 0xCA 80-8F uapi/scsi/cxlflash_ioctl.h |
| @@ -238,6 +238,12 @@ L: lm-sensors@lm-sensors.org · 237 unmodified lines | |||
| 238 | S: Maintained | 238 | S: Maintained |
| 239 | F: drivers/hwmon/abituguru3.c | 239 | F: drivers/hwmon/abituguru3.c |
| 240 | 240 | ||
| 241 | ACCES 104-DIO-48E GPIO DRIVER | ||
| 242 | M: William Breathitt Gray <vilhelm.gray@gmail.com> | ||
| 243 | L: linux-gpio@vger.kernel.org | ||
| 244 | S: Maintained | ||
| 245 | F: drivers/gpio/gpio-104-dio-48e.c | ||
| 246 | |||
| 241 | ACCES 104-IDI-48 GPIO DRIVER | 247 | ACCES 104-IDI-48 GPIO DRIVER |
| 242 | M: "William Breathitt Gray" <vilhelm.gray@gmail.com> | 248 | M: "William Breathitt Gray" <vilhelm.gray@gmail.com> |
| 243 | L: linux-gpio@vger.kernel.org | 249 | L: linux-gpio@vger.kernel.org |
| @@ -4827,10 +4833,14 @@ L: linux-gpio@vger.kernel.org · 4583 unmodified lines | |||
| 4827 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git | 4833 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git |
| 4828 | S: Maintained | 4834 | S: Maintained |
| 4829 | F: Documentation/gpio/ | 4835 | F: Documentation/gpio/ |
| 4836 | F: Documentation/ABI/testing/gpio-cdev | ||
| 4837 | F: Documentation/ABI/obsolete/sysfs-gpio | ||
| 4830 | F: drivers/gpio/ | 4838 | F: drivers/gpio/ |
| 4831 | F: include/linux/gpio/ | 4839 | F: include/linux/gpio/ |
| 4832 | F: include/linux/gpio.h | 4840 | F: include/linux/gpio.h |
| 4833 | F: include/asm-generic/gpio.h | 4841 | F: include/asm-generic/gpio.h |
| 4842 | F: include/uapi/linux/gpio.h | ||
| 4843 | F: tools/gpio/ | ||
| 4834 | 4844 | ||
| 4835 | GRE DEMULTIPLEXER DRIVER | 4845 | GRE DEMULTIPLEXER DRIVER |
| 4836 | M: Dmitry Kozlov <xeb@mail.ru> | 4846 | M: Dmitry Kozlov <xeb@mail.ru> |
| @@ -11931,6 +11941,12 @@ M: David Härdeman <david@hardeman.nu> · 7094 unmodified lines | |||
| 11931 | S: Maintained | 11941 | S: Maintained |
| 11932 | F: drivers/media/rc/winbond-cir.c | 11942 | F: drivers/media/rc/winbond-cir.c |
| 11933 | 11943 | ||
| 11944 | WINSYSTEMS WS16C48 GPIO DRIVER | ||
| 11945 | M: William Breathitt Gray <vilhelm.gray@gmail.com> | ||
| 11946 | L: linux-gpio@vger.kernel.org | ||
| 11947 | S: Maintained | ||
| 11948 | F: drivers/gpio/gpio-ws16c48.c | ||
| 11949 | |||
| 11934 | WIMAX STACK | 11950 | WIMAX STACK |
| 11935 | M: Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> | 11951 | M: Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> |
| 11936 | M: linux-wimax@intel.com | 11952 | M: linux-wimax@intel.com |
| @@ -1,4 +0,0 @@ | |||
| 1 | #ifndef __LINUX_GPIO_H | ||
| 2 | #warning Include linux/gpio.h instead of asm/gpio.h | ||
| 3 | #include <linux/gpio.h> | ||
| 4 | #endif | ||
| @@ -69,7 +69,7 @@ static void __scoop_gpio_set(struct scoop_dev *sdev, · 68 unmodified lines | |||
| 69 | 69 | ||
| 70 | static void scoop_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | 70 | static void scoop_gpio_set(struct gpio_chip *chip, unsigned offset, int value) |
| 71 | { | 71 | { |
| 72 | struct scoop_dev *sdev = container_of(chip, struct scoop_dev, gpio); | 72 | struct scoop_dev *sdev = gpiochip_get_data(chip); |
| 73 | unsigned long flags; | 73 | unsigned long flags; |
| 74 | 74 | ||
| 75 | spin_lock_irqsave(&sdev->scoop_lock, flags); | 75 | spin_lock_irqsave(&sdev->scoop_lock, flags); |
| @@ -81,7 +81,7 @@ static void scoop_gpio_set(struct gpio_chip *chip, unsigned offset, int value) · 5 unmodified lines | |||
| 81 | 81 | ||
| 82 | static int scoop_gpio_get(struct gpio_chip *chip, unsigned offset) | 82 | static int scoop_gpio_get(struct gpio_chip *chip, unsigned offset) |
| 83 | { | 83 | { |
| 84 | struct scoop_dev *sdev = container_of(chip, struct scoop_dev, gpio); | 84 | struct scoop_dev *sdev = gpiochip_get_data(chip); |
| 85 | 85 | ||
| 86 | /* XXX: I'm unsure, but it seems so */ | 86 | /* XXX: I'm unsure, but it seems so */ |
| 87 | return !!(ioread16(sdev->base + SCOOP_GPRR) & (1 << (offset + 1))); | 87 | return !!(ioread16(sdev->base + SCOOP_GPRR) & (1 << (offset + 1))); |
| @@ -90,7 +90,7 @@ static int scoop_gpio_get(struct gpio_chip *chip, unsigned offset) · 2 unmodified lines | |||
| 90 | static int scoop_gpio_direction_input(struct gpio_chip *chip, | 90 | static int scoop_gpio_direction_input(struct gpio_chip *chip, |
| 91 | unsigned offset) | 91 | unsigned offset) |
| 92 | { | 92 | { |
| 93 | struct scoop_dev *sdev = container_of(chip, struct scoop_dev, gpio); | 93 | struct scoop_dev *sdev = gpiochip_get_data(chip); |
| 94 | unsigned long flags; | 94 | unsigned long flags; |
| 95 | unsigned short gpcr; | 95 | unsigned short gpcr; |
| 96 | 96 | ||
| @@ -108,7 +108,7 @@ static int scoop_gpio_direction_input(struct gpio_chip *chip, · 11 unmodified lines | |||
| 108 | static int scoop_gpio_direction_output(struct gpio_chip *chip, | 108 | static int scoop_gpio_direction_output(struct gpio_chip *chip, |
| 109 | unsigned offset, int value) | 109 | unsigned offset, int value) |
| 110 | { | 110 | { |
| 111 | struct scoop_dev *sdev = container_of(chip, struct scoop_dev, gpio); | 111 | struct scoop_dev *sdev = gpiochip_get_data(chip); |
| 112 | unsigned long flags; | 112 | unsigned long flags; |
| 113 | unsigned short gpcr; | 113 | unsigned short gpcr; |
| 114 | 114 | ||
| @@ -224,7 +224,7 @@ static int scoop_probe(struct platform_device *pdev) · 109 unmodified lines | |||
| 224 | devptr->gpio.direction_input = scoop_gpio_direction_input; | 224 | devptr->gpio.direction_input = scoop_gpio_direction_input; |
| 225 | devptr->gpio.direction_output = scoop_gpio_direction_output; | 225 | devptr->gpio.direction_output = scoop_gpio_direction_output; |
| 226 | 226 | ||
| 227 | ret = gpiochip_add(&devptr->gpio); | 227 | ret = gpiochip_add_data(&devptr->gpio, devptr); |
| 228 | if (ret) | 228 | if (ret) |
| 229 | goto err_gpio; | 229 | goto err_gpio; |
| 230 | } | 230 | } |
| @@ -17,7 +17,7 @@ · 16 unmodified lines | |||
| 17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
| 18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
| 19 | #include <linux/irq.h> | 19 | #include <linux/irq.h> |
| 20 | #include <linux/gpio.h> | 20 | #include <linux/gpio/driver.h> |
| 21 | 21 | ||
| 22 | #include <mach/hardware.h> | 22 | #include <mach/hardware.h> |
| 23 | #include <mach/irqs.h> | 23 | #include <mach/irqs.h> |
| @@ -227,5 +227,5 @@ void __init gemini_gpio_init(void) · 203 unmodified lines | |||
| 227 | (void *)i); | 227 | (void *)i); |
| 228 | } | 228 | } |
| 229 | 229 | ||
| 230 | BUG_ON(gpiochip_add(&gemini_gpio_chip)); | 230 | BUG_ON(gpiochip_add_data(&gemini_gpio_chip, NULL)); |
| 231 | } | 231 | } |
| @@ -13,6 +13,8 @@ · 12 unmodified lines | |||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
| 15 | */ | 15 | */ |
| 16 | #include <linux/gpio/driver.h> | ||
| 17 | /* Needed for gpio_to_irq() */ | ||
| 16 | #include <linux/gpio.h> | 18 | #include <linux/gpio.h> |
| 17 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
| 18 | #include <linux/mtd/mtd.h> | 20 | #include <linux/mtd/mtd.h> |
| @@ -243,7 +245,7 @@ static void __init mx27ads_regulator_init(void) · 224 unmodified lines | |||
| 243 | vchip->ngpio = 1; | 245 | vchip->ngpio = 1; |
| 244 | vchip->direction_output = vgpio_dir_out; | 246 | vchip->direction_output = vgpio_dir_out; |
| 245 | vchip->set = vgpio_set; | 247 | vchip->set = vgpio_set; |
| 246 | gpiochip_add(vchip); | 248 | gpiochip_add_data(vchip, NULL); |
| 247 | 249 | ||
| 248 | platform_device_register_data(NULL, "reg-fixed-voltage", | 250 | platform_device_register_data(NULL, "reg-fixed-voltage", |
| 249 | PLATFORM_DEVID_AUTO, | 251 | PLATFORM_DEVID_AUTO, |
| @@ -27,7 +27,7 @@ · 26 unmodified lines | |||
| 27 | #include <linux/clockchips.h> | 27 | #include <linux/clockchips.h> |
| 28 | #include <linux/io.h> | 28 | #include <linux/io.h> |
| 29 | #include <linux/export.h> | 29 | #include <linux/export.h> |
| 30 | #include <linux/gpio.h> | 30 | #include <linux/gpio/driver.h> |
| 31 | #include <linux/cpu.h> | 31 | #include <linux/cpu.h> |
| 32 | #include <linux/pci.h> | 32 | #include <linux/pci.h> |
| 33 | #include <linux/sched_clock.h> | 33 | #include <linux/sched_clock.h> |
| @@ -461,7 +461,7 @@ void __init ixp4xx_sys_init(void) · 427 unmodified lines | |||
| 461 | 461 | ||
| 462 | platform_add_devices(ixp4xx_devices, ARRAY_SIZE(ixp4xx_devices)); | 462 | platform_add_devices(ixp4xx_devices, ARRAY_SIZE(ixp4xx_devices)); |
| 463 | 463 | ||
| 464 | gpiochip_add(&ixp4xx_gpio_chip); | 464 | gpiochip_add_data(&ixp4xx_gpio_chip, NULL); |
| 465 | 465 | ||
| 466 | if (cpu_is_ixp46x()) { | 466 | if (cpu_is_ixp46x()) { |
| 467 | int region; | 467 | int region; |
| @@ -664,7 +664,7 @@ static void __init h1940_map_io(void) · 663 unmodified lines | |||
| 664 | 664 | ||
| 665 | /* Add latch gpio chip, set latch initial value */ | 665 | /* Add latch gpio chip, set latch initial value */ |
| 666 | h1940_latch_control(0, 0); | 666 | h1940_latch_control(0, 0); |
| 667 | WARN_ON(gpiochip_add(&h1940_latch_gpiochip)); | 667 | WARN_ON(gpiochip_add_data(&h1940_latch_gpiochip, NULL)); |
| 668 | } | 668 | } |
| 669 | 669 | ||
| 670 | static void __init h1940_init_time(void) | 670 | static void __init h1940_init_time(void) |
| @@ -15,7 +15,7 @@ · 14 unmodified lines | |||
| 15 | #include <linux/mtd/mtd.h> | 15 | #include <linux/mtd/mtd.h> |
| 16 | #include <linux/mtd/partitions.h> | 16 | #include <linux/mtd/partitions.h> |
| 17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
| 18 | #include <linux/gpio.h> | 18 | #include <linux/gpio/driver.h> |
| 19 | 19 | ||
| 20 | #include <mach/hardware.h> | 20 | #include <mach/hardware.h> |
| 21 | #include <asm/setup.h> | 21 | #include <asm/setup.h> |
| @@ -369,7 +369,7 @@ static int __init simpad_init(void) · 347 unmodified lines | |||
| 369 | cs3_gpio.get = cs3_gpio_get; | 369 | cs3_gpio.get = cs3_gpio_get; |
| 370 | cs3_gpio.direction_input = cs3_gpio_direction_input; | 370 | cs3_gpio.direction_input = cs3_gpio_direction_input; |
| 371 | cs3_gpio.direction_output = cs3_gpio_direction_output; | 371 | cs3_gpio.direction_output = cs3_gpio_direction_output; |
| 372 | ret = gpiochip_add(&cs3_gpio); | 372 | ret = gpiochip_add_data(&cs3_gpio, NULL); |
| 373 | if (ret) | 373 | if (ret) |
| 374 | printk(KERN_WARNING "simpad: Unable to register cs3 GPIO device"); | 374 | printk(KERN_WARNING "simpad: Unable to register cs3 GPIO device"); |
| 375 | 375 | ||
| @@ -20,7 +20,7 @@ · 19 unmodified lines | |||
| 20 | #include <linux/list.h> | 20 | #include <linux/list.h> |
| 21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
| 22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
| 23 | #include <linux/gpio.h> | 23 | #include <linux/gpio/driver.h> |
| 24 | 24 | ||
| 25 | #include <mach/hardware.h> | 25 | #include <mach/hardware.h> |
| 26 | 26 | ||
| @@ -30,7 +30,6 @@ · 3 unmodified lines | |||
| 30 | #define GPIO_IN (0x0C) | 30 | #define GPIO_IN (0x0C) |
| 31 | #define GROUPINERV (0x10) | 31 | #define GROUPINERV (0x10) |
| 32 | #define GPIO_GPIO(Nb) (0x00000001 << (Nb)) | 32 | #define GPIO_GPIO(Nb) (0x00000001 << (Nb)) |
| 33 | #define to_nuc900_gpio_chip(c) container_of(c, struct nuc900_gpio_chip, chip) | ||
| 34 | 33 | ||
| 35 | #define NUC900_GPIO_CHIP(name, base_gpio, nr_gpio) \ | 34 | #define NUC900_GPIO_CHIP(name, base_gpio, nr_gpio) \ |
| 36 | { \ | 35 | { \ |
| @@ -53,7 +52,7 @@ struct nuc900_gpio_chip { · 16 unmodified lines | |||
| 53 | 52 | ||
| 54 | static int nuc900_gpio_get(struct gpio_chip *chip, unsigned offset) | 53 | static int nuc900_gpio_get(struct gpio_chip *chip, unsigned offset) |
| 55 | { | 54 | { |
| 56 | struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip); | 55 | struct nuc900_gpio_chip *nuc900_gpio = gpiochip_get_data(chip); |
| 57 | void __iomem *pio = nuc900_gpio->regbase + GPIO_IN; | 56 | void __iomem *pio = nuc900_gpio->regbase + GPIO_IN; |
| 58 | unsigned int regval; | 57 | unsigned int regval; |
| 59 | 58 | ||
| @@ -65,7 +64,7 @@ static int nuc900_gpio_get(struct gpio_chip *chip, unsigned offset) · 5 unmodified lines | |||
| 65 | 64 | ||
| 66 | static void nuc900_gpio_set(struct gpio_chip *chip, unsigned offset, int val) | 65 | static void nuc900_gpio_set(struct gpio_chip *chip, unsigned offset, int val) |
| 67 | { | 66 | { |
| 68 | struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip); | 67 | struct nuc900_gpio_chip *nuc900_gpio = gpiochip_get_data(chip); |
| 69 | void __iomem *pio = nuc900_gpio->regbase + GPIO_OUT; | 68 | void __iomem *pio = nuc900_gpio->regbase + GPIO_OUT; |
| 70 | unsigned int regval; | 69 | unsigned int regval; |
| 71 | unsigned long flags; | 70 | unsigned long flags; |
| @@ -86,7 +85,7 @@ static void nuc900_gpio_set(struct gpio_chip *chip, unsigned offset, int val) · 14 unmodified lines | |||
| 86 | 85 | ||
| 87 | static int nuc900_dir_input(struct gpio_chip *chip, unsigned offset) | 86 | static int nuc900_dir_input(struct gpio_chip *chip, unsigned offset) |
| 88 | { | 87 | { |
| 89 | struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip); | 88 | struct nuc900_gpio_chip *nuc900_gpio = gpiochip_get_data(chip); |
| 90 | void __iomem *pio = nuc900_gpio->regbase + GPIO_DIR; | 89 | void __iomem *pio = nuc900_gpio->regbase + GPIO_DIR; |
| 91 | unsigned int regval; | 90 | unsigned int regval; |
| 92 | unsigned long flags; | 91 | unsigned long flags; |
| @@ -104,7 +103,7 @@ static int nuc900_dir_input(struct gpio_chip *chip, unsigned offset) · 11 unmodified lines | |||
| 104 | 103 | ||
| 105 | static int nuc900_dir_output(struct gpio_chip *chip, unsigned offset, int val) | 104 | static int nuc900_dir_output(struct gpio_chip *chip, unsigned offset, int val) |
| 106 | { | 105 | { |
| 107 | struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip); | 106 | struct nuc900_gpio_chip *nuc900_gpio = gpiochip_get_data(chip); |
| 108 | void __iomem *outreg = nuc900_gpio->regbase + GPIO_OUT; | 107 | void __iomem *outreg = nuc900_gpio->regbase + GPIO_OUT; |
| 109 | void __iomem *pio = nuc900_gpio->regbase + GPIO_DIR; | 108 | void __iomem *pio = nuc900_gpio->regbase + GPIO_DIR; |
| 110 | unsigned int regval; | 109 | unsigned int regval; |
| @@ -149,6 +148,6 @@ void __init nuc900_init_gpio(int nr_group) · 38 unmodified lines | |||
| 149 | gpio_chip = &nuc900_gpio[i]; | 148 | gpio_chip = &nuc900_gpio[i]; |
| 150 | spin_lock_init(&gpio_chip->gpio_lock); | 149 | spin_lock_init(&gpio_chip->gpio_lock); |
| 151 | gpio_chip->regbase = GPIO_BASE + i * GROUPINERV; | 150 | gpio_chip->regbase = GPIO_BASE + i * GROUPINERV; |
| 152 | gpiochip_add(&gpio_chip->chip); | 151 | gpiochip_add_data(&gpio_chip->chip, gpio_chip); |
| 153 | } | 152 | } |
| 154 | } | 153 | } |
| @@ -154,8 +154,7 @@ err_out: · 153 unmodified lines | |||
| 154 | */ | 154 | */ |
| 155 | static int orion_gpio_request(struct gpio_chip *chip, unsigned pin) | 155 | static int orion_gpio_request(struct gpio_chip *chip, unsigned pin) |
| 156 | { | 156 | { |
| 157 | struct orion_gpio_chip *ochip = | 157 | struct orion_gpio_chip *ochip = gpiochip_get_data(chip); |
| 158 | container_of(chip, struct orion_gpio_chip, chip); | ||
| 159 | 158 | ||
| 160 | if (orion_gpio_is_valid(ochip, pin, GPIO_INPUT_OK) || | 159 | if (orion_gpio_is_valid(ochip, pin, GPIO_INPUT_OK) || |
| 161 | orion_gpio_is_valid(ochip, pin, GPIO_OUTPUT_OK)) | 160 | orion_gpio_is_valid(ochip, pin, GPIO_OUTPUT_OK)) |
| @@ -166,8 +165,7 @@ static int orion_gpio_request(struct gpio_chip *chip, unsigned pin) · 4 unmodified lines | |||
| 166 | 165 | ||
| 167 | static int orion_gpio_direction_input(struct gpio_chip *chip, unsigned pin) | 166 | static int orion_gpio_direction_input(struct gpio_chip *chip, unsigned pin) |
| 168 | { | 167 | { |
| 169 | struct orion_gpio_chip *ochip = | 168 | struct orion_gpio_chip *ochip = gpiochip_get_data(chip); |
| 170 | container_of(chip, struct orion_gpio_chip, chip); | ||
| 171 | unsigned long flags; | 169 | unsigned long flags; |
| 172 | 170 | ||
| 173 | if (!orion_gpio_is_valid(ochip, pin, GPIO_INPUT_OK)) | 171 | if (!orion_gpio_is_valid(ochip, pin, GPIO_INPUT_OK)) |
| @@ -182,8 +180,7 @@ static int orion_gpio_direction_input(struct gpio_chip *chip, unsigned pin) · 8 unmodified lines | |||
| 182 | 180 | ||
| 183 | static int orion_gpio_get(struct gpio_chip *chip, unsigned pin) | 181 | static int orion_gpio_get(struct gpio_chip *chip, unsigned pin) |
| 184 | { | 182 | { |
| 185 | struct orion_gpio_chip *ochip = | 183 | struct orion_gpio_chip *ochip = gpiochip_get_data(chip); |
| 186 | container_of(chip, struct orion_gpio_chip, chip); | ||
| 187 | int val; | 184 | int val; |
| 188 | 185 | ||
| 189 | if (readl(GPIO_IO_CONF(ochip)) & (1 << pin)) { | 186 | if (readl(GPIO_IO_CONF(ochip)) & (1 << pin)) { |
| @@ -198,8 +195,7 @@ static int orion_gpio_get(struct gpio_chip *chip, unsigned pin) · 8 unmodified lines | |||
| 198 | static int | 195 | static int |
| 199 | orion_gpio_direction_output(struct gpio_chip *chip, unsigned pin, int value) | 196 | orion_gpio_direction_output(struct gpio_chip *chip, unsigned pin, int value) |
| 200 | { | 197 | { |
| 201 | struct orion_gpio_chip *ochip = | 198 | struct orion_gpio_chip *ochip = gpiochip_get_data(chip); |
| 202 | container_of(chip, struct orion_gpio_chip, chip); | ||
| 203 | unsigned long flags; | 199 | unsigned long flags; |
| 204 | 200 | ||
| 205 | if (!orion_gpio_is_valid(ochip, pin, GPIO_OUTPUT_OK)) | 201 | if (!orion_gpio_is_valid(ochip, pin, GPIO_OUTPUT_OK)) |
| @@ -216,8 +212,7 @@ orion_gpio_direction_output(struct gpio_chip *chip, unsigned pin, int value) · 10 unmodified lines | |||
| 216 | 212 | ||
| 217 | static void orion_gpio_set(struct gpio_chip *chip, unsigned pin, int value) | 213 | static void orion_gpio_set(struct gpio_chip *chip, unsigned pin, int value) |
| 218 | { | 214 | { |
| 219 | struct orion_gpio_chip *ochip = | 215 | struct orion_gpio_chip *ochip = gpiochip_get_data(chip); |
| 220 | container_of(chip, struct orion_gpio_chip, chip); | ||
| 221 | unsigned long flags; | 216 | unsigned long flags; |
| 222 | 217 | ||
| 223 | spin_lock_irqsave(&ochip->lock, flags); | 218 | spin_lock_irqsave(&ochip->lock, flags); |
| @@ -227,8 +222,7 @@ static void orion_gpio_set(struct gpio_chip *chip, unsigned pin, int value) · 3 unmodified lines | |||
| 227 | 222 | ||
| 228 | static int orion_gpio_to_irq(struct gpio_chip *chip, unsigned pin) | 223 | static int orion_gpio_to_irq(struct gpio_chip *chip, unsigned pin) |
| 229 | { | 224 | { |
| 230 | struct orion_gpio_chip *ochip = | 225 | struct orion_gpio_chip *ochip = gpiochip_get_data(chip); |
| 231 | container_of(chip, struct orion_gpio_chip, chip); | ||
| 232 | 226 | ||
| 233 | return irq_create_mapping(ochip->domain, | 227 | return irq_create_mapping(ochip->domain, |
| 234 | ochip->secondary_irq_base + pin); | 228 | ochip->secondary_irq_base + pin); |
| @@ -445,8 +439,8 @@ static void gpio_irq_handler(struct irq_desc *desc) · 210 unmodified lines | |||
| 445 | 439 | ||
| 446 | static void orion_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) | 440 | static void orion_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) |
| 447 | { | 441 | { |
| 448 | struct orion_gpio_chip *ochip = | 442 | |
| 449 | container_of(chip, struct orion_gpio_chip, chip); | 443 | struct orion_gpio_chip *ochip = gpiochip_get_data(chip); |
| 450 | u32 out, io_conf, blink, in_pol, data_in, cause, edg_msk, lvl_msk; | 444 | u32 out, io_conf, blink, in_pol, data_in, cause, edg_msk, lvl_msk; |
| 451 | int i; | 445 | int i; |
| 452 | 446 | ||
| @@ -567,7 +561,7 @@ void __init orion_gpio_init(struct device_node *np, · 114 unmodified lines | |||
| 567 | ochip->mask_offset = mask_offset; | 561 | ochip->mask_offset = mask_offset; |
| 568 | ochip->secondary_irq_base = secondary_irq_base; | 562 | ochip->secondary_irq_base = secondary_irq_base; |
| 569 | 563 | ||
| 570 | gpiochip_add(&ochip->chip); | 564 | gpiochip_add_data(&ochip->chip, ochip); |
| 571 | 565 | ||
| 572 | /* | 566 | /* |
| 573 | * Mask and clear GPIO interrupts. | 567 | * Mask and clear GPIO interrupts. |
| @@ -27,7 +27,6 @@ · 26 unmodified lines | |||
| 27 | 27 | ||
| 28 | #include <asm/io.h> | 28 | #include <asm/io.h> |
| 29 | #include <asm/setup.h> | 29 | #include <asm/setup.h> |
| 30 | #include <asm/gpio.h> | ||
| 31 | 30 | ||
| 32 | #include <mach/at32ap700x.h> | 31 | #include <mach/at32ap700x.h> |
| 33 | #include <mach/board.h> | 32 | #include <mach/board.h> |
| @@ -14,8 +14,8 @@ · 13 unmodified lines | |||
| 14 | #include <linux/fs.h> | 14 | #include <linux/fs.h> |
| 15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
| 16 | #include <linux/irq.h> | 16 | #include <linux/irq.h> |
| 17 | #include <linux/gpio.h> | ||
| 17 | 18 | ||
| 18 | #include <asm/gpio.h> | ||
| 19 | #include <asm/io.h> | 19 | #include <asm/io.h> |
| 20 | 20 | ||
| 21 | #include <mach/portmux.h> | 21 | #include <mach/portmux.h> |
| @@ -11,6 +11,8 @@ · 10 unmodified lines | |||
| 11 | #include <linux/err.h> | 11 | #include <linux/err.h> |
| 12 | #include <linux/proc_fs.h> | 12 | #include <linux/proc_fs.h> |
| 13 | #include <linux/seq_file.h> | 13 | #include <linux/seq_file.h> |
| 14 | #include <linux/gpio/driver.h> | ||
| 15 | /* FIXME: consumer API required for gpio_set_value() etc, get rid of this */ | ||
| 14 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
| 15 | #include <linux/irq.h> | 17 | #include <linux/irq.h> |
| 16 | 18 | ||
| @@ -1159,7 +1161,7 @@ static int bfin_gpiolib_direction_output(struct gpio_chip *chip, unsigned gpio, · 1142 unmodified lines | |||
| 1159 | 1161 | ||
| 1160 | static int bfin_gpiolib_get_value(struct gpio_chip *chip, unsigned gpio) | 1162 | static int bfin_gpiolib_get_value(struct gpio_chip *chip, unsigned gpio) |
| 1161 | { | 1163 | { |
| 1162 | return bfin_gpio_get_value(gpio); | 1164 | return !!bfin_gpio_get_value(gpio); |
| 1163 | } | 1165 | } |
| 1164 | 1166 | ||
| 1165 | static void bfin_gpiolib_set_value(struct gpio_chip *chip, unsigned gpio, int value) | 1167 | static void bfin_gpiolib_set_value(struct gpio_chip *chip, unsigned gpio, int value) |
| @@ -1197,7 +1199,7 @@ static struct gpio_chip bfin_chip = { · 31 unmodified lines | |||
| 1197 | 1199 | ||
| 1198 | static int __init bfin_gpiolib_setup(void) | 1200 | static int __init bfin_gpiolib_setup(void) |
| 1199 | { | 1201 | { |
| 1200 | return gpiochip_add(&bfin_chip); | 1202 | return gpiochip_add_data(&bfin_chip, NULL); |
| 1201 | } | 1203 | } |
| 1202 | arch_initcall(bfin_gpiolib_setup); | 1204 | arch_initcall(bfin_gpiolib_setup); |
| 1203 | #endif | 1205 | #endif |
| @@ -11,9 +11,9 @@ · 10 unmodified lines | |||
| 11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
| 12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
| 13 | #include <linux/i2c/bfin_twi.h> | 13 | #include <linux/i2c/bfin_twi.h> |
| 14 | #include <linux/gpio.h> | ||
| 14 | 15 | ||
| 15 | #include <asm/blackfin.h> | 16 | #include <asm/blackfin.h> |
| 16 | #include <asm/gpio.h> | ||
| 17 | #include <asm/gptimers.h> | 17 | #include <asm/gptimers.h> |
| 18 | #include <asm/bfin_can.h> | 18 | #include <asm/bfin_can.h> |
| 19 | #include <asm/bfin_dma.h> | 19 | #include <asm/bfin_dma.h> |
| @@ -15,9 +15,9 @@ · 14 unmodified lines | |||
| 15 | #include <linux/spi/flash.h> | 15 | #include <linux/spi/flash.h> |
| 16 | #include <linux/irq.h> | 16 | #include <linux/irq.h> |
| 17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
| 18 | #include <linux/gpio.h> | ||
| 18 | #include <asm/bfin5xx_spi.h> | 19 | #include <asm/bfin5xx_spi.h> |
| 19 | #include <asm/dma.h> | 20 | #include <asm/dma.h> |
| 20 | #include <asm/gpio.h> | ||
| 21 | #include <asm/nand.h> | 21 | #include <asm/nand.h> |
| 22 | #include <asm/portmux.h> | 22 | #include <asm/portmux.h> |
| 23 | #include <asm/dpmc.h> | 23 | #include <asm/dpmc.h> |
| @@ -8,8 +8,8 @@ · 7 unmodified lines | |||
| 8 | 8 | ||
| 9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
| 10 | #include <linux/err.h> | 10 | #include <linux/err.h> |
| 11 | #include <linux/gpio.h> | ||
| 11 | #include <asm/blackfin.h> | 12 | #include <asm/blackfin.h> |
| 12 | #include <asm/gpio.h> | ||
| 13 | #include <asm/portmux.h> | 13 | #include <asm/portmux.h> |
| 14 | 14 | ||
| 15 | #define DEFINE_REG(reg, off) \ | 15 | #define DEFINE_REG(reg, off) \ |
| @@ -116,9 +116,9 @@ static struct gpio_chip bf538_porte_chip = { · 100 unmodified lines | |||
| 116 | 116 | ||
| 117 | static int __init bf538_extgpio_setup(void) | 117 | static int __init bf538_extgpio_setup(void) |
| 118 | { | 118 | { |
| 119 | return gpiochip_add(&bf538_portc_chip) | | 119 | return gpiochip_add_data(&bf538_portc_chip, NULL) | |
| 120 | gpiochip_add(&bf538_portd_chip) | | 120 | gpiochip_add_data(&bf538_portd_chip, NULL) | |
| 121 | gpiochip_add(&bf538_porte_chip); | 121 | gpiochip_add_data(&bf538_porte_chip, NULL); |
| 122 | } | 122 | } |
| 123 | arch_initcall(bf538_extgpio_setup); | 123 | arch_initcall(bf538_extgpio_setup); |
| 124 | 124 | ||
| @@ -17,9 +17,9 @@ · 16 unmodified lines | |||
| 17 | #include <linux/irq.h> | 17 | #include <linux/irq.h> |
| 18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
| 19 | #include <linux/usb/musb.h> | 19 | #include <linux/usb/musb.h> |
| 20 | #include <linux/gpio.h> | ||
| 20 | #include <asm/bfin5xx_spi.h> | 21 | #include <asm/bfin5xx_spi.h> |
| 21 | #include <asm/dma.h> | 22 | #include <asm/dma.h> |
| 22 | #include <asm/gpio.h> | ||
| 23 | #include <asm/nand.h> | 23 | #include <asm/nand.h> |
| 24 | #include <asm/portmux.h> | 24 | #include <asm/portmux.h> |
| 25 | #include <asm/bfin_sdh.h> | 25 | #include <asm/bfin_sdh.h> |
| @@ -20,9 +20,9 @@ · 19 unmodified lines | |||
| 20 | #include <linux/pinctrl/machine.h> | 20 | #include <linux/pinctrl/machine.h> |
| 21 | #include <linux/pinctrl/pinconf-generic.h> | 21 | #include <linux/pinctrl/pinconf-generic.h> |
| 22 | #include <linux/platform_data/pinctrl-adi2.h> | 22 | #include <linux/platform_data/pinctrl-adi2.h> |
| 23 | #include <linux/gpio.h> | ||
| 23 | #include <asm/bfin5xx_spi.h> | 24 | #include <asm/bfin5xx_spi.h> |
| 24 | #include <asm/dma.h> | 25 | #include <asm/dma.h> |
| 25 | #include <asm/gpio.h> | ||
| 26 | #include <asm/nand.h> | 26 | #include <asm/nand.h> |
| 27 | #include <asm/dpmc.h> | 27 | #include <asm/dpmc.h> |
| 28 | #include <asm/bfin_sport.h> | 28 | #include <asm/bfin_sport.h> |
| @@ -21,8 +21,8 @@ · 20 unmodified lines | |||
| 21 | #include <linux/pinctrl/pinconf-generic.h> | 21 | #include <linux/pinctrl/pinconf-generic.h> |
| 22 | #include <linux/platform_data/pinctrl-adi2.h> | 22 | #include <linux/platform_data/pinctrl-adi2.h> |
| 23 | #include <linux/spi/adi_spi3.h> | 23 | #include <linux/spi/adi_spi3.h> |
| 24 | #include <linux/gpio.h> | ||
| 24 | #include <asm/dma.h> | 25 | #include <asm/dma.h> |
| 25 | #include <asm/gpio.h> | ||
| 26 | #include <asm/nand.h> | 26 | #include <asm/nand.h> |
| 27 | #include <asm/dpmc.h> | 27 | #include <asm/dpmc.h> |
| 28 | #include <asm/portmux.h> | 28 | #include <asm/portmux.h> |
| @@ -17,13 +17,13 @@ · 16 unmodified lines | |||
| 17 | #include <linux/irq.h> | 17 | #include <linux/irq.h> |
| 18 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
| 19 | #include <linux/syscore_ops.h> | 19 | #include <linux/syscore_ops.h> |
| 20 | #include <linux/gpio.h> | ||
| 20 | #include <asm/delay.h> | 21 | #include <asm/delay.h> |
| 21 | #ifdef CONFIG_IPIPE | 22 | #ifdef CONFIG_IPIPE |
| 22 | #include <linux/ipipe.h> | 23 | #include <linux/ipipe.h> |
| 23 | #endif | 24 | #endif |
| 24 | #include <asm/traps.h> | 25 | #include <asm/traps.h> |
| 25 | #include <asm/blackfin.h> | 26 | #include <asm/blackfin.h> |
| 26 | #include <asm/gpio.h> | ||
| 27 | #include <asm/irq_handler.h> | 27 | #include <asm/irq_handler.h> |
| 28 | #include <asm/dpmc.h> | 28 | #include <asm/dpmc.h> |
| 29 | #include <asm/traps.h> | 29 | #include <asm/traps.h> |
| @@ -15,9 +15,9 @@ · 14 unmodified lines | |||
| 15 | #include <linux/io.h> | 15 | #include <linux/io.h> |
| 16 | #include <linux/irq.h> | 16 | #include <linux/irq.h> |
| 17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
| 18 | #include <linux/gpio.h> | ||
| 18 | 19 | ||
| 19 | #include <asm/cplb.h> | 20 | #include <asm/cplb.h> |
| 20 | #include <asm/gpio.h> | ||
| 21 | #include <asm/dma.h> | 21 | #include <asm/dma.h> |
| 22 | #include <asm/dpmc.h> | 22 | #include <asm/dpmc.h> |
| 23 | #include <asm/pm.h> | 23 | #include <asm/pm.h> |
| @@ -1,4 +0,0 @@ | |||
| 1 | #ifndef __LINUX_GPIO_H | ||
| 2 | #warning Include linux/gpio.h instead of asm/gpio.h | ||
| 3 | #include <linux/gpio.h> | ||
| 4 | #endif | ||
| @@ -178,7 +178,7 @@ static struct gpio_chip mcfgpio_chip = { · 177 unmodified lines | |||
| 178 | 178 | ||
| 179 | static int __init mcfgpio_sysinit(void) | 179 | static int __init mcfgpio_sysinit(void) |
| 180 | { | 180 | { |
| 181 | gpiochip_add(&mcfgpio_chip); | 181 | gpiochip_add_data(&mcfgpio_chip, NULL); |
| 182 | return subsys_system_register(&mcfgpio_subsys, NULL); | 182 | return subsys_system_register(&mcfgpio_subsys, NULL); |
| 183 | } | 183 | } |
| 184 | 184 | ||
| @@ -1,4 +0,0 @@ | |||
| 1 | #ifndef __LINUX_GPIO_H | ||
| 2 | #warning Include linux/gpio.h instead of asm/gpio.h | ||
| 3 | #include <linux/gpio.h> | ||
| 4 | #endif | ||
| @@ -1,4 +0,0 @@ | |||
| 1 | #ifndef __LINUX_GPIO_H | ||
| 2 | #warning Include linux/gpio.h instead of asm/gpio.h | ||
| 3 | #include <linux/gpio.h> | ||
| 4 | #endif | ||
| @@ -160,14 +160,14 @@ static int __init alchemy_gpiochip_init(void) · 159 unmodified lines | |||
| 160 | 160 | ||
| 161 | switch (alchemy_get_cputype()) { | 161 | switch (alchemy_get_cputype()) { |
| 162 | case ALCHEMY_CPU_AU1000: | 162 | case ALCHEMY_CPU_AU1000: |
| 163 | ret = gpiochip_add(&alchemy_gpio_chip[0]); | 163 | ret = gpiochip_add_data(&alchemy_gpio_chip[0], NULL); |
| 164 | break; | 164 | break; |
| 165 | case ALCHEMY_CPU_AU1500...ALCHEMY_CPU_AU1200: | 165 | case ALCHEMY_CPU_AU1500...ALCHEMY_CPU_AU1200: |
| 166 | ret = gpiochip_add(&alchemy_gpio_chip[0]); | 166 | ret = gpiochip_add_data(&alchemy_gpio_chip[0], NULL); |
| 167 | ret |= gpiochip_add(&alchemy_gpio_chip[1]); | 167 | ret |= gpiochip_add_data(&alchemy_gpio_chip[1], NULL); |
| 168 | break; | 168 | break; |
| 169 | case ALCHEMY_CPU_AU1300: | 169 | case ALCHEMY_CPU_AU1300: |
| 170 | ret = gpiochip_add(&au1300_gpiochip); | 170 | ret = gpiochip_add_data(&au1300_gpiochip, NULL); |
| 171 | break; | 171 | break; |
| 172 | } | 172 | } |
| 173 | return ret; | 173 | return ret; |
| @@ -33,8 +33,7 @@ struct ar7_gpio_chip { · 32 unmodified lines | |||
| 33 | 33 | ||
| 34 | static int ar7_gpio_get_value(struct gpio_chip *chip, unsigned gpio) | 34 | static int ar7_gpio_get_value(struct gpio_chip *chip, unsigned gpio) |
| 35 | { | 35 | { |
| 36 | struct ar7_gpio_chip *gpch = | 36 | struct ar7_gpio_chip *gpch = gpiochip_get_data(chip); |
| 37 | container_of(chip, struct ar7_gpio_chip, chip); | ||
| 38 | void __iomem *gpio_in = gpch->regs + AR7_GPIO_INPUT; | 37 | void __iomem *gpio_in = gpch->regs + AR7_GPIO_INPUT; |
| 39 | 38 | ||
| 40 | return !!(readl(gpio_in) & (1 << gpio)); | 39 | return !!(readl(gpio_in) & (1 << gpio)); |
| @@ -42,8 +41,7 @@ static int ar7_gpio_get_value(struct gpio_chip *chip, unsigned gpio) · 1 unmodified line | |||
| 42 | 41 | ||
| 43 | static int titan_gpio_get_value(struct gpio_chip *chip, unsigned gpio) | 42 | static int titan_gpio_get_value(struct gpio_chip *chip, unsigned gpio) |
| 44 | { | 43 | { |
| 45 | struct ar7_gpio_chip *gpch = | 44 | struct ar7_gpio_chip *gpch = gpiochip_get_data(chip); |
| 46 | container_of(chip, struct ar7_gpio_chip, chip); | ||
| 47 | void __iomem *gpio_in0 = gpch->regs + TITAN_GPIO_INPUT_0; | 45 | void __iomem *gpio_in0 = gpch->regs + TITAN_GPIO_INPUT_0; |
| 48 | void __iomem *gpio_in1 = gpch->regs + TITAN_GPIO_INPUT_1; | 46 | void __iomem *gpio_in1 = gpch->regs + TITAN_GPIO_INPUT_1; |
| 49 | 47 | ||
| @@ -53,8 +51,7 @@ static int titan_gpio_get_value(struct gpio_chip *chip, unsigned gpio) · 3 unmodified lines | |||
| 53 | static void ar7_gpio_set_value(struct gpio_chip *chip, | 51 | static void ar7_gpio_set_value(struct gpio_chip *chip, |
| 54 | unsigned gpio, int value) | 52 | unsigned gpio, int value) |
| 55 | { | 53 | { |
| 56 | struct ar7_gpio_chip *gpch = | 54 | struct ar7_gpio_chip *gpch = gpiochip_get_data(chip); |
| 57 | container_of(chip, struct ar7_gpio_chip, chip); | ||
| 58 | void __iomem *gpio_out = gpch->regs + AR7_GPIO_OUTPUT; | 55 | void __iomem *gpio_out = gpch->regs + AR7_GPIO_OUTPUT; |
| 59 | unsigned tmp; | 56 | unsigned tmp; |
| 60 | 57 | ||
| @@ -67,8 +64,7 @@ static void ar7_gpio_set_value(struct gpio_chip *chip, · 6 unmodified lines | |||
| 67 | static void titan_gpio_set_value(struct gpio_chip *chip, | 64 | static void titan_gpio_set_value(struct gpio_chip *chip, |
| 68 | unsigned gpio, int value) | 65 | unsigned gpio, int value) |
| 69 | { | 66 | { |
| 70 | struct ar7_gpio_chip *gpch = | 67 | struct ar7_gpio_chip *gpch = gpiochip_get_data(chip); |
| 71 | container_of(chip, struct ar7_gpio_chip, chip); | ||
| 72 | void __iomem *gpio_out0 = gpch->regs + TITAN_GPIO_OUTPUT_0; | 68 | void __iomem *gpio_out0 = gpch->regs + TITAN_GPIO_OUTPUT_0; |
| 73 | void __iomem *gpio_out1 = gpch->regs + TITAN_GPIO_OUTPUT_1; | 69 | void __iomem *gpio_out1 = gpch->regs + TITAN_GPIO_OUTPUT_1; |
| 74 | unsigned tmp; | 70 | unsigned tmp; |
| @@ -81,8 +77,7 @@ static void titan_gpio_set_value(struct gpio_chip *chip, · 6 unmodified lines | |||
| 81 | 77 | ||
| 82 | static int ar7_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) | 78 | static int ar7_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) |
| 83 | { | 79 | { |
| 84 | struct ar7_gpio_chip *gpch = | 80 | struct ar7_gpio_chip *gpch = gpiochip_get_data(chip); |
| 85 | container_of(chip, struct ar7_gpio_chip, chip); | ||
| 86 | void __iomem *gpio_dir = gpch->regs + AR7_GPIO_DIR; | 81 | void __iomem *gpio_dir = gpch->regs + AR7_GPIO_DIR; |
| 87 | 82 | ||
| 88 | writel(readl(gpio_dir) | (1 << gpio), gpio_dir); | 83 | writel(readl(gpio_dir) | (1 << gpio), gpio_dir); |
| @@ -92,8 +87,7 @@ static int ar7_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) · 3 unmodified lines | |||
| 92 | 87 | ||
| 93 | static int titan_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) | 88 | static int titan_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) |
| 94 | { | 89 | { |
| 95 | struct ar7_gpio_chip *gpch = | 90 | struct ar7_gpio_chip *gpch = gpiochip_get_data(chip); |
| 96 | container_of(chip, struct ar7_gpio_chip, chip); | ||
| 97 | void __iomem *gpio_dir0 = gpch->regs + TITAN_GPIO_DIR_0; | 91 | void __iomem *gpio_dir0 = gpch->regs + TITAN_GPIO_DIR_0; |
| 98 | void __iomem *gpio_dir1 = gpch->regs + TITAN_GPIO_DIR_1; | 92 | void __iomem *gpio_dir1 = gpch->regs + TITAN_GPIO_DIR_1; |
| 99 | 93 | ||
| @@ -108,8 +102,7 @@ static int titan_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) · 8 unmodified lines | |||
| 108 | static int ar7_gpio_direction_output(struct gpio_chip *chip, | 102 | static int ar7_gpio_direction_output(struct gpio_chip *chip, |
| 109 | unsigned gpio, int value) | 103 | unsigned gpio, int value) |
| 110 | { | 104 | { |
| 111 | struct ar7_gpio_chip *gpch = | 105 | struct ar7_gpio_chip *gpch = gpiochip_get_data(chip); |
| 112 | container_of(chip, struct ar7_gpio_chip, chip); | ||
| 113 | void __iomem *gpio_dir = gpch->regs + AR7_GPIO_DIR; | 106 | void __iomem *gpio_dir = gpch->regs + AR7_GPIO_DIR; |
| 114 | 107 | ||
| 115 | ar7_gpio_set_value(chip, gpio, value); | 108 | ar7_gpio_set_value(chip, gpio, value); |
| @@ -121,8 +114,7 @@ static int ar7_gpio_direction_output(struct gpio_chip *chip, · 5 unmodified lines | |||
| 121 | static int titan_gpio_direction_output(struct gpio_chip *chip, | 114 | static int titan_gpio_direction_output(struct gpio_chip *chip, |
| 122 | unsigned gpio, int value) | 115 | unsigned gpio, int value) |
| 123 | { | 116 | { |
| 124 | struct ar7_gpio_chip *gpch = | 117 | struct ar7_gpio_chip *gpch = gpiochip_get_data(chip); |
| 125 | container_of(chip, struct ar7_gpio_chip, chip); | ||
| 126 | void __iomem *gpio_dir0 = gpch->regs + TITAN_GPIO_DIR_0; | 118 | void __iomem *gpio_dir0 = gpch->regs + TITAN_GPIO_DIR_0; |
| 127 | void __iomem *gpio_dir1 = gpch->regs + TITAN_GPIO_DIR_1; | 119 | void __iomem *gpio_dir1 = gpch->regs + TITAN_GPIO_DIR_1; |
| 128 | 120 | ||
| @@ -335,7 +327,7 @@ int __init ar7_gpio_init(void) · 206 unmodified lines | |||
| 335 | return -ENOMEM; | 327 | return -ENOMEM; |
| 336 | } | 328 | } |
| 337 | 329 | ||
| 338 | ret = gpiochip_add(&gpch->chip); | 330 | ret = gpiochip_add_data(&gpch->chip, gpch); |
| 339 | if (ret) { | 331 | if (ret) { |
| 340 | printk(KERN_ERR "%s: failed to add gpiochip\n", | 332 | printk(KERN_ERR "%s: failed to add gpiochip\n", |
| 341 | gpch->chip.label); | 333 | gpch->chip.label); |
| @@ -11,7 +11,7 @@ · 10 unmodified lines | |||
| 11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
| 12 | #include <linux/spinlock.h> | 12 | #include <linux/spinlock.h> |
| 13 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
| 14 | #include <linux/gpio.h> | 14 | #include <linux/gpio/driver.h> |
| 15 | 15 | ||
| 16 | #include <bcm63xx_cpu.h> | 16 | #include <bcm63xx_cpu.h> |
| 17 | #include <bcm63xx_gpio.h> | 17 | #include <bcm63xx_gpio.h> |
| @@ -147,5 +147,5 @@ int __init bcm63xx_gpio_init(void) · 129 unmodified lines | |||
| 147 | bcm63xx_gpio_chip.ngpio = bcm63xx_gpio_count(); | 147 | bcm63xx_gpio_chip.ngpio = bcm63xx_gpio_count(); |
| 148 | pr_info("registering %d GPIOs\n", bcm63xx_gpio_chip.ngpio); | 148 | pr_info("registering %d GPIOs\n", bcm63xx_gpio_chip.ngpio); |
| 149 | 149 | ||
| 150 | return gpiochip_add(&bcm63xx_gpio_chip); | 150 | return gpiochip_add_data(&bcm63xx_gpio_chip, NULL); |
| 151 | } | 151 | } |
| @@ -18,6 +18,8 @@ · 17 unmodified lines | |||
| 18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
| 19 | 19 | ||
| 20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
| 21 | #include <linux/gpio/driver.h> | ||
| 22 | /* FIXME: needed for gpio_request(), try to remove consumer API from driver */ | ||
| 21 | #include <linux/gpio.h> | 23 | #include <linux/gpio.h> |
| 22 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
| 23 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
| @@ -91,9 +93,9 @@ static inline struct jz_gpio_chip *gpio_to_jz_gpio_chip(unsigned int gpio) · 67 unmodified lines | |||
| 91 | return &jz4740_gpio_chips[gpio >> 5]; | 93 | return &jz4740_gpio_chips[gpio >> 5]; |
| 92 | } | 94 | } |
| 93 | 95 | ||
| 94 | static inline struct jz_gpio_chip *gpio_chip_to_jz_gpio_chip(struct gpio_chip *gpio_chip) | 96 | static inline struct jz_gpio_chip *gpio_chip_to_jz_gpio_chip(struct gpio_chip *gc) |
| 95 | { | 97 | { |
| 96 | return container_of(gpio_chip, struct jz_gpio_chip, gpio_chip); | 98 | return gpiochip_get_data(gc); |
| 97 | } | 99 | } |
| 98 | 100 | ||
| 99 | static inline struct jz_gpio_chip *irq_to_jz_gpio_chip(struct irq_data *data) | 101 | static inline struct jz_gpio_chip *irq_to_jz_gpio_chip(struct irq_data *data) |
| @@ -234,7 +236,7 @@ static int jz_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) · 134 unmodified lines | |||
| 234 | 236 | ||
| 235 | static int jz_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) | 237 | static int jz_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) |
| 236 | { | 238 | { |
| 237 | struct jz_gpio_chip *jz_gpio = gpio_chip_to_jz_gpio_chip(chip); | 239 | struct jz_gpio_chip *jz_gpio = gpiochip_get_data(chip); |
| 238 | 240 | ||
| 239 | return jz_gpio->irq_base + gpio; | 241 | return jz_gpio->irq_base + gpio; |
| 240 | } | 242 | } |
| @@ -449,7 +451,7 @@ static void jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id) · 208 unmodified lines | |||
| 449 | irq_setup_generic_chip(gc, IRQ_MSK(chip->gpio_chip.ngpio), | 451 | irq_setup_generic_chip(gc, IRQ_MSK(chip->gpio_chip.ngpio), |
| 450 | IRQ_GC_INIT_NESTED_LOCK, 0, IRQ_NOPROBE | IRQ_LEVEL); | 452 | IRQ_GC_INIT_NESTED_LOCK, 0, IRQ_NOPROBE | IRQ_LEVEL); |
| 451 | 453 | ||
| 452 | gpiochip_add(&chip->gpio_chip); | 454 | gpiochip_add_data(&chip->gpio_chip, chip); |
| 453 | } | 455 | } |
| 454 | 456 | ||
| 455 | static int __init jz4740_gpio_init(void) | 457 | static int __init jz4740_gpio_init(void) |
| @@ -10,7 +10,7 @@ · 9 unmodified lines | |||
| 10 | 10 | ||
| 11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
| 12 | #include <linux/spinlock.h> | 12 | #include <linux/spinlock.h> |
| 13 | #include <linux/gpio.h> | 13 | #include <linux/gpio/driver.h> |
| 14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
| 15 | #include <linux/io.h> | 15 | #include <linux/io.h> |
| 16 | #include <asm/txx9pio.h> | 16 | #include <asm/txx9pio.h> |
| @@ -85,5 +85,5 @@ int __init txx9_gpio_init(unsigned long baseaddr, · 68 unmodified lines | |||
| 85 | return -ENODEV; | 85 | return -ENODEV; |
| 86 | txx9_gpio_chip.base = base; | 86 | txx9_gpio_chip.base = base; |
| 87 | txx9_gpio_chip.ngpio = num; | 87 | txx9_gpio_chip.ngpio = num; |
| 88 | return gpiochip_add(&txx9_gpio_chip); | 88 | return gpiochip_add_data(&txx9_gpio_chip, NULL); |
| 89 | } | 89 | } |
| @@ -32,7 +32,7 @@ · 31 unmodified lines | |||
| 32 | #include <linux/export.h> | 32 | #include <linux/export.h> |
| 33 | #include <linux/spinlock.h> | 33 | #include <linux/spinlock.h> |
| 34 | #include <linux/platform_device.h> | 34 | #include <linux/platform_device.h> |
| 35 | #include <linux/gpio.h> | 35 | #include <linux/gpio/driver.h> |
| 36 | 36 | ||
| 37 | #include <asm/mach-rc32434/rb.h> | 37 | #include <asm/mach-rc32434/rb.h> |
| 38 | #include <asm/mach-rc32434/gpio.h> | 38 | #include <asm/mach-rc32434/gpio.h> |
| @@ -88,7 +88,7 @@ static int rb532_gpio_get(struct gpio_chip *chip, unsigned offset) · 49 unmodified lines | |||
| 88 | { | 88 | { |
| 89 | struct rb532_gpio_chip *gpch; | 89 | struct rb532_gpio_chip *gpch; |
| 90 | 90 | ||
| 91 | gpch = container_of(chip, struct rb532_gpio_chip, chip); | 91 | gpch = gpiochip_get_data(chip); |
| 92 | return !!rb532_get_bit(offset, gpch->regbase + GPIOD); | 92 | return !!rb532_get_bit(offset, gpch->regbase + GPIOD); |
| 93 | } | 93 | } |
| 94 | 94 | ||
| @@ -100,7 +100,7 @@ static void rb532_gpio_set(struct gpio_chip *chip, · 5 unmodified lines | |||
| 100 | { | 100 | { |
| 101 | struct rb532_gpio_chip *gpch; | 101 | struct rb532_gpio_chip *gpch; |
| 102 | 102 | ||
| 103 | gpch = container_of(chip, struct rb532_gpio_chip, chip); | 103 | gpch = gpiochip_get_data(chip); |
| 104 | rb532_set_bit(value, offset, gpch->regbase + GPIOD); | 104 | rb532_set_bit(value, offset, gpch->regbase + GPIOD); |
| 105 | } | 105 | } |
| 106 | 106 | ||
| @@ -111,7 +111,7 @@ static int rb532_gpio_direction_input(struct gpio_chip *chip, unsigned offset) · 4 unmodified lines | |||
| 111 | { | 111 | { |
| 112 | struct rb532_gpio_chip *gpch; | 112 | struct rb532_gpio_chip *gpch; |
| 113 | 113 | ||
| 114 | gpch = container_of(chip, struct rb532_gpio_chip, chip); | 114 | gpch = gpiochip_get_data(chip); |
| 115 | 115 | ||
| 116 | /* disable alternate function in case it's set */ | 116 | /* disable alternate function in case it's set */ |
| 117 | rb532_set_bit(0, offset, gpch->regbase + GPIOFUNC); | 117 | rb532_set_bit(0, offset, gpch->regbase + GPIOFUNC); |
| @@ -128,7 +128,7 @@ static int rb532_gpio_direction_output(struct gpio_chip *chip, · 10 unmodified lines | |||
| 128 | { | 128 | { |
| 129 | struct rb532_gpio_chip *gpch; | 129 | struct rb532_gpio_chip *gpch; |
| 130 | 130 | ||
| 131 | gpch = container_of(chip, struct rb532_gpio_chip, chip); | 131 | gpch = gpiochip_get_data(chip); |
| 132 | 132 | ||
| 133 | /* disable alternate function in case it's set */ | 133 | /* disable alternate function in case it's set */ |
| 134 | rb532_set_bit(0, offset, gpch->regbase + GPIOFUNC); | 134 | rb532_set_bit(0, offset, gpch->regbase + GPIOFUNC); |
| @@ -200,7 +200,7 @@ int __init rb532_gpio_init(void) · 65 unmodified lines | |||
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | /* Register our GPIO chip */ | 202 | /* Register our GPIO chip */ |
| 203 | gpiochip_add(&rb532_gpio_chip->chip); | 203 | gpiochip_add_data(&rb532_gpio_chip->chip, rb532_gpio_chip); |
| 204 | 204 | ||
| 205 | return 0; | 205 | return 0; |
| 206 | } | 206 | } |
| @@ -17,7 +17,7 @@ · 16 unmodified lines | |||
| 17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
| 18 | #include <linux/clk.h> | 18 | #include <linux/clk.h> |
| 19 | #include <linux/err.h> | 19 | #include <linux/err.h> |
| 20 | #include <linux/gpio.h> | 20 | #include <linux/gpio/driver.h> |
| 21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
| 22 | #include <linux/serial_core.h> | 22 | #include <linux/serial_core.h> |
| 23 | #include <linux/mtd/physmap.h> | 23 | #include <linux/mtd/physmap.h> |
| @@ -687,16 +687,14 @@ struct txx9_iocled_data { · 663 unmodified lines | |||
| 687 | 687 | ||
| 688 | static int txx9_iocled_get(struct gpio_chip *chip, unsigned int offset) | 688 | static int txx9_iocled_get(struct gpio_chip *chip, unsigned int offset) |
| 689 | { | 689 | { |
| 690 | struct txx9_iocled_data *data = | 690 | struct txx9_iocled_data *data = gpiochip_get_data(chip); |
| 691 | container_of(chip, struct txx9_iocled_data, chip); | ||
| 692 | return !!(data->cur_val & (1 << offset)); | 691 | return !!(data->cur_val & (1 << offset)); |
| 693 | } | 692 | } |
| 694 | 693 | ||
| 695 | static void txx9_iocled_set(struct gpio_chip *chip, unsigned int offset, | 694 | static void txx9_iocled_set(struct gpio_chip *chip, unsigned int offset, |
| 696 | int value) | 695 | int value) |
| 697 | { | 696 | { |
| 698 | struct txx9_iocled_data *data = | 697 | struct txx9_iocled_data *data = gpiochip_get_data(chip); |
| 699 | container_of(chip, struct txx9_iocled_data, chip); | ||
| 700 | unsigned long flags; | 698 | unsigned long flags; |
| 701 | spin_lock_irqsave(&txx9_iocled_lock, flags); | 699 | spin_lock_irqsave(&txx9_iocled_lock, flags); |
| 702 | if (value) | 700 | if (value) |
| @@ -749,7 +747,7 @@ void __init txx9_iocled_init(unsigned long baseaddr, · 46 unmodified lines | |||
| 749 | iocled->chip.label = "iocled"; | 747 | iocled->chip.label = "iocled"; |
| 750 | iocled->chip.base = basenum; | 748 | iocled->chip.base = basenum; |
| 751 | iocled->chip.ngpio = num; | 749 | iocled->chip.ngpio = num; |
| 752 | if (gpiochip_add(&iocled->chip)) | 750 | if (gpiochip_add_data(&iocled->chip, iocled)) |
| 753 | goto out_unmap; | 751 | goto out_unmap; |
| 754 | if (basenum < 0) | 752 | if (basenum < 0) |
| 755 | basenum = iocled->chip.base; | 753 | basenum = iocled->chip.base; |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | |||
| 14 | #include <linux/ioport.h> | 14 | #include <linux/ioport.h> |
| 15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
| 16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
| 17 | #include <linux/gpio/driver.h> | ||
| 17 | #include <linux/gpio.h> | 18 | #include <linux/gpio.h> |
| 18 | #include <linux/mtd/physmap.h> | 19 | #include <linux/mtd/physmap.h> |
| 19 | 20 | ||
| @@ -335,7 +336,7 @@ static void __init rbtx4938_mtd_init(void) · 315 unmodified lines | |||
| 335 | 336 | ||
| 336 | static void __init rbtx4938_arch_init(void) | 337 | static void __init rbtx4938_arch_init(void) |
| 337 | { | 338 | { |
| 338 | gpiochip_add(&rbtx4938_spi_gpio_chip); | 339 | gpiochip_add_data(&rbtx4938_spi_gpio_chip, NULL); |
| 339 | rbtx4938_pci_setup(); | 340 | rbtx4938_pci_setup(); |
| 340 | rbtx4938_spi_init(); | 341 | rbtx4938_spi_init(); |
| 341 | } | 342 | } |
| @@ -1,4 +0,0 @@ | |||
| 1 | #ifndef __LINUX_GPIO_H | ||
| 2 | #warning Include linux/gpio.h instead of asm/gpio.h | ||
| 3 | #include <linux/gpio.h> | ||
| 4 | #endif | ||
| @@ -1,4 +0,0 @@ | |||
| 1 | #ifndef __LINUX_GPIO_H | ||
| 2 | #warning Include linux/gpio.h instead of asm/gpio.h | ||
| 3 | #include <linux/gpio.h> | ||
| 4 | #endif | ||
| @@ -78,7 +78,7 @@ static int ppc4xx_gpio_get(struct gpio_chip *gc, unsigned int gpio) · 77 unmodified lines | |||
| 78 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); | 78 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); |
| 79 | struct ppc4xx_gpio __iomem *regs = mm_gc->regs; | 79 | struct ppc4xx_gpio __iomem *regs = mm_gc->regs; |
| 80 | 80 | ||
| 81 | return in_be32(®s->ir) & GPIO_MASK(gpio); | 81 | return !!(in_be32(®s->ir) & GPIO_MASK(gpio)); |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | static inline void | 84 | static inline void |
| @@ -46,7 +46,7 @@ static int u8_gpio_get(struct gpio_chip *gc, unsigned int gpio) · 45 unmodified lines | |||
| 46 | { | 46 | { |
| 47 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); | 47 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); |
| 48 | 48 | ||
| 49 | return in_8(mm_gc->regs) & u8_pin2mask(gpio); | 49 | return !!(in_8(mm_gc->regs) & u8_pin2mask(gpio)); |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | static void u8_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) | 52 | static void u8_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) |
| @@ -13,7 +13,7 @@ · 12 unmodified lines | |||
| 13 | #ifndef __ASM_SH_MAGICPANELR2_H | 13 | #ifndef __ASM_SH_MAGICPANELR2_H |
| 14 | #define __ASM_SH_MAGICPANELR2_H | 14 | #define __ASM_SH_MAGICPANELR2_H |
| 15 | 15 | ||
| 16 | #include <asm/gpio.h> | 16 | #include <linux/gpio.h> |
| 17 | 17 | ||
| 18 | #define __IO_PREFIX mpr2 | 18 | #define __IO_PREFIX mpr2 |
| 19 | #include <asm/io_generic.h> | 19 | #include <asm/io_generic.h> |
| @@ -1,4 +0,0 @@ | |||
| 1 | #ifndef __LINUX_GPIO_H | ||
| 2 | #warning Include linux/gpio.h instead of asm/gpio.h | ||
| 3 | #include <linux/gpio.h> | ||
| 4 | #endif | ||
| @@ -52,7 +52,7 @@ device_initcall(puv3_gpio_leds_init); · 51 unmodified lines | |||
| 52 | 52 | ||
| 53 | static int puv3_gpio_get(struct gpio_chip *chip, unsigned offset) | 53 | static int puv3_gpio_get(struct gpio_chip *chip, unsigned offset) |
| 54 | { | 54 | { |
| 55 | return readl(GPIO_GPLR) & GPIO_GPIO(offset); | 55 | return !!(readl(GPIO_GPLR) & GPIO_GPIO(offset)); |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | static void puv3_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | 58 | static void puv3_gpio_set(struct gpio_chip *chip, unsigned offset, int value) |
| @@ -1,4 +0,0 @@ | |||
| 1 | #ifndef __LINUX_GPIO_H | ||
| 2 | #warning Include linux/gpio.h instead of asm/gpio.h | ||
| 3 | #include <linux/gpio.h> | ||
| 4 | #endif | ||
| @@ -1,4 +0,0 @@ | |||
| 1 | #ifndef __LINUX_GPIO_H | ||
| 2 | #warning Include linux/gpio.h instead of asm/gpio.h | ||
| 3 | #include <linux/gpio.h> | ||
| 4 | #endif | ||
| @@ -30,8 +30,7 @@ · 29 unmodified lines | |||
| 30 | #include <linux/ata_platform.h> | 30 | #include <linux/ata_platform.h> |
| 31 | #include <linux/platform_data/atmel.h> | 31 | #include <linux/platform_data/atmel.h> |
| 32 | #include <linux/regmap.h> | 32 | #include <linux/regmap.h> |
| 33 | 33 | #include <linux/gpio.h> | |
| 34 | #include <asm/gpio.h> | ||
| 35 | 34 | ||
| 36 | #define DRV_NAME "pata_at91" | 35 | #define DRV_NAME "pata_at91" |
| 37 | #define DRV_VERSION "0.3" | 36 | #define DRV_VERSION "0.3" |
| @@ -36,8 +36,8 @@ · 35 unmodified lines | |||
| 36 | #include <scsi/scsi_host.h> | 36 | #include <scsi/scsi_host.h> |
| 37 | #include <linux/libata.h> | 37 | #include <linux/libata.h> |
| 38 | #include <linux/platform_device.h> | 38 | #include <linux/platform_device.h> |
| 39 | #include <linux/gpio.h> | ||
| 39 | #include <asm/dma.h> | 40 | #include <asm/dma.h> |
| 40 | #include <asm/gpio.h> | ||
| 41 | #include <asm/portmux.h> | 41 | #include <asm/portmux.h> |
| 42 | 42 | ||
| 43 | #define DRV_NAME "pata-bf54x" | 43 | #define DRV_NAME "pata-bf54x" |
| @@ -126,6 +126,16 @@ config GPIO_AMDPT · 125 unmodified lines | |||
| 126 | driver for GPIO functionality on Promontory IOHub | 126 | driver for GPIO functionality on Promontory IOHub |
| 127 | Require ACPI ASL code to enumerate as a platform device. | 127 | Require ACPI ASL code to enumerate as a platform device. |
| 128 | 128 | ||
| 129 | config GPIO_ATH79 | ||
| 130 | tristate "Atheros AR71XX/AR724X/AR913X GPIO support" | ||
| 131 | default y if ATH79 | ||
| 132 | depends on ATH79 || COMPILE_TEST | ||
| 133 | select GPIO_GENERIC | ||
| 134 | select GPIOLIB_IRQCHIP | ||
| 135 | help | ||
| 136 | Select this option to enable GPIO driver for | ||
| 137 | Atheros AR71XX/AR724X/AR913X SoC devices. | ||
| 138 | |||
| 129 | config GPIO_BCM_KONA | 139 | config GPIO_BCM_KONA |
| 130 | bool "Broadcom Kona GPIO" | 140 | bool "Broadcom Kona GPIO" |
| 131 | depends on OF_GPIO && (ARCH_BCM_MOBILE || COMPILE_TEST) | 141 | depends on OF_GPIO && (ARCH_BCM_MOBILE || COMPILE_TEST) |
| @@ -256,10 +266,17 @@ config GPIO_LYNXPOINT · 124 unmodified lines | |||
| 256 | 266 | ||
| 257 | config GPIO_MB86S7X | 267 | config GPIO_MB86S7X |
| 258 | bool "GPIO support for Fujitsu MB86S7x Platforms" | 268 | bool "GPIO support for Fujitsu MB86S7x Platforms" |
| 259 | depends on ARCH_MB86S7X | 269 | depends on ARCH_MB86S7X || COMPILE_TEST |
| 260 | help | 270 | help |
| 261 | Say yes here to support the GPIO controller in Fujitsu MB86S70 SoCs. | 271 | Say yes here to support the GPIO controller in Fujitsu MB86S70 SoCs. |
| 262 | 272 | ||
| 273 | config GPIO_MENZ127 | ||
| 274 | tristate "MEN 16Z127 GPIO support" | ||
| 275 | depends on MCB | ||
| 276 | select GPIO_GENERIC | ||
| 277 | help | ||
| 278 | Say yes here to support the MEN 16Z127 GPIO Controller | ||
| 279 | |||
| 263 | config GPIO_MM_LANTIQ | 280 | config GPIO_MM_LANTIQ |
| 264 | bool "Lantiq Memory mapped GPIOs" | 281 | bool "Lantiq Memory mapped GPIOs" |
| 265 | depends on LANTIQ && SOC_XWAY | 282 | depends on LANTIQ && SOC_XWAY |
| @@ -270,7 +287,7 @@ config GPIO_MM_LANTIQ · 4 unmodified lines | |||
| 270 | 287 | ||
| 271 | config GPIO_MOXART | 288 | config GPIO_MOXART |
| 272 | bool "MOXART GPIO support" | 289 | bool "MOXART GPIO support" |
| 273 | depends on ARCH_MOXART | 290 | depends on ARCH_MOXART || COMPILE_TEST |
| 274 | select GPIO_GENERIC | 291 | select GPIO_GENERIC |
| 275 | help | 292 | help |
| 276 | Select this option to enable GPIO driver for | 293 | Select this option to enable GPIO driver for |
| @@ -281,12 +298,14 @@ config GPIO_MPC5200 · 4 unmodified lines | |||
| 281 | depends on PPC_MPC52xx | 298 | depends on PPC_MPC52xx |
| 282 | 299 | ||
| 283 | config GPIO_MPC8XXX | 300 | config GPIO_MPC8XXX |
| 284 | bool "MPC512x/MPC8xxx GPIO support" | 301 | bool "MPC512x/MPC8xxx/QorIQ GPIO support" |
| 285 | depends on PPC_MPC512x || PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || \ | 302 | depends on PPC_MPC512x || PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || \ |
| 286 | FSL_SOC_BOOKE || PPC_86xx | 303 | FSL_SOC_BOOKE || PPC_86xx || ARCH_LAYERSCAPE || ARM || \ |
| 304 | COMPILE_TEST | ||
| 305 | select GPIO_GENERIC | ||
| 287 | help | 306 | help |
| 288 | Say Y here if you're going to use hardware that connects to the | 307 | Say Y here if you're going to use hardware that connects to the |
| 289 | MPC512x/831x/834x/837x/8572/8610 GPIOs. | 308 | MPC512x/831x/834x/837x/8572/8610/QorIQ GPIOs. |
| 290 | 309 | ||
| 291 | config GPIO_MVEBU | 310 | config GPIO_MVEBU |
| 292 | def_bool y | 311 | def_bool y |
| @@ -339,7 +358,7 @@ config GPIO_PXA · 46 unmodified lines | |||
| 339 | 358 | ||
| 340 | config GPIO_RCAR | 359 | config GPIO_RCAR |
| 341 | tristate "Renesas R-Car GPIO" | 360 | tristate "Renesas R-Car GPIO" |
| 342 | depends on ARCH_SHMOBILE || COMPILE_TEST | 361 | depends on ARCH_RENESAS || COMPILE_TEST |
| 343 | select GPIOLIB_IRQCHIP | 362 | select GPIOLIB_IRQCHIP |
| 344 | help | 363 | help |
| 345 | Say yes here to support GPIO on Renesas R-Car SoCs. | 364 | Say yes here to support GPIO on Renesas R-Car SoCs. |
| @@ -380,6 +399,14 @@ config GPIO_TB10X · 34 unmodified lines | |||
| 380 | select GENERIC_IRQ_CHIP | 399 | select GENERIC_IRQ_CHIP |
| 381 | select OF_GPIO | 400 | select OF_GPIO |
| 382 | 401 | ||
| 402 | config GPIO_TS4800 | ||
| 403 | tristate "TS-4800 DIO blocks and compatibles" | ||
| 404 | depends on OF_GPIO | ||
| 405 | depends on SOC_IMX51 || COMPILE_TEST | ||
| 406 | select GPIO_GENERIC | ||
| 407 | help | ||
| 408 | This driver support TS-4800 FPGA GPIO controllers. | ||
| 409 | |||
| 383 | config GPIO_TZ1090 | 410 | config GPIO_TZ1090 |
| 384 | bool "Toumaz Xenif TZ1090 GPIO support" | 411 | bool "Toumaz Xenif TZ1090 GPIO support" |
| 385 | depends on SOC_TZ1090 | 412 | depends on SOC_TZ1090 |
| @@ -433,6 +460,7 @@ config GPIO_XGENE_SB · 47 unmodified lines | |||
| 433 | tristate "APM X-Gene GPIO standby controller support" | 460 | tristate "APM X-Gene GPIO standby controller support" |
| 434 | depends on ARCH_XGENE && OF_GPIO | 461 | depends on ARCH_XGENE && OF_GPIO |
| 435 | select GPIO_GENERIC | 462 | select GPIO_GENERIC |
| 463 | select GPIOLIB_IRQCHIP | ||
| 436 | help | 464 | help |
| 437 | This driver supports the GPIO block within the APM X-Gene | 465 | This driver supports the GPIO block within the APM X-Gene |
| 438 | Standby Domain. Say yes here to enable the GPIO functionality. | 466 | Standby Domain. Say yes here to enable the GPIO functionality. |
| @@ -487,6 +515,15 @@ endmenu · 48 unmodified lines | |||
| 487 | menu "Port-mapped I/O GPIO drivers" | 515 | menu "Port-mapped I/O GPIO drivers" |
| 488 | depends on X86 # Unconditional I/O space access | 516 | depends on X86 # Unconditional I/O space access |
| 489 | 517 | ||
| 518 | config GPIO_104_DIO_48E | ||
| 519 | tristate "ACCES 104-DIO-48E GPIO support" | ||
| 520 | select GPIOLIB_IRQCHIP | ||
| 521 | help | ||
| 522 | Enables GPIO support for the ACCES 104-DIO-48E family. The base port | ||
| 523 | address for the device may be configured via the dio_48e_base module | ||
| 524 | parameter. The interrupt line number for the device may be configured | ||
| 525 | via the dio_48e_irq module parameter. | ||
| 526 | |||
| 490 | config GPIO_104_IDIO_16 | 527 | config GPIO_104_IDIO_16 |
| 491 | tristate "ACCES 104-IDIO-16 GPIO support" | 528 | tristate "ACCES 104-IDIO-16 GPIO support" |
| 492 | select GPIOLIB_IRQCHIP | 529 | select GPIOLIB_IRQCHIP |
| @@ -506,10 +543,10 @@ config GPIO_104_IDI_48 · 13 unmodified lines | |||
| 506 | via the idi_48_irq module parameter. | 543 | via the idi_48_irq module parameter. |
| 507 | 544 | ||
| 508 | config GPIO_F7188X | 545 | config GPIO_F7188X |
| 509 | tristate "F71869, F71869A, F71882FG and F71889F GPIO support" | 546 | tristate "F71869, F71869A, F71882FG, F71889F and F81866 GPIO support" |
| 510 | help | 547 | help |
| 511 | This option enables support for GPIOs found on Fintek Super-I/O | 548 | This option enables support for GPIOs found on Fintek Super-I/O |
| 512 | chips F71869, F71869A, F71882FG and F71889F. | 549 | chips F71869, F71869A, F71882FG, F71889F and F81866. |
| 513 | 550 | ||
| 514 | To compile this driver as a module, choose M here: the module will | 551 | To compile this driver as a module, choose M here: the module will |
| 515 | be called f7188x-gpio. | 552 | be called f7188x-gpio. |
| @@ -570,6 +607,15 @@ config GPIO_TS5500 · 54 unmodified lines | |||
| 570 | blocks of the TS-5500: DIO1, DIO2 and the LCD port, and the TS-5600 | 607 | blocks of the TS-5500: DIO1, DIO2 and the LCD port, and the TS-5600 |
| 571 | LCD port. | 608 | LCD port. |
| 572 | 609 | ||
| 610 | config GPIO_WS16C48 | ||
| 611 | tristate "WinSystems WS16C48 GPIO support" | ||
| 612 | select GPIOLIB_IRQCHIP | ||
| 613 | help | ||
| 614 | Enables GPIO support for the WinSystems WS16C48. The base port address | ||
| 615 | for the device may be configured via the ws16c48_base module | ||
| 616 | parameter. The interrupt line number for the device may be configured | ||
| 617 | via the ws16c48_irq module parameter. | ||
| 618 | |||
| 573 | endmenu | 619 | endmenu |
| 574 | 620 | ||
| 575 | menu "I2C GPIO expanders" | 621 | menu "I2C GPIO expanders" |
| @@ -702,6 +748,14 @@ config GPIO_SX150X · 126 unmodified lines | |||
| 702 | 8 bits: sx1508q | 748 | 8 bits: sx1508q |
| 703 | 16 bits: sx1509q | 749 | 16 bits: sx1509q |
| 704 | 750 | ||
| 751 | config GPIO_TPIC2810 | ||
| 752 | tristate "TPIC2810 8-Bit I2C GPO expander" | ||
| 753 | help | ||
| 754 | Say yes here to enable the GPO driver for the TI TPIC2810 chip. | ||
| 755 | |||
| 756 | To compile this driver as a module, choose M here: the module will | ||
| 757 | be called gpio-tpic2810. | ||
| 758 | |||
| 705 | endmenu | 759 | endmenu |
| 706 | 760 | ||
| 707 | menu "MFD GPIO expanders" | 761 | menu "MFD GPIO expanders" |
| @@ -844,6 +898,13 @@ config GPIO_TIMBERDALE · 136 unmodified lines | |||
| 844 | ---help--- | 898 | ---help--- |
| 845 | Add support for the GPIO IP in the timberdale FPGA. | 899 | Add support for the GPIO IP in the timberdale FPGA. |
| 846 | 900 | ||
| 901 | config GPIO_TPS65218 | ||
| 902 | tristate "TPS65218 GPIO" | ||
| 903 | depends on MFD_TPS65218 | ||
| 904 | help | ||
| 905 | Select this option to enable GPIO driver for the TPS65218 | ||
| 906 | chip family. | ||
| 907 | |||
| 847 | config GPIO_TPS6586X | 908 | config GPIO_TPS6586X |
| 848 | bool "TPS6586X GPIO" | 909 | bool "TPS6586X GPIO" |
| 849 | depends on MFD_TPS6586X | 910 | depends on MFD_TPS6586X |
| @@ -860,7 +921,7 @@ config GPIO_TPS65910 · 10 unmodified lines | |||
| 860 | 921 | ||
| 861 | config GPIO_TPS65912 | 922 | config GPIO_TPS65912 |
| 862 | tristate "TI TPS65912 GPIO" | 923 | tristate "TI TPS65912 GPIO" |
| 863 | depends on (MFD_TPS65912_I2C || MFD_TPS65912_SPI) | 924 | depends on MFD_TPS65912 |
| 864 | help | 925 | help |
| 865 | This driver supports TPS65912 gpio chip | 926 | This driver supports TPS65912 gpio chip |
| 866 | 927 | ||
| @@ -1011,6 +1072,12 @@ config GPIO_MC33880 · 144 unmodified lines | |||
| 1011 | SPI driver for Freescale MC33880 high-side/low-side switch. | 1072 | SPI driver for Freescale MC33880 high-side/low-side switch. |
| 1012 | This provides GPIO interface supporting inputs and outputs. | 1073 | This provides GPIO interface supporting inputs and outputs. |
| 1013 | 1074 | ||
| 1075 | config GPIO_PISOSR | ||
| 1076 | tristate "Generic parallel-in/serial-out shift register" | ||
| 1077 | help | ||
| 1078 | GPIO driver for SPI compatible parallel-in/serial-out shift | ||
| 1079 | registers. These are input only devices. | ||
| 1080 | |||
| 1014 | endmenu | 1081 | endmenu |
| 1015 | 1082 | ||
| 1016 | menu "SPI or I2C GPIO expanders" | 1083 | menu "SPI or I2C GPIO expanders" |
| @@ -12,6 +12,7 @@ obj-$(CONFIG_GPIO_ACPI) += gpiolib-acpi.o · 11 unmodified lines | |||
| 12 | # Device drivers. Generally keep list sorted alphabetically | 12 | # Device drivers. Generally keep list sorted alphabetically |
| 13 | obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o | 13 | obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o |
| 14 | 14 | ||
| 15 | obj-$(CONFIG_GPIO_104_DIO_48E) += gpio-104-dio-48e.o | ||
| 15 | obj-$(CONFIG_GPIO_104_IDIO_16) += gpio-104-idio-16.o | 16 | obj-$(CONFIG_GPIO_104_IDIO_16) += gpio-104-idio-16.o |
| 16 | obj-$(CONFIG_GPIO_104_IDI_48) += gpio-104-idi-48.o | 17 | obj-$(CONFIG_GPIO_104_IDI_48) += gpio-104-idi-48.o |
| 17 | obj-$(CONFIG_GPIO_74X164) += gpio-74x164.o | 18 | obj-$(CONFIG_GPIO_74X164) += gpio-74x164.o |
| @@ -23,7 +24,7 @@ obj-$(CONFIG_GPIO_ALTERA) += gpio-altera.o · 5 unmodified lines | |||
| 23 | obj-$(CONFIG_GPIO_AMD8111) += gpio-amd8111.o | 24 | obj-$(CONFIG_GPIO_AMD8111) += gpio-amd8111.o |
| 24 | obj-$(CONFIG_GPIO_AMDPT) += gpio-amdpt.o | 25 | obj-$(CONFIG_GPIO_AMDPT) += gpio-amdpt.o |
| 25 | obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o | 26 | obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o |
| 26 | obj-$(CONFIG_ATH79) += gpio-ath79.o | 27 | obj-$(CONFIG_GPIO_ATH79) += gpio-ath79.o |
| 27 | obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o | 28 | obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o |
| 28 | obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o | 29 | obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o |
| 29 | obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o | 30 | obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o |
| @@ -58,6 +59,7 @@ obj-$(CONFIG_GPIO_MAX7300) += gpio-max7300.o · 28 unmodified lines | |||
| 58 | obj-$(CONFIG_GPIO_MAX7301) += gpio-max7301.o | 59 | obj-$(CONFIG_GPIO_MAX7301) += gpio-max7301.o |
| 59 | obj-$(CONFIG_GPIO_MAX732X) += gpio-max732x.o | 60 | obj-$(CONFIG_GPIO_MAX732X) += gpio-max732x.o |
| 60 | obj-$(CONFIG_GPIO_MB86S7X) += gpio-mb86s7x.o | 61 | obj-$(CONFIG_GPIO_MB86S7X) += gpio-mb86s7x.o |
| 62 | obj-$(CONFIG_GPIO_MENZ127) += gpio-menz127.o | ||
| 61 | obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o | 63 | obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o |
| 62 | obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o | 64 | obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o |
| 63 | obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o | 65 | obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o |
| @@ -75,6 +77,7 @@ obj-$(CONFIG_GPIO_OMAP) += gpio-omap.o · 11 unmodified lines | |||
| 75 | obj-$(CONFIG_GPIO_PCA953X) += gpio-pca953x.o | 77 | obj-$(CONFIG_GPIO_PCA953X) += gpio-pca953x.o |
| 76 | obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o | 78 | obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o |
| 77 | obj-$(CONFIG_GPIO_PCH) += gpio-pch.o | 79 | obj-$(CONFIG_GPIO_PCH) += gpio-pch.o |
| 80 | obj-$(CONFIG_GPIO_PISOSR) += gpio-pisosr.o | ||
| 78 | obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o | 81 | obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o |
| 79 | obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o | 82 | obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o |
| 80 | obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o | 83 | obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o |
| @@ -95,9 +98,12 @@ obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o · 14 unmodified lines | |||
| 95 | obj-$(CONFIG_ARCH_TEGRA) += gpio-tegra.o | 98 | obj-$(CONFIG_ARCH_TEGRA) += gpio-tegra.o |
| 96 | obj-$(CONFIG_GPIO_TIMBERDALE) += gpio-timberdale.o | 99 | obj-$(CONFIG_GPIO_TIMBERDALE) += gpio-timberdale.o |
| 97 | obj-$(CONFIG_GPIO_PALMAS) += gpio-palmas.o | 100 | obj-$(CONFIG_GPIO_PALMAS) += gpio-palmas.o |
| 101 | obj-$(CONFIG_GPIO_TPIC2810) += gpio-tpic2810.o | ||
| 102 | obj-$(CONFIG_GPIO_TPS65218) += gpio-tps65218.o | ||
| 98 | obj-$(CONFIG_GPIO_TPS6586X) += gpio-tps6586x.o | 103 | obj-$(CONFIG_GPIO_TPS6586X) += gpio-tps6586x.o |
| 99 | obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o | 104 | obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o |
| 100 | obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o | 105 | obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o |
| 106 | obj-$(CONFIG_GPIO_TS4800) += gpio-ts4800.o | ||
| 101 | obj-$(CONFIG_GPIO_TS5500) += gpio-ts5500.o | 107 | obj-$(CONFIG_GPIO_TS5500) += gpio-ts5500.o |
| 102 | obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o | 108 | obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o |
| 103 | obj-$(CONFIG_GPIO_TWL6040) += gpio-twl6040.o | 109 | obj-$(CONFIG_GPIO_TWL6040) += gpio-twl6040.o |
| @@ -111,6 +117,7 @@ obj-$(CONFIG_GPIO_VX855) += gpio-vx855.o · 7 unmodified lines | |||
| 111 | obj-$(CONFIG_GPIO_WM831X) += gpio-wm831x.o | 117 | obj-$(CONFIG_GPIO_WM831X) += gpio-wm831x.o |
| 112 | obj-$(CONFIG_GPIO_WM8350) += gpio-wm8350.o | 118 | obj-$(CONFIG_GPIO_WM8350) += gpio-wm8350.o |
| 113 | obj-$(CONFIG_GPIO_WM8994) += gpio-wm8994.o | 119 | obj-$(CONFIG_GPIO_WM8994) += gpio-wm8994.o |
| 120 | obj-$(CONFIG_GPIO_WS16C48) += gpio-ws16c48.o | ||
| 114 | obj-$(CONFIG_GPIO_XGENE) += gpio-xgene.o | 121 | obj-$(CONFIG_GPIO_XGENE) += gpio-xgene.o |
| 115 | obj-$(CONFIG_GPIO_XGENE_SB) += gpio-xgene-sb.o | 122 | obj-$(CONFIG_GPIO_XGENE_SB) += gpio-xgene-sb.o |
| 116 | obj-$(CONFIG_GPIO_XILINX) += gpio-xilinx.o | 123 | obj-$(CONFIG_GPIO_XILINX) += gpio-xilinx.o |
| @@ -155,7 +155,7 @@ struct gpio_desc *devm_get_gpiod_from_child(struct device *dev, · 154 unmodified lines | |||
| 155 | suffixes[i]); | 155 | suffixes[i]); |
| 156 | 156 | ||
| 157 | desc = fwnode_get_named_gpiod(child, prop_name); | 157 | desc = fwnode_get_named_gpiod(child, prop_name); |
| 158 | if (!IS_ERR(desc) || (PTR_ERR(desc) == -EPROBE_DEFER)) | 158 | if (!IS_ERR(desc) || (PTR_ERR(desc) != -ENOENT)) |
| 159 | break; | 159 | break; |
| 160 | } | 160 | } |
| 161 | if (IS_ERR(desc)) { | 161 | if (IS_ERR(desc)) { |
| @@ -0,0 +1,430 @@ | |||
| 1 | /* | ||
| 2 | * GPIO driver for the ACCES 104-DIO-48E | ||
| 3 | * Copyright (C) 2016 William Breathitt Gray | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License, version 2, as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, but | ||
| 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 12 | * General Public License for more details. | ||
| 13 | */ | ||
| 14 | #include <linux/bitops.h> | ||
| 15 | #include <linux/device.h> | ||
| 16 | #include <linux/errno.h> | ||
| 17 | #include <linux/gpio/driver.h> | ||
| 18 | #include <linux/io.h> | ||
| 19 | #include <linux/ioport.h> | ||
| 20 | #include <linux/interrupt.h> | ||
| 21 | #include <linux/irqdesc.h> | ||
| 22 | #include <linux/kernel.h> | ||
| 23 | #include <linux/module.h> | ||
| 24 | #include <linux/moduleparam.h> | ||
| 25 | #include <linux/platform_device.h> | ||
| 26 | #include <linux/spinlock.h> | ||
| 27 | |||
| 28 | static unsigned dio_48e_base; | ||
| 29 | module_param(dio_48e_base, uint, 0); | ||
| 30 | MODULE_PARM_DESC(dio_48e_base, "ACCES 104-DIO-48E base address"); | ||
| 31 | static unsigned dio_48e_irq; | ||
| 32 | module_param(dio_48e_irq, uint, 0); | ||
| 33 | MODULE_PARM_DESC(dio_48e_irq, "ACCES 104-DIO-48E interrupt line number"); | ||
| 34 | |||
| 35 | /** | ||
| 36 | * struct dio48e_gpio - GPIO device private data structure | ||
| 37 | * @chip: instance of the gpio_chip | ||
| 38 | * @io_state: bit I/O state (whether bit is set to input or output) | ||
| 39 | * @out_state: output bits state | ||
| 40 | * @control: Control registers state | ||
| 41 | * @lock: synchronization lock to prevent I/O race conditions | ||
| 42 | * @base: base port address of the GPIO device | ||
| 43 | * @irq: Interrupt line number | ||
| 44 | * @irq_mask: I/O bits affected by interrupts | ||
| 45 | */ | ||
| 46 | struct dio48e_gpio { | ||
| 47 | struct gpio_chip chip; | ||
| 48 | unsigned char io_state[6]; | ||
| 49 | unsigned char out_state[6]; | ||
| 50 | unsigned char control[2]; | ||
| 51 | spinlock_t lock; | ||
| 52 | unsigned base; | ||
| 53 | unsigned irq; | ||
| 54 | unsigned char irq_mask; | ||
| 55 | }; | ||
| 56 | |||
| 57 | static int dio48e_gpio_get_direction(struct gpio_chip *chip, unsigned offset) | ||
| 58 | { | ||
| 59 | struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip); | ||
| 60 | const unsigned port = offset / 8; | ||
| 61 | const unsigned mask = BIT(offset % 8); | ||
| 62 | |||
| 63 | return !!(dio48egpio->io_state[port] & mask); | ||
| 64 | } | ||
| 65 | |||
| 66 | static int dio48e_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | ||
| 67 | { | ||
| 68 | struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip); | ||
| 69 | const unsigned io_port = offset / 8; | ||
| 70 | const unsigned control_port = io_port / 2; | ||
| 71 | const unsigned control_addr = dio48egpio->base + 3 + control_port*4; | ||
| 72 | unsigned long flags; | ||
| 73 | unsigned control; | ||
| 74 | |||
| 75 | spin_lock_irqsave(&dio48egpio->lock, flags); | ||
| 76 | |||
| 77 | /* Check if configuring Port C */ | ||
| 78 | if (io_port == 2 || io_port == 5) { | ||
| 79 | /* Port C can be configured by nibble */ | ||
| 80 | if (offset % 8 > 3) { | ||
| 81 | dio48egpio->io_state[io_port] |= 0xF0; | ||
| 82 | dio48egpio->control[control_port] |= BIT(3); | ||
| 83 | } else { | ||
| 84 | dio48egpio->io_state[io_port] |= 0x0F; | ||
| 85 | dio48egpio->control[control_port] |= BIT(0); | ||
| 86 | } | ||
| 87 | } else { | ||
| 88 | dio48egpio->io_state[io_port] |= 0xFF; | ||
| 89 | if (io_port == 0 || io_port == 3) | ||
| 90 | dio48egpio->control[control_port] |= BIT(4); | ||
| 91 | else | ||
| 92 | dio48egpio->control[control_port] |= BIT(1); | ||
| 93 | } | ||
| 94 | |||
| 95 | control = BIT(7) | dio48egpio->control[control_port]; | ||
| 96 | outb(control, control_addr); | ||
| 97 | control &= ~BIT(7); | ||
| 98 | outb(control, control_addr); | ||
| 99 | |||
| 100 | spin_unlock_irqrestore(&dio48egpio->lock, flags); | ||
| 101 | |||
| 102 | return 0; | ||
| 103 | } | ||
| 104 | |||
| 105 | static int dio48e_gpio_direction_output(struct gpio_chip *chip, unsigned offset, | ||
| 106 | int value) | ||
| 107 | { | ||
| 108 | struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip); | ||
| 109 | const unsigned io_port = offset / 8; | ||
| 110 | const unsigned control_port = io_port / 2; | ||
| 111 | const unsigned mask = BIT(offset % 8); | ||
| 112 | const unsigned control_addr = dio48egpio->base + 3 + control_port*4; | ||
| 113 | const unsigned out_port = (io_port > 2) ? io_port + 1 : io_port; | ||
| 114 | unsigned long flags; | ||
| 115 | unsigned control; | ||
| 116 | |||
| 117 | spin_lock_irqsave(&dio48egpio->lock, flags); | ||
| 118 | |||
| 119 | /* Check if configuring Port C */ | ||
| 120 | if (io_port == 2 || io_port == 5) { | ||
| 121 | /* Port C can be configured by nibble */ | ||
| 122 | if (offset % 8 > 3) { | ||
| 123 | dio48egpio->io_state[io_port] &= 0x0F; | ||
| 124 | dio48egpio->control[control_port] &= ~BIT(3); | ||
| 125 | } else { | ||
| 126 | dio48egpio->io_state[io_port] &= 0xF0; | ||
| 127 | dio48egpio->control[control_port] &= ~BIT(0); | ||
| 128 | } | ||
| 129 | } else { | ||
| 130 | dio48egpio->io_state[io_port] &= 0x00; | ||
| 131 | if (io_port == 0 || io_port == 3) | ||
| 132 | dio48egpio->control[control_port] &= ~BIT(4); | ||
| 133 | else | ||
| 134 | dio48egpio->control[control_port] &= ~BIT(1); | ||
| 135 | } | ||
| 136 | |||
| 137 | if (value) | ||
| 138 | dio48egpio->out_state[io_port] |= mask; | ||
| 139 | else | ||
| 140 | dio48egpio->out_state[io_port] &= ~mask; | ||
| 141 | |||
| 142 | control = BIT(7) | dio48egpio->control[control_port]; | ||
| 143 | outb(control, control_addr); | ||
| 144 | |||
| 145 | outb(dio48egpio->out_state[io_port], dio48egpio->base + out_port); | ||
| 146 | |||
| 147 | control &= ~BIT(7); | ||
| 148 | outb(control, control_addr); | ||
| 149 | |||
| 150 | spin_unlock_irqrestore(&dio48egpio->lock, flags); | ||
| 151 | |||
| 152 | return 0; | ||
| 153 | } | ||
| 154 | |||
| 155 | static int dio48e_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
| 156 | { | ||
| 157 | struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip); | ||
| 158 | const unsigned port = offset / 8; | ||
| 159 | const unsigned mask = BIT(offset % 8); | ||
| 160 | const unsigned in_port = (port > 2) ? port + 1 : port; | ||
| 161 | unsigned long flags; | ||
| 162 | unsigned port_state; | ||
| 163 | |||
| 164 | spin_lock_irqsave(&dio48egpio->lock, flags); | ||
| 165 | |||
| 166 | /* ensure that GPIO is set for input */ | ||
| 167 | if (!(dio48egpio->io_state[port] & mask)) { | ||
| 168 | spin_unlock_irqrestore(&dio48egpio->lock, flags); | ||
| 169 | return -EINVAL; | ||
| 170 | } | ||
| 171 | |||
| 172 | port_state = inb(dio48egpio->base + in_port); | ||
| 173 | |||
| 174 | spin_unlock_irqrestore(&dio48egpio->lock, flags); | ||
| 175 | |||
| 176 | return !!(port_state & mask); | ||
| 177 | } | ||
| 178 | |||
| 179 | static void dio48e_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
| 180 | { | ||
| 181 | struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip); | ||
| 182 | const unsigned port = offset / 8; | ||
| 183 | const unsigned mask = BIT(offset % 8); | ||
| 184 | const unsigned out_port = (port > 2) ? port + 1 : port; | ||
| 185 | unsigned long flags; | ||
| 186 | |||
| 187 | spin_lock_irqsave(&dio48egpio->lock, flags); | ||
| 188 | |||
| 189 | if (value) | ||
| 190 | dio48egpio->out_state[port] |= mask; | ||
| 191 | else | ||
| 192 | dio48egpio->out_state[port] &= ~mask; | ||
| 193 | |||
| 194 | outb(dio48egpio->out_state[port], dio48egpio->base + out_port); | ||
| 195 | |||
| 196 | spin_unlock_irqrestore(&dio48egpio->lock, flags); | ||
| 197 | } | ||
| 198 | |||
| 199 | static void dio48e_irq_ack(struct irq_data *data) | ||
| 200 | { | ||
| 201 | } | ||
| 202 | |||
| 203 | static void dio48e_irq_mask(struct irq_data *data) | ||
| 204 | { | ||
| 205 | struct gpio_chip *chip = irq_data_get_irq_chip_data(data); | ||
| 206 | struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip); | ||
| 207 | const unsigned long offset = irqd_to_hwirq(data); | ||
| 208 | unsigned long flags; | ||
| 209 | |||
| 210 | /* only bit 3 on each respective Port C supports interrupts */ | ||
| 211 | if (offset != 19 && offset != 43) | ||
| 212 | return; | ||
| 213 | |||
| 214 | spin_lock_irqsave(&dio48egpio->lock, flags); | ||
| 215 | |||
| 216 | if (offset == 19) | ||
| 217 | dio48egpio->irq_mask &= ~BIT(0); | ||
| 218 | else | ||
| 219 | dio48egpio->irq_mask &= ~BIT(1); | ||
| 220 | |||
| 221 | if (!dio48egpio->irq_mask) | ||
| 222 | /* disable interrupts */ | ||
| 223 | inb(dio48egpio->base + 0xB); | ||
| 224 | |||
| 225 | spin_unlock_irqrestore(&dio48egpio->lock, flags); | ||
| 226 | } | ||
| 227 | |||
| 228 | static void dio48e_irq_unmask(struct irq_data *data) | ||
| 229 | { | ||
| 230 | struct gpio_chip *chip = irq_data_get_irq_chip_data(data); | ||
| 231 | struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip); | ||
| 232 | const unsigned long offset = irqd_to_hwirq(data); | ||
| 233 | unsigned long flags; | ||
| 234 | |||
| 235 | /* only bit 3 on each respective Port C supports interrupts */ | ||
| 236 | if (offset != 19 && offset != 43) | ||
| 237 | return; | ||
| 238 | |||
| 239 | spin_lock_irqsave(&dio48egpio->lock, flags); | ||
| 240 | |||
| 241 | if (!dio48egpio->irq_mask) { | ||
| 242 | /* enable interrupts */ | ||
| 243 | outb(0x00, dio48egpio->base + 0xF); | ||
| 244 | outb(0x00, dio48egpio->base + 0xB); | ||
| 245 | } | ||
| 246 | |||
| 247 | if (offset == 19) | ||
| 248 | dio48egpio->irq_mask |= BIT(0); | ||
| 249 | else | ||
| 250 | dio48egpio->irq_mask |= BIT(1); | ||
| 251 | |||
| 252 | spin_unlock_irqrestore(&dio48egpio->lock, flags); | ||
| 253 | } | ||
| 254 | |||
| 255 | static int dio48e_irq_set_type(struct irq_data *data, unsigned flow_type) | ||
| 256 | { | ||
| 257 | const unsigned long offset = irqd_to_hwirq(data); | ||
| 258 | |||
| 259 | /* only bit 3 on each respective Port C supports interrupts */ | ||
| 260 | if (offset != 19 && offset != 43) | ||
| 261 | return -EINVAL; | ||
| 262 | |||
| 263 | if (flow_type != IRQ_TYPE_NONE && flow_type != IRQ_TYPE_EDGE_RISING) | ||
| 264 | return -EINVAL; | ||
| 265 | |||
| 266 | return 0; | ||
| 267 | } | ||
| 268 | |||
| 269 | static struct irq_chip dio48e_irqchip = { | ||
| 270 | .name = "104-dio-48e", | ||
| 271 | .irq_ack = dio48e_irq_ack, | ||
| 272 | .irq_mask = dio48e_irq_mask, | ||
| 273 | .irq_unmask = dio48e_irq_unmask, | ||
| 274 | .irq_set_type = dio48e_irq_set_type | ||
| 275 | }; | ||
| 276 | |||
| 277 | static irqreturn_t dio48e_irq_handler(int irq, void *dev_id) | ||
| 278 | { | ||
| 279 | struct dio48e_gpio *const dio48egpio = dev_id; | ||
| 280 | struct gpio_chip *const chip = &dio48egpio->chip; | ||
| 281 | const unsigned long irq_mask = dio48egpio->irq_mask; | ||
| 282 | unsigned long gpio; | ||
| 283 | |||
| 284 | for_each_set_bit(gpio, &irq_mask, 2) | ||
| 285 | generic_handle_irq(irq_find_mapping(chip->irqdomain, | ||
| 286 | 19 + gpio*24)); | ||
| 287 | |||
| 288 | spin_lock(&dio48egpio->lock); | ||
| 289 | |||
| 290 | outb(0x00, dio48egpio->base + 0xF); | ||
| 291 | |||
| 292 | spin_unlock(&dio48egpio->lock); | ||
| 293 | |||
| 294 | return IRQ_HANDLED; | ||
| 295 | } | ||
| 296 | |||
| 297 | static int __init dio48e_probe(struct platform_device *pdev) | ||
| 298 | { | ||
| 299 | struct device *dev = &pdev->dev; | ||
| 300 | struct dio48e_gpio *dio48egpio; | ||
| 301 | const unsigned base = dio_48e_base; | ||
| 302 | const unsigned extent = 16; | ||
| 303 | const char *const name = dev_name(dev); | ||
| 304 | int err; | ||
| 305 | const unsigned irq = dio_48e_irq; | ||
| 306 | |||
| 307 | dio48egpio = devm_kzalloc(dev, sizeof(*dio48egpio), GFP_KERNEL); | ||
| 308 | if (!dio48egpio) | ||
| 309 | return -ENOMEM; | ||
| 310 | |||
| 311 | if (!devm_request_region(dev, base, extent, name)) { | ||
| 312 | dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", | ||
| 313 | base, base + extent); | ||
| 314 | return -EBUSY; | ||
| 315 | } | ||
| 316 | |||
| 317 | dio48egpio->chip.label = name; | ||
| 318 | dio48egpio->chip.parent = dev; | ||
| 319 | dio48egpio->chip.owner = THIS_MODULE; | ||
| 320 | dio48egpio->chip.base = -1; | ||
| 321 | dio48egpio->chip.ngpio = 48; | ||
| 322 | dio48egpio->chip.get_direction = dio48e_gpio_get_direction; | ||
| 323 | dio48egpio->chip.direction_input = dio48e_gpio_direction_input; | ||
| 324 | dio48egpio->chip.direction_output = dio48e_gpio_direction_output; | ||
| 325 | dio48egpio->chip.get = dio48e_gpio_get; | ||
| 326 | dio48egpio->chip.set = dio48e_gpio_set; | ||
| 327 | dio48egpio->base = base; | ||
| 328 | dio48egpio->irq = irq; | ||
| 329 | |||
| 330 | spin_lock_init(&dio48egpio->lock); | ||
| 331 | |||
| 332 | dev_set_drvdata(dev, dio48egpio); | ||
| 333 | |||
| 334 | err = gpiochip_add_data(&dio48egpio->chip, dio48egpio); | ||
| 335 | if (err) { | ||
| 336 | dev_err(dev, "GPIO registering failed (%d)\n", err); | ||
| 337 | return err; | ||
| 338 | } | ||
| 339 | |||
| 340 | /* initialize all GPIO as output */ | ||
| 341 | outb(0x80, base + 3); | ||
| 342 | outb(0x00, base); | ||
| 343 | outb(0x00, base + 1); | ||
| 344 | outb(0x00, base + 2); | ||
| 345 | outb(0x00, base + 3); | ||
| 346 | outb(0x80, base + 7); | ||
| 347 | outb(0x00, base + 4); | ||
| 348 | outb(0x00, base + 5); | ||
| 349 | outb(0x00, base + 6); | ||
| 350 | outb(0x00, base + 7); | ||
| 351 | |||
| 352 | /* disable IRQ by default */ | ||
| 353 | inb(base + 0xB); | ||
| 354 | |||
| 355 | err = gpiochip_irqchip_add(&dio48egpio->chip, &dio48e_irqchip, 0, | ||
| 356 | handle_edge_irq, IRQ_TYPE_NONE); | ||
| 357 | if (err) { | ||
| 358 | dev_err(dev, "Could not add irqchip (%d)\n", err); | ||
| 359 | goto err_gpiochip_remove; | ||
| 360 | } | ||
| 361 | |||
| 362 | err = request_irq(irq, dio48e_irq_handler, 0, name, dio48egpio); | ||
| 363 | if (err) { | ||
| 364 | dev_err(dev, "IRQ handler registering failed (%d)\n", err); | ||
| 365 | goto err_gpiochip_remove; | ||
| 366 | } | ||
| 367 | |||
| 368 | return 0; | ||
| 369 | |||
| 370 | err_gpiochip_remove: | ||
| 371 | gpiochip_remove(&dio48egpio->chip); | ||
| 372 | return err; | ||
| 373 | } | ||
| 374 | |||
| 375 | static int dio48e_remove(struct platform_device *pdev) | ||
| 376 | { | ||
| 377 | struct dio48e_gpio *const dio48egpio = platform_get_drvdata(pdev); | ||
| 378 | |||
| 379 | free_irq(dio48egpio->irq, dio48egpio); | ||
| 380 | gpiochip_remove(&dio48egpio->chip); | ||
| 381 | |||
| 382 | return 0; | ||
| 383 | } | ||
| 384 | |||
| 385 | static struct platform_device *dio48e_device; | ||
| 386 | |||
| 387 | static struct platform_driver dio48e_driver = { | ||
| 388 | .driver = { | ||
| 389 | .name = "104-dio-48e" | ||
| 390 | }, | ||
| 391 | .remove = dio48e_remove | ||
| 392 | }; | ||
| 393 | |||
| 394 | static void __exit dio48e_exit(void) | ||
| 395 | { | ||
| 396 | platform_device_unregister(dio48e_device); | ||
| 397 | platform_driver_unregister(&dio48e_driver); | ||
| 398 | } | ||
| 399 | |||
| 400 | static int __init dio48e_init(void) | ||
| 401 | { | ||
| 402 | int err; | ||
| 403 | |||
| 404 | dio48e_device = platform_device_alloc(dio48e_driver.driver.name, -1); | ||
| 405 | if (!dio48e_device) | ||
| 406 | return -ENOMEM; | ||
| 407 | |||
| 408 | err = platform_device_add(dio48e_device); | ||
| 409 | if (err) | ||
| 410 | goto err_platform_device; | ||
| 411 | |||
| 412 | err = platform_driver_probe(&dio48e_driver, dio48e_probe); | ||
| 413 | if (err) | ||
| 414 | goto err_platform_driver; | ||
| 415 | |||
| 416 | return 0; | ||
| 417 | |||
| 418 | err_platform_driver: | ||
| 419 | platform_device_del(dio48e_device); | ||
| 420 | err_platform_device: | ||
| 421 | platform_device_put(dio48e_device); | ||
| 422 | return err; | ||
| 423 | } | ||
| 424 | |||
| 425 | module_init(dio48e_init); | ||
| 426 | module_exit(dio48e_exit); | ||
| 427 | |||
| 428 | MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>"); | ||
| 429 | MODULE_DESCRIPTION("ACCES 104-DIO-48E GPIO driver"); | ||
| 430 | MODULE_LICENSE("GPL v2"); | ||
| @@ -39,7 +39,6 @@ MODULE_PARM_DESC(idi_48_irq, "ACCES 104-IDI-48 interrupt line number"); · 38 unmodified lines | |||
| 39 | * @ack_lock: synchronization lock to prevent IRQ handler race conditions | 39 | * @ack_lock: synchronization lock to prevent IRQ handler race conditions |
| 40 | * @irq_mask: input bits affected by interrupts | 40 | * @irq_mask: input bits affected by interrupts |
| 41 | * @base: base port address of the GPIO device | 41 | * @base: base port address of the GPIO device |
| 42 | * @extent: extent of port address region of the GPIO device | ||
| 43 | * @irq: Interrupt line number | 42 | * @irq: Interrupt line number |
| 44 | * @cos_enb: Change-Of-State IRQ enable boundaries mask | 43 | * @cos_enb: Change-Of-State IRQ enable boundaries mask |
| 45 | */ | 44 | */ |
| @@ -49,7 +48,6 @@ struct idi_48_gpio { · 3 unmodified lines | |||
| 49 | spinlock_t ack_lock; | 48 | spinlock_t ack_lock; |
| 50 | unsigned char irq_mask[6]; | 49 | unsigned char irq_mask[6]; |
| 51 | unsigned base; | 50 | unsigned base; |
| 52 | unsigned extent; | ||
| 53 | unsigned irq; | 51 | unsigned irq; |
| 54 | unsigned char cos_enb; | 52 | unsigned char cos_enb; |
| 55 | }; | 53 | }; |
| @@ -227,11 +225,10 @@ static int __init idi_48_probe(struct platform_device *pdev) · 171 unmodified lines | |||
| 227 | if (!idi48gpio) | 225 | if (!idi48gpio) |
| 228 | return -ENOMEM; | 226 | return -ENOMEM; |
| 229 | 227 | ||
| 230 | if (!request_region(base, extent, name)) { | 228 | if (!devm_request_region(dev, base, extent, name)) { |
| 231 | dev_err(dev, "Unable to lock %s port addresses (0x%X-0x%X)\n", | 229 | dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", |
| 232 | name, base, base + extent); | 230 | base, base + extent); |
| 233 | err = -EBUSY; | 231 | return -EBUSY; |
| 234 | goto err_lock_io_port; | ||
| 235 | } | 232 | } |
| 236 | 233 | ||
| 237 | idi48gpio->chip.label = name; | 234 | idi48gpio->chip.label = name; |
| @@ -243,7 +240,6 @@ static int __init idi_48_probe(struct platform_device *pdev) · 5 unmodified lines | |||
| 243 | idi48gpio->chip.direction_input = idi_48_gpio_direction_input; | 240 | idi48gpio->chip.direction_input = idi_48_gpio_direction_input; |
| 244 | idi48gpio->chip.get = idi_48_gpio_get; | 241 | idi48gpio->chip.get = idi_48_gpio_get; |
| 245 | idi48gpio->base = base; | 242 | idi48gpio->base = base; |
| 246 | idi48gpio->extent = extent; | ||
| 247 | idi48gpio->irq = irq; | 243 | idi48gpio->irq = irq; |
| 248 | 244 | ||
| 249 | spin_lock_init(&idi48gpio->lock); | 245 | spin_lock_init(&idi48gpio->lock); |
| @@ -253,7 +249,7 @@ static int __init idi_48_probe(struct platform_device *pdev) · 3 unmodified lines | |||
| 253 | err = gpiochip_add_data(&idi48gpio->chip, idi48gpio); | 249 | err = gpiochip_add_data(&idi48gpio->chip, idi48gpio); |
| 254 | if (err) { | 250 | if (err) { |
| 255 | dev_err(dev, "GPIO registering failed (%d)\n", err); | 251 | dev_err(dev, "GPIO registering failed (%d)\n", err); |
| 256 | goto err_gpio_register; | 252 | return err; |
| 257 | } | 253 | } |
| 258 | 254 | ||
| 259 | /* Disable IRQ by default */ | 255 | /* Disable IRQ by default */ |
| @@ -264,23 +260,20 @@ static int __init idi_48_probe(struct platform_device *pdev) · 4 unmodified lines | |||
| 264 | handle_edge_irq, IRQ_TYPE_NONE); | 260 | handle_edge_irq, IRQ_TYPE_NONE); |
| 265 | if (err) { | 261 | if (err) { |
| 266 | dev_err(dev, "Could not add irqchip (%d)\n", err); | 262 | dev_err(dev, "Could not add irqchip (%d)\n", err); |
| 267 | goto err_gpiochip_irqchip_add; | 263 | goto err_gpiochip_remove; |
| 268 | } | 264 | } |
| 269 | 265 | ||
| 270 | err = request_irq(irq, idi_48_irq_handler, 0, name, idi48gpio); | 266 | err = request_irq(irq, idi_48_irq_handler, IRQF_SHARED, name, |
| 267 | idi48gpio); | ||
| 271 | if (err) { | 268 | if (err) { |
| 272 | dev_err(dev, "IRQ handler registering failed (%d)\n", err); | 269 | dev_err(dev, "IRQ handler registering failed (%d)\n", err); |
| 273 | goto err_request_irq; | 270 | goto err_gpiochip_remove; |
| 274 | } | 271 | } |
| 275 | 272 | ||
| 276 | return 0; | 273 | return 0; |
| 277 | 274 | ||
| 278 | err_request_irq: | 275 | err_gpiochip_remove: |
| 279 | err_gpiochip_irqchip_add: | ||
| 280 | gpiochip_remove(&idi48gpio->chip); | 276 | gpiochip_remove(&idi48gpio->chip); |
| 281 | err_gpio_register: | ||
| 282 | release_region(base, extent); | ||
| 283 | err_lock_io_port: | ||
| 284 | return err; | 277 | return err; |
| 285 | } | 278 | } |
| 286 | 279 | ||
| @@ -290,7 +283,6 @@ static int idi_48_remove(struct platform_device *pdev) · 3 unmodified lines | |||
| 290 | 283 | ||
| 291 | free_irq(idi48gpio->irq, idi48gpio); | 284 | free_irq(idi48gpio->irq, idi48gpio); |
| 292 | gpiochip_remove(&idi48gpio->chip); | 285 | gpiochip_remove(&idi48gpio->chip); |
| 293 | release_region(idi48gpio->base, idi48gpio->extent); | ||
| 294 | 286 | ||
| 295 | return 0; | 287 | return 0; |
| 296 | } | 288 | } |
| @@ -340,4 +332,4 @@ module_exit(idi_48_exit); · 43 unmodified lines | |||
| 340 | 332 | ||
| 341 | MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>"); | 333 | MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>"); |
| 342 | MODULE_DESCRIPTION("ACCES 104-IDI-48 GPIO driver"); | 334 | MODULE_DESCRIPTION("ACCES 104-IDI-48 GPIO driver"); |
| 343 | MODULE_LICENSE("GPL"); | 335 | MODULE_LICENSE("GPL v2"); |
| @@ -38,7 +38,6 @@ MODULE_PARM_DESC(idio_16_irq, "ACCES 104-IDIO-16 interrupt line number"); · 37 unmodified lines | |||
| 38 | * @lock: synchronization lock to prevent I/O race conditions | 38 | * @lock: synchronization lock to prevent I/O race conditions |
| 39 | * @irq_mask: I/O bits affected by interrupts | 39 | * @irq_mask: I/O bits affected by interrupts |
| 40 | * @base: base port address of the GPIO device | 40 | * @base: base port address of the GPIO device |
| 41 | * @extent: extent of port address region of the GPIO device | ||
| 42 | * @irq: Interrupt line number | 41 | * @irq: Interrupt line number |
| 43 | * @out_state: output bits state | 42 | * @out_state: output bits state |
| 44 | */ | 43 | */ |
| @@ -47,7 +46,6 @@ struct idio_16_gpio { · 2 unmodified lines | |||
| 47 | spinlock_t lock; | 46 | spinlock_t lock; |
| 48 | unsigned long irq_mask; | 47 | unsigned long irq_mask; |
| 49 | unsigned base; | 48 | unsigned base; |
| 50 | unsigned extent; | ||
| 51 | unsigned irq; | 49 | unsigned irq; |
| 52 | unsigned out_state; | 50 | unsigned out_state; |
| 53 | }; | 51 | }; |
| @@ -201,11 +199,10 @@ static int __init idio_16_probe(struct platform_device *pdev) · 147 unmodified lines | |||
| 201 | if (!idio16gpio) | 199 | if (!idio16gpio) |
| 202 | return -ENOMEM; | 200 | return -ENOMEM; |
| 203 | 201 | ||
| 204 | if (!request_region(base, extent, name)) { | 202 | if (!devm_request_region(dev, base, extent, name)) { |
| 205 | dev_err(dev, "Unable to lock %s port addresses (0x%X-0x%X)\n", | 203 | dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", |
| 206 | name, base, base + extent); | 204 | base, base + extent); |
| 207 | err = -EBUSY; | 205 | return -EBUSY; |
| 208 | goto err_lock_io_port; | ||
| 209 | } | 206 | } |
| 210 | 207 | ||
| 211 | idio16gpio->chip.label = name; | 208 | idio16gpio->chip.label = name; |
| @@ -219,7 +216,6 @@ static int __init idio_16_probe(struct platform_device *pdev) · 7 unmodified lines | |||
| 219 | idio16gpio->chip.get = idio_16_gpio_get; | 216 | idio16gpio->chip.get = idio_16_gpio_get; |
| 220 | idio16gpio->chip.set = idio_16_gpio_set; | 217 | idio16gpio->chip.set = idio_16_gpio_set; |
| 221 | idio16gpio->base = base; | 218 | idio16gpio->base = base; |
| 222 | idio16gpio->extent = extent; | ||
| 223 | idio16gpio->irq = irq; | 219 | idio16gpio->irq = irq; |
| 224 | idio16gpio->out_state = 0xFFFF; | 220 | idio16gpio->out_state = 0xFFFF; |
| 225 | 221 | ||
| @@ -230,7 +226,7 @@ static int __init idio_16_probe(struct platform_device *pdev) · 4 unmodified lines | |||
| 230 | err = gpiochip_add_data(&idio16gpio->chip, idio16gpio); | 226 | err = gpiochip_add_data(&idio16gpio->chip, idio16gpio); |
| 231 | if (err) { | 227 | if (err) { |
| 232 | dev_err(dev, "GPIO registering failed (%d)\n", err); | 228 | dev_err(dev, "GPIO registering failed (%d)\n", err); |
| 233 | goto err_gpio_register; | 229 | return err; |
| 234 | } | 230 | } |
| 235 | 231 | ||
| 236 | /* Disable IRQ by default */ | 232 | /* Disable IRQ by default */ |
| @@ -241,23 +237,19 @@ static int __init idio_16_probe(struct platform_device *pdev) · 4 unmodified lines | |||
| 241 | handle_edge_irq, IRQ_TYPE_NONE); | 237 | handle_edge_irq, IRQ_TYPE_NONE); |
| 242 | if (err) { | 238 | if (err) { |
| 243 | dev_err(dev, "Could not add irqchip (%d)\n", err); | 239 | dev_err(dev, "Could not add irqchip (%d)\n", err); |
| 244 | goto err_gpiochip_irqchip_add; | 240 | goto err_gpiochip_remove; |
| 245 | } | 241 | } |
| 246 | 242 | ||
| 247 | err = request_irq(irq, idio_16_irq_handler, 0, name, idio16gpio); | 243 | err = request_irq(irq, idio_16_irq_handler, 0, name, idio16gpio); |
| 248 | if (err) { | 244 | if (err) { |
| 249 | dev_err(dev, "IRQ handler registering failed (%d)\n", err); | 245 | dev_err(dev, "IRQ handler registering failed (%d)\n", err); |
| 250 | goto err_request_irq; | 246 | goto err_gpiochip_remove; |
| 251 | } | 247 | } |
| 252 | 248 | ||
| 253 | return 0; | 249 | return 0; |
| 254 | 250 | ||
| 255 | err_request_irq: | 251 | err_gpiochip_remove: |
| 256 | err_gpiochip_irqchip_add: | ||
| 257 | gpiochip_remove(&idio16gpio->chip); | 252 | gpiochip_remove(&idio16gpio->chip); |
| 258 | err_gpio_register: | ||
| 259 | release_region(base, extent); | ||
| 260 | err_lock_io_port: | ||
| 261 | return err; | 253 | return err; |
| 262 | } | 254 | } |
| 263 | 255 | ||
| @@ -267,7 +259,6 @@ static int idio_16_remove(struct platform_device *pdev) · 3 unmodified lines | |||
| 267 | 259 | ||
| 268 | free_irq(idio16gpio->irq, idio16gpio); | 260 | free_irq(idio16gpio->irq, idio16gpio); |
| 269 | gpiochip_remove(&idio16gpio->chip); | 261 | gpiochip_remove(&idio16gpio->chip); |
| 270 | release_region(idio16gpio->base, idio16gpio->extent); | ||
| 271 | 262 | ||
| 272 | return 0; | 263 | return 0; |
| 273 | } | 264 | } |
| @@ -317,4 +308,4 @@ module_exit(idio_16_exit); · 43 unmodified lines | |||
| 317 | 308 | ||
| 318 | MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>"); | 309 | MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>"); |
| 319 | MODULE_DESCRIPTION("ACCES 104-IDIO-16 GPIO driver"); | 310 | MODULE_DESCRIPTION("ACCES 104-IDIO-16 GPIO driver"); |
| 320 | MODULE_LICENSE("GPL"); | 311 | MODULE_LICENSE("GPL v2"); |
| @@ -140,15 +140,7 @@ static int mmio_74xx_gpio_probe(struct platform_device *pdev) · 139 unmodified lines | |||
| 140 | 140 | ||
| 141 | platform_set_drvdata(pdev, priv); | 141 | platform_set_drvdata(pdev, priv); |
| 142 | 142 | ||
| 143 | return gpiochip_add_data(&priv->gc, priv); | 143 | return devm_gpiochip_add_data(&pdev->dev, &priv->gc, priv); |
| 144 | } | ||
| 145 | |||
| 146 | static int mmio_74xx_gpio_remove(struct platform_device *pdev) | ||
| 147 | { | ||
| 148 | struct mmio_74xx_gpio_priv *priv = platform_get_drvdata(pdev); | ||
| 149 | |||
| 150 | gpiochip_remove(&priv->gc); | ||
| 151 | return 0; | ||
| 152 | } | 144 | } |
| 153 | 145 | ||
| 154 | static struct platform_driver mmio_74xx_gpio_driver = { | 146 | static struct platform_driver mmio_74xx_gpio_driver = { |
| @@ -157,7 +149,6 @@ static struct platform_driver mmio_74xx_gpio_driver = { · 2 unmodified lines | |||
| 157 | .of_match_table = mmio_74xx_gpio_ids, | 149 | .of_match_table = mmio_74xx_gpio_ids, |
| 158 | }, | 150 | }, |
| 159 | .probe = mmio_74xx_gpio_probe, | 151 | .probe = mmio_74xx_gpio_probe, |
| 160 | .remove = mmio_74xx_gpio_remove, | ||
| 161 | }; | 152 | }; |
| 162 | module_platform_driver(mmio_74xx_gpio_driver); | 153 | module_platform_driver(mmio_74xx_gpio_driver); |
| 163 | 154 | ||
| @@ -265,7 +265,7 @@ static int adnp_gpio_setup(struct adnp *adnp, unsigned int num_gpios) · 264 unmodified lines | |||
| 265 | chip->of_node = chip->parent->of_node; | 265 | chip->of_node = chip->parent->of_node; |
| 266 | chip->owner = THIS_MODULE; | 266 | chip->owner = THIS_MODULE; |
| 267 | 267 | ||
| 268 | err = gpiochip_add_data(chip, adnp); | 268 | err = devm_gpiochip_add_data(&adnp->client->dev, chip, adnp); |
| 269 | if (err) | 269 | if (err) |
| 270 | return err; | 270 | return err; |
| 271 | 271 | ||
| @@ -520,14 +520,6 @@ static int adnp_i2c_probe(struct i2c_client *client, · 248 unmodified lines | |||
| 520 | return 0; | 520 | return 0; |
| 521 | } | 521 | } |
| 522 | 522 | ||
| 523 | static int adnp_i2c_remove(struct i2c_client *client) | ||
| 524 | { | ||
| 525 | struct adnp *adnp = i2c_get_clientdata(client); | ||
| 526 | |||
| 527 | gpiochip_remove(&adnp->gpio); | ||
| 528 | return 0; | ||
| 529 | } | ||
| 530 | |||
| 531 | static const struct i2c_device_id adnp_i2c_id[] = { | 523 | static const struct i2c_device_id adnp_i2c_id[] = { |
| 532 | { "gpio-adnp" }, | 524 | { "gpio-adnp" }, |
| 533 | { }, | 525 | { }, |
| @@ -546,7 +538,6 @@ static struct i2c_driver adnp_i2c_driver = { · 12 unmodified lines | |||
| 546 | .of_match_table = adnp_of_match, | 538 | .of_match_table = adnp_of_match, |
| 547 | }, | 539 | }, |
| 548 | .probe = adnp_i2c_probe, | 540 | .probe = adnp_i2c_probe, |
| 549 | .remove = adnp_i2c_remove, | ||
| 550 | .id_table = adnp_i2c_id, | 541 | .id_table = adnp_i2c_id, |
| 551 | }; | 542 | }; |
| 552 | module_i2c_driver(adnp_i2c_driver); | 543 | module_i2c_driver(adnp_i2c_driver); |
| @@ -153,7 +153,7 @@ static int adp5520_gpio_probe(struct platform_device *pdev) · 152 unmodified lines | |||
| 153 | goto err; | 153 | goto err; |
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | ret = gpiochip_add_data(&dev->gpio_chip, dev); | 156 | ret = devm_gpiochip_add_data(&pdev->dev, &dev->gpio_chip, dev); |
| 157 | if (ret) | 157 | if (ret) |
| 158 | goto err; | 158 | goto err; |
| 159 | 159 | ||
| @@ -164,22 +164,11 @@ err: · 4 unmodified lines | |||
| 164 | return ret; | 164 | return ret; |
| 165 | } | 165 | } |
| 166 | 166 | ||
| 167 | static int adp5520_gpio_remove(struct platform_device *pdev) | ||
| 168 | { | ||
| 169 | struct adp5520_gpio *dev; | ||
| 170 | |||
| 171 | dev = platform_get_drvdata(pdev); | ||
| 172 | gpiochip_remove(&dev->gpio_chip); | ||
| 173 | |||
| 174 | return 0; | ||
| 175 | } | ||
| 176 | |||
| 177 | static struct platform_driver adp5520_gpio_driver = { | 167 | static struct platform_driver adp5520_gpio_driver = { |
| 178 | .driver = { | 168 | .driver = { |
| 179 | .name = "adp5520-gpio", | 169 | .name = "adp5520-gpio", |
| 180 | }, | 170 | }, |
| 181 | .probe = adp5520_gpio_probe, | 171 | .probe = adp5520_gpio_probe, |
| 182 | .remove = adp5520_gpio_remove, | ||
| 183 | }; | 172 | }; |
| 184 | 173 | ||
| 185 | module_platform_driver(adp5520_gpio_driver); | 174 | module_platform_driver(adp5520_gpio_driver); |
| @@ -414,7 +414,7 @@ static int adp5588_gpio_probe(struct i2c_client *client, · 413 unmodified lines | |||
| 414 | } | 414 | } |
| 415 | } | 415 | } |
| 416 | 416 | ||
| 417 | ret = gpiochip_add_data(&dev->gpio_chip, dev); | 417 | ret = devm_gpiochip_add_data(&client->dev, &dev->gpio_chip, dev); |
| 418 | if (ret) | 418 | if (ret) |
| 419 | goto err_irq; | 419 | goto err_irq; |
| 420 | 420 | ||
| @@ -457,8 +457,6 @@ static int adp5588_gpio_remove(struct i2c_client *client) · 36 unmodified lines | |||
| 457 | if (dev->irq_base) | 457 | if (dev->irq_base) |
| 458 | free_irq(dev->client->irq, dev); | 458 | free_irq(dev->client->irq, dev); |
| 459 | 459 | ||
| 460 | gpiochip_remove(&dev->gpio_chip); | ||
| 461 | |||
| 462 | return 0; | 460 | return 0; |
| 463 | } | 461 | } |
| 464 | 462 | ||
| @@ -25,6 +25,7 @@ · 24 unmodified lines | |||
| 25 | * License version 2. This program is licensed "as is" without any | 25 | * License version 2. This program is licensed "as is" without any |
| 26 | * warranty of any kind, whether express or implied. | 26 | * warranty of any kind, whether express or implied. |
| 27 | */ | 27 | */ |
| 28 | #include <linux/ioport.h> | ||
| 28 | #include <linux/module.h> | 29 | #include <linux/module.h> |
| 29 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
| 30 | #include <linux/gpio.h> | 31 | #include <linux/gpio.h> |
| @@ -204,7 +205,8 @@ found: · 173 unmodified lines | |||
| 204 | gp.pmbase &= 0x0000FF00; | 205 | gp.pmbase &= 0x0000FF00; |
| 205 | if (gp.pmbase == 0) | 206 | if (gp.pmbase == 0) |
| 206 | goto out; | 207 | goto out; |
| 207 | if (!request_region(gp.pmbase + PMBASE_OFFSET, PMBASE_SIZE, "AMD GPIO")) { | 208 | if (!devm_request_region(&pdev->dev, gp.pmbase + PMBASE_OFFSET, |
| 209 | PMBASE_SIZE, "AMD GPIO")) { | ||
| 208 | dev_err(&pdev->dev, "AMD GPIO region 0x%x already in use!\n", | 210 | dev_err(&pdev->dev, "AMD GPIO region 0x%x already in use!\n", |
| 209 | gp.pmbase + PMBASE_OFFSET); | 211 | gp.pmbase + PMBASE_OFFSET); |
| 210 | err = -EBUSY; | 212 | err = -EBUSY; |
| @@ -213,7 +215,6 @@ found: · 2 unmodified lines | |||
| 213 | gp.pm = ioport_map(gp.pmbase + PMBASE_OFFSET, PMBASE_SIZE); | 215 | gp.pm = ioport_map(gp.pmbase + PMBASE_OFFSET, PMBASE_SIZE); |
| 214 | if (!gp.pm) { | 216 | if (!gp.pm) { |
| 215 | dev_err(&pdev->dev, "Couldn't map io port into io memory\n"); | 217 | dev_err(&pdev->dev, "Couldn't map io port into io memory\n"); |
| 216 | release_region(gp.pmbase + PMBASE_OFFSET, PMBASE_SIZE); | ||
| 217 | err = -ENOMEM; | 218 | err = -ENOMEM; |
| 218 | goto out; | 219 | goto out; |
| 219 | } | 220 | } |
| @@ -228,7 +229,6 @@ found: · 8 unmodified lines | |||
| 228 | printk(KERN_ERR "GPIO registering failed (%d)\n", | 229 | printk(KERN_ERR "GPIO registering failed (%d)\n", |
| 229 | err); | 230 | err); |
| 230 | ioport_unmap(gp.pm); | 231 | ioport_unmap(gp.pm); |
| 231 | release_region(gp.pmbase + PMBASE_OFFSET, PMBASE_SIZE); | ||
| 232 | goto out; | 232 | goto out; |
| 233 | } | 233 | } |
| 234 | out: | 234 | out: |
| @@ -239,7 +239,6 @@ static void __exit amd_gpio_exit(void) · 4 unmodified lines | |||
| 239 | { | 239 | { |
| 240 | gpiochip_remove(&gp.chip); | 240 | gpiochip_remove(&gp.chip); |
| 241 | ioport_unmap(gp.pm); | 241 | ioport_unmap(gp.pm); |
| 242 | release_region(gp.pmbase + PMBASE_OFFSET, PMBASE_SIZE); | ||
| 243 | } | 242 | } |
| 244 | 243 | ||
| 245 | module_init(amd_gpio_init); | 244 | module_init(amd_gpio_init); |
| @@ -132,7 +132,8 @@ static int arizona_gpio_probe(struct platform_device *pdev) · 131 unmodified lines | |||
| 132 | else | 132 | else |
| 133 | arizona_gpio->gpio_chip.base = -1; | 133 | arizona_gpio->gpio_chip.base = -1; |
| 134 | 134 | ||
| 135 | ret = gpiochip_add_data(&arizona_gpio->gpio_chip, arizona_gpio); | 135 | ret = devm_gpiochip_add_data(&pdev->dev, &arizona_gpio->gpio_chip, |
| 136 | arizona_gpio); | ||
| 136 | if (ret < 0) { | 137 | if (ret < 0) { |
| 137 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", | 138 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", |
| 138 | ret); | 139 | ret); |
| @@ -147,18 +148,9 @@ err: · 8 unmodified lines | |||
| 147 | return ret; | 148 | return ret; |
| 148 | } | 149 | } |
| 149 | 150 | ||
| 150 | static int arizona_gpio_remove(struct platform_device *pdev) | ||
| 151 | { | ||
| 152 | struct arizona_gpio *arizona_gpio = platform_get_drvdata(pdev); | ||
| 153 | |||
| 154 | gpiochip_remove(&arizona_gpio->gpio_chip); | ||
| 155 | return 0; | ||
| 156 | } | ||
| 157 | |||
| 158 | static struct platform_driver arizona_gpio_driver = { | 151 | static struct platform_driver arizona_gpio_driver = { |
| 159 | .driver.name = "arizona-gpio", | 152 | .driver.name = "arizona-gpio", |
| 160 | .probe = arizona_gpio_probe, | 153 | .probe = arizona_gpio_probe, |
| 161 | .remove = arizona_gpio_remove, | ||
| 162 | }; | 154 | }; |
| 163 | 155 | ||
| 164 | module_platform_driver(arizona_gpio_driver); | 156 | module_platform_driver(arizona_gpio_driver); |
| @@ -1,12 +1,11 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Atheros AR71XX/AR724X/AR913X GPIO API support | 2 | * Atheros AR71XX/AR724X/AR913X GPIO API support |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2015 Alban Bedel <albeu@free.fr> | ||
| 4 | * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> | 5 | * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> |
| 5 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | 6 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> |
| 6 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | 7 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> |
| 7 | * | 8 | * |
| 8 | * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify it | 9 | * This program is free software; you can redistribute it and/or modify it |
| 11 | * under the terms of the GNU General Public License version 2 as published | 10 | * under the terms of the GNU General Public License version 2 as published |
| 12 | * by the Free Software Foundation. | 11 | * by the Free Software Foundation. |
| @@ -15,118 +14,204 @@ · 2 unmodified lines | |||
| 15 | #include <linux/gpio/driver.h> | 14 | #include <linux/gpio/driver.h> |
| 16 | #include <linux/platform_data/gpio-ath79.h> | 15 | #include <linux/platform_data/gpio-ath79.h> |
| 17 | #include <linux/of_device.h> | 16 | #include <linux/of_device.h> |
| 17 | #include <linux/interrupt.h> | ||
| 18 | #include <linux/irq.h> | ||
| 19 | |||
| 20 | #define AR71XX_GPIO_REG_OE 0x00 | ||
| 21 | #define AR71XX_GPIO_REG_IN 0x04 | ||
| 22 | #define AR71XX_GPIO_REG_SET 0x0c | ||
| 23 | #define AR71XX_GPIO_REG_CLEAR 0x10 | ||
| 18 | 24 | ||
| 19 | #include <asm/mach-ath79/ar71xx_regs.h> | 25 | #define AR71XX_GPIO_REG_INT_ENABLE 0x14 |
| 26 | #define AR71XX_GPIO_REG_INT_TYPE 0x18 | ||
| 27 | #define AR71XX_GPIO_REG_INT_POLARITY 0x1c | ||
| 28 | #define AR71XX_GPIO_REG_INT_PENDING 0x20 | ||
| 29 | #define AR71XX_GPIO_REG_INT_MASK 0x24 | ||
| 20 | 30 | ||
| 21 | struct ath79_gpio_ctrl { | 31 | struct ath79_gpio_ctrl { |
| 22 | struct gpio_chip chip; | 32 | struct gpio_chip gc; |
| 23 | void __iomem *base; | 33 | void __iomem *base; |
| 24 | spinlock_t lock; | 34 | spinlock_t lock; |
| 35 | unsigned long both_edges; | ||
| 25 | }; | 36 | }; |
| 26 | 37 | ||
| 27 | static void ath79_gpio_set_value(struct gpio_chip *chip, | 38 | static struct ath79_gpio_ctrl *irq_data_to_ath79_gpio(struct irq_data *data) |
| 28 | unsigned gpio, int value) | ||
| 29 | { | 39 | { |
| 30 | struct ath79_gpio_ctrl *ctrl = gpiochip_get_data(chip); | 40 | struct gpio_chip *gc = irq_data_get_irq_chip_data(data); |
| 31 | 41 | ||
| 32 | if (value) | 42 | return container_of(gc, struct ath79_gpio_ctrl, gc); |
| 33 | __raw_writel(BIT(gpio), ctrl->base + AR71XX_GPIO_REG_SET); | ||
| 34 | else | ||
| 35 | __raw_writel(BIT(gpio), ctrl->base + AR71XX_GPIO_REG_CLEAR); | ||
| 36 | } | 43 | } |
| 37 | 44 | ||
| 38 | static int ath79_gpio_get_value(struct gpio_chip *chip, unsigned gpio) | 45 | static u32 ath79_gpio_read(struct ath79_gpio_ctrl *ctrl, unsigned reg) |
| 39 | { | 46 | { |
| 40 | struct ath79_gpio_ctrl *ctrl = gpiochip_get_data(chip); | 47 | return readl(ctrl->base + reg); |
| 48 | } | ||
| 41 | 49 | ||
| 42 | return (__raw_readl(ctrl->base + AR71XX_GPIO_REG_IN) >> gpio) & 1; | 50 | static void ath79_gpio_write(struct ath79_gpio_ctrl *ctrl, |
| 51 | unsigned reg, u32 val) | ||
| 52 | { | ||
| 53 | return writel(val, ctrl->base + reg); | ||
| 43 | } | 54 | } |
| 44 | 55 | ||
| 45 | static int ath79_gpio_direction_input(struct gpio_chip *chip, | 56 | static bool ath79_gpio_update_bits( |
| 46 | unsigned offset) | 57 | struct ath79_gpio_ctrl *ctrl, unsigned reg, u32 mask, u32 bits) |
| 47 | { | 58 | { |
| 48 | struct ath79_gpio_ctrl *ctrl = gpiochip_get_data(chip); | 59 | u32 old_val, new_val; |
| 60 | |||
| 61 | old_val = ath79_gpio_read(ctrl, reg); | ||
| 62 | new_val = (old_val & ~mask) | (bits & mask); | ||
| 63 | |||
| 64 | if (new_val != old_val) | ||
| 65 | ath79_gpio_write(ctrl, reg, new_val); | ||
| 66 | |||
| 67 | return new_val != old_val; | ||
| 68 | } | ||
| 69 | |||
| 70 | static void ath79_gpio_irq_unmask(struct irq_data *data) | ||
| 71 | { | ||
| 72 | struct ath79_gpio_ctrl *ctrl = irq_data_to_ath79_gpio(data); | ||
| 73 | u32 mask = BIT(irqd_to_hwirq(data)); | ||
| 49 | unsigned long flags; | 74 | unsigned long flags; |
| 50 | 75 | ||
| 51 | spin_lock_irqsave(&ctrl->lock, flags); | 76 | spin_lock_irqsave(&ctrl->lock, flags); |
| 77 | ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, mask); | ||
| 78 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
| 79 | } | ||
| 52 | 80 | ||
| 53 | __raw_writel( | 81 | static void ath79_gpio_irq_mask(struct irq_data *data) |
| 54 | __raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) & ~BIT(offset), | 82 | { |
| 55 | ctrl->base + AR71XX_GPIO_REG_OE); | 83 | struct ath79_gpio_ctrl *ctrl = irq_data_to_ath79_gpio(data); |
| 84 | u32 mask = BIT(irqd_to_hwirq(data)); | ||
| 85 | unsigned long flags; | ||
| 56 | 86 | ||
| 87 | spin_lock_irqsave(&ctrl->lock, flags); | ||
| 88 | ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, 0); | ||
| 57 | spin_unlock_irqrestore(&ctrl->lock, flags); | 89 | spin_unlock_irqrestore(&ctrl->lock, flags); |
| 58 | |||
| 59 | return 0; | ||
| 60 | } | 90 | } |
| 61 | 91 | ||
| 62 | static int ath79_gpio_direction_output(struct gpio_chip *chip, | 92 | static void ath79_gpio_irq_enable(struct irq_data *data) |
| 63 | unsigned offset, int value) | ||
| 64 | { | 93 | { |
| 65 | struct ath79_gpio_ctrl *ctrl = gpiochip_get_data(chip); | 94 | struct ath79_gpio_ctrl *ctrl = irq_data_to_ath79_gpio(data); |
| 95 | u32 mask = BIT(irqd_to_hwirq(data)); | ||
| 66 | unsigned long flags; | 96 | unsigned long flags; |
| 67 | 97 | ||
| 68 | spin_lock_irqsave(&ctrl->lock, flags); | 98 | spin_lock_irqsave(&ctrl->lock, flags); |
| 99 | ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_ENABLE, mask, mask); | ||
| 100 | ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, mask); | ||
| 101 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
| 102 | } | ||
| 69 | 103 | ||
| 70 | if (value) | 104 | static void ath79_gpio_irq_disable(struct irq_data *data) |
| 71 | __raw_writel(BIT(offset), ctrl->base + AR71XX_GPIO_REG_SET); | 105 | { |
| 72 | else | 106 | struct ath79_gpio_ctrl *ctrl = irq_data_to_ath79_gpio(data); |
| 73 | __raw_writel(BIT(offset), ctrl->base + AR71XX_GPIO_REG_CLEAR); | 107 | u32 mask = BIT(irqd_to_hwirq(data)); |
| 74 | 108 | unsigned long flags; | |
| 75 | __raw_writel( | ||
| 76 | __raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) | BIT(offset), | ||
| 77 | ctrl->base + AR71XX_GPIO_REG_OE); | ||
| 78 | 109 | ||
| 110 | spin_lock_irqsave(&ctrl->lock, flags); | ||
| 111 | ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, 0); | ||
| 112 | ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_ENABLE, mask, 0); | ||
| 79 | spin_unlock_irqrestore(&ctrl->lock, flags); | 113 | spin_unlock_irqrestore(&ctrl->lock, flags); |
| 80 | |||
| 81 | return 0; | ||
| 82 | } | 114 | } |
| 83 | 115 | ||
| 84 | static int ar934x_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | 116 | static int ath79_gpio_irq_set_type(struct irq_data *data, |
| 117 | unsigned int flow_type) | ||
| 85 | { | 118 | { |
| 86 | struct ath79_gpio_ctrl *ctrl = gpiochip_get_data(chip); | 119 | struct ath79_gpio_ctrl *ctrl = irq_data_to_ath79_gpio(data); |
| 120 | u32 mask = BIT(irqd_to_hwirq(data)); | ||
| 121 | u32 type = 0, polarity = 0; | ||
| 87 | unsigned long flags; | 122 | unsigned long flags; |
| 123 | bool disabled; | ||
| 124 | |||
| 125 | switch (flow_type) { | ||
| 126 | case IRQ_TYPE_EDGE_RISING: | ||
| 127 | polarity |= mask; | ||
| 128 | case IRQ_TYPE_EDGE_FALLING: | ||
| 129 | case IRQ_TYPE_EDGE_BOTH: | ||
| 130 | break; | ||
| 131 | |||
| 132 | case IRQ_TYPE_LEVEL_HIGH: | ||
| 133 | polarity |= mask; | ||
| 134 | case IRQ_TYPE_LEVEL_LOW: | ||
| 135 | type |= mask; | ||
| 136 | break; | ||
| 137 | |||
| 138 | default: | ||
| 139 | return -EINVAL; | ||
| 140 | } | ||
| 88 | 141 | ||
| 89 | spin_lock_irqsave(&ctrl->lock, flags); | 142 | spin_lock_irqsave(&ctrl->lock, flags); |
| 90 | 143 | ||
| 91 | __raw_writel( | 144 | if (flow_type == IRQ_TYPE_EDGE_BOTH) { |
| 92 | __raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) | BIT(offset), | 145 | ctrl->both_edges |= mask; |
| 93 | ctrl->base + AR71XX_GPIO_REG_OE); | 146 | polarity = ~ath79_gpio_read(ctrl, AR71XX_GPIO_REG_IN); |
| 147 | } else { | ||
| 148 | ctrl->both_edges &= ~mask; | ||
| 149 | } | ||
| 150 | |||
| 151 | /* As the IRQ configuration can't be loaded atomically we | ||
| 152 | * have to disable the interrupt while the configuration state | ||
| 153 | * is invalid. | ||
| 154 | */ | ||
| 155 | disabled = ath79_gpio_update_bits( | ||
| 156 | ctrl, AR71XX_GPIO_REG_INT_ENABLE, mask, 0); | ||
| 157 | |||
| 158 | ath79_gpio_update_bits( | ||
| 159 | ctrl, AR71XX_GPIO_REG_INT_TYPE, mask, type); | ||
| 160 | ath79_gpio_update_bits( | ||
| 161 | ctrl, AR71XX_GPIO_REG_INT_POLARITY, mask, polarity); | ||
| 162 | |||
| 163 | if (disabled) | ||
| 164 | ath79_gpio_update_bits( | ||
| 165 | ctrl, AR71XX_GPIO_REG_INT_ENABLE, mask, mask); | ||
| 94 | 166 | ||
| 95 | spin_unlock_irqrestore(&ctrl->lock, flags); | 167 | spin_unlock_irqrestore(&ctrl->lock, flags); |
| 96 | 168 | ||
| 97 | return 0; | 169 | return 0; |
| 98 | } | 170 | } |
| 99 | 171 | ||
| 100 | static int ar934x_gpio_direction_output(struct gpio_chip *chip, unsigned offset, | 172 | static struct irq_chip ath79_gpio_irqchip = { |
| 101 | int value) | 173 | .name = "gpio-ath79", |
| 174 | .irq_enable = ath79_gpio_irq_enable, | ||
| 175 | .irq_disable = ath79_gpio_irq_disable, | ||
| 176 | .irq_mask = ath79_gpio_irq_mask, | ||
| 177 | .irq_unmask = ath79_gpio_irq_unmask, | ||
| 178 | .irq_set_type = ath79_gpio_irq_set_type, | ||
| 179 | }; | ||
| 180 | |||
| 181 | static void ath79_gpio_irq_handler(struct irq_desc *desc) | ||
| 102 | { | 182 | { |
| 103 | struct ath79_gpio_ctrl *ctrl = gpiochip_get_data(chip); | 183 | struct gpio_chip *gc = irq_desc_get_handler_data(desc); |
| 104 | unsigned long flags; | 184 | struct irq_chip *irqchip = irq_desc_get_chip(desc); |
| 185 | struct ath79_gpio_ctrl *ctrl = | ||
| 186 | container_of(gc, struct ath79_gpio_ctrl, gc); | ||
| 187 | unsigned long flags, pending; | ||
| 188 | u32 both_edges, state; | ||
| 189 | int irq; | ||
| 190 | |||
| 191 | chained_irq_enter(irqchip, desc); | ||
| 105 | 192 | ||
| 106 | spin_lock_irqsave(&ctrl->lock, flags); | 193 | spin_lock_irqsave(&ctrl->lock, flags); |
| 107 | 194 | ||
| 108 | if (value) | 195 | pending = ath79_gpio_read(ctrl, AR71XX_GPIO_REG_INT_PENDING); |
| 109 | __raw_writel(BIT(offset), ctrl->base + AR71XX_GPIO_REG_SET); | ||
| 110 | else | ||
| 111 | __raw_writel(BIT(offset), ctrl->base + AR71XX_GPIO_REG_CLEAR); | ||
| 112 | 196 | ||
| 113 | __raw_writel( | 197 | /* Update the polarity of the both edges irqs */ |
| 114 | __raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) & ~BIT(offset), | 198 | both_edges = ctrl->both_edges & pending; |
| 115 | ctrl->base + AR71XX_GPIO_REG_OE); | 199 | if (both_edges) { |
| 200 | state = ath79_gpio_read(ctrl, AR71XX_GPIO_REG_IN); | ||
| 201 | ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_POLARITY, | ||
| 202 | both_edges, ~state); | ||
| 203 | } | ||
| 116 | 204 | ||
| 117 | spin_unlock_irqrestore(&ctrl->lock, flags); | 205 | spin_unlock_irqrestore(&ctrl->lock, flags); |
| 118 | 206 | ||
| 119 | return 0; | 207 | if (pending) { |
| 120 | } | 208 | for_each_set_bit(irq, &pending, gc->ngpio) |
| 209 | generic_handle_irq( | ||
| 210 | irq_linear_revmap(gc->irqdomain, irq)); | ||
| 211 | } | ||
| 121 | 212 | ||
| 122 | static const struct gpio_chip ath79_gpio_chip = { | 213 | chained_irq_exit(irqchip, desc); |
| 123 | .label = "ath79", | 214 | } |
| 124 | .get = ath79_gpio_get_value, | ||
| 125 | .set = ath79_gpio_set_value, | ||
| 126 | .direction_input = ath79_gpio_direction_input, | ||
| 127 | .direction_output = ath79_gpio_direction_output, | ||
| 128 | .base = 0, | ||
| 129 | }; | ||
| 130 | 215 | ||
| 131 | static const struct of_device_id ath79_gpio_of_match[] = { | 216 | static const struct of_device_id ath79_gpio_of_match[] = { |
| 132 | { .compatible = "qca,ar7100-gpio" }, | 217 | { .compatible = "qca,ar7100-gpio" }, |
| @@ -147,6 +232,7 @@ static int ath79_gpio_probe(struct platform_device *pdev) · 14 unmodified lines | |||
| 147 | ctrl = devm_kzalloc(&pdev->dev, sizeof(*ctrl), GFP_KERNEL); | 232 | ctrl = devm_kzalloc(&pdev->dev, sizeof(*ctrl), GFP_KERNEL); |
| 148 | if (!ctrl) | 233 | if (!ctrl) |
| 149 | return -ENOMEM; | 234 | return -ENOMEM; |
| 235 | platform_set_drvdata(pdev, ctrl); | ||
| 150 | 236 | ||
| 151 | if (np) { | 237 | if (np) { |
| 152 | err = of_property_read_u32(np, "ngpios", &ath79_gpio_count); | 238 | err = of_property_read_u32(np, "ngpios", &ath79_gpio_count); |
| @@ -154,10 +240,6 @@ static int ath79_gpio_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 154 | dev_err(&pdev->dev, "ngpios property is not valid\n"); | 240 | dev_err(&pdev->dev, "ngpios property is not valid\n"); |
| 155 | return err; | 241 | return err; |
| 156 | } | 242 | } |
| 157 | if (ath79_gpio_count >= 32) { | ||
| 158 | dev_err(&pdev->dev, "ngpios must be less than 32\n"); | ||
| 159 | return -EINVAL; | ||
| 160 | } | ||
| 161 | oe_inverted = of_device_is_compatible(np, "qca,ar9340-gpio"); | 243 | oe_inverted = of_device_is_compatible(np, "qca,ar9340-gpio"); |
| 162 | } else if (pdata) { | 244 | } else if (pdata) { |
| 163 | ath79_gpio_count = pdata->ngpios; | 245 | ath79_gpio_count = pdata->ngpios; |
| @@ -167,6 +249,11 @@ static int ath79_gpio_probe(struct platform_device *pdev) · 3 unmodified lines | |||
| 167 | return -EINVAL; | 249 | return -EINVAL; |
| 168 | } | 250 | } |
| 169 | 251 | ||
| 252 | if (ath79_gpio_count >= 32) { | ||
| 253 | dev_err(&pdev->dev, "ngpios must be less than 32\n"); | ||
| 254 | return -EINVAL; | ||
| 255 | } | ||
| 256 | |||
| 170 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 257 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 171 | ctrl->base = devm_ioremap_nocache( | 258 | ctrl->base = devm_ioremap_nocache( |
| 172 | &pdev->dev, res->start, resource_size(res)); | 259 | &pdev->dev, res->start, resource_size(res)); |
| @@ -174,21 +261,53 @@ static int ath79_gpio_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 174 | return -ENOMEM; | 261 | return -ENOMEM; |
| 175 | 262 | ||
| 176 | spin_lock_init(&ctrl->lock); | 263 | spin_lock_init(&ctrl->lock); |
| 177 | memcpy(&ctrl->chip, &ath79_gpio_chip, sizeof(ctrl->chip)); | 264 | err = bgpio_init(&ctrl->gc, &pdev->dev, 4, |
| 178 | ctrl->chip.parent = &pdev->dev; | 265 | ctrl->base + AR71XX_GPIO_REG_IN, |
| 179 | ctrl->chip.ngpio = ath79_gpio_count; | 266 | ctrl->base + AR71XX_GPIO_REG_SET, |
| 180 | if (oe_inverted) { | 267 | ctrl->base + AR71XX_GPIO_REG_CLEAR, |
| 181 | ctrl->chip.direction_input = ar934x_gpio_direction_input; | 268 | oe_inverted ? NULL : ctrl->base + AR71XX_GPIO_REG_OE, |
| 182 | ctrl->chip.direction_output = ar934x_gpio_direction_output; | 269 | oe_inverted ? ctrl->base + AR71XX_GPIO_REG_OE : NULL, |
| 270 | 0); | ||
| 271 | if (err) { | ||
| 272 | dev_err(&pdev->dev, "bgpio_init failed\n"); | ||
| 273 | return err; | ||
| 183 | } | 274 | } |
| 275 | /* Use base 0 to stay compatible with legacy platforms */ | ||
| 276 | ctrl->gc.base = 0; | ||
| 184 | 277 | ||
| 185 | err = gpiochip_add_data(&ctrl->chip, ctrl); | 278 | err = gpiochip_add_data(&ctrl->gc, ctrl); |
| 186 | if (err) { | 279 | if (err) { |
| 187 | dev_err(&pdev->dev, | 280 | dev_err(&pdev->dev, |
| 188 | "cannot add AR71xx GPIO chip, error=%d", err); | 281 | "cannot add AR71xx GPIO chip, error=%d", err); |
| 189 | return err; | 282 | return err; |
| 190 | } | 283 | } |
| 191 | 284 | ||
| 285 | if (np && !of_property_read_bool(np, "interrupt-controller")) | ||
| 286 | return 0; | ||
| 287 | |||
| 288 | err = gpiochip_irqchip_add(&ctrl->gc, &ath79_gpio_irqchip, 0, | ||
| 289 | handle_simple_irq, IRQ_TYPE_NONE); | ||
| 290 | if (err) { | ||
| 291 | dev_err(&pdev->dev, "failed to add gpiochip_irqchip\n"); | ||
| 292 | goto gpiochip_remove; | ||
| 293 | } | ||
| 294 | |||
| 295 | gpiochip_set_chained_irqchip(&ctrl->gc, &ath79_gpio_irqchip, | ||
| 296 | platform_get_irq(pdev, 0), | ||
| 297 | ath79_gpio_irq_handler); | ||
| 298 | |||
| 299 | return 0; | ||
| 300 | |||
| 301 | gpiochip_remove: | ||
| 302 | gpiochip_remove(&ctrl->gc); | ||
| 303 | return err; | ||
| 304 | } | ||
| 305 | |||
| 306 | static int ath79_gpio_remove(struct platform_device *pdev) | ||
| 307 | { | ||
| 308 | struct ath79_gpio_ctrl *ctrl = platform_get_drvdata(pdev); | ||
| 309 | |||
| 310 | gpiochip_remove(&ctrl->gc); | ||
| 192 | return 0; | 311 | return 0; |
| 193 | } | 312 | } |
| 194 | 313 | ||
| @@ -198,6 +317,7 @@ static struct platform_driver ath79_gpio_driver = { · 3 unmodified lines | |||
| 198 | .of_match_table = ath79_gpio_of_match, | 317 | .of_match_table = ath79_gpio_of_match, |
| 199 | }, | 318 | }, |
| 200 | .probe = ath79_gpio_probe, | 319 | .probe = ath79_gpio_probe, |
| 320 | .remove = ath79_gpio_remove, | ||
| 201 | }; | 321 | }; |
| 202 | 322 | ||
| 203 | module_platform_driver(ath79_gpio_driver); | 323 | module_platform_driver(ath79_gpio_driver); |
| @@ -630,7 +630,7 @@ static int bcm_kona_gpio_probe(struct platform_device *pdev) · 629 unmodified lines | |||
| 630 | 630 | ||
| 631 | bcm_kona_gpio_reset(kona_gpio); | 631 | bcm_kona_gpio_reset(kona_gpio); |
| 632 | 632 | ||
| 633 | ret = gpiochip_add_data(chip, kona_gpio); | 633 | ret = devm_gpiochip_add_data(dev, chip, kona_gpio); |
| 634 | if (ret < 0) { | 634 | if (ret < 0) { |
| 635 | dev_err(dev, "Couldn't add GPIO chip -- %d\n", ret); | 635 | dev_err(dev, "Couldn't add GPIO chip -- %d\n", ret); |
| 636 | goto err_irq_domain; | 636 | goto err_irq_domain; |
| @@ -233,17 +233,14 @@ static void brcmstb_gpio_irq_handler(struct irq_desc *desc) · 232 unmodified lines | |||
| 233 | struct gpio_chip *gc = irq_desc_get_handler_data(desc); | 233 | struct gpio_chip *gc = irq_desc_get_handler_data(desc); |
| 234 | struct brcmstb_gpio_priv *priv = brcmstb_gpio_gc_to_priv(gc); | 234 | struct brcmstb_gpio_priv *priv = brcmstb_gpio_gc_to_priv(gc); |
| 235 | struct irq_chip *chip = irq_desc_get_chip(desc); | 235 | struct irq_chip *chip = irq_desc_get_chip(desc); |
| 236 | struct list_head *pos; | 236 | struct brcmstb_gpio_bank *bank; |
| 237 | 237 | ||
| 238 | /* Interrupts weren't properly cleared during probe */ | 238 | /* Interrupts weren't properly cleared during probe */ |
| 239 | BUG_ON(!priv || !chip); | 239 | BUG_ON(!priv || !chip); |
| 240 | 240 | ||
| 241 | chained_irq_enter(chip, desc); | 241 | chained_irq_enter(chip, desc); |
| 242 | list_for_each(pos, &priv->bank_list) { | 242 | list_for_each_entry(bank, &priv->bank_list, node) |
| 243 | struct brcmstb_gpio_bank *bank = | ||
| 244 | list_entry(pos, struct brcmstb_gpio_bank, node); | ||
| 245 | brcmstb_gpio_irq_bank_handler(bank); | 243 | brcmstb_gpio_irq_bank_handler(bank); |
| 246 | } | ||
| 247 | chained_irq_exit(chip, desc); | 244 | chained_irq_exit(chip, desc); |
| 248 | } | 245 | } |
| 249 | 246 | ||
| @@ -280,7 +277,6 @@ static int brcmstb_gpio_sanity_check_banks(struct device *dev, · 30 unmodified lines | |||
| 280 | static int brcmstb_gpio_remove(struct platform_device *pdev) | 277 | static int brcmstb_gpio_remove(struct platform_device *pdev) |
| 281 | { | 278 | { |
| 282 | struct brcmstb_gpio_priv *priv = platform_get_drvdata(pdev); | 279 | struct brcmstb_gpio_priv *priv = platform_get_drvdata(pdev); |
| 283 | struct list_head *pos; | ||
| 284 | struct brcmstb_gpio_bank *bank; | 280 | struct brcmstb_gpio_bank *bank; |
| 285 | int ret = 0; | 281 | int ret = 0; |
| 286 | 282 | ||
| @@ -293,10 +289,9 @@ static int brcmstb_gpio_remove(struct platform_device *pdev) · 6 unmodified lines | |||
| 293 | * You can lose return values below, but we report all errors, and it's | 289 | * You can lose return values below, but we report all errors, and it's |
| 294 | * more important to actually perform all of the steps. | 290 | * more important to actually perform all of the steps. |
| 295 | */ | 291 | */ |
| 296 | list_for_each(pos, &priv->bank_list) { | 292 | list_for_each_entry(bank, &priv->bank_list, node) |
| 297 | bank = list_entry(pos, struct brcmstb_gpio_bank, node); | ||
| 298 | gpiochip_remove(&bank->gc); | 293 | gpiochip_remove(&bank->gc); |
| 299 | } | 294 | |
| 300 | if (priv->reboot_notifier.notifier_call) { | 295 | if (priv->reboot_notifier.notifier_call) { |
| 301 | ret = unregister_reboot_notifier(&priv->reboot_notifier); | 296 | ret = unregister_reboot_notifier(&priv->reboot_notifier); |
| 302 | if (ret) | 297 | if (ret) |
| @@ -67,15 +67,7 @@ static int clps711x_gpio_probe(struct platform_device *pdev) · 66 unmodified lines | |||
| 67 | gc->owner = THIS_MODULE; | 67 | gc->owner = THIS_MODULE; |
| 68 | platform_set_drvdata(pdev, gc); | 68 | platform_set_drvdata(pdev, gc); |
| 69 | 69 | ||
| 70 | return gpiochip_add_data(gc, NULL); | 70 | return devm_gpiochip_add_data(&pdev->dev, gc, NULL); |
| 71 | } | ||
| 72 | |||
| 73 | static int clps711x_gpio_remove(struct platform_device *pdev) | ||
| 74 | { | ||
| 75 | struct gpio_chip *gc = platform_get_drvdata(pdev); | ||
| 76 | |||
| 77 | gpiochip_remove(gc); | ||
| 78 | return 0; | ||
| 79 | } | 71 | } |
| 80 | 72 | ||
| 81 | static const struct of_device_id __maybe_unused clps711x_gpio_ids[] = { | 73 | static const struct of_device_id __maybe_unused clps711x_gpio_ids[] = { |
| @@ -90,7 +82,6 @@ static struct platform_driver clps711x_gpio_driver = { · 8 unmodified lines | |||
| 90 | .of_match_table = of_match_ptr(clps711x_gpio_ids), | 82 | .of_match_table = of_match_ptr(clps711x_gpio_ids), |
| 91 | }, | 83 | }, |
| 92 | .probe = clps711x_gpio_probe, | 84 | .probe = clps711x_gpio_probe, |
| 93 | .remove = clps711x_gpio_remove, | ||
| 94 | }; | 85 | }; |
| 95 | module_platform_driver(clps711x_gpio_driver); | 86 | module_platform_driver(clps711x_gpio_driver); |
| 96 | 87 | ||
| @@ -345,7 +345,7 @@ static int crystalcove_gpio_probe(struct platform_device *pdev) · 344 unmodified lines | |||
| 345 | cg->chip.dbg_show = crystalcove_gpio_dbg_show; | 345 | cg->chip.dbg_show = crystalcove_gpio_dbg_show; |
| 346 | cg->regmap = pmic->regmap; | 346 | cg->regmap = pmic->regmap; |
| 347 | 347 | ||
| 348 | retval = gpiochip_add_data(&cg->chip, cg); | 348 | retval = devm_gpiochip_add_data(&pdev->dev, &cg->chip, cg); |
| 349 | if (retval) { | 349 | if (retval) { |
| 350 | dev_warn(&pdev->dev, "add gpio chip error: %d\n", retval); | 350 | dev_warn(&pdev->dev, "add gpio chip error: %d\n", retval); |
| 351 | return retval; | 351 | return retval; |
| @@ -359,14 +359,10 @@ static int crystalcove_gpio_probe(struct platform_device *pdev) · 7 unmodified lines | |||
| 359 | 359 | ||
| 360 | if (retval) { | 360 | if (retval) { |
| 361 | dev_warn(&pdev->dev, "request irq failed: %d\n", retval); | 361 | dev_warn(&pdev->dev, "request irq failed: %d\n", retval); |
| 362 | goto out_remove_gpio; | 362 | return retval; |
| 363 | } | 363 | } |
| 364 | 364 | ||
| 365 | return 0; | 365 | return 0; |
| 366 | |||
| 367 | out_remove_gpio: | ||
| 368 | gpiochip_remove(&cg->chip); | ||
| 369 | return retval; | ||
| 370 | } | 366 | } |
| 371 | 367 | ||
| 372 | static int crystalcove_gpio_remove(struct platform_device *pdev) | 368 | static int crystalcove_gpio_remove(struct platform_device *pdev) |
| @@ -374,7 +370,6 @@ static int crystalcove_gpio_remove(struct platform_device *pdev) · 1 unmodified line | |||
| 374 | struct crystalcove_gpio *cg = platform_get_drvdata(pdev); | 370 | struct crystalcove_gpio *cg = platform_get_drvdata(pdev); |
| 375 | int irq = platform_get_irq(pdev, 0); | 371 | int irq = platform_get_irq(pdev, 0); |
| 376 | 372 | ||
| 377 | gpiochip_remove(&cg->chip); | ||
| 378 | if (irq >= 0) | 373 | if (irq >= 0) |
| 379 | free_irq(irq, cg); | 374 | free_irq(irq, cg); |
| 380 | return 0; | 375 | return 0; |
| @@ -320,13 +320,13 @@ static int cs5535_gpio_probe(struct platform_device *pdev) · 319 unmodified lines | |||
| 320 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 320 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| 321 | if (!res) { | 321 | if (!res) { |
| 322 | dev_err(&pdev->dev, "can't fetch device resource info\n"); | 322 | dev_err(&pdev->dev, "can't fetch device resource info\n"); |
| 323 | goto done; | 323 | return err; |
| 324 | } | 324 | } |
| 325 | 325 | ||
| 326 | if (!devm_request_region(&pdev->dev, res->start, resource_size(res), | 326 | if (!devm_request_region(&pdev->dev, res->start, resource_size(res), |
| 327 | pdev->name)) { | 327 | pdev->name)) { |
| 328 | dev_err(&pdev->dev, "can't request region\n"); | 328 | dev_err(&pdev->dev, "can't request region\n"); |
| 329 | goto done; | 329 | return err; |
| 330 | } | 330 | } |
| 331 | 331 | ||
| 332 | /* set up the driver-specific struct */ | 332 | /* set up the driver-specific struct */ |
| @@ -348,19 +348,10 @@ static int cs5535_gpio_probe(struct platform_device *pdev) · 15 unmodified lines | |||
| 348 | mask_orig, mask); | 348 | mask_orig, mask); |
| 349 | 349 | ||
| 350 | /* finally, register with the generic GPIO API */ | 350 | /* finally, register with the generic GPIO API */ |
| 351 | err = gpiochip_add_data(&cs5535_gpio_chip.chip, &cs5535_gpio_chip); | 351 | err = devm_gpiochip_add_data(&pdev->dev, &cs5535_gpio_chip.chip, |
| 352 | &cs5535_gpio_chip); | ||
| 352 | if (err) | 353 | if (err) |
| 353 | goto done; | 354 | return err; |
| 354 | |||
| 355 | return 0; | ||
| 356 | |||
| 357 | done: | ||
| 358 | return err; | ||
| 359 | } | ||
| 360 | |||
| 361 | static int cs5535_gpio_remove(struct platform_device *pdev) | ||
| 362 | { | ||
| 363 | gpiochip_remove(&cs5535_gpio_chip.chip); | ||
| 364 | 355 | ||
| 365 | return 0; | 356 | return 0; |
| 366 | } | 357 | } |
| @@ -370,7 +361,6 @@ static struct platform_driver cs5535_gpio_driver = { · 3 unmodified lines | |||
| 370 | .name = DRV_NAME, | 361 | .name = DRV_NAME, |
| 371 | }, | 362 | }, |
| 372 | .probe = cs5535_gpio_probe, | 363 | .probe = cs5535_gpio_probe, |
| 373 | .remove = cs5535_gpio_remove, | ||
| 374 | }; | 364 | }; |
| 375 | 365 | ||
| 376 | module_platform_driver(cs5535_gpio_driver); | 366 | module_platform_driver(cs5535_gpio_driver); |
| @@ -214,7 +214,7 @@ static int da9052_gpio_probe(struct platform_device *pdev) · 213 unmodified lines | |||
| 214 | if (pdata && pdata->gpio_base) | 214 | if (pdata && pdata->gpio_base) |
| 215 | gpio->gp.base = pdata->gpio_base; | 215 | gpio->gp.base = pdata->gpio_base; |
| 216 | 216 | ||
| 217 | ret = gpiochip_add_data(&gpio->gp, gpio); | 217 | ret = devm_gpiochip_add_data(&pdev->dev, &gpio->gp, gpio); |
| 218 | if (ret < 0) { | 218 | if (ret < 0) { |
| 219 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); | 219 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); |
| 220 | return ret; | 220 | return ret; |
| @@ -225,17 +225,8 @@ static int da9052_gpio_probe(struct platform_device *pdev) · 4 unmodified lines | |||
| 225 | return 0; | 225 | return 0; |
| 226 | } | 226 | } |
| 227 | 227 | ||
| 228 | static int da9052_gpio_remove(struct platform_device *pdev) | ||
| 229 | { | ||
| 230 | struct da9052_gpio *gpio = platform_get_drvdata(pdev); | ||
| 231 | |||
| 232 | gpiochip_remove(&gpio->gp); | ||
| 233 | return 0; | ||
| 234 | } | ||
| 235 | |||
| 236 | static struct platform_driver da9052_gpio_driver = { | 228 | static struct platform_driver da9052_gpio_driver = { |
| 237 | .probe = da9052_gpio_probe, | 229 | .probe = da9052_gpio_probe, |
| 238 | .remove = da9052_gpio_remove, | ||
| 239 | .driver = { | 230 | .driver = { |
| 240 | .name = "da9052-gpio", | 231 | .name = "da9052-gpio", |
| 241 | }, | 232 | }, |
| @@ -151,31 +151,19 @@ static int da9055_gpio_probe(struct platform_device *pdev) · 150 unmodified lines | |||
| 151 | if (pdata && pdata->gpio_base) | 151 | if (pdata && pdata->gpio_base) |
| 152 | gpio->gp.base = pdata->gpio_base; | 152 | gpio->gp.base = pdata->gpio_base; |
| 153 | 153 | ||
| 154 | ret = gpiochip_add_data(&gpio->gp, gpio); | 154 | ret = devm_gpiochip_add_data(&pdev->dev, &gpio->gp, gpio); |
| 155 | if (ret < 0) { | 155 | if (ret < 0) { |
| 156 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); | 156 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); |
| 157 | goto err_mem; | 157 | return ret; |
| 158 | } | 158 | } |
| 159 | 159 | ||
| 160 | platform_set_drvdata(pdev, gpio); | 160 | platform_set_drvdata(pdev, gpio); |
| 161 | 161 | ||
| 162 | return 0; | 162 | return 0; |
| 163 | |||
| 164 | err_mem: | ||
| 165 | return ret; | ||
| 166 | } | ||
| 167 | |||
| 168 | static int da9055_gpio_remove(struct platform_device *pdev) | ||
| 169 | { | ||
| 170 | struct da9055_gpio *gpio = platform_get_drvdata(pdev); | ||
| 171 | |||
| 172 | gpiochip_remove(&gpio->gp); | ||
| 173 | return 0; | ||
| 174 | } | 163 | } |
| 175 | 164 | ||
| 176 | static struct platform_driver da9055_gpio_driver = { | 165 | static struct platform_driver da9055_gpio_driver = { |
| 177 | .probe = da9055_gpio_probe, | 166 | .probe = da9055_gpio_probe, |
| 178 | .remove = da9055_gpio_remove, | ||
| 179 | .driver = { | 167 | .driver = { |
| 180 | .name = "da9055-gpio", | 168 | .name = "da9055-gpio", |
| 181 | }, | 169 | }, |
| @@ -258,6 +258,8 @@ static int davinci_gpio_probe(struct platform_device *pdev) · 257 unmodified lines | |||
| 258 | spin_lock_init(&chips[i].lock); | 258 | spin_lock_init(&chips[i].lock); |
| 259 | 259 | ||
| 260 | regs = gpio2regs(base); | 260 | regs = gpio2regs(base); |
| 261 | if (!regs) | ||
| 262 | return -ENXIO; | ||
| 261 | chips[i].regs = regs; | 263 | chips[i].regs = regs; |
| 262 | chips[i].set_data = ®s->set_data; | 264 | chips[i].set_data = ®s->set_data; |
| 263 | chips[i].clr_data = ®s->clr_data; | 265 | chips[i].clr_data = ®s->clr_data; |
| @@ -433,8 +435,7 @@ static struct irq_chip *davinci_gpio_get_irq_chip(unsigned int irq) · 169 unmodified lines | |||
| 433 | { | 435 | { |
| 434 | static struct irq_chip_type gpio_unbanked; | 436 | static struct irq_chip_type gpio_unbanked; |
| 435 | 437 | ||
| 436 | gpio_unbanked = *container_of(irq_get_chip(irq), | 438 | gpio_unbanked = *irq_data_get_chip_type(irq_get_irq_data(irq)); |
| 437 | struct irq_chip_type, chip); | ||
| 438 | 439 | ||
| 439 | return &gpio_unbanked.chip; | 440 | return &gpio_unbanked.chip; |
| 440 | }; | 441 | }; |
| @@ -479,40 +479,32 @@ static int dln2_gpio_probe(struct platform_device *pdev) · 478 unmodified lines | |||
| 479 | 479 | ||
| 480 | platform_set_drvdata(pdev, dln2); | 480 | platform_set_drvdata(pdev, dln2); |
| 481 | 481 | ||
| 482 | ret = gpiochip_add_data(&dln2->gpio, dln2); | 482 | ret = devm_gpiochip_add_data(dev, &dln2->gpio, dln2); |
| 483 | if (ret < 0) { | 483 | if (ret < 0) { |
| 484 | dev_err(dev, "failed to add gpio chip: %d\n", ret); | 484 | dev_err(dev, "failed to add gpio chip: %d\n", ret); |
| 485 | goto out; | 485 | return ret; |
| 486 | } | 486 | } |
| 487 | 487 | ||
| 488 | ret = gpiochip_irqchip_add(&dln2->gpio, &dln2_gpio_irqchip, 0, | 488 | ret = gpiochip_irqchip_add(&dln2->gpio, &dln2_gpio_irqchip, 0, |
| 489 | handle_simple_irq, IRQ_TYPE_NONE); | 489 | handle_simple_irq, IRQ_TYPE_NONE); |
| 490 | if (ret < 0) { | 490 | if (ret < 0) { |
| 491 | dev_err(dev, "failed to add irq chip: %d\n", ret); | 491 | dev_err(dev, "failed to add irq chip: %d\n", ret); |
| 492 | goto out_gpiochip_remove; | 492 | return ret; |
| 493 | } | 493 | } |
| 494 | 494 | ||
| 495 | ret = dln2_register_event_cb(pdev, DLN2_GPIO_CONDITION_MET_EV, | 495 | ret = dln2_register_event_cb(pdev, DLN2_GPIO_CONDITION_MET_EV, |
| 496 | dln2_gpio_event); | 496 | dln2_gpio_event); |
| 497 | if (ret) { | 497 | if (ret) { |
| 498 | dev_err(dev, "failed to register event cb: %d\n", ret); | 498 | dev_err(dev, "failed to register event cb: %d\n", ret); |
| 499 | goto out_gpiochip_remove; | 499 | return ret; |
| 500 | } | 500 | } |
| 501 | 501 | ||
| 502 | return 0; | 502 | return 0; |
| 503 | |||
| 504 | out_gpiochip_remove: | ||
| 505 | gpiochip_remove(&dln2->gpio); | ||
| 506 | out: | ||
| 507 | return ret; | ||
| 508 | } | 503 | } |
| 509 | 504 | ||
| 510 | static int dln2_gpio_remove(struct platform_device *pdev) | 505 | static int dln2_gpio_remove(struct platform_device *pdev) |
| 511 | { | 506 | { |
| 512 | struct dln2_gpio *dln2 = platform_get_drvdata(pdev); | ||
| 513 | |||
| 514 | dln2_unregister_event_cb(pdev, DLN2_GPIO_CONDITION_MET_EV); | 507 | dln2_unregister_event_cb(pdev, DLN2_GPIO_CONDITION_MET_EV); |
| 515 | gpiochip_remove(&dln2->gpio); | ||
| 516 | 508 | ||
| 517 | return 0; | 509 | return 0; |
| 518 | } | 510 | } |
| @@ -339,7 +339,7 @@ static int ep93xx_gpio_add_bank(struct gpio_chip *gc, struct device *dev, · 338 unmodified lines | |||
| 339 | gc->to_irq = ep93xx_gpio_to_irq; | 339 | gc->to_irq = ep93xx_gpio_to_irq; |
| 340 | } | 340 | } |
| 341 | 341 | ||
| 342 | return gpiochip_add_data(gc, NULL); | 342 | return devm_gpiochip_add_data(dev, gc, NULL); |
| 343 | } | 343 | } |
| 344 | 344 | ||
| 345 | static int ep93xx_gpio_probe(struct platform_device *pdev) | 345 | static int ep93xx_gpio_probe(struct platform_device *pdev) |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * GPIO driver for Fintek Super-I/O F71869, F71869A, F71882 and F71889 | 2 | * GPIO driver for Fintek Super-I/O F71869, F71869A, F71882, F71889 and F81866 |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2010-2013 LaCie | 4 | * Copyright (C) 2010-2013 LaCie |
| 5 | * | 5 | * |
| @@ -36,14 +36,16 @@ · 30 unmodified lines | |||
| 36 | #define SIO_F71869A_ID 0x1007 /* F71869A chipset ID */ | 36 | #define SIO_F71869A_ID 0x1007 /* F71869A chipset ID */ |
| 37 | #define SIO_F71882_ID 0x0541 /* F71882 chipset ID */ | 37 | #define SIO_F71882_ID 0x0541 /* F71882 chipset ID */ |
| 38 | #define SIO_F71889_ID 0x0909 /* F71889 chipset ID */ | 38 | #define SIO_F71889_ID 0x0909 /* F71889 chipset ID */ |
| 39 | #define SIO_F81866_ID 0x1010 /* F81866 chipset ID */ | ||
| 39 | 40 | ||
| 40 | enum chips { f71869, f71869a, f71882fg, f71889f }; | 41 | enum chips { f71869, f71869a, f71882fg, f71889f, f81866 }; |
| 41 | 42 | ||
| 42 | static const char * const f7188x_names[] = { | 43 | static const char * const f7188x_names[] = { |
| 43 | "f71869", | 44 | "f71869", |
| 44 | "f71869a", | 45 | "f71869a", |
| 45 | "f71882fg", | 46 | "f71882fg", |
| 46 | "f71889f", | 47 | "f71889f", |
| 48 | "f81866", | ||
| 47 | }; | 49 | }; |
| 48 | 50 | ||
| 49 | struct f7188x_sio { | 51 | struct f7188x_sio { |
| @@ -190,6 +192,18 @@ static struct f7188x_gpio_bank f71889_gpio_bank[] = { · 140 unmodified lines | |||
| 190 | F7188X_GPIO_BANK(70, 8, 0x80), | 192 | F7188X_GPIO_BANK(70, 8, 0x80), |
| 191 | }; | 193 | }; |
| 192 | 194 | ||
| 195 | static struct f7188x_gpio_bank f81866_gpio_bank[] = { | ||
| 196 | F7188X_GPIO_BANK(0, 8, 0xF0), | ||
| 197 | F7188X_GPIO_BANK(10, 8, 0xE0), | ||
| 198 | F7188X_GPIO_BANK(20, 8, 0xD0), | ||
| 199 | F7188X_GPIO_BANK(30, 8, 0xC0), | ||
| 200 | F7188X_GPIO_BANK(40, 8, 0xB0), | ||
| 201 | F7188X_GPIO_BANK(50, 8, 0xA0), | ||
| 202 | F7188X_GPIO_BANK(60, 8, 0x90), | ||
| 203 | F7188X_GPIO_BANK(70, 8, 0x80), | ||
| 204 | F7188X_GPIO_BANK(80, 8, 0x88), | ||
| 205 | }; | ||
| 206 | |||
| 193 | static int f7188x_gpio_direction_in(struct gpio_chip *chip, unsigned offset) | 207 | static int f7188x_gpio_direction_in(struct gpio_chip *chip, unsigned offset) |
| 194 | { | 208 | { |
| 195 | int err; | 209 | int err; |
| @@ -318,6 +332,10 @@ static int f7188x_gpio_probe(struct platform_device *pdev) · 122 unmodified lines | |||
| 318 | data->nr_bank = ARRAY_SIZE(f71889_gpio_bank); | 332 | data->nr_bank = ARRAY_SIZE(f71889_gpio_bank); |
| 319 | data->bank = f71889_gpio_bank; | 333 | data->bank = f71889_gpio_bank; |
| 320 | break; | 334 | break; |
| 335 | case f81866: | ||
| 336 | data->nr_bank = ARRAY_SIZE(f81866_gpio_bank); | ||
| 337 | data->bank = f81866_gpio_bank; | ||
| 338 | break; | ||
| 321 | default: | 339 | default: |
| 322 | return -ENODEV; | 340 | return -ENODEV; |
| 323 | } | 341 | } |
| @@ -332,36 +350,15 @@ static int f7188x_gpio_probe(struct platform_device *pdev) · 8 unmodified lines | |||
| 332 | bank->chip.parent = &pdev->dev; | 350 | bank->chip.parent = &pdev->dev; |
| 333 | bank->data = data; | 351 | bank->data = data; |
| 334 | 352 | ||
| 335 | err = gpiochip_add_data(&bank->chip, bank); | 353 | err = devm_gpiochip_add_data(&pdev->dev, &bank->chip, bank); |
| 336 | if (err) { | 354 | if (err) { |
| 337 | dev_err(&pdev->dev, | 355 | dev_err(&pdev->dev, |
| 338 | "Failed to register gpiochip %d: %d\n", | 356 | "Failed to register gpiochip %d: %d\n", |
| 339 | i, err); | 357 | i, err); |
| 340 | goto err_gpiochip; | 358 | return err; |
| 341 | } | 359 | } |
| 342 | } | 360 | } |
| 343 | 361 | ||
| 344 | return 0; | ||
| 345 | |||
| 346 | err_gpiochip: | ||
| 347 | for (i = i - 1; i >= 0; i--) { | ||
| 348 | struct f7188x_gpio_bank *bank = &data->bank[i]; | ||
| 349 | gpiochip_remove(&bank->chip); | ||
| 350 | } | ||
| 351 | |||
| 352 | return err; | ||
| 353 | } | ||
| 354 | |||
| 355 | static int f7188x_gpio_remove(struct platform_device *pdev) | ||
| 356 | { | ||
| 357 | int i; | ||
| 358 | struct f7188x_gpio_data *data = platform_get_drvdata(pdev); | ||
| 359 | |||
| 360 | for (i = 0; i < data->nr_bank; i++) { | ||
| 361 | struct f7188x_gpio_bank *bank = &data->bank[i]; | ||
| 362 | gpiochip_remove(&bank->chip); | ||
| 363 | } | ||
| 364 | |||
| 365 | return 0; | 362 | return 0; |
| 366 | } | 363 | } |
| 367 | 364 | ||
| @@ -395,6 +392,9 @@ static int __init f7188x_find(int addr, struct f7188x_sio *sio) · 27 unmodified lines | |||
| 395 | case SIO_F71889_ID: | 392 | case SIO_F71889_ID: |
| 396 | sio->type = f71889f; | 393 | sio->type = f71889f; |
| 397 | break; | 394 | break; |
| 395 | case SIO_F81866_ID: | ||
| 396 | sio->type = f81866; | ||
| 397 | break; | ||
| 398 | default: | 398 | default: |
| 399 | pr_info(DRVNAME ": Unsupported Fintek device 0x%04x\n", devid); | 399 | pr_info(DRVNAME ": Unsupported Fintek device 0x%04x\n", devid); |
| 400 | goto err; | 400 | goto err; |
| @@ -455,7 +455,6 @@ static struct platform_driver f7188x_gpio_driver = { · 54 unmodified lines | |||
| 455 | .name = DRVNAME, | 455 | .name = DRVNAME, |
| 456 | }, | 456 | }, |
| 457 | .probe = f7188x_gpio_probe, | 457 | .probe = f7188x_gpio_probe, |
| 458 | .remove = f7188x_gpio_remove, | ||
| 459 | }; | 458 | }; |
| 460 | 459 | ||
| 461 | static int __init f7188x_gpio_init(void) | 460 | static int __init f7188x_gpio_init(void) |
| @@ -485,6 +484,6 @@ static void __exit f7188x_gpio_exit(void) · 23 unmodified lines | |||
| 485 | } | 484 | } |
| 486 | module_exit(f7188x_gpio_exit); | 485 | module_exit(f7188x_gpio_exit); |
| 487 | 486 | ||
| 488 | MODULE_DESCRIPTION("GPIO driver for Super-I/O chips F71869, F71869A, F71882FG and F71889F"); | 487 | MODULE_DESCRIPTION("GPIO driver for Super-I/O chips F71869, F71869A, F71882FG, F71889F and F81866"); |
| 489 | MODULE_AUTHOR("Simon Guinot <simon.guinot@sequanux.org>"); | 488 | MODULE_AUTHOR("Simon Guinot <simon.guinot@sequanux.org>"); |
| 490 | MODULE_LICENSE("GPL"); | 489 | MODULE_LICENSE("GPL"); |
| @@ -89,7 +89,7 @@ static int __init gef_gpio_probe(struct platform_device *pdev) · 88 unmodified lines | |||
| 89 | gc->of_node = pdev->dev.of_node; | 89 | gc->of_node = pdev->dev.of_node; |
| 90 | 90 | ||
| 91 | /* This function adds a memory mapped GPIO chip */ | 91 | /* This function adds a memory mapped GPIO chip */ |
| 92 | ret = gpiochip_add_data(gc, NULL); | 92 | ret = devm_gpiochip_add_data(&pdev->dev, gc, NULL); |
| 93 | if (ret) | 93 | if (ret) |
| 94 | goto err0; | 94 | goto err0; |
| 95 | 95 | ||
| @@ -628,15 +628,7 @@ static int bgpio_pdev_probe(struct platform_device *pdev) · 627 unmodified lines | |||
| 628 | 628 | ||
| 629 | platform_set_drvdata(pdev, gc); | 629 | platform_set_drvdata(pdev, gc); |
| 630 | 630 | ||
| 631 | return gpiochip_add_data(gc, NULL); | 631 | return devm_gpiochip_add_data(&pdev->dev, gc, NULL); |
| 632 | } | ||
| 633 | |||
| 634 | static int bgpio_pdev_remove(struct platform_device *pdev) | ||
| 635 | { | ||
| 636 | struct gpio_chip *gc = platform_get_drvdata(pdev); | ||
| 637 | |||
| 638 | gpiochip_remove(gc); | ||
| 639 | return 0; | ||
| 640 | } | 632 | } |
| 641 | 633 | ||
| 642 | static const struct platform_device_id bgpio_id_table[] = { | 634 | static const struct platform_device_id bgpio_id_table[] = { |
| @@ -657,7 +649,6 @@ static struct platform_driver bgpio_driver = { · 14 unmodified lines | |||
| 657 | }, | 649 | }, |
| 658 | .id_table = bgpio_id_table, | 650 | .id_table = bgpio_id_table, |
| 659 | .probe = bgpio_pdev_probe, | 651 | .probe = bgpio_pdev_probe, |
| 660 | .remove = bgpio_pdev_remove, | ||
| 661 | }; | 652 | }; |
| 662 | 653 | ||
| 663 | module_platform_driver(bgpio_driver); | 654 | module_platform_driver(bgpio_driver); |
| @@ -20,6 +20,7 @@ · 19 unmodified lines | |||
| 20 | 20 | ||
| 21 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 21 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
| 22 | 22 | ||
| 23 | #include <linux/ioport.h> | ||
| 23 | #include <linux/module.h> | 24 | #include <linux/module.h> |
| 24 | #include <linux/pci.h> | 25 | #include <linux/pci.h> |
| 25 | #include <linux/gpio.h> | 26 | #include <linux/gpio.h> |
| @@ -384,8 +385,8 @@ static struct ichx_desc avoton_desc = { · 358 unmodified lines | |||
| 384 | .use_outlvl_cache = true, | 385 | .use_outlvl_cache = true, |
| 385 | }; | 386 | }; |
| 386 | 387 | ||
| 387 | static int ichx_gpio_request_regions(struct resource *res_base, | 388 | static int ichx_gpio_request_regions(struct device *dev, |
| 388 | const char *name, u8 use_gpio) | 389 | struct resource *res_base, const char *name, u8 use_gpio) |
| 389 | { | 390 | { |
| 390 | int i; | 391 | int i; |
| 391 | 392 | ||
| @@ -395,34 +396,12 @@ static int ichx_gpio_request_regions(struct resource *res_base, · 3 unmodified lines | |||
| 395 | for (i = 0; i < ARRAY_SIZE(ichx_priv.desc->regs[0]); i++) { | 396 | for (i = 0; i < ARRAY_SIZE(ichx_priv.desc->regs[0]); i++) { |
| 396 | if (!(use_gpio & (1 << i))) | 397 | if (!(use_gpio & (1 << i))) |
| 397 | continue; | 398 | continue; |
| 398 | if (!request_region( | 399 | if (!devm_request_region(dev, |
| 399 | res_base->start + ichx_priv.desc->regs[0][i], | 400 | res_base->start + ichx_priv.desc->regs[0][i], |
| 400 | ichx_priv.desc->reglen[i], name)) | 401 | ichx_priv.desc->reglen[i], name)) |
| 401 | goto request_err; | 402 | return -EBUSY; |
| 402 | } | 403 | } |
| 403 | return 0; | 404 | return 0; |
| 404 | |||
| 405 | request_err: | ||
| 406 | /* Clean up: release already requested regions, if any */ | ||
| 407 | for (i--; i >= 0; i--) { | ||
| 408 | if (!(use_gpio & (1 << i))) | ||
| 409 | continue; | ||
| 410 | release_region(res_base->start + ichx_priv.desc->regs[0][i], | ||
| 411 | ichx_priv.desc->reglen[i]); | ||
| 412 | } | ||
| 413 | return -EBUSY; | ||
| 414 | } | ||
| 415 | |||
| 416 | static void ichx_gpio_release_regions(struct resource *res_base, u8 use_gpio) | ||
| 417 | { | ||
| 418 | int i; | ||
| 419 | |||
| 420 | for (i = 0; i < ARRAY_SIZE(ichx_priv.desc->regs[0]); i++) { | ||
| 421 | if (!(use_gpio & (1 << i))) | ||
| 422 | continue; | ||
| 423 | release_region(res_base->start + ichx_priv.desc->regs[0][i], | ||
| 424 | ichx_priv.desc->reglen[i]); | ||
| 425 | } | ||
| 426 | } | 405 | } |
| 427 | 406 | ||
| 428 | static int ichx_gpio_probe(struct platform_device *pdev) | 407 | static int ichx_gpio_probe(struct platform_device *pdev) |
| @@ -468,7 +447,7 @@ static int ichx_gpio_probe(struct platform_device *pdev) · 39 unmodified lines | |||
| 468 | spin_lock_init(&ichx_priv.lock); | 447 | spin_lock_init(&ichx_priv.lock); |
| 469 | res_base = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPIO); | 448 | res_base = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPIO); |
| 470 | ichx_priv.use_gpio = ich_info->use_gpio; | 449 | ichx_priv.use_gpio = ich_info->use_gpio; |
| 471 | err = ichx_gpio_request_regions(res_base, pdev->name, | 450 | err = ichx_gpio_request_regions(&pdev->dev, res_base, pdev->name, |
| 472 | ichx_priv.use_gpio); | 451 | ichx_priv.use_gpio); |
| 473 | if (err) | 452 | if (err) |
| 474 | return err; | 453 | return err; |
| @@ -489,8 +468,8 @@ static int ichx_gpio_probe(struct platform_device *pdev) · 14 unmodified lines | |||
| 489 | goto init; | 468 | goto init; |
| 490 | } | 469 | } |
| 491 | 470 | ||
| 492 | if (!request_region(res_pm->start, resource_size(res_pm), | 471 | if (!devm_request_region(&pdev->dev, res_pm->start, |
| 493 | pdev->name)) { | 472 | resource_size(res_pm), pdev->name)) { |
| 494 | pr_warn("ACPI BAR is busy, GPI 0 - 15 unavailable\n"); | 473 | pr_warn("ACPI BAR is busy, GPI 0 - 15 unavailable\n"); |
| 495 | goto init; | 474 | goto init; |
| 496 | } | 475 | } |
| @@ -502,31 +481,19 @@ init: · 5 unmodified lines | |||
| 502 | err = gpiochip_add_data(&ichx_priv.chip, NULL); | 481 | err = gpiochip_add_data(&ichx_priv.chip, NULL); |
| 503 | if (err) { | 482 | if (err) { |
| 504 | pr_err("Failed to register GPIOs\n"); | 483 | pr_err("Failed to register GPIOs\n"); |
| 505 | goto add_err; | 484 | return err; |
| 506 | } | 485 | } |
| 507 | 486 | ||
| 508 | pr_info("GPIO from %d to %d on %s\n", ichx_priv.chip.base, | 487 | pr_info("GPIO from %d to %d on %s\n", ichx_priv.chip.base, |
| 509 | ichx_priv.chip.base + ichx_priv.chip.ngpio - 1, DRV_NAME); | 488 | ichx_priv.chip.base + ichx_priv.chip.ngpio - 1, DRV_NAME); |
| 510 | 489 | ||
| 511 | return 0; | 490 | return 0; |
| 512 | |||
| 513 | add_err: | ||
| 514 | ichx_gpio_release_regions(ichx_priv.gpio_base, ichx_priv.use_gpio); | ||
| 515 | if (ichx_priv.pm_base) | ||
| 516 | release_region(ichx_priv.pm_base->start, | ||
| 517 | resource_size(ichx_priv.pm_base)); | ||
| 518 | return err; | ||
| 519 | } | 491 | } |
| 520 | 492 | ||
| 521 | static int ichx_gpio_remove(struct platform_device *pdev) | 493 | static int ichx_gpio_remove(struct platform_device *pdev) |
| 522 | { | 494 | { |
| 523 | gpiochip_remove(&ichx_priv.chip); | 495 | gpiochip_remove(&ichx_priv.chip); |
| 524 | 496 | ||
| 525 | ichx_gpio_release_regions(ichx_priv.gpio_base, ichx_priv.use_gpio); | ||
| 526 | if (ichx_priv.pm_base) | ||
| 527 | release_region(ichx_priv.pm_base->start, | ||
| 528 | resource_size(ichx_priv.pm_base)); | ||
| 529 | |||
| 530 | return 0; | 497 | return 0; |
| 531 | } | 498 | } |
| 532 | 499 | ||
| @@ -114,7 +114,7 @@ static int iop3xx_gpio_probe(struct platform_device *pdev) · 113 unmodified lines | |||
| 114 | if (IS_ERR(base)) | 114 | if (IS_ERR(base)) |
| 115 | return PTR_ERR(base); | 115 | return PTR_ERR(base); |
| 116 | 116 | ||
| 117 | return gpiochip_add_data(&iop3xx_chip, NULL); | 117 | return devm_gpiochip_add_data(&pdev->dev, &iop3xx_chip, NULL); |
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | static struct platform_driver iop3xx_gpio_driver = { | 120 | static struct platform_driver iop3xx_gpio_driver = { |
| @@ -182,7 +182,7 @@ static int ttl_probe(struct platform_device *pdev) · 181 unmodified lines | |||
| 182 | gpio->base = -1; | 182 | gpio->base = -1; |
| 183 | gpio->ngpio = 20; | 183 | gpio->ngpio = 20; |
| 184 | 184 | ||
| 185 | ret = gpiochip_add_data(gpio, NULL); | 185 | ret = devm_gpiochip_add_data(dev, gpio, NULL); |
| 186 | if (ret) { | 186 | if (ret) { |
| 187 | dev_err(dev, "unable to add GPIO chip\n"); | 187 | dev_err(dev, "unable to add GPIO chip\n"); |
| 188 | return ret; | 188 | return ret; |
| @@ -191,21 +191,11 @@ static int ttl_probe(struct platform_device *pdev) · 2 unmodified lines | |||
| 191 | return 0; | 191 | return 0; |
| 192 | } | 192 | } |
| 193 | 193 | ||
| 194 | static int ttl_remove(struct platform_device *pdev) | ||
| 195 | { | ||
| 196 | struct ttl_module *mod = platform_get_drvdata(pdev); | ||
| 197 | |||
| 198 | gpiochip_remove(&mod->gpio); | ||
| 199 | |||
| 200 | return 0; | ||
| 201 | } | ||
| 202 | |||
| 203 | static struct platform_driver ttl_driver = { | 194 | static struct platform_driver ttl_driver = { |
| 204 | .driver = { | 195 | .driver = { |
| 205 | .name = DRV_NAME, | 196 | .name = DRV_NAME, |
| 206 | }, | 197 | }, |
| 207 | .probe = ttl_probe, | 198 | .probe = ttl_probe, |
| 208 | .remove = ttl_remove, | ||
| 209 | }; | 199 | }; |
| 210 | 200 | ||
| 211 | module_platform_driver(ttl_driver); | 201 | module_platform_driver(ttl_driver); |
| @@ -178,7 +178,7 @@ static int kempld_gpio_probe(struct platform_device *pdev) · 177 unmodified lines | |||
| 178 | return -ENODEV; | 178 | return -ENODEV; |
| 179 | } | 179 | } |
| 180 | 180 | ||
| 181 | ret = gpiochip_add_data(chip, gpio); | 181 | ret = devm_gpiochip_add_data(dev, chip, gpio); |
| 182 | if (ret) { | 182 | if (ret) { |
| 183 | dev_err(dev, "Could not register GPIO chip\n"); | 183 | dev_err(dev, "Could not register GPIO chip\n"); |
| 184 | return ret; | 184 | return ret; |
| @@ -190,20 +190,11 @@ static int kempld_gpio_probe(struct platform_device *pdev) · 5 unmodified lines | |||
| 190 | return 0; | 190 | return 0; |
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | static int kempld_gpio_remove(struct platform_device *pdev) | ||
| 194 | { | ||
| 195 | struct kempld_gpio_data *gpio = platform_get_drvdata(pdev); | ||
| 196 | |||
| 197 | gpiochip_remove(&gpio->chip); | ||
| 198 | return 0; | ||
| 199 | } | ||
| 200 | |||
| 201 | static struct platform_driver kempld_gpio_driver = { | 193 | static struct platform_driver kempld_gpio_driver = { |
| 202 | .driver = { | 194 | .driver = { |
| 203 | .name = "kempld-gpio", | 195 | .name = "kempld-gpio", |
| 204 | }, | 196 | }, |
| 205 | .probe = kempld_gpio_probe, | 197 | .probe = kempld_gpio_probe, |
| 206 | .remove = kempld_gpio_remove, | ||
| 207 | }; | 198 | }; |
| 208 | 199 | ||
| 209 | module_platform_driver(kempld_gpio_driver); | 200 | module_platform_driver(kempld_gpio_driver); |
| @@ -205,18 +205,6 @@ static int ks8695_gpio_to_irq(struct gpio_chip *gc, unsigned int pin) · 204 unmodified lines | |||
| 205 | return gpio_irq[pin]; | 205 | return gpio_irq[pin]; |
| 206 | } | 206 | } |
| 207 | 207 | ||
| 208 | /* | ||
| 209 | * Map IRQ number to GPIO line. | ||
| 210 | */ | ||
| 211 | int irq_to_gpio(unsigned int irq) | ||
| 212 | { | ||
| 213 | if ((irq < KS8695_IRQ_EXTERN0) || (irq > KS8695_IRQ_EXTERN3)) | ||
| 214 | return -EINVAL; | ||
| 215 | |||
| 216 | return (irq - KS8695_IRQ_EXTERN0); | ||
| 217 | } | ||
| 218 | EXPORT_SYMBOL(irq_to_gpio); | ||
| 219 | |||
| 220 | /* GPIOLIB interface */ | 208 | /* GPIOLIB interface */ |
| 221 | 209 | ||
| 222 | static struct gpio_chip ks8695_gpio_chip = { | 210 | static struct gpio_chip ks8695_gpio_chip = { |
| @@ -204,15 +204,8 @@ static int lp3943_gpio_probe(struct platform_device *pdev) · 203 unmodified lines | |||
| 204 | 204 | ||
| 205 | platform_set_drvdata(pdev, lp3943_gpio); | 205 | platform_set_drvdata(pdev, lp3943_gpio); |
| 206 | 206 | ||
| 207 | return gpiochip_add_data(&lp3943_gpio->chip, lp3943_gpio); | 207 | return devm_gpiochip_add_data(&pdev->dev, &lp3943_gpio->chip, |
| 208 | } | 208 | lp3943_gpio); |
| 209 | |||
| 210 | static int lp3943_gpio_remove(struct platform_device *pdev) | ||
| 211 | { | ||
| 212 | struct lp3943_gpio *lp3943_gpio = platform_get_drvdata(pdev); | ||
| 213 | |||
| 214 | gpiochip_remove(&lp3943_gpio->chip); | ||
| 215 | return 0; | ||
| 216 | } | 209 | } |
| 217 | 210 | ||
| 218 | static const struct of_device_id lp3943_gpio_of_match[] = { | 211 | static const struct of_device_id lp3943_gpio_of_match[] = { |
| @@ -223,7 +216,6 @@ MODULE_DEVICE_TABLE(of, lp3943_gpio_of_match); · 4 unmodified lines | |||
| 223 | 216 | ||
| 224 | static struct platform_driver lp3943_gpio_driver = { | 217 | static struct platform_driver lp3943_gpio_driver = { |
| 225 | .probe = lp3943_gpio_probe, | 218 | .probe = lp3943_gpio_probe, |
| 226 | .remove = lp3943_gpio_remove, | ||
| 227 | .driver = { | 219 | .driver = { |
| 228 | .name = "lp3943-gpio", | 220 | .name = "lp3943-gpio", |
| 229 | .of_match_table = lp3943_gpio_of_match, | 221 | .of_match_table = lp3943_gpio_of_match, |
| @@ -547,7 +547,7 @@ static int lpc32xx_gpio_probe(struct platform_device *pdev) · 546 unmodified lines | |||
| 547 | lpc32xx_gpiochip[i].chip.of_gpio_n_cells = 3; | 547 | lpc32xx_gpiochip[i].chip.of_gpio_n_cells = 3; |
| 548 | lpc32xx_gpiochip[i].chip.of_node = pdev->dev.of_node; | 548 | lpc32xx_gpiochip[i].chip.of_node = pdev->dev.of_node; |
| 549 | } | 549 | } |
| 550 | gpiochip_add_data(&lpc32xx_gpiochip[i].chip, | 550 | devm_gpiochip_add_data(&pdev->dev, &lpc32xx_gpiochip[i].chip, |
| 551 | &lpc32xx_gpiochip[i]); | 551 | &lpc32xx_gpiochip[i]); |
| 552 | } | 552 | } |
| 553 | 553 | ||
| @@ -370,7 +370,7 @@ static int lp_gpio_probe(struct platform_device *pdev) · 369 unmodified lines | |||
| 370 | gc->can_sleep = false; | 370 | gc->can_sleep = false; |
| 371 | gc->parent = dev; | 371 | gc->parent = dev; |
| 372 | 372 | ||
| 373 | ret = gpiochip_add_data(gc, lg); | 373 | ret = devm_gpiochip_add_data(dev, gc, lg); |
| 374 | if (ret) { | 374 | if (ret) { |
| 375 | dev_err(dev, "failed adding lp-gpio chip\n"); | 375 | dev_err(dev, "failed adding lp-gpio chip\n"); |
| 376 | return ret; | 376 | return ret; |
| @@ -439,9 +439,7 @@ MODULE_DEVICE_TABLE(acpi, lynxpoint_gpio_acpi_match); · 62 unmodified lines | |||
| 439 | 439 | ||
| 440 | static int lp_gpio_remove(struct platform_device *pdev) | 440 | static int lp_gpio_remove(struct platform_device *pdev) |
| 441 | { | 441 | { |
| 442 | struct lp_gpio *lg = platform_get_drvdata(pdev); | ||
| 443 | pm_runtime_disable(&pdev->dev); | 442 | pm_runtime_disable(&pdev->dev); |
| 444 | gpiochip_remove(&lg->chip); | ||
| 445 | return 0; | 443 | return 0; |
| 446 | } | 444 | } |
| 447 | 445 | ||
| @@ -103,17 +103,7 @@ static int mc9s08dz60_probe(struct i2c_client *client, · 102 unmodified lines | |||
| 103 | mc9s->client = client; | 103 | mc9s->client = client; |
| 104 | i2c_set_clientdata(client, mc9s); | 104 | i2c_set_clientdata(client, mc9s); |
| 105 | 105 | ||
| 106 | return gpiochip_add_data(&mc9s->chip, mc9s); | 106 | return devm_gpiochip_add_data(&client->dev, &mc9s->chip, mc9s); |
| 107 | } | ||
| 108 | |||
| 109 | static int mc9s08dz60_remove(struct i2c_client *client) | ||
| 110 | { | ||
| 111 | struct mc9s08dz60 *mc9s; | ||
| 112 | |||
| 113 | mc9s = i2c_get_clientdata(client); | ||
| 114 | |||
| 115 | gpiochip_remove(&mc9s->chip); | ||
| 116 | return 0; | ||
| 117 | } | 107 | } |
| 118 | 108 | ||
| 119 | static const struct i2c_device_id mc9s08dz60_id[] = { | 109 | static const struct i2c_device_id mc9s08dz60_id[] = { |
| @@ -128,7 +118,6 @@ static struct i2c_driver mc9s08dz60_i2c_driver = { · 8 unmodified lines | |||
| 128 | .name = "mc9s08dz60", | 118 | .name = "mc9s08dz60", |
| 129 | }, | 119 | }, |
| 130 | .probe = mc9s08dz60_probe, | 120 | .probe = mc9s08dz60_probe, |
| 131 | .remove = mc9s08dz60_remove, | ||
| 132 | .id_table = mc9s08dz60_id, | 121 | .id_table = mc9s08dz60_id, |
| 133 | }; | 122 | }; |
| 134 | 123 | ||
| @@ -31,6 +31,7 @@ · 30 unmodified lines | |||
| 31 | #define MCP_TYPE_S17 1 | 31 | #define MCP_TYPE_S17 1 |
| 32 | #define MCP_TYPE_008 2 | 32 | #define MCP_TYPE_008 2 |
| 33 | #define MCP_TYPE_017 3 | 33 | #define MCP_TYPE_017 3 |
| 34 | #define MCP_TYPE_S18 4 | ||
| 34 | 35 | ||
| 35 | /* Registers are all 8 bits wide. | 36 | /* Registers are all 8 bits wide. |
| 36 | * | 37 | * |
| @@ -48,6 +49,7 @@ · 11 unmodified lines | |||
| 48 | # define IOCON_HAEN (1 << 3) | 49 | # define IOCON_HAEN (1 << 3) |
| 49 | # define IOCON_ODR (1 << 2) | 50 | # define IOCON_ODR (1 << 2) |
| 50 | # define IOCON_INTPOL (1 << 1) | 51 | # define IOCON_INTPOL (1 << 1) |
| 52 | # define IOCON_INTCC (1) | ||
| 51 | #define MCP_GPPU 0x06 | 53 | #define MCP_GPPU 0x06 |
| 52 | #define MCP_INTF 0x07 | 54 | #define MCP_INTF 0x07 |
| 53 | #define MCP_INTCAP 0x08 | 55 | #define MCP_INTCAP 0x08 |
| @@ -617,6 +619,12 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, · 563 unmodified lines | |||
| 617 | mcp->chip.ngpio = 16; | 619 | mcp->chip.ngpio = 16; |
| 618 | mcp->chip.label = "mcp23s17"; | 620 | mcp->chip.label = "mcp23s17"; |
| 619 | break; | 621 | break; |
| 622 | |||
| 623 | case MCP_TYPE_S18: | ||
| 624 | mcp->ops = &mcp23s17_ops; | ||
| 625 | mcp->chip.ngpio = 16; | ||
| 626 | mcp->chip.label = "mcp23s18"; | ||
| 627 | break; | ||
| 620 | #endif /* CONFIG_SPI_MASTER */ | 628 | #endif /* CONFIG_SPI_MASTER */ |
| 621 | 629 | ||
| 622 | #if IS_ENABLED(CONFIG_I2C) | 630 | #if IS_ENABLED(CONFIG_I2C) |
| @@ -657,8 +665,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, · 34 unmodified lines | |||
| 657 | of_property_read_bool(mcp->chip.parent->of_node, | 665 | of_property_read_bool(mcp->chip.parent->of_node, |
| 658 | "microchip,irq-active-high"); | 666 | "microchip,irq-active-high"); |
| 659 | 667 | ||
| 660 | if (type == MCP_TYPE_017) | 668 | mirror = pdata->mirror; |
| 661 | mirror = pdata->mirror; | ||
| 662 | } | 669 | } |
| 663 | 670 | ||
| 664 | if ((status & IOCON_SEQOP) || !(status & IOCON_HAEN) || mirror || | 671 | if ((status & IOCON_SEQOP) || !(status & IOCON_HAEN) || mirror || |
| @@ -674,6 +681,9 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, · 9 unmodified lines | |||
| 674 | if (mirror) | 681 | if (mirror) |
| 675 | status |= IOCON_MIRROR | (IOCON_MIRROR << 8); | 682 | status |= IOCON_MIRROR | (IOCON_MIRROR << 8); |
| 676 | 683 | ||
| 684 | if (type == MCP_TYPE_S18) | ||
| 685 | status |= IOCON_INTCC | (IOCON_INTCC << 8); | ||
| 686 | |||
| 677 | status = mcp->ops->write(mcp, MCP_IOCON, status); | 687 | status = mcp->ops->write(mcp, MCP_IOCON, status); |
| 678 | if (status < 0) | 688 | if (status < 0) |
| 679 | goto fail; | 689 | goto fail; |
| @@ -735,6 +745,10 @@ static const struct of_device_id mcp23s08_spi_of_match[] = { · 55 unmodified lines | |||
| 735 | .compatible = "microchip,mcp23s17", | 745 | .compatible = "microchip,mcp23s17", |
| 736 | .data = (void *) MCP_TYPE_S17, | 746 | .data = (void *) MCP_TYPE_S17, |
| 737 | }, | 747 | }, |
| 748 | { | ||
| 749 | .compatible = "microchip,mcp23s18", | ||
| 750 | .data = (void *) MCP_TYPE_S18, | ||
| 751 | }, | ||
| 738 | /* NOTE: The use of the mcp prefix is deprecated and will be removed. */ | 752 | /* NOTE: The use of the mcp prefix is deprecated and will be removed. */ |
| 739 | { | 753 | { |
| 740 | .compatible = "mcp,mcp23s08", | 754 | .compatible = "mcp,mcp23s08", |
| @@ -803,6 +817,8 @@ static int mcp230xx_probe(struct i2c_client *client, · 62 unmodified lines | |||
| 803 | pdata = devm_kzalloc(&client->dev, | 817 | pdata = devm_kzalloc(&client->dev, |
| 804 | sizeof(struct mcp23s08_platform_data), | 818 | sizeof(struct mcp23s08_platform_data), |
| 805 | GFP_KERNEL); | 819 | GFP_KERNEL); |
| 820 | if (!pdata) | ||
| 821 | return -ENOMEM; | ||
| 806 | pdata->base = -1; | 822 | pdata->base = -1; |
| 807 | } | 823 | } |
| 808 | } | 824 | } |
| @@ -969,8 +985,8 @@ static int mcp23s08_probe(struct spi_device *spi) · 160 unmodified lines | |||
| 969 | goto fail; | 985 | goto fail; |
| 970 | 986 | ||
| 971 | if (pdata->base != -1) | 987 | if (pdata->base != -1) |
| 972 | pdata->base += (type == MCP_TYPE_S17) ? 16 : 8; | 988 | pdata->base += data->mcp[addr]->chip.ngpio; |
| 973 | ngpio += (type == MCP_TYPE_S17) ? 16 : 8; | 989 | ngpio += data->mcp[addr]->chip.ngpio; |
| 974 | } | 990 | } |
| 975 | data->ngpio = ngpio; | 991 | data->ngpio = ngpio; |
| 976 | 992 | ||
| @@ -1012,6 +1028,7 @@ static int mcp23s08_remove(struct spi_device *spi) · 35 unmodified lines | |||
| 1012 | static const struct spi_device_id mcp23s08_ids[] = { | 1028 | static const struct spi_device_id mcp23s08_ids[] = { |
| 1013 | { "mcp23s08", MCP_TYPE_S08 }, | 1029 | { "mcp23s08", MCP_TYPE_S08 }, |
| 1014 | { "mcp23s17", MCP_TYPE_S17 }, | 1030 | { "mcp23s17", MCP_TYPE_S17 }, |
| 1031 | { "mcp23s18", MCP_TYPE_S18 }, | ||
| 1015 | { }, | 1032 | { }, |
| 1016 | }; | 1033 | }; |
| 1017 | MODULE_DEVICE_TABLE(spi, mcp23s08_ids); | 1034 | MODULE_DEVICE_TABLE(spi, mcp23s08_ids); |
| @@ -0,0 +1,200 @@ | |||
| 1 | /* | ||
| 2 | * MEN 16Z127 GPIO driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2016 MEN Mikroelektronik GmbH (www.men.de) | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms of the GNU General Public License as published by the Free | ||
| 8 | * Software Foundation; version 2 of the License. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/kernel.h> | ||
| 12 | #include <linux/module.h> | ||
| 13 | #include <linux/io.h> | ||
| 14 | #include <linux/err.h> | ||
| 15 | #include <linux/mcb.h> | ||
| 16 | #include <linux/bitops.h> | ||
| 17 | #include <linux/gpio/driver.h> | ||
| 18 | |||
| 19 | #define MEN_Z127_CTRL 0x00 | ||
| 20 | #define MEN_Z127_PSR 0x04 | ||
| 21 | #define MEN_Z127_IRQR 0x08 | ||
| 22 | #define MEN_Z127_GPIODR 0x0c | ||
| 23 | #define MEN_Z127_IER1 0x10 | ||
| 24 | #define MEN_Z127_IER2 0x14 | ||
| 25 | #define MEN_Z127_DBER 0x18 | ||
| 26 | #define MEN_Z127_ODER 0x1C | ||
| 27 | #define GPIO_TO_DBCNT_REG(gpio) ((gpio * 4) + 0x80) | ||
| 28 | |||
| 29 | #define MEN_Z127_DB_MIN_US 50 | ||
| 30 | /* 16 bit compare register. Each bit represents 50us */ | ||
| 31 | #define MEN_Z127_DB_MAX_US (0xffff * MEN_Z127_DB_MIN_US) | ||
| 32 | #define MEN_Z127_DB_IN_RANGE(db) ((db >= MEN_Z127_DB_MIN_US) && \ | ||
| 33 | (db <= MEN_Z127_DB_MAX_US)) | ||
| 34 | |||
| 35 | struct men_z127_gpio { | ||
| 36 | struct gpio_chip gc; | ||
| 37 | void __iomem *reg_base; | ||
| 38 | struct mcb_device *mdev; | ||
| 39 | struct resource *mem; | ||
| 40 | spinlock_t lock; | ||
| 41 | }; | ||
| 42 | |||
| 43 | static int men_z127_debounce(struct gpio_chip *gc, unsigned gpio, | ||
| 44 | unsigned debounce) | ||
| 45 | { | ||
| 46 | struct men_z127_gpio *priv = gpiochip_get_data(gc); | ||
| 47 | struct device *dev = &priv->mdev->dev; | ||
| 48 | unsigned int rnd; | ||
| 49 | u32 db_en, db_cnt; | ||
| 50 | |||
| 51 | if (!MEN_Z127_DB_IN_RANGE(debounce)) { | ||
| 52 | dev_err(dev, "debounce value %u out of range", debounce); | ||
| 53 | return -EINVAL; | ||
| 54 | } | ||
| 55 | |||
| 56 | if (debounce > 0) { | ||
| 57 | /* round up or down depending on MSB-1 */ | ||
| 58 | rnd = fls(debounce) - 1; | ||
| 59 | |||
| 60 | if (rnd && (debounce & BIT(rnd - 1))) | ||
| 61 | debounce = round_up(debounce, MEN_Z127_DB_MIN_US); | ||
| 62 | else | ||
| 63 | debounce = round_down(debounce, MEN_Z127_DB_MIN_US); | ||
| 64 | |||
| 65 | if (debounce > MEN_Z127_DB_MAX_US) | ||
| 66 | debounce = MEN_Z127_DB_MAX_US; | ||
| 67 | |||
| 68 | /* 50us per register unit */ | ||
| 69 | debounce /= 50; | ||
| 70 | } | ||
| 71 | |||
| 72 | spin_lock(&priv->lock); | ||
| 73 | |||
| 74 | db_en = readl(priv->reg_base + MEN_Z127_DBER); | ||
| 75 | |||
| 76 | if (debounce == 0) { | ||
| 77 | db_en &= ~BIT(gpio); | ||
| 78 | db_cnt = 0; | ||
| 79 | } else { | ||
| 80 | db_en |= BIT(gpio); | ||
| 81 | db_cnt = debounce; | ||
| 82 | } | ||
| 83 | |||
| 84 | writel(db_en, priv->reg_base + MEN_Z127_DBER); | ||
| 85 | writel(db_cnt, priv->reg_base + GPIO_TO_DBCNT_REG(gpio)); | ||
| 86 | |||
| 87 | spin_unlock(&priv->lock); | ||
| 88 | |||
| 89 | return 0; | ||
| 90 | } | ||
| 91 | |||
| 92 | static int men_z127_request(struct gpio_chip *gc, unsigned gpio_pin) | ||
| 93 | { | ||
| 94 | struct men_z127_gpio *priv = gpiochip_get_data(gc); | ||
| 95 | u32 od_en; | ||
| 96 | |||
| 97 | if (gpio_pin >= gc->ngpio) | ||
| 98 | return -EINVAL; | ||
| 99 | |||
| 100 | spin_lock(&priv->lock); | ||
| 101 | od_en = readl(priv->reg_base + MEN_Z127_ODER); | ||
| 102 | |||
| 103 | if (gpiochip_line_is_open_drain(gc, gpio_pin)) | ||
| 104 | od_en |= BIT(gpio_pin); | ||
| 105 | else | ||
| 106 | od_en &= ~BIT(gpio_pin); | ||
| 107 | |||
| 108 | writel(od_en, priv->reg_base + MEN_Z127_ODER); | ||
| 109 | spin_unlock(&priv->lock); | ||
| 110 | |||
| 111 | return 0; | ||
| 112 | } | ||
| 113 | |||
| 114 | static int men_z127_probe(struct mcb_device *mdev, | ||
| 115 | const struct mcb_device_id *id) | ||
| 116 | { | ||
| 117 | struct men_z127_gpio *men_z127_gpio; | ||
| 118 | struct device *dev = &mdev->dev; | ||
| 119 | int ret; | ||
| 120 | |||
| 121 | men_z127_gpio = devm_kzalloc(dev, sizeof(struct men_z127_gpio), | ||
| 122 | GFP_KERNEL); | ||
| 123 | if (!men_z127_gpio) | ||
| 124 | return -ENOMEM; | ||
| 125 | |||
| 126 | men_z127_gpio->mem = mcb_request_mem(mdev, dev_name(dev)); | ||
| 127 | if (IS_ERR(men_z127_gpio->mem)) { | ||
| 128 | dev_err(dev, "failed to request device memory"); | ||
| 129 | return PTR_ERR(men_z127_gpio->mem); | ||
| 130 | } | ||
| 131 | |||
| 132 | men_z127_gpio->reg_base = ioremap(men_z127_gpio->mem->start, | ||
| 133 | resource_size(men_z127_gpio->mem)); | ||
| 134 | if (men_z127_gpio->reg_base == NULL) { | ||
| 135 | ret = -ENXIO; | ||
| 136 | goto err_release; | ||
| 137 | } | ||
| 138 | |||
| 139 | men_z127_gpio->mdev = mdev; | ||
| 140 | mcb_set_drvdata(mdev, men_z127_gpio); | ||
| 141 | |||
| 142 | ret = bgpio_init(&men_z127_gpio->gc, &mdev->dev, 4, | ||
| 143 | men_z127_gpio->reg_base + MEN_Z127_PSR, | ||
| 144 | men_z127_gpio->reg_base + MEN_Z127_CTRL, | ||
| 145 | NULL, | ||
| 146 | men_z127_gpio->reg_base + MEN_Z127_GPIODR, | ||
| 147 | NULL, 0); | ||
| 148 | if (ret) | ||
| 149 | goto err_unmap; | ||
| 150 | |||
| 151 | men_z127_gpio->gc.set_debounce = men_z127_debounce; | ||
| 152 | men_z127_gpio->gc.request = men_z127_request; | ||
| 153 | |||
| 154 | ret = gpiochip_add_data(&men_z127_gpio->gc, men_z127_gpio); | ||
| 155 | if (ret) { | ||
| 156 | dev_err(dev, "failed to register MEN 16Z127 GPIO controller"); | ||
| 157 | goto err_unmap; | ||
| 158 | } | ||
| 159 | |||
| 160 | dev_info(dev, "MEN 16Z127 GPIO driver registered"); | ||
| 161 | |||
| 162 | return 0; | ||
| 163 | |||
| 164 | err_unmap: | ||
| 165 | iounmap(men_z127_gpio->reg_base); | ||
| 166 | err_release: | ||
| 167 | mcb_release_mem(men_z127_gpio->mem); | ||
| 168 | return ret; | ||
| 169 | } | ||
| 170 | |||
| 171 | static void men_z127_remove(struct mcb_device *mdev) | ||
| 172 | { | ||
| 173 | struct men_z127_gpio *men_z127_gpio = mcb_get_drvdata(mdev); | ||
| 174 | |||
| 175 | gpiochip_remove(&men_z127_gpio->gc); | ||
| 176 | iounmap(men_z127_gpio->reg_base); | ||
| 177 | mcb_release_mem(men_z127_gpio->mem); | ||
| 178 | } | ||
| 179 | |||
| 180 | static const struct mcb_device_id men_z127_ids[] = { | ||
| 181 | { .device = 0x7f }, | ||
| 182 | { } | ||
| 183 | }; | ||
| 184 | MODULE_DEVICE_TABLE(mcb, men_z127_ids); | ||
| 185 | |||
| 186 | static struct mcb_driver men_z127_driver = { | ||
| 187 | .driver = { | ||
| 188 | .name = "z127-gpio", | ||
| 189 | .owner = THIS_MODULE, | ||
| 190 | }, | ||
| 191 | .probe = men_z127_probe, | ||
| 192 | .remove = men_z127_remove, | ||
| 193 | .id_table = men_z127_ids, | ||
| 194 | }; | ||
| 195 | module_mcb_driver(men_z127_driver); | ||
| 196 | |||
| 197 | MODULE_AUTHOR("Andreas Werner <andreas.werner@men.de>"); | ||
| 198 | MODULE_DESCRIPTION("MEN 16z127 GPIO Controller"); | ||
| 199 | MODULE_LICENSE("GPL v2"); | ||
| 200 | MODULE_ALIAS("mcb:16z127"); | ||
| @@ -57,13 +57,10 @@ static int moxart_gpio_probe(struct platform_device *pdev) · 56 unmodified lines | |||
| 57 | gc->label = "moxart-gpio"; | 57 | gc->label = "moxart-gpio"; |
| 58 | gc->request = gpiochip_generic_request; | 58 | gc->request = gpiochip_generic_request; |
| 59 | gc->free = gpiochip_generic_free; | 59 | gc->free = gpiochip_generic_free; |
| 60 | gc->bgpio_data = gc->read_reg(gc->reg_set); | ||
| 61 | gc->base = 0; | 60 | gc->base = 0; |
| 62 | gc->ngpio = 32; | ||
| 63 | gc->parent = dev; | ||
| 64 | gc->owner = THIS_MODULE; | 61 | gc->owner = THIS_MODULE; |
| 65 | 62 | ||
| 66 | ret = gpiochip_add_data(gc, NULL); | 63 | ret = devm_gpiochip_add_data(dev, gc, NULL); |
| 67 | if (ret) { | 64 | if (ret) { |
| 68 | dev_err(dev, "%s: gpiochip_add failed\n", | 65 | dev_err(dev, "%s: gpiochip_add failed\n", |
| 69 | dev->of_node->full_name); | 66 | dev->of_node->full_name); |
| @@ -25,7 +25,6 @@ · 24 unmodified lines | |||
| 25 | #include <linux/of_platform.h> | 25 | #include <linux/of_platform.h> |
| 26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
| 27 | 27 | ||
| 28 | #include <asm/gpio.h> | ||
| 29 | #include <asm/mpc52xx.h> | 28 | #include <asm/mpc52xx.h> |
| 30 | #include <sysdev/fsl_soc.h> | 29 | #include <sysdev/fsl_soc.h> |
| 31 | 30 | ||
| @@ -1,7 +1,8 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * GPIOs on MPC512x/8349/8572/8610 and compatible | 2 | * GPIOs on MPC512x/8349/8572/8610/QorIQ and compatible |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2008 Peter Korsgaard <jacmet@sunsite.dk> | 4 | * Copyright (C) 2008 Peter Korsgaard <jacmet@sunsite.dk> |
| 5 | * Copyright (C) 2016 Freescale Semiconductor Inc. | ||
| 5 | * | 6 | * |
| 6 | * This file is licensed under the terms of the GNU General Public License | 7 | * This file is licensed under the terms of the GNU General Public License |
| 7 | * version 2. This program is licensed "as is" without any warranty of any | 8 | * version 2. This program is licensed "as is" without any warranty of any |
| @@ -14,11 +15,12 @@ · 6 unmodified lines | |||
| 14 | #include <linux/io.h> | 15 | #include <linux/io.h> |
| 15 | #include <linux/of.h> | 16 | #include <linux/of.h> |
| 16 | #include <linux/of_gpio.h> | 17 | #include <linux/of_gpio.h> |
| 18 | #include <linux/of_address.h> | ||
| 17 | #include <linux/of_irq.h> | 19 | #include <linux/of_irq.h> |
| 18 | #include <linux/of_platform.h> | 20 | #include <linux/of_platform.h> |
| 19 | #include <linux/gpio.h> | ||
| 20 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
| 21 | #include <linux/irq.h> | 22 | #include <linux/irq.h> |
| 23 | #include <linux/gpio/driver.h> | ||
| 22 | 24 | ||
| 23 | #define MPC8XXX_GPIO_PINS 32 | 25 | #define MPC8XXX_GPIO_PINS 32 |
| 24 | 26 | ||
| @@ -31,32 +33,17 @@ · 6 unmodified lines | |||
| 31 | #define GPIO_ICR2 0x18 | 33 | #define GPIO_ICR2 0x18 |
| 32 | 34 | ||
| 33 | struct mpc8xxx_gpio_chip { | 35 | struct mpc8xxx_gpio_chip { |
| 34 | struct of_mm_gpio_chip mm_gc; | 36 | struct gpio_chip gc; |
| 37 | void __iomem *regs; | ||
| 35 | raw_spinlock_t lock; | 38 | raw_spinlock_t lock; |
| 36 | 39 | ||
| 37 | /* | 40 | int (*direction_output)(struct gpio_chip *chip, |
| 38 | * shadowed data register to be able to clear/set output pins in | 41 | unsigned offset, int value); |
| 39 | * open drain mode safely | 42 | |
| 40 | */ | ||
| 41 | u32 data; | ||
| 42 | struct irq_domain *irq; | 43 | struct irq_domain *irq; |
| 43 | unsigned int irqn; | 44 | unsigned int irqn; |
| 44 | const void *of_dev_id_data; | ||
| 45 | }; | 45 | }; |
| 46 | 46 | ||
| 47 | static inline u32 mpc8xxx_gpio2mask(unsigned int gpio) | ||
| 48 | { | ||
| 49 | return 1u << (MPC8XXX_GPIO_PINS - 1 - gpio); | ||
| 50 | } | ||
| 51 | |||
| 52 | static void mpc8xxx_gpio_save_regs(struct of_mm_gpio_chip *mm) | ||
| 53 | { | ||
| 54 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = | ||
| 55 | container_of(mm, struct mpc8xxx_gpio_chip, mm_gc); | ||
| 56 | |||
| 57 | mpc8xxx_gc->data = in_be32(mm->regs + GPIO_DAT); | ||
| 58 | } | ||
| 59 | |||
| 60 | /* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs | 47 | /* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs |
| 61 | * defined as output cannot be determined by reading GPDAT register, | 48 | * defined as output cannot be determined by reading GPDAT register, |
| 62 | * so we use shadow data register instead. The status of input pins | 49 | * so we use shadow data register instead. The status of input pins |
| @@ -65,117 +52,36 @@ static void mpc8xxx_gpio_save_regs(struct of_mm_gpio_chip *mm) · 2 unmodified lines | |||
| 65 | static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio) | 52 | static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio) |
| 66 | { | 53 | { |
| 67 | u32 val; | 54 | u32 val; |
| 68 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | ||
| 69 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = gpiochip_get_data(gc); | 55 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = gpiochip_get_data(gc); |
| 70 | u32 out_mask, out_shadow; | 56 | u32 out_mask, out_shadow; |
| 71 | 57 | ||
| 72 | out_mask = in_be32(mm->regs + GPIO_DIR); | 58 | out_mask = gc->read_reg(mpc8xxx_gc->regs + GPIO_DIR); |
| 73 | 59 | val = gc->read_reg(mpc8xxx_gc->regs + GPIO_DAT) & ~out_mask; | |
| 74 | val = in_be32(mm->regs + GPIO_DAT) & ~out_mask; | 60 | out_shadow = gc->bgpio_data & out_mask; |
| 75 | out_shadow = mpc8xxx_gc->data & out_mask; | ||
| 76 | |||
| 77 | return !!((val | out_shadow) & mpc8xxx_gpio2mask(gpio)); | ||
| 78 | } | ||
| 79 | |||
| 80 | static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio) | ||
| 81 | { | ||
| 82 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | ||
| 83 | |||
| 84 | return in_be32(mm->regs + GPIO_DAT) & mpc8xxx_gpio2mask(gpio); | ||
| 85 | } | ||
| 86 | |||
| 87 | static void mpc8xxx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) | ||
| 88 | { | ||
| 89 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | ||
| 90 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = gpiochip_get_data(gc); | ||
| 91 | unsigned long flags; | ||
| 92 | |||
| 93 | raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
| 94 | |||
| 95 | if (val) | ||
| 96 | mpc8xxx_gc->data |= mpc8xxx_gpio2mask(gpio); | ||
| 97 | else | ||
| 98 | mpc8xxx_gc->data &= ~mpc8xxx_gpio2mask(gpio); | ||
| 99 | |||
| 100 | out_be32(mm->regs + GPIO_DAT, mpc8xxx_gc->data); | ||
| 101 | |||
| 102 | raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
| 103 | } | ||
| 104 | |||
| 105 | static void mpc8xxx_gpio_set_multiple(struct gpio_chip *gc, | ||
| 106 | unsigned long *mask, unsigned long *bits) | ||
| 107 | { | ||
| 108 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | ||
| 109 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = gpiochip_get_data(gc); | ||
| 110 | unsigned long flags; | ||
| 111 | int i; | ||
| 112 | |||
| 113 | raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
| 114 | |||
| 115 | for (i = 0; i < gc->ngpio; i++) { | ||
| 116 | if (*mask == 0) | ||
| 117 | break; | ||
| 118 | if (__test_and_clear_bit(i, mask)) { | ||
| 119 | if (test_bit(i, bits)) | ||
| 120 | mpc8xxx_gc->data |= mpc8xxx_gpio2mask(i); | ||
| 121 | else | ||
| 122 | mpc8xxx_gc->data &= ~mpc8xxx_gpio2mask(i); | ||
| 123 | } | ||
| 124 | } | ||
| 125 | |||
| 126 | out_be32(mm->regs + GPIO_DAT, mpc8xxx_gc->data); | ||
| 127 | |||
| 128 | raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
| 129 | } | ||
| 130 | |||
| 131 | static int mpc8xxx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) | ||
| 132 | { | ||
| 133 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | ||
| 134 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = gpiochip_get_data(gc); | ||
| 135 | unsigned long flags; | ||
| 136 | 61 | ||
| 137 | raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | 62 | return !!((val | out_shadow) & gc->pin2mask(gc, gpio)); |
| 138 | |||
| 139 | clrbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio)); | ||
| 140 | |||
| 141 | raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
| 142 | |||
| 143 | return 0; | ||
| 144 | } | 63 | } |
| 145 | 64 | ||
| 146 | static int mpc8xxx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | 65 | static int mpc5121_gpio_dir_out(struct gpio_chip *gc, |
| 66 | unsigned int gpio, int val) | ||
| 147 | { | 67 | { |
| 148 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | ||
| 149 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = gpiochip_get_data(gc); | 68 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = gpiochip_get_data(gc); |
| 150 | unsigned long flags; | ||
| 151 | |||
| 152 | mpc8xxx_gpio_set(gc, gpio, val); | ||
| 153 | |||
| 154 | raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
| 155 | |||
| 156 | setbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio)); | ||
| 157 | |||
| 158 | raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
| 159 | |||
| 160 | return 0; | ||
| 161 | } | ||
| 162 | |||
| 163 | static int mpc5121_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | ||
| 164 | { | ||
| 165 | /* GPIO 28..31 are input only on MPC5121 */ | 69 | /* GPIO 28..31 are input only on MPC5121 */ |
| 166 | if (gpio >= 28) | 70 | if (gpio >= 28) |
| 167 | return -EINVAL; | 71 | return -EINVAL; |
| 168 | 72 | ||
| 169 | return mpc8xxx_gpio_dir_out(gc, gpio, val); | 73 | return mpc8xxx_gc->direction_output(gc, gpio, val); |
| 170 | } | 74 | } |
| 171 | 75 | ||
| 172 | static int mpc5125_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | 76 | static int mpc5125_gpio_dir_out(struct gpio_chip *gc, |
| 77 | unsigned int gpio, int val) | ||
| 173 | { | 78 | { |
| 79 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = gpiochip_get_data(gc); | ||
| 174 | /* GPIO 0..3 are input only on MPC5125 */ | 80 | /* GPIO 0..3 are input only on MPC5125 */ |
| 175 | if (gpio <= 3) | 81 | if (gpio <= 3) |
| 176 | return -EINVAL; | 82 | return -EINVAL; |
| 177 | 83 | ||
| 178 | return mpc8xxx_gpio_dir_out(gc, gpio, val); | 84 | return mpc8xxx_gc->direction_output(gc, gpio, val); |
| 179 | } | 85 | } |
| 180 | 86 | ||
| 181 | static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset) | 87 | static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset) |
| @@ -192,10 +98,11 @@ static void mpc8xxx_gpio_irq_cascade(struct irq_desc *desc) · 10 unmodified lines | |||
| 192 | { | 98 | { |
| 193 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_desc_get_handler_data(desc); | 99 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_desc_get_handler_data(desc); |
| 194 | struct irq_chip *chip = irq_desc_get_chip(desc); | 100 | struct irq_chip *chip = irq_desc_get_chip(desc); |
| 195 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | 101 | struct gpio_chip *gc = &mpc8xxx_gc->gc; |
| 196 | unsigned int mask; | 102 | unsigned int mask; |
| 197 | 103 | ||
| 198 | mask = in_be32(mm->regs + GPIO_IER) & in_be32(mm->regs + GPIO_IMR); | 104 | mask = gc->read_reg(mpc8xxx_gc->regs + GPIO_IER) |
| 105 | & gc->read_reg(mpc8xxx_gc->regs + GPIO_IMR); | ||
| 199 | if (mask) | 106 | if (mask) |
| 200 | generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq, | 107 | generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq, |
| 201 | 32 - ffs(mask))); | 108 | 32 - ffs(mask))); |
| @@ -206,12 +113,14 @@ static void mpc8xxx_gpio_irq_cascade(struct irq_desc *desc) · 4 unmodified lines | |||
| 206 | static void mpc8xxx_irq_unmask(struct irq_data *d) | 113 | static void mpc8xxx_irq_unmask(struct irq_data *d) |
| 207 | { | 114 | { |
| 208 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d); | 115 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d); |
| 209 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | 116 | struct gpio_chip *gc = &mpc8xxx_gc->gc; |
| 210 | unsigned long flags; | 117 | unsigned long flags; |
| 211 | 118 | ||
| 212 | raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | 119 | raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); |
| 213 | 120 | ||
| 214 | setbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d))); | 121 | gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR, |
| 122 | gc->read_reg(mpc8xxx_gc->regs + GPIO_IMR) | ||
| 123 | | gc->pin2mask(gc, irqd_to_hwirq(d))); | ||
| 215 | 124 | ||
| 216 | raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | 125 | raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); |
| 217 | } | 126 | } |
| @@ -219,12 +128,14 @@ static void mpc8xxx_irq_unmask(struct irq_data *d) · 1 unmodified line | |||
| 219 | static void mpc8xxx_irq_mask(struct irq_data *d) | 128 | static void mpc8xxx_irq_mask(struct irq_data *d) |
| 220 | { | 129 | { |
| 221 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d); | 130 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d); |
| 222 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | 131 | struct gpio_chip *gc = &mpc8xxx_gc->gc; |
| 223 | unsigned long flags; | 132 | unsigned long flags; |
| 224 | 133 | ||
| 225 | raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | 134 | raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); |
| 226 | 135 | ||
| 227 | clrbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d))); | 136 | gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR, |
| 137 | gc->read_reg(mpc8xxx_gc->regs + GPIO_IMR) | ||
| 138 | & ~(gc->pin2mask(gc, irqd_to_hwirq(d)))); | ||
| 228 | 139 | ||
| 229 | raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | 140 | raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); |
| 230 | } | 141 | } |
| @@ -232,29 +143,32 @@ static void mpc8xxx_irq_mask(struct irq_data *d) · 1 unmodified line | |||
| 232 | static void mpc8xxx_irq_ack(struct irq_data *d) | 143 | static void mpc8xxx_irq_ack(struct irq_data *d) |
| 233 | { | 144 | { |
| 234 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d); | 145 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d); |
| 235 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | 146 | struct gpio_chip *gc = &mpc8xxx_gc->gc; |
| 236 | 147 | ||
| 237 | out_be32(mm->regs + GPIO_IER, mpc8xxx_gpio2mask(irqd_to_hwirq(d))); | 148 | gc->write_reg(mpc8xxx_gc->regs + GPIO_IER, |
| 149 | gc->pin2mask(gc, irqd_to_hwirq(d))); | ||
| 238 | } | 150 | } |
| 239 | 151 | ||
| 240 | static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type) | 152 | static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type) |
| 241 | { | 153 | { |
| 242 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d); | 154 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d); |
| 243 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | 155 | struct gpio_chip *gc = &mpc8xxx_gc->gc; |
| 244 | unsigned long flags; | 156 | unsigned long flags; |
| 245 | 157 | ||
| 246 | switch (flow_type) { | 158 | switch (flow_type) { |
| 247 | case IRQ_TYPE_EDGE_FALLING: | 159 | case IRQ_TYPE_EDGE_FALLING: |
| 248 | raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | 160 | raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); |
| 249 | setbits32(mm->regs + GPIO_ICR, | 161 | gc->write_reg(mpc8xxx_gc->regs + GPIO_ICR, |
| 250 | mpc8xxx_gpio2mask(irqd_to_hwirq(d))); | 162 | gc->read_reg(mpc8xxx_gc->regs + GPIO_ICR) |
| 163 | | gc->pin2mask(gc, irqd_to_hwirq(d))); | ||
| 251 | raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | 164 | raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); |
| 252 | break; | 165 | break; |
| 253 | 166 | ||
| 254 | case IRQ_TYPE_EDGE_BOTH: | 167 | case IRQ_TYPE_EDGE_BOTH: |
| 255 | raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | 168 | raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); |
| 256 | clrbits32(mm->regs + GPIO_ICR, | 169 | gc->write_reg(mpc8xxx_gc->regs + GPIO_ICR, |
| 257 | mpc8xxx_gpio2mask(irqd_to_hwirq(d))); | 170 | gc->read_reg(mpc8xxx_gc->regs + GPIO_ICR) |
| 171 | & ~(gc->pin2mask(gc, irqd_to_hwirq(d)))); | ||
| 258 | raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | 172 | raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); |
| 259 | break; | 173 | break; |
| 260 | 174 | ||
| @@ -268,17 +182,17 @@ static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type) · 7 unmodified lines | |||
| 268 | static int mpc512x_irq_set_type(struct irq_data *d, unsigned int flow_type) | 182 | static int mpc512x_irq_set_type(struct irq_data *d, unsigned int flow_type) |
| 269 | { | 183 | { |
| 270 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d); | 184 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d); |
| 271 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | 185 | struct gpio_chip *gc = &mpc8xxx_gc->gc; |
| 272 | unsigned long gpio = irqd_to_hwirq(d); | 186 | unsigned long gpio = irqd_to_hwirq(d); |
| 273 | void __iomem *reg; | 187 | void __iomem *reg; |
| 274 | unsigned int shift; | 188 | unsigned int shift; |
| 275 | unsigned long flags; | 189 | unsigned long flags; |
| 276 | 190 | ||
| 277 | if (gpio < 16) { | 191 | if (gpio < 16) { |
| 278 | reg = mm->regs + GPIO_ICR; | 192 | reg = mpc8xxx_gc->regs + GPIO_ICR; |
| 279 | shift = (15 - gpio) * 2; | 193 | shift = (15 - gpio) * 2; |
| 280 | } else { | 194 | } else { |
| 281 | reg = mm->regs + GPIO_ICR2; | 195 | reg = mpc8xxx_gc->regs + GPIO_ICR2; |
| 282 | shift = (15 - (gpio % 16)) * 2; | 196 | shift = (15 - (gpio % 16)) * 2; |
| 283 | } | 197 | } |
| 284 | 198 | ||
| @@ -286,20 +200,22 @@ static int mpc512x_irq_set_type(struct irq_data *d, unsigned int flow_type) · 1 unmodified line | |||
| 286 | case IRQ_TYPE_EDGE_FALLING: | 200 | case IRQ_TYPE_EDGE_FALLING: |
| 287 | case IRQ_TYPE_LEVEL_LOW: | 201 | case IRQ_TYPE_LEVEL_LOW: |
| 288 | raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | 202 | raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); |
| 289 | clrsetbits_be32(reg, 3 << shift, 2 << shift); | 203 | gc->write_reg(reg, (gc->read_reg(reg) & ~(3 << shift)) |
| 204 | | (2 << shift)); | ||
| 290 | raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | 205 | raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); |
| 291 | break; | 206 | break; |
| 292 | 207 | ||
| 293 | case IRQ_TYPE_EDGE_RISING: | 208 | case IRQ_TYPE_EDGE_RISING: |
| 294 | case IRQ_TYPE_LEVEL_HIGH: | 209 | case IRQ_TYPE_LEVEL_HIGH: |
| 295 | raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | 210 | raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); |
| 296 | clrsetbits_be32(reg, 3 << shift, 1 << shift); | 211 | gc->write_reg(reg, (gc->read_reg(reg) & ~(3 << shift)) |
| 212 | | (1 << shift)); | ||
| 297 | raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | 213 | raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); |
| 298 | break; | 214 | break; |
| 299 | 215 | ||
| 300 | case IRQ_TYPE_EDGE_BOTH: | 216 | case IRQ_TYPE_EDGE_BOTH: |
| 301 | raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | 217 | raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); |
| 302 | clrbits32(reg, 3 << shift); | 218 | gc->write_reg(reg, (gc->read_reg(reg) & ~(3 << shift))); |
| 303 | raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | 219 | raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); |
| 304 | break; | 220 | break; |
| 305 | 221 | ||
| @@ -354,8 +270,6 @@ static const struct mpc8xxx_gpio_devtype mpc8572_gpio_devtype = { · 48 unmodified lines | |||
| 354 | }; | 270 | }; |
| 355 | 271 | ||
| 356 | static const struct mpc8xxx_gpio_devtype mpc8xxx_gpio_devtype_default = { | 272 | static const struct mpc8xxx_gpio_devtype mpc8xxx_gpio_devtype_default = { |
| 357 | .gpio_dir_out = mpc8xxx_gpio_dir_out, | ||
| 358 | .gpio_get = mpc8xxx_gpio_get, | ||
| 359 | .irq_set_type = mpc8xxx_irq_set_type, | 273 | .irq_set_type = mpc8xxx_irq_set_type, |
| 360 | }; | 274 | }; |
| 361 | 275 | ||
| @@ -374,9 +288,7 @@ static int mpc8xxx_probe(struct platform_device *pdev) · 12 unmodified lines | |||
| 374 | { | 288 | { |
| 375 | struct device_node *np = pdev->dev.of_node; | 289 | struct device_node *np = pdev->dev.of_node; |
| 376 | struct mpc8xxx_gpio_chip *mpc8xxx_gc; | 290 | struct mpc8xxx_gpio_chip *mpc8xxx_gc; |
| 377 | struct of_mm_gpio_chip *mm_gc; | 291 | struct gpio_chip *gc; |
| 378 | struct gpio_chip *gc; | ||
| 379 | const struct of_device_id *id; | ||
| 380 | const struct mpc8xxx_gpio_devtype *devtype = | 292 | const struct mpc8xxx_gpio_devtype *devtype = |
| 381 | of_device_get_match_data(&pdev->dev); | 293 | of_device_get_match_data(&pdev->dev); |
| 382 | int ret; | 294 | int ret; |
| @@ -389,12 +301,34 @@ static int mpc8xxx_probe(struct platform_device *pdev) · 6 unmodified lines | |||
| 389 | 301 | ||
| 390 | raw_spin_lock_init(&mpc8xxx_gc->lock); | 302 | raw_spin_lock_init(&mpc8xxx_gc->lock); |
| 391 | 303 | ||
| 392 | mm_gc = &mpc8xxx_gc->mm_gc; | 304 | mpc8xxx_gc->regs = of_iomap(np, 0); |
| 393 | gc = &mm_gc->gc; | 305 | if (!mpc8xxx_gc->regs) |
| 306 | return -ENOMEM; | ||
| 307 | |||
| 308 | gc = &mpc8xxx_gc->gc; | ||
| 309 | |||
| 310 | if (of_property_read_bool(np, "little-endian")) { | ||
| 311 | ret = bgpio_init(gc, &pdev->dev, 4, | ||
| 312 | mpc8xxx_gc->regs + GPIO_DAT, | ||
| 313 | NULL, NULL, | ||
| 314 | mpc8xxx_gc->regs + GPIO_DIR, NULL, | ||
| 315 | BGPIOF_BIG_ENDIAN); | ||
| 316 | if (ret) | ||
| 317 | goto err; | ||
| 318 | dev_dbg(&pdev->dev, "GPIO registers are LITTLE endian\n"); | ||
| 319 | } else { | ||
| 320 | ret = bgpio_init(gc, &pdev->dev, 4, | ||
| 321 | mpc8xxx_gc->regs + GPIO_DAT, | ||
| 322 | NULL, NULL, | ||
| 323 | mpc8xxx_gc->regs + GPIO_DIR, NULL, | ||
| 324 | BGPIOF_BIG_ENDIAN | ||
| 325 | | BGPIOF_BIG_ENDIAN_BYTE_ORDER); | ||
| 326 | if (ret) | ||
| 327 | goto err; | ||
| 328 | dev_dbg(&pdev->dev, "GPIO registers are BIG endian\n"); | ||
| 329 | } | ||
| 394 | 330 | ||
| 395 | mm_gc->save_regs = mpc8xxx_gpio_save_regs; | 331 | mpc8xxx_gc->direction_output = gc->direction_output; |
| 396 | gc->ngpio = MPC8XXX_GPIO_PINS; | ||
| 397 | gc->direction_input = mpc8xxx_gpio_dir_in; | ||
| 398 | 332 | ||
| 399 | if (!devtype) | 333 | if (!devtype) |
| 400 | devtype = &mpc8xxx_gpio_devtype_default; | 334 | devtype = &mpc8xxx_gpio_devtype_default; |
| @@ -405,18 +339,22 @@ static int mpc8xxx_probe(struct platform_device *pdev) · 4 unmodified lines | |||
| 405 | */ | 339 | */ |
| 406 | mpc8xxx_irq_chip.irq_set_type = devtype->irq_set_type; | 340 | mpc8xxx_irq_chip.irq_set_type = devtype->irq_set_type; |
| 407 | 341 | ||
| 408 | gc->direction_output = devtype->gpio_dir_out ?: mpc8xxx_gpio_dir_out; | 342 | if (devtype->gpio_dir_out) |
| 409 | gc->get = devtype->gpio_get ?: mpc8xxx_gpio_get; | 343 | gc->direction_output = devtype->gpio_dir_out; |
| 410 | gc->set = mpc8xxx_gpio_set; | 344 | if (devtype->gpio_get) |
| 411 | gc->set_multiple = mpc8xxx_gpio_set_multiple; | 345 | gc->get = devtype->gpio_get; |
| 346 | |||
| 412 | gc->to_irq = mpc8xxx_gpio_to_irq; | 347 | gc->to_irq = mpc8xxx_gpio_to_irq; |
| 413 | 348 | ||
| 414 | ret = of_mm_gpiochip_add_data(np, mm_gc, mpc8xxx_gc); | 349 | ret = gpiochip_add_data(gc, mpc8xxx_gc); |
| 415 | if (ret) | 350 | if (ret) { |
| 416 | return ret; | 351 | pr_err("%s: GPIO chip registration failed with status %d\n", |
| 352 | np->full_name, ret); | ||
| 353 | goto err; | ||
| 354 | } | ||
| 417 | 355 | ||
| 418 | mpc8xxx_gc->irqn = irq_of_parse_and_map(np, 0); | 356 | mpc8xxx_gc->irqn = irq_of_parse_and_map(np, 0); |
| 419 | if (mpc8xxx_gc->irqn == NO_IRQ) | 357 | if (!mpc8xxx_gc->irqn) |
| 420 | return 0; | 358 | return 0; |
| 421 | 359 | ||
| 422 | mpc8xxx_gc->irq = irq_domain_add_linear(np, MPC8XXX_GPIO_PINS, | 360 | mpc8xxx_gc->irq = irq_domain_add_linear(np, MPC8XXX_GPIO_PINS, |
| @@ -424,18 +362,16 @@ static int mpc8xxx_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 424 | if (!mpc8xxx_gc->irq) | 362 | if (!mpc8xxx_gc->irq) |
| 425 | return 0; | 363 | return 0; |
| 426 | 364 | ||
| 427 | id = of_match_node(mpc8xxx_gpio_ids, np); | ||
| 428 | if (id) | ||
| 429 | mpc8xxx_gc->of_dev_id_data = id->data; | ||
| 430 | |||
| 431 | /* ack and mask all irqs */ | 365 | /* ack and mask all irqs */ |
| 432 | out_be32(mm_gc->regs + GPIO_IER, 0xffffffff); | 366 | gc->write_reg(mpc8xxx_gc->regs + GPIO_IER, 0xffffffff); |
| 433 | out_be32(mm_gc->regs + GPIO_IMR, 0); | 367 | gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR, 0); |
| 434 | 368 | ||
| 435 | irq_set_chained_handler_and_data(mpc8xxx_gc->irqn, | 369 | irq_set_chained_handler_and_data(mpc8xxx_gc->irqn, |
| 436 | mpc8xxx_gpio_irq_cascade, mpc8xxx_gc); | 370 | mpc8xxx_gpio_irq_cascade, mpc8xxx_gc); |
| 437 | |||
| 438 | return 0; | 371 | return 0; |
| 372 | err: | ||
| 373 | iounmap(mpc8xxx_gc->regs); | ||
| 374 | return ret; | ||
| 439 | } | 375 | } |
| 440 | 376 | ||
| 441 | static int mpc8xxx_remove(struct platform_device *pdev) | 377 | static int mpc8xxx_remove(struct platform_device *pdev) |
| @@ -447,7 +383,8 @@ static int mpc8xxx_remove(struct platform_device *pdev) · 5 unmodified lines | |||
| 447 | irq_domain_remove(mpc8xxx_gc->irq); | 383 | irq_domain_remove(mpc8xxx_gc->irq); |
| 448 | } | 384 | } |
| 449 | 385 | ||
| 450 | of_mm_gpiochip_remove(&mpc8xxx_gc->mm_gc); | 386 | gpiochip_remove(&mpc8xxx_gc->gc); |
| 387 | iounmap(mpc8xxx_gc->regs); | ||
| 451 | 388 | ||
| 452 | return 0; | 389 | return 0; |
| 453 | } | 390 | } |
| @@ -756,7 +756,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev) · 755 unmodified lines | |||
| 756 | BUG(); | 756 | BUG(); |
| 757 | } | 757 | } |
| 758 | 758 | ||
| 759 | gpiochip_add_data(&mvchip->chip, mvchip); | 759 | devm_gpiochip_add_data(&pdev->dev, &mvchip->chip, mvchip); |
| 760 | 760 | ||
| 761 | /* Some gpio controllers do not provide irq support */ | 761 | /* Some gpio controllers do not provide irq support */ |
| 762 | if (!of_irq_count(np)) | 762 | if (!of_irq_count(np)) |
| @@ -777,16 +777,14 @@ static int mvebu_gpio_probe(struct platform_device *pdev) · 14 unmodified lines | |||
| 777 | mvchip->irqbase = irq_alloc_descs(-1, 0, ngpios, -1); | 777 | mvchip->irqbase = irq_alloc_descs(-1, 0, ngpios, -1); |
| 778 | if (mvchip->irqbase < 0) { | 778 | if (mvchip->irqbase < 0) { |
| 779 | dev_err(&pdev->dev, "no irqs\n"); | 779 | dev_err(&pdev->dev, "no irqs\n"); |
| 780 | err = mvchip->irqbase; | 780 | return mvchip->irqbase; |
| 781 | goto err_gpiochip_add; | ||
| 782 | } | 781 | } |
| 783 | 782 | ||
| 784 | gc = irq_alloc_generic_chip("mvebu_gpio_irq", 2, mvchip->irqbase, | 783 | gc = irq_alloc_generic_chip("mvebu_gpio_irq", 2, mvchip->irqbase, |
| 785 | mvchip->membase, handle_level_irq); | 784 | mvchip->membase, handle_level_irq); |
| 786 | if (!gc) { | 785 | if (!gc) { |
| 787 | dev_err(&pdev->dev, "Cannot allocate generic irq_chip\n"); | 786 | dev_err(&pdev->dev, "Cannot allocate generic irq_chip\n"); |
| 788 | err = -ENOMEM; | 787 | return -ENOMEM; |
| 789 | goto err_gpiochip_add; | ||
| 790 | } | 788 | } |
| 791 | 789 | ||
| 792 | gc->private = mvchip; | 790 | gc->private = mvchip; |
| @@ -828,9 +826,6 @@ err_generic_chip: · 35 unmodified lines | |||
| 828 | IRQ_LEVEL | IRQ_NOPROBE); | 826 | IRQ_LEVEL | IRQ_NOPROBE); |
| 829 | kfree(gc); | 827 | kfree(gc); |
| 830 | 828 | ||
| 831 | err_gpiochip_add: | ||
| 832 | gpiochip_remove(&mvchip->chip); | ||
| 833 | |||
| 834 | return err; | 829 | return err; |
| 835 | } | 830 | } |
| 836 | 831 | ||
| @@ -462,14 +462,14 @@ static int mxc_gpio_probe(struct platform_device *pdev) · 461 unmodified lines | |||
| 462 | port->gc.base = (pdev->id < 0) ? of_alias_get_id(np, "gpio") * 32 : | 462 | port->gc.base = (pdev->id < 0) ? of_alias_get_id(np, "gpio") * 32 : |
| 463 | pdev->id * 32; | 463 | pdev->id * 32; |
| 464 | 464 | ||
| 465 | err = gpiochip_add_data(&port->gc, port); | 465 | err = devm_gpiochip_add_data(&pdev->dev, &port->gc, port); |
| 466 | if (err) | 466 | if (err) |
| 467 | goto out_bgio; | 467 | goto out_bgio; |
| 468 | 468 | ||
| 469 | irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id()); | 469 | irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id()); |
| 470 | if (irq_base < 0) { | 470 | if (irq_base < 0) { |
| 471 | err = irq_base; | 471 | err = irq_base; |
| 472 | goto out_gpiochip_remove; | 472 | goto out_bgio; |
| 473 | } | 473 | } |
| 474 | 474 | ||
| 475 | port->domain = irq_domain_add_legacy(np, 32, irq_base, 0, | 475 | port->domain = irq_domain_add_legacy(np, 32, irq_base, 0, |
| @@ -492,8 +492,6 @@ out_irqdomain_remove: · 16 unmodified lines | |||
| 492 | irq_domain_remove(port->domain); | 492 | irq_domain_remove(port->domain); |
| 493 | out_irqdesc_free: | 493 | out_irqdesc_free: |
| 494 | irq_free_descs(irq_base, 32); | 494 | irq_free_descs(irq_base, 32); |
| 495 | out_gpiochip_remove: | ||
| 496 | gpiochip_remove(&port->gc); | ||
| 497 | out_bgio: | 495 | out_bgio: |
| 498 | dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, err); | 496 | dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, err); |
| 499 | return err; | 497 | return err; |
| @@ -117,7 +117,7 @@ static int octeon_gpio_probe(struct platform_device *pdev) · 116 unmodified lines | |||
| 117 | chip->get = octeon_gpio_get; | 117 | chip->get = octeon_gpio_get; |
| 118 | chip->direction_output = octeon_gpio_dir_out; | 118 | chip->direction_output = octeon_gpio_dir_out; |
| 119 | chip->set = octeon_gpio_set; | 119 | chip->set = octeon_gpio_set; |
| 120 | err = gpiochip_add_data(chip, gpio); | 120 | err = devm_gpiochip_add_data(&pdev->dev, chip, gpio); |
| 121 | if (err) | 121 | if (err) |
| 122 | goto out; | 122 | goto out; |
| 123 | 123 | ||
| @@ -126,13 +126,6 @@ out: · 2 unmodified lines | |||
| 126 | return err; | 126 | return err; |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | static int octeon_gpio_remove(struct platform_device *pdev) | ||
| 130 | { | ||
| 131 | struct gpio_chip *chip = dev_get_platdata(&pdev->dev); | ||
| 132 | gpiochip_remove(chip); | ||
| 133 | return 0; | ||
| 134 | } | ||
| 135 | |||
| 136 | static struct of_device_id octeon_gpio_match[] = { | 129 | static struct of_device_id octeon_gpio_match[] = { |
| 137 | { | 130 | { |
| 138 | .compatible = "cavium,octeon-3860-gpio", | 131 | .compatible = "cavium,octeon-3860-gpio", |
| @@ -147,7 +140,6 @@ static struct platform_driver octeon_gpio_driver = { · 8 unmodified lines | |||
| 147 | .of_match_table = octeon_gpio_match, | 140 | .of_match_table = octeon_gpio_match, |
| 148 | }, | 141 | }, |
| 149 | .probe = octeon_gpio_probe, | 142 | .probe = octeon_gpio_probe, |
| 150 | .remove = octeon_gpio_remove, | ||
| 151 | }; | 143 | }; |
| 152 | 144 | ||
| 153 | module_platform_driver(octeon_gpio_driver); | 145 | module_platform_driver(octeon_gpio_driver); |
| @@ -66,7 +66,6 @@ struct gpio_bank { · 65 unmodified lines | |||
| 66 | u32 irq_usage; | 66 | u32 irq_usage; |
| 67 | u32 dbck_enable_mask; | 67 | u32 dbck_enable_mask; |
| 68 | bool dbck_enabled; | 68 | bool dbck_enabled; |
| 69 | struct device *dev; | ||
| 70 | bool is_mpuio; | 69 | bool is_mpuio; |
| 71 | bool dbck_flag; | 70 | bool dbck_flag; |
| 72 | bool loses_context; | 71 | bool loses_context; |
| @@ -627,7 +626,7 @@ static int omap_set_gpio_wakeup(struct gpio_bank *bank, unsigned offset, · 554 unmodified lines | |||
| 627 | unsigned long flags; | 626 | unsigned long flags; |
| 628 | 627 | ||
| 629 | if (bank->non_wakeup_gpios & gpio_bit) { | 628 | if (bank->non_wakeup_gpios & gpio_bit) { |
| 630 | dev_err(bank->dev, | 629 | dev_err(bank->chip.parent, |
| 631 | "Unable to modify wakeup on non-wakeup GPIO%d\n", | 630 | "Unable to modify wakeup on non-wakeup GPIO%d\n", |
| 632 | offset); | 631 | offset); |
| 633 | return -EINVAL; | 632 | return -EINVAL; |
| @@ -669,7 +668,7 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) · 35 unmodified lines | |||
| 669 | * enable the bank module. | 668 | * enable the bank module. |
| 670 | */ | 669 | */ |
| 671 | if (!BANK_USED(bank)) | 670 | if (!BANK_USED(bank)) |
| 672 | pm_runtime_get_sync(bank->dev); | 671 | pm_runtime_get_sync(chip->parent); |
| 673 | 672 | ||
| 674 | raw_spin_lock_irqsave(&bank->lock, flags); | 673 | raw_spin_lock_irqsave(&bank->lock, flags); |
| 675 | omap_enable_gpio_module(bank, offset); | 674 | omap_enable_gpio_module(bank, offset); |
| @@ -698,7 +697,7 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) · 22 unmodified lines | |||
| 698 | * disable the bank module. | 697 | * disable the bank module. |
| 699 | */ | 698 | */ |
| 700 | if (!BANK_USED(bank)) | 699 | if (!BANK_USED(bank)) |
| 701 | pm_runtime_put(bank->dev); | 700 | pm_runtime_put(chip->parent); |
| 702 | } | 701 | } |
| 703 | 702 | ||
| 704 | /* | 703 | /* |
| @@ -723,7 +722,7 @@ static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank) · 18 unmodified lines | |||
| 723 | if (WARN_ON(!isr_reg)) | 722 | if (WARN_ON(!isr_reg)) |
| 724 | goto exit; | 723 | goto exit; |
| 725 | 724 | ||
| 726 | pm_runtime_get_sync(bank->dev); | 725 | pm_runtime_get_sync(bank->chip.parent); |
| 727 | 726 | ||
| 728 | while (1) { | 727 | while (1) { |
| 729 | u32 isr_saved, level_mask = 0; | 728 | u32 isr_saved, level_mask = 0; |
| @@ -776,7 +775,7 @@ static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank) · 46 unmodified lines | |||
| 776 | } | 775 | } |
| 777 | } | 776 | } |
| 778 | exit: | 777 | exit: |
| 779 | pm_runtime_put(bank->dev); | 778 | pm_runtime_put(bank->chip.parent); |
| 780 | return IRQ_HANDLED; | 779 | return IRQ_HANDLED; |
| 781 | } | 780 | } |
| 782 | 781 | ||
| @@ -826,7 +825,7 @@ static void omap_gpio_irq_bus_lock(struct irq_data *data) · 43 unmodified lines | |||
| 826 | struct gpio_bank *bank = omap_irq_data_get_bank(data); | 825 | struct gpio_bank *bank = omap_irq_data_get_bank(data); |
| 827 | 826 | ||
| 828 | if (!BANK_USED(bank)) | 827 | if (!BANK_USED(bank)) |
| 829 | pm_runtime_get_sync(bank->dev); | 828 | pm_runtime_get_sync(bank->chip.parent); |
| 830 | } | 829 | } |
| 831 | 830 | ||
| 832 | static void gpio_irq_bus_sync_unlock(struct irq_data *data) | 831 | static void gpio_irq_bus_sync_unlock(struct irq_data *data) |
| @@ -838,7 +837,7 @@ static void gpio_irq_bus_sync_unlock(struct irq_data *data) · 5 unmodified lines | |||
| 838 | * disable the bank module. | 837 | * disable the bank module. |
| 839 | */ | 838 | */ |
| 840 | if (!BANK_USED(bank)) | 839 | if (!BANK_USED(bank)) |
| 841 | pm_runtime_put(bank->dev); | 840 | pm_runtime_put(bank->chip.parent); |
| 842 | } | 841 | } |
| 843 | 842 | ||
| 844 | static void omap_gpio_ack_irq(struct irq_data *d) | 843 | static void omap_gpio_ack_irq(struct irq_data *d) |
| @@ -1100,7 +1099,8 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc) · 255 unmodified lines | |||
| 1100 | 1099 | ||
| 1101 | ret = gpiochip_add_data(&bank->chip, bank); | 1100 | ret = gpiochip_add_data(&bank->chip, bank); |
| 1102 | if (ret) { | 1101 | if (ret) { |
| 1103 | dev_err(bank->dev, "Could not register gpio chip %d\n", ret); | 1102 | dev_err(bank->chip.parent, |
| 1103 | "Could not register gpio chip %d\n", ret); | ||
| 1104 | return ret; | 1104 | return ret; |
| 1105 | } | 1105 | } |
| 1106 | 1106 | ||
| @@ -1114,7 +1114,7 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc) · 7 unmodified lines | |||
| 1114 | */ | 1114 | */ |
| 1115 | irq_base = irq_alloc_descs(-1, 0, bank->width, 0); | 1115 | irq_base = irq_alloc_descs(-1, 0, bank->width, 0); |
| 1116 | if (irq_base < 0) { | 1116 | if (irq_base < 0) { |
| 1117 | dev_err(bank->dev, "Couldn't allocate IRQ numbers\n"); | 1117 | dev_err(bank->chip.parent, "Couldn't allocate IRQ numbers\n"); |
| 1118 | return -ENODEV; | 1118 | return -ENODEV; |
| 1119 | } | 1119 | } |
| 1120 | #endif | 1120 | #endif |
| @@ -1131,15 +1131,17 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc) · 10 unmodified lines | |||
| 1131 | IRQ_TYPE_NONE); | 1131 | IRQ_TYPE_NONE); |
| 1132 | 1132 | ||
| 1133 | if (ret) { | 1133 | if (ret) { |
| 1134 | dev_err(bank->dev, "Couldn't add irqchip to gpiochip %d\n", ret); | 1134 | dev_err(bank->chip.parent, |
| 1135 | "Couldn't add irqchip to gpiochip %d\n", ret); | ||
| 1135 | gpiochip_remove(&bank->chip); | 1136 | gpiochip_remove(&bank->chip); |
| 1136 | return -ENODEV; | 1137 | return -ENODEV; |
| 1137 | } | 1138 | } |
| 1138 | 1139 | ||
| 1139 | gpiochip_set_chained_irqchip(&bank->chip, irqc, bank->irq, NULL); | 1140 | gpiochip_set_chained_irqchip(&bank->chip, irqc, bank->irq, NULL); |
| 1140 | 1141 | ||
| 1141 | ret = devm_request_irq(bank->dev, bank->irq, omap_gpio_irq_handler, | 1142 | ret = devm_request_irq(bank->chip.parent, bank->irq, |
| 1142 | 0, dev_name(bank->dev), bank); | 1143 | omap_gpio_irq_handler, |
| 1144 | 0, dev_name(bank->chip.parent), bank); | ||
| 1143 | if (ret) | 1145 | if (ret) |
| 1144 | gpiochip_remove(&bank->chip); | 1146 | gpiochip_remove(&bank->chip); |
| 1145 | 1147 | ||
| @@ -1196,7 +1198,6 @@ static int omap_gpio_probe(struct platform_device *pdev) · 50 unmodified lines | |||
| 1196 | return bank->irq; | 1198 | return bank->irq; |
| 1197 | } | 1199 | } |
| 1198 | 1200 | ||
| 1199 | bank->dev = dev; | ||
| 1200 | bank->chip.parent = dev; | 1201 | bank->chip.parent = dev; |
| 1201 | bank->chip.owner = THIS_MODULE; | 1202 | bank->chip.owner = THIS_MODULE; |
| 1202 | bank->dbck_flag = pdata->dbck_flag; | 1203 | bank->dbck_flag = pdata->dbck_flag; |
| @@ -1235,9 +1236,9 @@ static int omap_gpio_probe(struct platform_device *pdev) · 32 unmodified lines | |||
| 1235 | } | 1236 | } |
| 1236 | 1237 | ||
| 1237 | if (bank->dbck_flag) { | 1238 | if (bank->dbck_flag) { |
| 1238 | bank->dbck = devm_clk_get(bank->dev, "dbclk"); | 1239 | bank->dbck = devm_clk_get(dev, "dbclk"); |
| 1239 | if (IS_ERR(bank->dbck)) { | 1240 | if (IS_ERR(bank->dbck)) { |
| 1240 | dev_err(bank->dev, | 1241 | dev_err(dev, |
| 1241 | "Could not get gpio dbck. Disable debounce\n"); | 1242 | "Could not get gpio dbck. Disable debounce\n"); |
| 1242 | bank->dbck_flag = false; | 1243 | bank->dbck_flag = false; |
| 1243 | } else { | 1244 | } else { |
| @@ -1247,9 +1248,9 @@ static int omap_gpio_probe(struct platform_device *pdev) · 3 unmodified lines | |||
| 1247 | 1248 | ||
| 1248 | platform_set_drvdata(pdev, bank); | 1249 | platform_set_drvdata(pdev, bank); |
| 1249 | 1250 | ||
| 1250 | pm_runtime_enable(bank->dev); | 1251 | pm_runtime_enable(dev); |
| 1251 | pm_runtime_irq_safe(bank->dev); | 1252 | pm_runtime_irq_safe(dev); |
| 1252 | pm_runtime_get_sync(bank->dev); | 1253 | pm_runtime_get_sync(dev); |
| 1253 | 1254 | ||
| 1254 | if (bank->is_mpuio) | 1255 | if (bank->is_mpuio) |
| 1255 | omap_mpuio_init(bank); | 1256 | omap_mpuio_init(bank); |
| @@ -1258,14 +1259,14 @@ static int omap_gpio_probe(struct platform_device *pdev) · 2 unmodified lines | |||
| 1258 | 1259 | ||
| 1259 | ret = omap_gpio_chip_init(bank, irqc); | 1260 | ret = omap_gpio_chip_init(bank, irqc); |
| 1260 | if (ret) { | 1261 | if (ret) { |
| 1261 | pm_runtime_put_sync(bank->dev); | 1262 | pm_runtime_put_sync(dev); |
| 1262 | pm_runtime_disable(bank->dev); | 1263 | pm_runtime_disable(dev); |
| 1263 | return ret; | 1264 | return ret; |
| 1264 | } | 1265 | } |
| 1265 | 1266 | ||
| 1266 | omap_gpio_show_rev(bank); | 1267 | omap_gpio_show_rev(bank); |
| 1267 | 1268 | ||
| 1268 | pm_runtime_put(bank->dev); | 1269 | pm_runtime_put(dev); |
| 1269 | 1270 | ||
| 1270 | list_add_tail(&bank->node, &omap_gpio_list); | 1271 | list_add_tail(&bank->node, &omap_gpio_list); |
| 1271 | 1272 | ||
| @@ -1278,7 +1279,7 @@ static int omap_gpio_remove(struct platform_device *pdev) · 6 unmodified lines | |||
| 1278 | 1279 | ||
| 1279 | list_del(&bank->node); | 1280 | list_del(&bank->node); |
| 1280 | gpiochip_remove(&bank->chip); | 1281 | gpiochip_remove(&bank->chip); |
| 1281 | pm_runtime_disable(bank->dev); | 1282 | pm_runtime_disable(&pdev->dev); |
| 1282 | if (bank->dbck_flag) | 1283 | if (bank->dbck_flag) |
| 1283 | clk_unprepare(bank->dbck); | 1284 | clk_unprepare(bank->dbck); |
| 1284 | 1285 | ||
| @@ -1348,7 +1349,7 @@ static int omap_gpio_runtime_suspend(struct device *dev) · 63 unmodified lines | |||
| 1348 | update_gpio_context_count: | 1349 | update_gpio_context_count: |
| 1349 | if (bank->get_context_loss_count) | 1350 | if (bank->get_context_loss_count) |
| 1350 | bank->context_loss_count = | 1351 | bank->context_loss_count = |
| 1351 | bank->get_context_loss_count(bank->dev); | 1352 | bank->get_context_loss_count(dev); |
| 1352 | 1353 | ||
| 1353 | omap_gpio_dbck_disable(bank); | 1354 | omap_gpio_dbck_disable(bank); |
| 1354 | raw_spin_unlock_irqrestore(&bank->lock, flags); | 1355 | raw_spin_unlock_irqrestore(&bank->lock, flags); |
| @@ -1378,7 +1379,7 @@ static int omap_gpio_runtime_resume(struct device *dev) · 23 unmodified lines | |||
| 1378 | 1379 | ||
| 1379 | if (bank->get_context_loss_count) | 1380 | if (bank->get_context_loss_count) |
| 1380 | bank->context_loss_count = | 1381 | bank->context_loss_count = |
| 1381 | bank->get_context_loss_count(bank->dev); | 1382 | bank->get_context_loss_count(dev); |
| 1382 | } | 1383 | } |
| 1383 | 1384 | ||
| 1384 | omap_gpio_dbck_enable(bank); | 1385 | omap_gpio_dbck_enable(bank); |
| @@ -1398,7 +1399,7 @@ static int omap_gpio_runtime_resume(struct device *dev) · 13 unmodified lines | |||
| 1398 | if (!bank->get_context_loss_count) { | 1399 | if (!bank->get_context_loss_count) { |
| 1399 | omap_gpio_restore_context(bank); | 1400 | omap_gpio_restore_context(bank); |
| 1400 | } else { | 1401 | } else { |
| 1401 | c = bank->get_context_loss_count(bank->dev); | 1402 | c = bank->get_context_loss_count(dev); |
| 1402 | if (c != bank->context_loss_count) { | 1403 | if (c != bank->context_loss_count) { |
| 1403 | omap_gpio_restore_context(bank); | 1404 | omap_gpio_restore_context(bank); |
| 1404 | } else { | 1405 | } else { |
| @@ -1481,7 +1482,7 @@ void omap2_gpio_prepare_for_idle(int pwr_mode) · 76 unmodified lines | |||
| 1481 | 1482 | ||
| 1482 | bank->power_mode = pwr_mode; | 1483 | bank->power_mode = pwr_mode; |
| 1483 | 1484 | ||
| 1484 | pm_runtime_put_sync_suspend(bank->dev); | 1485 | pm_runtime_put_sync_suspend(bank->chip.parent); |
| 1485 | } | 1486 | } |
| 1486 | } | 1487 | } |
| 1487 | 1488 | ||
| @@ -1493,7 +1494,7 @@ void omap2_gpio_resume_after_idle(void) · 5 unmodified lines | |||
| 1493 | if (!BANK_USED(bank) || !bank->loses_context) | 1494 | if (!BANK_USED(bank) || !bank->loses_context) |
| 1494 | continue; | 1495 | continue; |
| 1495 | 1496 | ||
| 1496 | pm_runtime_get_sync(bank->dev); | 1497 | pm_runtime_get_sync(bank->chip.parent); |
| 1497 | } | 1498 | } |
| 1498 | } | 1499 | } |
| 1499 | #endif | 1500 | #endif |
| @@ -195,7 +195,8 @@ static int palmas_gpio_probe(struct platform_device *pdev) · 194 unmodified lines | |||
| 195 | else | 195 | else |
| 196 | palmas_gpio->gpio_chip.base = -1; | 196 | palmas_gpio->gpio_chip.base = -1; |
| 197 | 197 | ||
| 198 | ret = gpiochip_add_data(&palmas_gpio->gpio_chip, palmas_gpio); | 198 | ret = devm_gpiochip_add_data(&pdev->dev, &palmas_gpio->gpio_chip, |
| 199 | palmas_gpio); | ||
| 199 | if (ret < 0) { | 200 | if (ret < 0) { |
| 200 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); | 201 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); |
| 201 | return ret; | 202 | return ret; |
| @@ -205,20 +206,11 @@ static int palmas_gpio_probe(struct platform_device *pdev) · 3 unmodified lines | |||
| 205 | return ret; | 206 | return ret; |
| 206 | } | 207 | } |
| 207 | 208 | ||
| 208 | static int palmas_gpio_remove(struct platform_device *pdev) | ||
| 209 | { | ||
| 210 | struct palmas_gpio *palmas_gpio = platform_get_drvdata(pdev); | ||
| 211 | |||
| 212 | gpiochip_remove(&palmas_gpio->gpio_chip); | ||
| 213 | return 0; | ||
| 214 | } | ||
| 215 | |||
| 216 | static struct platform_driver palmas_gpio_driver = { | 209 | static struct platform_driver palmas_gpio_driver = { |
| 217 | .driver.name = "palmas-gpio", | 210 | .driver.name = "palmas-gpio", |
| 218 | .driver.owner = THIS_MODULE, | 211 | .driver.owner = THIS_MODULE, |
| 219 | .driver.of_match_table = of_palmas_gpio_match, | 212 | .driver.of_match_table = of_palmas_gpio_match, |
| 220 | .probe = palmas_gpio_probe, | 213 | .probe = palmas_gpio_probe, |
| 221 | .remove = palmas_gpio_remove, | ||
| 222 | }; | 214 | }; |
| 223 | 215 | ||
| 224 | static int __init palmas_gpio_init(void) | 216 | static int __init palmas_gpio_init(void) |
| @@ -367,9 +367,11 @@ static void pca953x_gpio_set_multiple(struct gpio_chip *gc, · 366 unmodified lines | |||
| 367 | memcpy(reg_val, chip->reg_output, NBANK(chip)); | 367 | memcpy(reg_val, chip->reg_output, NBANK(chip)); |
| 368 | mutex_lock(&chip->i2c_lock); | 368 | mutex_lock(&chip->i2c_lock); |
| 369 | for(bank=0; bank<NBANK(chip); bank++) { | 369 | for(bank=0; bank<NBANK(chip); bank++) { |
| 370 | unsigned bankmask = mask[bank/4] >> ((bank % 4) * 8); | 370 | unsigned bankmask = mask[bank / sizeof(*mask)] >> |
| 371 | ((bank % sizeof(*mask)) * 8); | ||
| 371 | if(bankmask) { | 372 | if(bankmask) { |
| 372 | unsigned bankval = bits[bank/4] >> ((bank % 4) * 8); | 373 | unsigned bankval = bits[bank / sizeof(*bits)] >> |
| 374 | ((bank % sizeof(*bits)) * 8); | ||
| 373 | reg_val[bank] = (reg_val[bank] & ~bankmask) | bankval; | 375 | reg_val[bank] = (reg_val[bank] & ~bankmask) | bankval; |
| 374 | } | 376 | } |
| 375 | } | 377 | } |
| @@ -754,7 +756,7 @@ static int pca953x_probe(struct i2c_client *client, · 378 unmodified lines | |||
| 754 | if (ret) | 756 | if (ret) |
| 755 | return ret; | 757 | return ret; |
| 756 | 758 | ||
| 757 | ret = gpiochip_add_data(&chip->gpio_chip, chip); | 759 | ret = devm_gpiochip_add_data(&client->dev, &chip->gpio_chip, chip); |
| 758 | if (ret) | 760 | if (ret) |
| 759 | return ret; | 761 | return ret; |
| 760 | 762 | ||
| @@ -789,8 +791,6 @@ static int pca953x_remove(struct i2c_client *client) · 28 unmodified lines | |||
| 789 | } | 791 | } |
| 790 | } | 792 | } |
| 791 | 793 | ||
| 792 | gpiochip_remove(&chip->gpio_chip); | ||
| 793 | |||
| 794 | return 0; | 794 | return 0; |
| 795 | } | 795 | } |
| 796 | 796 | ||
| @@ -372,7 +372,7 @@ static int pcf857x_probe(struct i2c_client *client, · 371 unmodified lines | |||
| 372 | gpio->out = ~n_latch; | 372 | gpio->out = ~n_latch; |
| 373 | gpio->status = gpio->out; | 373 | gpio->status = gpio->out; |
| 374 | 374 | ||
| 375 | status = gpiochip_add_data(&gpio->chip, gpio); | 375 | status = devm_gpiochip_add_data(&client->dev, &gpio->chip, gpio); |
| 376 | if (status < 0) | 376 | if (status < 0) |
| 377 | goto fail; | 377 | goto fail; |
| 378 | 378 | ||
| @@ -383,7 +383,7 @@ static int pcf857x_probe(struct i2c_client *client, · 4 unmodified lines | |||
| 383 | IRQ_TYPE_NONE); | 383 | IRQ_TYPE_NONE); |
| 384 | if (status) { | 384 | if (status) { |
| 385 | dev_err(&client->dev, "cannot add irqchip\n"); | 385 | dev_err(&client->dev, "cannot add irqchip\n"); |
| 386 | goto fail_irq; | 386 | goto fail; |
| 387 | } | 387 | } |
| 388 | 388 | ||
| 389 | status = devm_request_threaded_irq(&client->dev, client->irq, | 389 | status = devm_request_threaded_irq(&client->dev, client->irq, |
| @@ -391,7 +391,7 @@ static int pcf857x_probe(struct i2c_client *client, · 1 unmodified line | |||
| 391 | IRQF_TRIGGER_FALLING | IRQF_SHARED, | 391 | IRQF_TRIGGER_FALLING | IRQF_SHARED, |
| 392 | dev_name(&client->dev), gpio); | 392 | dev_name(&client->dev), gpio); |
| 393 | if (status) | 393 | if (status) |
| 394 | goto fail_irq; | 394 | goto fail; |
| 395 | 395 | ||
| 396 | gpiochip_set_chained_irqchip(&gpio->chip, &pcf857x_irq_chip, | 396 | gpiochip_set_chained_irqchip(&gpio->chip, &pcf857x_irq_chip, |
| 397 | client->irq, NULL); | 397 | client->irq, NULL); |
| @@ -413,9 +413,6 @@ static int pcf857x_probe(struct i2c_client *client, · 15 unmodified lines | |||
| 413 | 413 | ||
| 414 | return 0; | 414 | return 0; |
| 415 | 415 | ||
| 416 | fail_irq: | ||
| 417 | gpiochip_remove(&gpio->chip); | ||
| 418 | |||
| 419 | fail: | 416 | fail: |
| 420 | dev_dbg(&client->dev, "probe error %d for '%s'\n", status, | 417 | dev_dbg(&client->dev, "probe error %d for '%s'\n", status, |
| 421 | client->name); | 418 | client->name); |
| @@ -440,7 +437,6 @@ static int pcf857x_remove(struct i2c_client *client) · 18 unmodified lines | |||
| 440 | } | 437 | } |
| 441 | } | 438 | } |
| 442 | 439 | ||
| 443 | gpiochip_remove(&gpio->chip); | ||
| 444 | return status; | 440 | return status; |
| 445 | } | 441 | } |
| 446 | 442 | ||
| @@ -0,0 +1,183 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ | ||
| 3 | * Andrew F. Davis <afd@ti.com> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or | ||
| 6 | * modify it under the terms of the GNU General Public License version 2 as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
| 10 | * kind, whether expressed or implied; without even the implied warranty | ||
| 11 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License version 2 for more details. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/delay.h> | ||
| 16 | #include <linux/gpio/consumer.h> | ||
| 17 | #include <linux/gpio/driver.h> | ||
| 18 | #include <linux/module.h> | ||
| 19 | #include <linux/mutex.h> | ||
| 20 | #include <linux/spi/spi.h> | ||
| 21 | |||
| 22 | #define DEFAULT_NGPIO 8 | ||
| 23 | |||
| 24 | /** | ||
| 25 | * struct pisosr_gpio - GPIO driver data | ||
| 26 | * @chip: GPIO controller chip | ||
| 27 | * @spi: SPI device pointer | ||
| 28 | * @buffer: Buffer for device reads | ||
| 29 | * @buffer_size: Size of buffer | ||
| 30 | * @load_gpio: GPIO pin used to load input into device | ||
| 31 | * @lock: Protects read sequences | ||
| 32 | */ | ||
| 33 | struct pisosr_gpio { | ||
| 34 | struct gpio_chip chip; | ||
| 35 | struct spi_device *spi; | ||
| 36 | u8 *buffer; | ||
| 37 | size_t buffer_size; | ||
| 38 | struct gpio_desc *load_gpio; | ||
| 39 | struct mutex lock; | ||
| 40 | }; | ||
| 41 | |||
| 42 | static int pisosr_gpio_refresh(struct pisosr_gpio *gpio) | ||
| 43 | { | ||
| 44 | int ret; | ||
| 45 | |||
| 46 | mutex_lock(&gpio->lock); | ||
| 47 | |||
| 48 | if (gpio->load_gpio) { | ||
| 49 | gpiod_set_value_cansleep(gpio->load_gpio, 1); | ||
| 50 | udelay(1); /* registers load time (~10ns) */ | ||
| 51 | gpiod_set_value_cansleep(gpio->load_gpio, 0); | ||
| 52 | udelay(1); /* registers recovery time (~5ns) */ | ||
| 53 | } | ||
| 54 | |||
| 55 | ret = spi_read(gpio->spi, gpio->buffer, gpio->buffer_size); | ||
| 56 | |||
| 57 | mutex_unlock(&gpio->lock); | ||
| 58 | |||
| 59 | return ret; | ||
| 60 | } | ||
| 61 | |||
| 62 | static int pisosr_gpio_get_direction(struct gpio_chip *chip, | ||
| 63 | unsigned offset) | ||
| 64 | { | ||
| 65 | /* This device always input */ | ||
| 66 | return 1; | ||
| 67 | } | ||
| 68 | |||
| 69 | static int pisosr_gpio_direction_input(struct gpio_chip *chip, | ||
| 70 | unsigned offset) | ||
| 71 | { | ||
| 72 | /* This device always input */ | ||
| 73 | return 0; | ||
| 74 | } | ||
| 75 | |||
| 76 | static int pisosr_gpio_direction_output(struct gpio_chip *chip, | ||
| 77 | unsigned offset, int value) | ||
| 78 | { | ||
| 79 | /* This device is input only */ | ||
| 80 | return -EINVAL; | ||
| 81 | } | ||
| 82 | |||
| 83 | static int pisosr_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
| 84 | { | ||
| 85 | struct pisosr_gpio *gpio = gpiochip_get_data(chip); | ||
| 86 | |||
| 87 | /* Refresh may not always be needed */ | ||
| 88 | pisosr_gpio_refresh(gpio); | ||
| 89 | |||
| 90 | return (gpio->buffer[offset / 8] >> (offset % 8)) & 0x1; | ||
| 91 | } | ||
| 92 | |||
| 93 | static struct gpio_chip template_chip = { | ||
| 94 | .label = "pisosr-gpio", | ||
| 95 | .owner = THIS_MODULE, | ||
| 96 | .get_direction = pisosr_gpio_get_direction, | ||
| 97 | .direction_input = pisosr_gpio_direction_input, | ||
| 98 | .direction_output = pisosr_gpio_direction_output, | ||
| 99 | .get = pisosr_gpio_get, | ||
| 100 | .base = -1, | ||
| 101 | .ngpio = DEFAULT_NGPIO, | ||
| 102 | .can_sleep = true, | ||
| 103 | }; | ||
| 104 | |||
| 105 | static int pisosr_gpio_probe(struct spi_device *spi) | ||
| 106 | { | ||
| 107 | struct device *dev = &spi->dev; | ||
| 108 | struct pisosr_gpio *gpio; | ||
| 109 | int ret; | ||
| 110 | |||
| 111 | gpio = devm_kzalloc(dev, sizeof(*gpio), GFP_KERNEL); | ||
| 112 | if (!gpio) | ||
| 113 | return -ENOMEM; | ||
| 114 | |||
| 115 | spi_set_drvdata(spi, gpio); | ||
| 116 | |||
| 117 | gpio->chip = template_chip; | ||
| 118 | gpio->chip.parent = dev; | ||
| 119 | of_property_read_u16(dev->of_node, "ngpios", &gpio->chip.ngpio); | ||
| 120 | |||
| 121 | gpio->spi = spi; | ||
| 122 | |||
| 123 | gpio->buffer_size = DIV_ROUND_UP(gpio->chip.ngpio, 8); | ||
| 124 | gpio->buffer = devm_kzalloc(dev, gpio->buffer_size, GFP_KERNEL); | ||
| 125 | if (!gpio->buffer) | ||
| 126 | return -ENOMEM; | ||
| 127 | |||
| 128 | gpio->load_gpio = devm_gpiod_get_optional(dev, "load", GPIOD_OUT_LOW); | ||
| 129 | if (IS_ERR(gpio->load_gpio)) { | ||
| 130 | ret = PTR_ERR(gpio->load_gpio); | ||
| 131 | if (ret != -EPROBE_DEFER) | ||
| 132 | dev_err(dev, "Unable to allocate load GPIO\n"); | ||
| 133 | return ret; | ||
| 134 | } | ||
| 135 | |||
| 136 | mutex_init(&gpio->lock); | ||
| 137 | |||
| 138 | ret = gpiochip_add_data(&gpio->chip, gpio); | ||
| 139 | if (ret < 0) { | ||
| 140 | dev_err(dev, "Unable to register gpiochip\n"); | ||
| 141 | return ret; | ||
| 142 | } | ||
| 143 | |||
| 144 | return 0; | ||
| 145 | } | ||
| 146 | |||
| 147 | static int pisosr_gpio_remove(struct spi_device *spi) | ||
| 148 | { | ||
| 149 | struct pisosr_gpio *gpio = spi_get_drvdata(spi); | ||
| 150 | |||
| 151 | gpiochip_remove(&gpio->chip); | ||
| 152 | |||
| 153 | mutex_destroy(&gpio->lock); | ||
| 154 | |||
| 155 | return 0; | ||
| 156 | } | ||
| 157 | |||
| 158 | static const struct spi_device_id pisosr_gpio_id_table[] = { | ||
| 159 | { "pisosr-gpio", }, | ||
| 160 | { /* sentinel */ } | ||
| 161 | }; | ||
| 162 | MODULE_DEVICE_TABLE(spi, pisosr_gpio_id_table); | ||
| 163 | |||
| 164 | static const struct of_device_id pisosr_gpio_of_match_table[] = { | ||
| 165 | { .compatible = "pisosr-gpio", }, | ||
| 166 | { /* sentinel */ } | ||
| 167 | }; | ||
| 168 | MODULE_DEVICE_TABLE(of, pisosr_gpio_of_match_table); | ||
| 169 | |||
| 170 | static struct spi_driver pisosr_gpio_driver = { | ||
| 171 | .driver = { | ||
| 172 | .name = "pisosr-gpio", | ||
| 173 | .of_match_table = pisosr_gpio_of_match_table, | ||
| 174 | }, | ||
| 175 | .probe = pisosr_gpio_probe, | ||
| 176 | .remove = pisosr_gpio_remove, | ||
| 177 | .id_table = pisosr_gpio_id_table, | ||
| 178 | }; | ||
| 179 | module_spi_driver(pisosr_gpio_driver); | ||
| 180 | |||
| 181 | MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>"); | ||
| 182 | MODULE_DESCRIPTION("SPI Compatible PISO Shift Register GPIO Driver"); | ||
| 183 | MODULE_LICENSE("GPL v2"); | ||
| @@ -136,15 +136,8 @@ static int rc5t583_gpio_probe(struct platform_device *pdev) · 135 unmodified lines | |||
| 136 | 136 | ||
| 137 | platform_set_drvdata(pdev, rc5t583_gpio); | 137 | platform_set_drvdata(pdev, rc5t583_gpio); |
| 138 | 138 | ||
| 139 | return gpiochip_add_data(&rc5t583_gpio->gpio_chip, rc5t583_gpio); | 139 | return devm_gpiochip_add_data(&pdev->dev, &rc5t583_gpio->gpio_chip, |
| 140 | } | 140 | rc5t583_gpio); |
| 141 | |||
| 142 | static int rc5t583_gpio_remove(struct platform_device *pdev) | ||
| 143 | { | ||
| 144 | struct rc5t583_gpio *rc5t583_gpio = platform_get_drvdata(pdev); | ||
| 145 | |||
| 146 | gpiochip_remove(&rc5t583_gpio->gpio_chip); | ||
| 147 | return 0; | ||
| 148 | } | 141 | } |
| 149 | 142 | ||
| 150 | static struct platform_driver rc5t583_gpio_driver = { | 143 | static struct platform_driver rc5t583_gpio_driver = { |
| @@ -152,7 +145,6 @@ static struct platform_driver rc5t583_gpio_driver = { · 1 unmodified line | |||
| 152 | .name = "rc5t583-gpio", | 145 | .name = "rc5t583-gpio", |
| 153 | }, | 146 | }, |
| 154 | .probe = rc5t583_gpio_probe, | 147 | .probe = rc5t583_gpio_probe, |
| 155 | .remove = rc5t583_gpio_remove, | ||
| 156 | }; | 148 | }; |
| 157 | 149 | ||
| 158 | static int __init rc5t583_gpio_init(void) | 150 | static int __init rc5t583_gpio_init(void) |
| @@ -194,23 +194,14 @@ static int rdc321x_gpio_probe(struct platform_device *pdev) · 193 unmodified lines | |||
| 194 | 194 | ||
| 195 | dev_info(&pdev->dev, "registering %d GPIOs\n", | 195 | dev_info(&pdev->dev, "registering %d GPIOs\n", |
| 196 | rdc321x_gpio_dev->chip.ngpio); | 196 | rdc321x_gpio_dev->chip.ngpio); |
| 197 | return gpiochip_add_data(&rdc321x_gpio_dev->chip, rdc321x_gpio_dev); | 197 | return devm_gpiochip_add_data(&pdev->dev, &rdc321x_gpio_dev->chip, |
| 198 | } | 198 | rdc321x_gpio_dev); |
| 199 | |||
| 200 | static int rdc321x_gpio_remove(struct platform_device *pdev) | ||
| 201 | { | ||
| 202 | struct rdc321x_gpio *rdc321x_gpio_dev = platform_get_drvdata(pdev); | ||
| 203 | |||
| 204 | gpiochip_remove(&rdc321x_gpio_dev->chip); | ||
| 205 | |||
| 206 | return 0; | ||
| 207 | } | 199 | } |
| 208 | 200 | ||
| 209 | static struct platform_driver rdc321x_gpio_driver = { | 201 | static struct platform_driver rdc321x_gpio_driver = { |
| 210 | .driver.name = "rdc321x-gpio", | 202 | .driver.name = "rdc321x-gpio", |
| 211 | .driver.owner = THIS_MODULE, | 203 | .driver.owner = THIS_MODULE, |
| 212 | .probe = rdc321x_gpio_probe, | 204 | .probe = rdc321x_gpio_probe, |
| 213 | .remove = rdc321x_gpio_remove, | ||
| 214 | }; | 205 | }; |
| 215 | 206 | ||
| 216 | module_platform_driver(rdc321x_gpio_driver); | 207 | module_platform_driver(rdc321x_gpio_driver); |
| @@ -215,15 +215,7 @@ static int sch_gpio_probe(struct platform_device *pdev) · 214 unmodified lines | |||
| 215 | 215 | ||
| 216 | platform_set_drvdata(pdev, sch); | 216 | platform_set_drvdata(pdev, sch); |
| 217 | 217 | ||
| 218 | return gpiochip_add_data(&sch->chip, sch); | 218 | return devm_gpiochip_add_data(&pdev->dev, &sch->chip, sch); |
| 219 | } | ||
| 220 | |||
| 221 | static int sch_gpio_remove(struct platform_device *pdev) | ||
| 222 | { | ||
| 223 | struct sch_gpio *sch = platform_get_drvdata(pdev); | ||
| 224 | |||
| 225 | gpiochip_remove(&sch->chip); | ||
| 226 | return 0; | ||
| 227 | } | 219 | } |
| 228 | 220 | ||
| 229 | static struct platform_driver sch_gpio_driver = { | 221 | static struct platform_driver sch_gpio_driver = { |
| @@ -231,7 +223,6 @@ static struct platform_driver sch_gpio_driver = { · 1 unmodified line | |||
| 231 | .name = "sch_gpio", | 223 | .name = "sch_gpio", |
| 232 | }, | 224 | }, |
| 233 | .probe = sch_gpio_probe, | 225 | .probe = sch_gpio_probe, |
| 234 | .remove = sch_gpio_remove, | ||
| 235 | }; | 226 | }; |
| 236 | 227 | ||
| 237 | module_platform_driver(sch_gpio_driver); | 228 | module_platform_driver(sch_gpio_driver); |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | |||
| 12 | * (at your option) any later version. | 12 | * (at your option) any later version. |
| 13 | */ | 13 | */ |
| 14 | 14 | ||
| 15 | #include <linux/ioport.h> | ||
| 15 | #include <linux/module.h> | 16 | #include <linux/module.h> |
| 16 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
| 17 | #include <linux/init.h> | 18 | #include <linux/init.h> |
| @@ -228,7 +229,8 @@ static int sch311x_gpio_probe(struct platform_device *pdev) · 210 unmodified lines | |||
| 228 | int err, i; | 229 | int err, i; |
| 229 | 230 | ||
| 230 | /* we can register all GPIO data registers at once */ | 231 | /* we can register all GPIO data registers at once */ |
| 231 | if (!request_region(pdata->runtime_reg + GP1, 6, DRV_NAME)) { | 232 | if (!devm_request_region(&pdev->dev, pdata->runtime_reg + GP1, 6, |
| 233 | DRV_NAME)) { | ||
| 232 | dev_err(&pdev->dev, "Failed to request region 0x%04x-0x%04x.\n", | 234 | dev_err(&pdev->dev, "Failed to request region 0x%04x-0x%04x.\n", |
| 233 | pdata->runtime_reg + GP1, pdata->runtime_reg + GP1 + 5); | 235 | pdata->runtime_reg + GP1, pdata->runtime_reg + GP1 + 5); |
| 234 | return -EBUSY; | 236 | return -EBUSY; |
| @@ -273,7 +275,6 @@ static int sch311x_gpio_probe(struct platform_device *pdev) · 38 unmodified lines | |||
| 273 | return 0; | 275 | return 0; |
| 274 | 276 | ||
| 275 | exit_err: | 277 | exit_err: |
| 276 | release_region(pdata->runtime_reg + GP1, 6); | ||
| 277 | /* release already registered chips */ | 278 | /* release already registered chips */ |
| 278 | for (--i; i >= 0; i--) | 279 | for (--i; i >= 0; i--) |
| 279 | gpiochip_remove(&priv->blocks[i].chip); | 280 | gpiochip_remove(&priv->blocks[i].chip); |
| @@ -282,12 +283,9 @@ exit_err: · 2 unmodified lines | |||
| 282 | 283 | ||
| 283 | static int sch311x_gpio_remove(struct platform_device *pdev) | 284 | static int sch311x_gpio_remove(struct platform_device *pdev) |
| 284 | { | 285 | { |
| 285 | struct sch311x_pdev_data *pdata = dev_get_platdata(&pdev->dev); | ||
| 286 | struct sch311x_gpio_priv *priv = platform_get_drvdata(pdev); | 286 | struct sch311x_gpio_priv *priv = platform_get_drvdata(pdev); |
| 287 | int i; | 287 | int i; |
| 288 | 288 | ||
| 289 | release_region(pdata->runtime_reg + GP1, 6); | ||
| 290 | |||
| 291 | for (i = 0; i < ARRAY_SIZE(priv->blocks); i++) { | 289 | for (i = 0; i < ARRAY_SIZE(priv->blocks); i++) { |
| 292 | gpiochip_remove(&priv->blocks[i].chip); | 290 | gpiochip_remove(&priv->blocks[i].chip); |
| 293 | dev_info(&pdev->dev, | 291 | dev_info(&pdev->dev, |
| @@ -165,7 +165,7 @@ static int spics_gpio_probe(struct platform_device *pdev) · 164 unmodified lines | |||
| 165 | spics->chip.owner = THIS_MODULE; | 165 | spics->chip.owner = THIS_MODULE; |
| 166 | spics->last_off = -1; | 166 | spics->last_off = -1; |
| 167 | 167 | ||
| 168 | ret = gpiochip_add_data(&spics->chip, spics); | 168 | ret = devm_gpiochip_add_data(&pdev->dev, &spics->chip, spics); |
| 169 | if (ret) { | 169 | if (ret) { |
| 170 | dev_err(&pdev->dev, "unable to add gpio chip\n"); | 170 | dev_err(&pdev->dev, "unable to add gpio chip\n"); |
| 171 | return ret; | 171 | return ret; |
| @@ -409,7 +409,7 @@ static int gsta_probe(struct platform_device *dev) · 408 unmodified lines | |||
| 409 | goto err_free_descs; | 409 | goto err_free_descs; |
| 410 | } | 410 | } |
| 411 | 411 | ||
| 412 | err = gpiochip_add_data(&chip->gpio, chip); | 412 | err = devm_gpiochip_add_data(&dev->dev, &chip->gpio, chip); |
| 413 | if (err < 0) { | 413 | if (err < 0) { |
| 414 | dev_err(&dev->dev, "sta2x11 gpio: Can't register (%i)\n", | 414 | dev_err(&dev->dev, "sta2x11 gpio: Can't register (%i)\n", |
| 415 | -err); | 415 | -err); |
| @@ -258,7 +258,7 @@ static int xway_stp_probe(struct platform_device *pdev) · 257 unmodified lines | |||
| 258 | 258 | ||
| 259 | ret = xway_stp_hw_init(chip); | 259 | ret = xway_stp_hw_init(chip); |
| 260 | if (!ret) | 260 | if (!ret) |
| 261 | ret = gpiochip_add_data(&chip->gc, chip); | 261 | ret = devm_gpiochip_add_data(&pdev->dev, &chip->gc, chip); |
| 262 | 262 | ||
| 263 | if (!ret) | 263 | if (!ret) |
| 264 | dev_info(&pdev->dev, "Init done\n"); | 264 | dev_info(&pdev->dev, "Init done\n"); |
| @@ -687,7 +687,7 @@ static int sx150x_probe(struct i2c_client *client, · 686 unmodified lines | |||
| 687 | if (rc < 0) | 687 | if (rc < 0) |
| 688 | return rc; | 688 | return rc; |
| 689 | 689 | ||
| 690 | rc = gpiochip_add_data(&chip->gpio_chip, chip); | 690 | rc = devm_gpiochip_add_data(&client->dev, &chip->gpio_chip, chip); |
| 691 | if (rc) | 691 | if (rc) |
| 692 | return rc; | 692 | return rc; |
| 693 | 693 | ||
| @@ -696,24 +696,11 @@ static int sx150x_probe(struct i2c_client *client, · 2 unmodified lines | |||
| 696 | pdata->irq_summary, | 696 | pdata->irq_summary, |
| 697 | pdata->irq_base); | 697 | pdata->irq_base); |
| 698 | if (rc < 0) | 698 | if (rc < 0) |
| 699 | goto probe_fail_post_gpiochip_add; | 699 | return rc; |
| 700 | } | 700 | } |
| 701 | 701 | ||
| 702 | i2c_set_clientdata(client, chip); | 702 | i2c_set_clientdata(client, chip); |
| 703 | 703 | ||
| 704 | return 0; | ||
| 705 | probe_fail_post_gpiochip_add: | ||
| 706 | gpiochip_remove(&chip->gpio_chip); | ||
| 707 | return rc; | ||
| 708 | } | ||
| 709 | |||
| 710 | static int sx150x_remove(struct i2c_client *client) | ||
| 711 | { | ||
| 712 | struct sx150x_chip *chip; | ||
| 713 | |||
| 714 | chip = i2c_get_clientdata(client); | ||
| 715 | gpiochip_remove(&chip->gpio_chip); | ||
| 716 | |||
| 717 | return 0; | 704 | return 0; |
| 718 | } | 705 | } |
| 719 | 706 | ||
| @@ -723,7 +710,6 @@ static struct i2c_driver sx150x_driver = { · 3 unmodified lines | |||
| 723 | .of_match_table = of_match_ptr(sx150x_of_match), | 710 | .of_match_table = of_match_ptr(sx150x_of_match), |
| 724 | }, | 711 | }, |
| 725 | .probe = sx150x_probe, | 712 | .probe = sx150x_probe, |
| 726 | .remove = sx150x_remove, | ||
| 727 | .id_table = sx150x_id, | 713 | .id_table = sx150x_id, |
| 728 | }; | 714 | }; |
| 729 | 715 | ||
| @@ -238,15 +238,7 @@ static int syscon_gpio_probe(struct platform_device *pdev) · 237 unmodified lines | |||
| 238 | 238 | ||
| 239 | platform_set_drvdata(pdev, priv); | 239 | platform_set_drvdata(pdev, priv); |
| 240 | 240 | ||
| 241 | return gpiochip_add_data(&priv->chip, priv); | 241 | return devm_gpiochip_add_data(&pdev->dev, &priv->chip, priv); |
| 242 | } | ||
| 243 | |||
| 244 | static int syscon_gpio_remove(struct platform_device *pdev) | ||
| 245 | { | ||
| 246 | struct syscon_gpio_priv *priv = platform_get_drvdata(pdev); | ||
| 247 | |||
| 248 | gpiochip_remove(&priv->chip); | ||
| 249 | return 0; | ||
| 250 | } | 242 | } |
| 251 | 243 | ||
| 252 | static struct platform_driver syscon_gpio_driver = { | 244 | static struct platform_driver syscon_gpio_driver = { |
| @@ -255,7 +247,6 @@ static struct platform_driver syscon_gpio_driver = { · 2 unmodified lines | |||
| 255 | .of_match_table = syscon_gpio_ids, | 247 | .of_match_table = syscon_gpio_ids, |
| 256 | }, | 248 | }, |
| 257 | .probe = syscon_gpio_probe, | 249 | .probe = syscon_gpio_probe, |
| 258 | .remove = syscon_gpio_remove, | ||
| 259 | }; | 250 | }; |
| 260 | module_platform_driver(syscon_gpio_driver); | 251 | module_platform_driver(syscon_gpio_driver); |
| 261 | 252 | ||
| @@ -205,10 +205,10 @@ static int tb10x_gpio_probe(struct platform_device *pdev) · 204 unmodified lines | |||
| 205 | tb10x_gpio->gc.can_sleep = false; | 205 | tb10x_gpio->gc.can_sleep = false; |
| 206 | 206 | ||
| 207 | 207 | ||
| 208 | ret = gpiochip_add_data(&tb10x_gpio->gc, tb10x_gpio); | 208 | ret = devm_gpiochip_add_data(&pdev->dev, &tb10x_gpio->gc, tb10x_gpio); |
| 209 | if (ret < 0) { | 209 | if (ret < 0) { |
| 210 | dev_err(&pdev->dev, "Could not add gpiochip.\n"); | 210 | dev_err(&pdev->dev, "Could not add gpiochip.\n"); |
| 211 | goto fail_gpiochip_registration; | 211 | return ret; |
| 212 | } | 212 | } |
| 213 | 213 | ||
| 214 | platform_set_drvdata(pdev, tb10x_gpio); | 214 | platform_set_drvdata(pdev, tb10x_gpio); |
| @@ -219,7 +219,7 @@ static int tb10x_gpio_probe(struct platform_device *pdev) · 4 unmodified lines | |||
| 219 | ret = platform_get_irq(pdev, 0); | 219 | ret = platform_get_irq(pdev, 0); |
| 220 | if (ret < 0) { | 220 | if (ret < 0) { |
| 221 | dev_err(&pdev->dev, "No interrupt specified.\n"); | 221 | dev_err(&pdev->dev, "No interrupt specified.\n"); |
| 222 | goto fail_get_irq; | 222 | return ret; |
| 223 | } | 223 | } |
| 224 | 224 | ||
| 225 | tb10x_gpio->gc.to_irq = tb10x_gpio_to_irq; | 225 | tb10x_gpio->gc.to_irq = tb10x_gpio_to_irq; |
| @@ -229,14 +229,13 @@ static int tb10x_gpio_probe(struct platform_device *pdev) · 3 unmodified lines | |||
| 229 | IRQF_TRIGGER_NONE | IRQF_SHARED, | 229 | IRQF_TRIGGER_NONE | IRQF_SHARED, |
| 230 | dev_name(&pdev->dev), tb10x_gpio); | 230 | dev_name(&pdev->dev), tb10x_gpio); |
| 231 | if (ret != 0) | 231 | if (ret != 0) |
| 232 | goto fail_request_irq; | 232 | return ret; |
| 233 | 233 | ||
| 234 | tb10x_gpio->domain = irq_domain_add_linear(dn, | 234 | tb10x_gpio->domain = irq_domain_add_linear(dn, |
| 235 | tb10x_gpio->gc.ngpio, | 235 | tb10x_gpio->gc.ngpio, |
| 236 | &irq_generic_chip_ops, NULL); | 236 | &irq_generic_chip_ops, NULL); |
| 237 | if (!tb10x_gpio->domain) { | 237 | if (!tb10x_gpio->domain) { |
| 238 | ret = -ENOMEM; | 238 | return -ENOMEM; |
| 239 | goto fail_irq_domain; | ||
| 240 | } | 239 | } |
| 241 | 240 | ||
| 242 | ret = irq_alloc_domain_generic_chips(tb10x_gpio->domain, | 241 | ret = irq_alloc_domain_generic_chips(tb10x_gpio->domain, |
| @@ -244,7 +243,7 @@ static int tb10x_gpio_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 244 | handle_edge_irq, IRQ_NOREQUEST, IRQ_NOPROBE, | 243 | handle_edge_irq, IRQ_NOREQUEST, IRQ_NOPROBE, |
| 245 | IRQ_GC_INIT_MASK_CACHE); | 244 | IRQ_GC_INIT_MASK_CACHE); |
| 246 | if (ret) | 245 | if (ret) |
| 247 | goto fail_irq_domain; | 246 | return ret; |
| 248 | 247 | ||
| 249 | gc = tb10x_gpio->domain->gc->gc[0]; | 248 | gc = tb10x_gpio->domain->gc->gc[0]; |
| 250 | gc->reg_base = tb10x_gpio->base; | 249 | gc->reg_base = tb10x_gpio->base; |
| @@ -258,14 +257,6 @@ static int tb10x_gpio_probe(struct platform_device *pdev) · 7 unmodified lines | |||
| 258 | } | 257 | } |
| 259 | 258 | ||
| 260 | return 0; | 259 | return 0; |
| 261 | |||
| 262 | fail_irq_domain: | ||
| 263 | fail_request_irq: | ||
| 264 | fail_get_irq: | ||
| 265 | gpiochip_remove(&tb10x_gpio->gc); | ||
| 266 | fail_gpiochip_registration: | ||
| 267 | fail_ioremap: | ||
| 268 | return ret; | ||
| 269 | } | 260 | } |
| 270 | 261 | ||
| 271 | static int tb10x_gpio_remove(struct platform_device *pdev) | 262 | static int tb10x_gpio_remove(struct platform_device *pdev) |
| @@ -278,7 +269,6 @@ static int tb10x_gpio_remove(struct platform_device *pdev) · 6 unmodified lines | |||
| 278 | kfree(tb10x_gpio->domain->gc); | 269 | kfree(tb10x_gpio->domain->gc); |
| 279 | irq_domain_remove(tb10x_gpio->domain); | 270 | irq_domain_remove(tb10x_gpio->domain); |
| 280 | } | 271 | } |
| 281 | gpiochip_remove(&tb10x_gpio->gc); | ||
| 282 | 272 | ||
| 283 | return 0; | 273 | return 0; |
| 284 | } | 274 | } |
| @@ -272,7 +272,8 @@ static int tc3589x_gpio_probe(struct platform_device *pdev) · 271 unmodified lines | |||
| 272 | return ret; | 272 | return ret; |
| 273 | } | 273 | } |
| 274 | 274 | ||
| 275 | ret = gpiochip_add_data(&tc3589x_gpio->chip, tc3589x_gpio); | 275 | ret = devm_gpiochip_add_data(&pdev->dev, &tc3589x_gpio->chip, |
| 276 | tc3589x_gpio); | ||
| 276 | if (ret) { | 277 | if (ret) { |
| 277 | dev_err(&pdev->dev, "unable to add gpiochip: %d\n", ret); | 278 | dev_err(&pdev->dev, "unable to add gpiochip: %d\n", ret); |
| 278 | return ret; | 279 | return ret; |
| @@ -299,20 +300,10 @@ static int tc3589x_gpio_probe(struct platform_device *pdev) · 20 unmodified lines | |||
| 299 | return 0; | 300 | return 0; |
| 300 | } | 301 | } |
| 301 | 302 | ||
| 302 | static int tc3589x_gpio_remove(struct platform_device *pdev) | ||
| 303 | { | ||
| 304 | struct tc3589x_gpio *tc3589x_gpio = platform_get_drvdata(pdev); | ||
| 305 | |||
| 306 | gpiochip_remove(&tc3589x_gpio->chip); | ||
| 307 | |||
| 308 | return 0; | ||
| 309 | } | ||
| 310 | |||
| 311 | static struct platform_driver tc3589x_gpio_driver = { | 303 | static struct platform_driver tc3589x_gpio_driver = { |
| 312 | .driver.name = "tc3589x-gpio", | 304 | .driver.name = "tc3589x-gpio", |
| 313 | .driver.owner = THIS_MODULE, | 305 | .driver.owner = THIS_MODULE, |
| 314 | .probe = tc3589x_gpio_probe, | 306 | .probe = tc3589x_gpio_probe, |
| 315 | .remove = tc3589x_gpio_remove, | ||
| 316 | }; | 307 | }; |
| 317 | 308 | ||
| 318 | static int __init tc3589x_gpio_init(void) | 309 | static int __init tc3589x_gpio_init(void) |
| @@ -545,7 +545,7 @@ static int tegra_gpio_probe(struct platform_device *pdev) · 544 unmodified lines | |||
| 545 | 545 | ||
| 546 | tegra_gpio_chip.of_node = pdev->dev.of_node; | 546 | tegra_gpio_chip.of_node = pdev->dev.of_node; |
| 547 | 547 | ||
| 548 | ret = gpiochip_add_data(&tegra_gpio_chip, NULL); | 548 | ret = devm_gpiochip_add_data(&pdev->dev, &tegra_gpio_chip, NULL); |
| 549 | if (ret < 0) { | 549 | if (ret < 0) { |
| 550 | irq_domain_remove(irq_domain); | 550 | irq_domain_remove(irq_domain); |
| 551 | return ret; | 551 | return ret; |
| @@ -237,12 +237,6 @@ static int timbgpio_probe(struct platform_device *pdev) · 236 unmodified lines | |||
| 237 | return -EINVAL; | 237 | return -EINVAL; |
| 238 | } | 238 | } |
| 239 | 239 | ||
| 240 | iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 241 | if (!iomem) { | ||
| 242 | dev_err(dev, "Unable to get resource\n"); | ||
| 243 | return -EINVAL; | ||
| 244 | } | ||
| 245 | |||
| 246 | tgpio = devm_kzalloc(dev, sizeof(struct timbgpio), GFP_KERNEL); | 240 | tgpio = devm_kzalloc(dev, sizeof(struct timbgpio), GFP_KERNEL); |
| 247 | if (!tgpio) { | 241 | if (!tgpio) { |
| 248 | dev_err(dev, "Memory alloc failed\n"); | 242 | dev_err(dev, "Memory alloc failed\n"); |
| @@ -252,17 +246,10 @@ static int timbgpio_probe(struct platform_device *pdev) · 3 unmodified lines | |||
| 252 | 246 | ||
| 253 | spin_lock_init(&tgpio->lock); | 247 | spin_lock_init(&tgpio->lock); |
| 254 | 248 | ||
| 255 | if (!devm_request_mem_region(dev, iomem->start, resource_size(iomem), | 249 | iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 256 | DRIVER_NAME)) { | 250 | tgpio->membase = devm_ioremap_resource(dev, iomem); |
| 257 | dev_err(dev, "Region already claimed\n"); | 251 | if (IS_ERR(tgpio->membase)) |
| 258 | return -EBUSY; | 252 | return PTR_ERR(tgpio->membase); |
| 259 | } | ||
| 260 | |||
| 261 | tgpio->membase = devm_ioremap(dev, iomem->start, resource_size(iomem)); | ||
| 262 | if (!tgpio->membase) { | ||
| 263 | dev_err(dev, "Cannot ioremap\n"); | ||
| 264 | return -ENOMEM; | ||
| 265 | } | ||
| 266 | 253 | ||
| 267 | gc = &tgpio->gpio; | 254 | gc = &tgpio->gpio; |
| 268 | 255 | ||
| @@ -279,7 +266,7 @@ static int timbgpio_probe(struct platform_device *pdev) · 10 unmodified lines | |||
| 279 | gc->ngpio = pdata->nr_pins; | 266 | gc->ngpio = pdata->nr_pins; |
| 280 | gc->can_sleep = false; | 267 | gc->can_sleep = false; |
| 281 | 268 | ||
| 282 | err = gpiochip_add_data(gc, tgpio); | 269 | err = devm_gpiochip_add_data(&pdev->dev, gc, tgpio); |
| 283 | if (err) | 270 | if (err) |
| 284 | return err; | 271 | return err; |
| 285 | 272 | ||
| @@ -320,8 +307,6 @@ static int timbgpio_remove(struct platform_device *pdev) · 34 unmodified lines | |||
| 320 | irq_set_handler_data(irq, NULL); | 307 | irq_set_handler_data(irq, NULL); |
| 321 | } | 308 | } |
| 322 | 309 | ||
| 323 | gpiochip_remove(&tgpio->gpio); | ||
| 324 | |||
| 325 | return 0; | 310 | return 0; |
| 326 | } | 311 | } |
| 327 | 312 | ||
| @@ -0,0 +1,170 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ | ||
| 3 | * Andrew F. Davis <afd@ti.com> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or | ||
| 6 | * modify it under the terms of the GNU General Public License version 2 as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
| 10 | * kind, whether expressed or implied; without even the implied warranty | ||
| 11 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License version 2 for more details. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/gpio/driver.h> | ||
| 16 | #include <linux/i2c.h> | ||
| 17 | #include <linux/module.h> | ||
| 18 | #include <linux/mutex.h> | ||
| 19 | |||
| 20 | #define TPIC2810_WS_COMMAND 0x44 | ||
| 21 | |||
| 22 | /** | ||
| 23 | * struct tpic2810 - GPIO driver data | ||
| 24 | * @chip: GPIO controller chip | ||
| 25 | * @client: I2C device pointer | ||
| 26 | * @buffer: Buffer for device register | ||
| 27 | * @lock: Protects write sequences | ||
| 28 | */ | ||
| 29 | struct tpic2810 { | ||
| 30 | struct gpio_chip chip; | ||
| 31 | struct i2c_client *client; | ||
| 32 | u8 buffer; | ||
| 33 | struct mutex lock; | ||
| 34 | }; | ||
| 35 | |||
| 36 | static void tpic2810_set(struct gpio_chip *chip, unsigned offset, int value); | ||
| 37 | |||
| 38 | static int tpic2810_get_direction(struct gpio_chip *chip, | ||
| 39 | unsigned offset) | ||
| 40 | { | ||
| 41 | /* This device always output */ | ||
| 42 | return 0; | ||
| 43 | } | ||
| 44 | |||
| 45 | static int tpic2810_direction_input(struct gpio_chip *chip, | ||
| 46 | unsigned offset) | ||
| 47 | { | ||
| 48 | /* This device is output only */ | ||
| 49 | return -EINVAL; | ||
| 50 | } | ||
| 51 | |||
| 52 | static int tpic2810_direction_output(struct gpio_chip *chip, | ||
| 53 | unsigned offset, int value) | ||
| 54 | { | ||
| 55 | /* This device always output */ | ||
| 56 | tpic2810_set(chip, offset, value); | ||
| 57 | return 0; | ||
| 58 | } | ||
| 59 | |||
| 60 | static void tpic2810_set(struct gpio_chip *chip, unsigned offset, int value) | ||
| 61 | { | ||
| 62 | struct tpic2810 *gpio = gpiochip_get_data(chip); | ||
| 63 | |||
| 64 | mutex_lock(&gpio->lock); | ||
| 65 | |||
| 66 | if (value) | ||
| 67 | gpio->buffer |= BIT(offset); | ||
| 68 | else | ||
| 69 | gpio->buffer &= ~BIT(offset); | ||
| 70 | |||
| 71 | i2c_smbus_write_byte_data(gpio->client, TPIC2810_WS_COMMAND, | ||
| 72 | gpio->buffer); | ||
| 73 | |||
| 74 | mutex_unlock(&gpio->lock); | ||
| 75 | } | ||
| 76 | |||
| 77 | static void tpic2810_set_multiple(struct gpio_chip *chip, unsigned long *mask, | ||
| 78 | unsigned long *bits) | ||
| 79 | { | ||
| 80 | struct tpic2810 *gpio = gpiochip_get_data(chip); | ||
| 81 | |||
| 82 | mutex_lock(&gpio->lock); | ||
| 83 | |||
| 84 | /* clear bits under mask */ | ||
| 85 | gpio->buffer &= ~(*mask); | ||
| 86 | /* set bits under mask */ | ||
| 87 | gpio->buffer |= ((*mask) & (*bits)); | ||
| 88 | |||
| 89 | i2c_smbus_write_byte_data(gpio->client, TPIC2810_WS_COMMAND, | ||
| 90 | gpio->buffer); | ||
| 91 | |||
| 92 | mutex_unlock(&gpio->lock); | ||
| 93 | } | ||
| 94 | |||
| 95 | static struct gpio_chip template_chip = { | ||
| 96 | .label = "tpic2810", | ||
| 97 | .owner = THIS_MODULE, | ||
| 98 | .get_direction = tpic2810_get_direction, | ||
| 99 | .direction_input = tpic2810_direction_input, | ||
| 100 | .direction_output = tpic2810_direction_output, | ||
| 101 | .set = tpic2810_set, | ||
| 102 | .set_multiple = tpic2810_set_multiple, | ||
| 103 | .base = -1, | ||
| 104 | .ngpio = 8, | ||
| 105 | .can_sleep = true, | ||
| 106 | }; | ||
| 107 | |||
| 108 | static const struct of_device_id tpic2810_of_match_table[] = { | ||
| 109 | { .compatible = "ti,tpic2810" }, | ||
| 110 | { /* sentinel */ } | ||
| 111 | }; | ||
| 112 | MODULE_DEVICE_TABLE(of, tpic2810_of_match_table); | ||
| 113 | |||
| 114 | static int tpic2810_probe(struct i2c_client *client, | ||
| 115 | const struct i2c_device_id *id) | ||
| 116 | { | ||
| 117 | struct tpic2810 *gpio; | ||
| 118 | int ret; | ||
| 119 | |||
| 120 | gpio = devm_kzalloc(&client->dev, sizeof(*gpio), GFP_KERNEL); | ||
| 121 | if (!gpio) | ||
| 122 | return -ENOMEM; | ||
| 123 | |||
| 124 | i2c_set_clientdata(client, gpio); | ||
| 125 | |||
| 126 | gpio->chip = template_chip; | ||
| 127 | gpio->chip.parent = &client->dev; | ||
| 128 | |||
| 129 | gpio->client = client; | ||
| 130 | |||
| 131 | mutex_init(&gpio->lock); | ||
| 132 | |||
| 133 | ret = gpiochip_add_data(&gpio->chip, gpio); | ||
| 134 | if (ret < 0) { | ||
| 135 | dev_err(&client->dev, "Unable to register gpiochip\n"); | ||
| 136 | return ret; | ||
| 137 | } | ||
| 138 | |||
| 139 | return 0; | ||
| 140 | } | ||
| 141 | |||
| 142 | static int tpic2810_remove(struct i2c_client *client) | ||
| 143 | { | ||
| 144 | struct tpic2810 *gpio = i2c_get_clientdata(client); | ||
| 145 | |||
| 146 | gpiochip_remove(&gpio->chip); | ||
| 147 | |||
| 148 | return 0; | ||
| 149 | } | ||
| 150 | |||
| 151 | static const struct i2c_device_id tpic2810_id_table[] = { | ||
| 152 | { "tpic2810", }, | ||
| 153 | { /* sentinel */ } | ||
| 154 | }; | ||
| 155 | MODULE_DEVICE_TABLE(i2c, tpic2810_id_table); | ||
| 156 | |||
| 157 | static struct i2c_driver tpic2810_driver = { | ||
| 158 | .driver = { | ||
| 159 | .name = "tpic2810", | ||
| 160 | .of_match_table = tpic2810_of_match_table, | ||
| 161 | }, | ||
| 162 | .probe = tpic2810_probe, | ||
| 163 | .remove = tpic2810_remove, | ||
| 164 | .id_table = tpic2810_id_table, | ||
| 165 | }; | ||
| 166 | module_i2c_driver(tpic2810_driver); | ||
| 167 | |||
| 168 | MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>"); | ||
| 169 | MODULE_DESCRIPTION("TPIC2810 8-Bit LED Driver GPIO Driver"); | ||
| 170 | MODULE_LICENSE("GPL v2"); | ||
| @@ -0,0 +1,222 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2015 Verifone Int. | ||
| 3 | * | ||
| 4 | * Author: Nicolas Saenz Julienne <nicolassaenzj@gmail.com> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify i t | ||
| 7 | * under the terms of the GNU General Public License as published by th e | ||
| 8 | * Free Software Foundation; either version 2 of the License, or (at you r | ||
| 9 | * option) any later version. | ||
| 10 | * | ||
| 11 | * This driver is based on the gpio-tps65912 implementation. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/errno.h> | ||
| 17 | #include <linux/gpio/driver.h> | ||
| 18 | #include <linux/platform_device.h> | ||
| 19 | #include <linux/mfd/tps65218.h> | ||
| 20 | |||
| 21 | struct tps65218_gpio { | ||
| 22 | struct tps65218 *tps65218; | ||
| 23 | struct gpio_chip gpio_chip; | ||
| 24 | }; | ||
| 25 | |||
| 26 | static int tps65218_gpio_get(struct gpio_chip *gc, unsigned offset) | ||
| 27 | { | ||
| 28 | struct tps65218_gpio *tps65218_gpio = gpiochip_get_data(gc); | ||
| 29 | struct tps65218 *tps65218 = tps65218_gpio->tps65218; | ||
| 30 | unsigned int val; | ||
| 31 | int ret; | ||
| 32 | |||
| 33 | ret = tps65218_reg_read(tps65218, TPS65218_REG_ENABLE2, &val); | ||
| 34 | if (ret) | ||
| 35 | return ret; | ||
| 36 | |||
| 37 | return !!(val & (TPS65218_ENABLE2_GPIO1 << offset)); | ||
| 38 | } | ||
| 39 | |||
| 40 | static void tps65218_gpio_set(struct gpio_chip *gc, unsigned offset, | ||
| 41 | int value) | ||
| 42 | { | ||
| 43 | struct tps65218_gpio *tps65218_gpio = gpiochip_get_data(gc); | ||
| 44 | struct tps65218 *tps65218 = tps65218_gpio->tps65218; | ||
| 45 | |||
| 46 | if (value) | ||
| 47 | tps65218_set_bits(tps65218, TPS65218_REG_ENABLE2, | ||
| 48 | TPS65218_ENABLE2_GPIO1 << offset, | ||
| 49 | TPS65218_ENABLE2_GPIO1 << offset, | ||
| 50 | TPS65218_PROTECT_L1); | ||
| 51 | else | ||
| 52 | tps65218_clear_bits(tps65218, TPS65218_REG_ENABLE2, | ||
| 53 | TPS65218_ENABLE2_GPIO1 << offset, | ||
| 54 | TPS65218_PROTECT_L1); | ||
| 55 | } | ||
| 56 | |||
| 57 | static int tps65218_gpio_output(struct gpio_chip *gc, unsigned offset, | ||
| 58 | int value) | ||
| 59 | { | ||
| 60 | /* Only drives GPOs */ | ||
| 61 | tps65218_gpio_set(gc, offset, value); | ||
| 62 | return 0; | ||
| 63 | } | ||
| 64 | |||
| 65 | static int tps65218_gpio_input(struct gpio_chip *gc, unsigned offset) | ||
| 66 | { | ||
| 67 | return -EPERM; | ||
| 68 | } | ||
| 69 | |||
| 70 | static int tps65218_gpio_request(struct gpio_chip *gc, unsigned offset) | ||
| 71 | { | ||
| 72 | struct tps65218_gpio *tps65218_gpio = gpiochip_get_data(gc); | ||
| 73 | struct tps65218 *tps65218 = tps65218_gpio->tps65218; | ||
| 74 | int ret; | ||
| 75 | |||
| 76 | if (gpiochip_line_is_open_source(gc, offset)) { | ||
| 77 | dev_err(gc->parent, "can't work as open source\n"); | ||
| 78 | return -EINVAL; | ||
| 79 | } | ||
| 80 | |||
| 81 | switch (offset) { | ||
| 82 | case 0: | ||
| 83 | if (!gpiochip_line_is_open_drain(gc, offset)) { | ||
| 84 | dev_err(gc->parent, "GPO1 works only as open drain\n"); | ||
| 85 | return -EINVAL; | ||
| 86 | } | ||
| 87 | |||
| 88 | /* Disable sequencer for GPO1 */ | ||
| 89 | ret = tps65218_clear_bits(tps65218, TPS65218_REG_SEQ7, | ||
| 90 | TPS65218_SEQ7_GPO1_SEQ_MASK, | ||
| 91 | TPS65218_PROTECT_L1); | ||
| 92 | if (ret) | ||
| 93 | return ret; | ||
| 94 | |||
| 95 | /* Setup GPO1 */ | ||
| 96 | ret = tps65218_clear_bits(tps65218, TPS65218_REG_CONFIG1, | ||
| 97 | TPS65218_CONFIG1_IO1_SEL, | ||
| 98 | TPS65218_PROTECT_L1); | ||
| 99 | if (ret) | ||
| 100 | return ret; | ||
| 101 | |||
| 102 | break; | ||
| 103 | case 1: | ||
| 104 | /* GP02 is push-pull by default, can be set as open drain. */ | ||
| 105 | if (gpiochip_line_is_open_drain(gc, offset)) { | ||
| 106 | ret = tps65218_clear_bits(tps65218, | ||
| 107 | TPS65218_REG_CONFIG1, | ||
| 108 | TPS65218_CONFIG1_GPO2_BUF, | ||
| 109 | TPS65218_PROTECT_L1); | ||
| 110 | if (ret) | ||
| 111 | return ret; | ||
| 112 | } | ||
| 113 | |||
| 114 | /* Setup GPO2 */ | ||
| 115 | ret = tps65218_clear_bits(tps65218, TPS65218_REG_CONFIG1, | ||
| 116 | TPS65218_CONFIG1_IO1_SEL, | ||
| 117 | TPS65218_PROTECT_L1); | ||
| 118 | if (ret) | ||
| 119 | return ret; | ||
| 120 | |||
| 121 | break; | ||
| 122 | |||
| 123 | case 2: | ||
| 124 | if (!gpiochip_line_is_open_drain(gc, offset)) { | ||
| 125 | dev_err(gc->parent, "GPO3 works only as open drain\n"); | ||
| 126 | return -EINVAL; | ||
| 127 | } | ||
| 128 | |||
| 129 | /* Disable sequencer for GPO3 */ | ||
| 130 | ret = tps65218_clear_bits(tps65218, TPS65218_REG_SEQ7, | ||
| 131 | TPS65218_SEQ7_GPO3_SEQ_MASK, | ||
| 132 | TPS65218_PROTECT_L1); | ||
| 133 | if (ret) | ||
| 134 | return ret; | ||
| 135 | |||
| 136 | /* Setup GPO3 */ | ||
| 137 | ret = tps65218_clear_bits(tps65218, TPS65218_REG_CONFIG2, | ||
| 138 | TPS65218_CONFIG2_DC12_RST, | ||
| 139 | TPS65218_PROTECT_L1); | ||
| 140 | if (ret) | ||
| 141 | return ret; | ||
| 142 | |||
| 143 | break; | ||
| 144 | default: | ||
| 145 | return -EINVAL; | ||
| 146 | } | ||
| 147 | |||
| 148 | return 0; | ||
| 149 | } | ||
| 150 | |||
| 151 | static struct gpio_chip template_chip = { | ||
| 152 | .label = "gpio-tps65218", | ||
| 153 | .owner = THIS_MODULE, | ||
| 154 | .request = tps65218_gpio_request, | ||
| 155 | .direction_output = tps65218_gpio_output, | ||
| 156 | .direction_input = tps65218_gpio_input, | ||
| 157 | .get = tps65218_gpio_get, | ||
| 158 | .set = tps65218_gpio_set, | ||
| 159 | .can_sleep = true, | ||
| 160 | .ngpio = 3, | ||
| 161 | .base = -1, | ||
| 162 | }; | ||
| 163 | |||
| 164 | static int tps65218_gpio_probe(struct platform_device *pdev) | ||
| 165 | { | ||
| 166 | struct tps65218 *tps65218 = dev_get_drvdata(pdev->dev.parent); | ||
| 167 | struct tps65218_gpio *tps65218_gpio; | ||
| 168 | int ret; | ||
| 169 | |||
| 170 | tps65218_gpio = devm_kzalloc(&pdev->dev, sizeof(*tps65218_gpio), | ||
| 171 | GFP_KERNEL); | ||
| 172 | if (!tps65218_gpio) | ||
| 173 | return -ENOMEM; | ||
| 174 | |||
| 175 | tps65218_gpio->tps65218 = tps65218; | ||
| 176 | tps65218_gpio->gpio_chip = template_chip; | ||
| 177 | tps65218_gpio->gpio_chip.parent = &pdev->dev; | ||
| 178 | #ifdef CONFIG_OF_GPIO | ||
| 179 | tps65218_gpio->gpio_chip.of_node = pdev->dev.of_node; | ||
| 180 | #endif | ||
| 181 | |||
| 182 | ret = gpiochip_add_data(&tps65218_gpio->gpio_chip, tps65218_gpio); | ||
| 183 | if (ret < 0) { | ||
| 184 | dev_err(&pdev->dev, "Failed to register gpiochip, %d\n", ret); | ||
| 185 | return ret; | ||
| 186 | } | ||
| 187 | |||
| 188 | platform_set_drvdata(pdev, tps65218_gpio); | ||
| 189 | |||
| 190 | return ret; | ||
| 191 | } | ||
| 192 | |||
| 193 | static int tps65218_gpio_remove(struct platform_device *pdev) | ||
| 194 | { | ||
| 195 | struct tps65218_gpio *tps65218_gpio = platform_get_drvdata(pdev); | ||
| 196 | |||
| 197 | gpiochip_remove(&tps65218_gpio->gpio_chip); | ||
| 198 | |||
| 199 | return 0; | ||
| 200 | } | ||
| 201 | |||
| 202 | static const struct of_device_id tps65218_dt_match[] = { | ||
| 203 | { .compatible = "ti,tps65218-gpio" }, | ||
| 204 | { } | ||
| 205 | }; | ||
| 206 | MODULE_DEVICE_TABLE(of, tps65218_dt_match); | ||
| 207 | |||
| 208 | static struct platform_driver tps65218_gpio_driver = { | ||
| 209 | .driver = { | ||
| 210 | .name = "tps65218-gpio", | ||
| 211 | .of_match_table = of_match_ptr(tps65218_dt_match) | ||
| 212 | }, | ||
| 213 | .probe = tps65218_gpio_probe, | ||
| 214 | .remove = tps65218_gpio_remove, | ||
| 215 | }; | ||
| 216 | |||
| 217 | module_platform_driver(tps65218_gpio_driver); | ||
| 218 | |||
| 219 | MODULE_AUTHOR("Nicolas Saenz Julienne <nicolassaenzj@gmail.com>"); | ||
| 220 | MODULE_DESCRIPTION("GPO interface for TPS65218 PMICs"); | ||
| 221 | MODULE_LICENSE("GPL v2"); | ||
| 222 | MODULE_ALIAS("platform:tps65218-gpio"); | ||
| @@ -117,7 +117,8 @@ static int tps6586x_gpio_probe(struct platform_device *pdev) · 116 unmodified lines | |||
| 117 | else | 117 | else |
| 118 | tps6586x_gpio->gpio_chip.base = -1; | 118 | tps6586x_gpio->gpio_chip.base = -1; |
| 119 | 119 | ||
| 120 | ret = gpiochip_add_data(&tps6586x_gpio->gpio_chip, tps6586x_gpio); | 120 | ret = devm_gpiochip_add_data(&pdev->dev, &tps6586x_gpio->gpio_chip, |
| 121 | tps6586x_gpio); | ||
| 121 | if (ret < 0) { | 122 | if (ret < 0) { |
| 122 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); | 123 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); |
| 123 | return ret; | 124 | return ret; |
| @@ -128,19 +129,10 @@ static int tps6586x_gpio_probe(struct platform_device *pdev) · 4 unmodified lines | |||
| 128 | return ret; | 129 | return ret; |
| 129 | } | 130 | } |
| 130 | 131 | ||
| 131 | static int tps6586x_gpio_remove(struct platform_device *pdev) | ||
| 132 | { | ||
| 133 | struct tps6586x_gpio *tps6586x_gpio = platform_get_drvdata(pdev); | ||
| 134 | |||
| 135 | gpiochip_remove(&tps6586x_gpio->gpio_chip); | ||
| 136 | return 0; | ||
| 137 | } | ||
| 138 | |||
| 139 | static struct platform_driver tps6586x_gpio_driver = { | 132 | static struct platform_driver tps6586x_gpio_driver = { |
| 140 | .driver.name = "tps6586x-gpio", | 133 | .driver.name = "tps6586x-gpio", |
| 141 | .driver.owner = THIS_MODULE, | 134 | .driver.owner = THIS_MODULE, |
| 142 | .probe = tps6586x_gpio_probe, | 135 | .probe = tps6586x_gpio_probe, |
| 143 | .remove = tps6586x_gpio_remove, | ||
| 144 | }; | 136 | }; |
| 145 | 137 | ||
| 146 | static int __init tps6586x_gpio_init(void) | 138 | static int __init tps6586x_gpio_init(void) |
| @@ -170,7 +170,8 @@ static int tps65910_gpio_probe(struct platform_device *pdev) · 169 unmodified lines | |||
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | skip_init: | 172 | skip_init: |
| 173 | ret = gpiochip_add_data(&tps65910_gpio->gpio_chip, tps65910_gpio); | 173 | ret = devm_gpiochip_add_data(&pdev->dev, &tps65910_gpio->gpio_chip, |
| 174 | tps65910_gpio); | ||
| 174 | if (ret < 0) { | 175 | if (ret < 0) { |
| 175 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); | 176 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); |
| 176 | return ret; | 177 | return ret; |
| @@ -181,19 +182,10 @@ skip_init: · 4 unmodified lines | |||
| 181 | return ret; | 182 | return ret; |
| 182 | } | 183 | } |
| 183 | 184 | ||
| 184 | static int tps65910_gpio_remove(struct platform_device *pdev) | ||
| 185 | { | ||
| 186 | struct tps65910_gpio *tps65910_gpio = platform_get_drvdata(pdev); | ||
| 187 | |||
| 188 | gpiochip_remove(&tps65910_gpio->gpio_chip); | ||
| 189 | return 0; | ||
| 190 | } | ||
| 191 | |||
| 192 | static struct platform_driver tps65910_gpio_driver = { | 185 | static struct platform_driver tps65910_gpio_driver = { |
| 193 | .driver.name = "tps65910-gpio", | 186 | .driver.name = "tps65910-gpio", |
| 194 | .driver.owner = THIS_MODULE, | 187 | .driver.owner = THIS_MODULE, |
| 195 | .probe = tps65910_gpio_probe, | 188 | .probe = tps65910_gpio_probe, |
| 196 | .remove = tps65910_gpio_remove, | ||
| 197 | }; | 189 | }; |
| 198 | 190 | ||
| 199 | static int __init tps65910_gpio_init(void) | 191 | static int __init tps65910_gpio_init(void) |
| @@ -1,151 +1,149 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright 2011 Texas Instruments Inc. | 2 | * GPIO driver for TI TPS65912x PMICs |
| 3 | * | 3 | * |
| 4 | * Author: Margarita Olaya <magi@slimlogic.co.uk> | 4 | * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ |
| 5 | * Andrew F. Davis <afd@ti.com> | ||
| 5 | * | 6 | * |
| 6 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or |
| 7 | * under the terms of the GNU General Public License as published by the | 8 | * modify it under the terms of the GNU General Public License version 2 as |
| 8 | * Free Software Foundation; either version 2 of the License, or (at your | 9 | * published by the Free Software Foundation. |
| 9 | * option) any later version. | ||
| 10 | * | 10 | * |
| 11 | * This driver is based on wm8350 implementation. | 11 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any |
| 12 | * kind, whether expressed or implied; without even the implied warranty | ||
| 13 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License version 2 for more details. | ||
| 15 | * | ||
| 16 | * Based on the Arizona GPIO driver and the previous TPS65912 driver by | ||
| 17 | * Margarita Olaya Cabrera <magi@slimlogic.co.uk> | ||
| 12 | */ | 18 | */ |
| 13 | 19 | ||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/errno.h> | ||
| 17 | #include <linux/gpio.h> | 20 | #include <linux/gpio.h> |
| 18 | #include <linux/mfd/core.h> | 21 | #include <linux/module.h> |
| 19 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
| 20 | #include <linux/seq_file.h> | 23 | |
| 21 | #include <linux/slab.h> | ||
| 22 | #include <linux/mfd/tps65912.h> | 24 | #include <linux/mfd/tps65912.h> |
| 23 | 25 | ||
| 24 | struct tps65912_gpio_data { | 26 | struct tps65912_gpio { |
| 25 | struct tps65912 *tps65912; | ||
| 26 | struct gpio_chip gpio_chip; | 27 | struct gpio_chip gpio_chip; |
| 28 | struct tps65912 *tps; | ||
| 27 | }; | 29 | }; |
| 28 | 30 | ||
| 29 | static int tps65912_gpio_get(struct gpio_chip *gc, unsigned offset) | 31 | static int tps65912_gpio_get_direction(struct gpio_chip *gc, |
| 32 | unsigned offset) | ||
| 30 | { | 33 | { |
| 31 | struct tps65912_gpio_data *tps65912_gpio = gpiochip_get_data(gc); | 34 | struct tps65912_gpio *gpio = gpiochip_get_data(gc); |
| 32 | struct tps65912 *tps65912 = tps65912_gpio->tps65912; | ||
| 33 | int val; | ||
| 34 | 35 | ||
| 35 | val = tps65912_reg_read(tps65912, TPS65912_GPIO1 + offset); | 36 | int ret, val; |
| 36 | 37 | ||
| 37 | if (val & GPIO_STS_MASK) | 38 | ret = regmap_read(gpio->tps->regmap, TPS65912_GPIO1 + offset, &val); |
| 38 | return 1; | 39 | if (ret) |
| 40 | return ret; | ||
| 39 | 41 | ||
| 40 | return 0; | 42 | if (val & GPIO_CFG_MASK) |
| 43 | return GPIOF_DIR_OUT; | ||
| 44 | else | ||
| 45 | return GPIOF_DIR_IN; | ||
| 41 | } | 46 | } |
| 42 | 47 | ||
| 43 | static void tps65912_gpio_set(struct gpio_chip *gc, unsigned offset, | 48 | static int tps65912_gpio_direction_input(struct gpio_chip *gc, unsigned offset) |
| 44 | int value) | ||
| 45 | { | 49 | { |
| 46 | struct tps65912_gpio_data *tps65912_gpio = gpiochip_get_data(gc); | 50 | struct tps65912_gpio *gpio = gpiochip_get_data(gc); |
| 47 | struct tps65912 *tps65912 = tps65912_gpio->tps65912; | ||
| 48 | 51 | ||
| 49 | if (value) | 52 | return regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset, |
| 50 | tps65912_set_bits(tps65912, TPS65912_GPIO1 + offset, | 53 | GPIO_CFG_MASK, 0); |
| 51 | GPIO_SET_MASK); | ||
| 52 | else | ||
| 53 | tps65912_clear_bits(tps65912, TPS65912_GPIO1 + offset, | ||
| 54 | GPIO_SET_MASK); | ||
| 55 | } | 54 | } |
| 56 | 55 | ||
| 57 | static int tps65912_gpio_output(struct gpio_chip *gc, unsigned offset, | 56 | static int tps65912_gpio_direction_output(struct gpio_chip *gc, |
| 58 | int value) | 57 | unsigned offset, int value) |
| 59 | { | 58 | { |
| 60 | struct tps65912_gpio_data *tps65912_gpio = gpiochip_get_data(gc); | 59 | struct tps65912_gpio *gpio = gpiochip_get_data(gc); |
| 61 | struct tps65912 *tps65912 = tps65912_gpio->tps65912; | ||
| 62 | 60 | ||
| 63 | /* Set the initial value */ | 61 | /* Set the initial value */ |
| 64 | tps65912_gpio_set(gc, offset, value); | 62 | regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset, |
| 63 | GPIO_SET_MASK, value ? GPIO_SET_MASK : 0); | ||
| 64 | |||
| 65 | return regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset, | ||
| 66 | GPIO_CFG_MASK, GPIO_CFG_MASK); | ||
| 67 | } | ||
| 68 | |||
| 69 | static int tps65912_gpio_get(struct gpio_chip *gc, unsigned offset) | ||
| 70 | { | ||
| 71 | struct tps65912_gpio *gpio = gpiochip_get_data(gc); | ||
| 72 | int ret, val; | ||
| 73 | |||
| 74 | ret = regmap_read(gpio->tps->regmap, TPS65912_GPIO1 + offset, &val); | ||
| 75 | if (ret) | ||
| 76 | return ret; | ||
| 77 | |||
| 78 | if (val & GPIO_STS_MASK) | ||
| 79 | return 1; | ||
| 65 | 80 | ||
| 66 | return tps65912_set_bits(tps65912, TPS65912_GPIO1 + offset, | 81 | return 0; |
| 67 | GPIO_CFG_MASK); | ||
| 68 | } | 82 | } |
| 69 | 83 | ||
| 70 | static int tps65912_gpio_input(struct gpio_chip *gc, unsigned offset) | 84 | static void tps65912_gpio_set(struct gpio_chip *gc, unsigned offset, |
| 85 | int value) | ||
| 71 | { | 86 | { |
| 72 | struct tps65912_gpio_data *tps65912_gpio = gpiochip_get_data(gc); | 87 | struct tps65912_gpio *gpio = gpiochip_get_data(gc); |
| 73 | struct tps65912 *tps65912 = tps65912_gpio->tps65912; | ||
| 74 | 88 | ||
| 75 | return tps65912_clear_bits(tps65912, TPS65912_GPIO1 + offset, | 89 | regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset, |
| 76 | GPIO_CFG_MASK); | 90 | GPIO_SET_MASK, value ? GPIO_SET_MASK : 0); |
| 77 | } | 91 | } |
| 78 | 92 | ||
| 79 | static struct gpio_chip template_chip = { | 93 | static struct gpio_chip template_chip = { |
| 80 | .label = "tps65912", | 94 | .label = "tps65912-gpio", |
| 81 | .owner = THIS_MODULE, | 95 | .owner = THIS_MODULE, |
| 82 | .direction_input = tps65912_gpio_input, | 96 | .get_direction = tps65912_gpio_get_direction, |
| 83 | .direction_output = tps65912_gpio_output, | 97 | .direction_input = tps65912_gpio_direction_input, |
| 98 | .direction_output = tps65912_gpio_direction_output, | ||
| 84 | .get = tps65912_gpio_get, | 99 | .get = tps65912_gpio_get, |
| 85 | .set = tps65912_gpio_set, | 100 | .set = tps65912_gpio_set, |
| 86 | .can_sleep = true, | ||
| 87 | .ngpio = 5, | ||
| 88 | .base = -1, | 101 | .base = -1, |
| 102 | .ngpio = 5, | ||
| 103 | .can_sleep = true, | ||
| 89 | }; | 104 | }; |
| 90 | 105 | ||
| 91 | static int tps65912_gpio_probe(struct platform_device *pdev) | 106 | static int tps65912_gpio_probe(struct platform_device *pdev) |
| 92 | { | 107 | { |
| 93 | struct tps65912 *tps65912 = dev_get_drvdata(pdev->dev.parent); | 108 | struct tps65912 *tps = dev_get_drvdata(pdev->dev.parent); |
| 94 | struct tps65912_board *pdata = dev_get_platdata(tps65912->dev); | 109 | struct tps65912_gpio *gpio; |
| 95 | struct tps65912_gpio_data *tps65912_gpio; | ||
| 96 | int ret; | 110 | int ret; |
| 97 | 111 | ||
| 98 | tps65912_gpio = devm_kzalloc(&pdev->dev, sizeof(*tps65912_gpio), | 112 | gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); |
| 99 | GFP_KERNEL); | 113 | if (!gpio) |
| 100 | if (tps65912_gpio == NULL) | ||
| 101 | return -ENOMEM; | 114 | return -ENOMEM; |
| 102 | 115 | ||
| 103 | tps65912_gpio->tps65912 = tps65912; | 116 | gpio->tps = dev_get_drvdata(pdev->dev.parent); |
| 104 | tps65912_gpio->gpio_chip = template_chip; | 117 | gpio->gpio_chip = template_chip; |
| 105 | tps65912_gpio->gpio_chip.parent = &pdev->dev; | 118 | gpio->gpio_chip.parent = tps->dev; |
| 106 | if (pdata && pdata->gpio_base) | ||
| 107 | tps65912_gpio->gpio_chip.base = pdata->gpio_base; | ||
| 108 | 119 | ||
| 109 | ret = gpiochip_add_data(&tps65912_gpio->gpio_chip, tps65912_gpio); | 120 | ret = devm_gpiochip_add_data(&pdev->dev, &gpio->gpio_chip, |
| 121 | gpio); | ||
| 110 | if (ret < 0) { | 122 | if (ret < 0) { |
| 111 | dev_err(&pdev->dev, "Failed to register gpiochip, %d\n", ret); | 123 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); |
| 112 | return ret; | 124 | return ret; |
| 113 | } | 125 | } |
| 114 | 126 | ||
| 115 | platform_set_drvdata(pdev, tps65912_gpio); | 127 | platform_set_drvdata(pdev, gpio); |
| 116 | |||
| 117 | return ret; | ||
| 118 | } | ||
| 119 | 128 | ||
| 120 | static int tps65912_gpio_remove(struct platform_device *pdev) | ||
| 121 | { | ||
| 122 | struct tps65912_gpio_data *tps65912_gpio = platform_get_drvdata(pdev); | ||
| 123 | |||
| 124 | gpiochip_remove(&tps65912_gpio->gpio_chip); | ||
| 125 | return 0; | 129 | return 0; |
| 126 | } | 130 | } |
| 127 | 131 | ||
| 132 | static const struct platform_device_id tps65912_gpio_id_table[] = { | ||
| 133 | { "tps65912-gpio", }, | ||
| 134 | { /* sentinel */ } | ||
| 135 | }; | ||
| 136 | MODULE_DEVICE_TABLE(platform, tps65912_gpio_id_table); | ||
| 137 | |||
| 128 | static struct platform_driver tps65912_gpio_driver = { | 138 | static struct platform_driver tps65912_gpio_driver = { |
| 129 | .driver = { | 139 | .driver = { |
| 130 | .name = "tps65912-gpio", | 140 | .name = "tps65912-gpio", |
| 131 | }, | 141 | }, |
| 132 | .probe = tps65912_gpio_probe, | 142 | .probe = tps65912_gpio_probe, |
| 133 | .remove = tps65912_gpio_remove, | 143 | .id_table = tps65912_gpio_id_table, |
| 134 | }; | 144 | }; |
| 145 | module_platform_driver(tps65912_gpio_driver); | ||
| 135 | 146 | ||
| 136 | static int __init tps65912_gpio_init(void) | 147 | MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>"); |
| 137 | { | 148 | MODULE_DESCRIPTION("TPS65912 GPIO driver"); |
| 138 | return platform_driver_register(&tps65912_gpio_driver); | ||
| 139 | } | ||
| 140 | subsys_initcall(tps65912_gpio_init); | ||
| 141 | |||
| 142 | static void __exit tps65912_gpio_exit(void) | ||
| 143 | { | ||
| 144 | platform_driver_unregister(&tps65912_gpio_driver); | ||
| 145 | } | ||
| 146 | module_exit(tps65912_gpio_exit); | ||
| 147 | |||
| 148 | MODULE_AUTHOR("Margarita Olaya Cabrera <magi@slimlogic.co.uk>"); | ||
| 149 | MODULE_DESCRIPTION("GPIO interface for TPS65912 PMICs"); | ||
| 150 | MODULE_LICENSE("GPL v2"); | 149 | MODULE_LICENSE("GPL v2"); |
| 151 | MODULE_ALIAS("platform:tps65912-gpio"); | ||
| @@ -0,0 +1,81 @@ | |||
| 1 | /* | ||
| 2 | * GPIO driver for the TS-4800 board | ||
| 3 | * | ||
| 4 | * Copyright (c) 2016 - Savoir-faire Linux | ||
| 5 | * | ||
| 6 | * This file is licensed under the terms of the GNU General Public | ||
| 7 | * License version 2. This program is licensed "as is" without any | ||
| 8 | * warranty of any kind, whether express or implied. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/gpio/driver.h> | ||
| 12 | #include <linux/of_address.h> | ||
| 13 | #include <linux/of_device.h> | ||
| 14 | #include <linux/platform_device.h> | ||
| 15 | |||
| 16 | #define DEFAULT_PIN_NUMBER 16 | ||
| 17 | #define INPUT_REG_OFFSET 0x00 | ||
| 18 | #define OUTPUT_REG_OFFSET 0x02 | ||
| 19 | #define DIRECTION_REG_OFFSET 0x04 | ||
| 20 | |||
| 21 | static int ts4800_gpio_probe(struct platform_device *pdev) | ||
| 22 | { | ||
| 23 | struct device_node *node; | ||
| 24 | struct gpio_chip *chip; | ||
| 25 | struct resource *res; | ||
| 26 | void __iomem *base_addr; | ||
| 27 | int retval; | ||
| 28 | u32 ngpios; | ||
| 29 | |||
| 30 | chip = devm_kzalloc(&pdev->dev, sizeof(struct gpio_chip), GFP_KERNEL); | ||
| 31 | if (!chip) | ||
| 32 | return -ENOMEM; | ||
| 33 | |||
| 34 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 35 | base_addr = devm_ioremap_resource(&pdev->dev, res); | ||
| 36 | if (IS_ERR(base_addr)) | ||
| 37 | return PTR_ERR(base_addr); | ||
| 38 | |||
| 39 | node = pdev->dev.of_node; | ||
| 40 | if (!node) | ||
| 41 | return -EINVAL; | ||
| 42 | |||
| 43 | retval = of_property_read_u32(node, "ngpios", &ngpios); | ||
| 44 | if (retval == -EINVAL) | ||
| 45 | ngpios = DEFAULT_PIN_NUMBER; | ||
| 46 | else if (retval) | ||
| 47 | return retval; | ||
| 48 | |||
| 49 | retval = bgpio_init(chip, &pdev->dev, 2, base_addr + INPUT_REG_OFFSET, | ||
| 50 | base_addr + OUTPUT_REG_OFFSET, NULL, | ||
| 51 | base_addr + DIRECTION_REG_OFFSET, NULL, 0); | ||
| 52 | if (retval) { | ||
| 53 | dev_err(&pdev->dev, "bgpio_init failed\n"); | ||
| 54 | return retval; | ||
| 55 | } | ||
| 56 | |||
| 57 | chip->ngpio = ngpios; | ||
| 58 | |||
| 59 | platform_set_drvdata(pdev, chip); | ||
| 60 | |||
| 61 | return devm_gpiochip_add_data(&pdev->dev, chip, NULL); | ||
| 62 | } | ||
| 63 | |||
| 64 | static const struct of_device_id ts4800_gpio_of_match[] = { | ||
| 65 | { .compatible = "technologic,ts4800-gpio", }, | ||
| 66 | {}, | ||
| 67 | }; | ||
| 68 | |||
| 69 | static struct platform_driver ts4800_gpio_driver = { | ||
| 70 | .driver = { | ||
| 71 | .name = "ts4800-gpio", | ||
| 72 | .of_match_table = ts4800_gpio_of_match, | ||
| 73 | }, | ||
| 74 | .probe = ts4800_gpio_probe, | ||
| 75 | }; | ||
| 76 | |||
| 77 | module_platform_driver_probe(ts4800_gpio_driver, ts4800_gpio_probe); | ||
| 78 | |||
| 79 | MODULE_AUTHOR("Julien Grossholtz <julien.grossholtz@savoirfairelinux.com>"); | ||
| 80 | MODULE_DESCRIPTION("TS4800 FPGA GPIO driver"); | ||
| 81 | MODULE_LICENSE("GPL v2"); | ||
| @@ -409,7 +409,7 @@ static int ts5500_dio_probe(struct platform_device *pdev) · 408 unmodified lines | |||
| 409 | break; | 409 | break; |
| 410 | } | 410 | } |
| 411 | 411 | ||
| 412 | ret = gpiochip_add_data(&priv->gpio_chip, priv); | 412 | ret = devm_gpiochip_add_data(dev, &priv->gpio_chip, priv); |
| 413 | if (ret) { | 413 | if (ret) { |
| 414 | dev_err(dev, "failed to register the gpio chip\n"); | 414 | dev_err(dev, "failed to register the gpio chip\n"); |
| 415 | return ret; | 415 | return ret; |
| @@ -418,13 +418,10 @@ static int ts5500_dio_probe(struct platform_device *pdev) · 2 unmodified lines | |||
| 418 | ret = ts5500_enable_irq(priv); | 418 | ret = ts5500_enable_irq(priv); |
| 419 | if (ret) { | 419 | if (ret) { |
| 420 | dev_err(dev, "invalid interrupt %d\n", priv->hwirq); | 420 | dev_err(dev, "invalid interrupt %d\n", priv->hwirq); |
| 421 | goto cleanup; | 421 | return ret; |
| 422 | } | 422 | } |
| 423 | 423 | ||
| 424 | return 0; | 424 | return 0; |
| 425 | cleanup: | ||
| 426 | gpiochip_remove(&priv->gpio_chip); | ||
| 427 | return ret; | ||
| 428 | } | 425 | } |
| 429 | 426 | ||
| 430 | static int ts5500_dio_remove(struct platform_device *pdev) | 427 | static int ts5500_dio_remove(struct platform_device *pdev) |
| @@ -432,7 +429,7 @@ static int ts5500_dio_remove(struct platform_device *pdev) · 1 unmodified line | |||
| 432 | struct ts5500_priv *priv = platform_get_drvdata(pdev); | 429 | struct ts5500_priv *priv = platform_get_drvdata(pdev); |
| 433 | 430 | ||
| 434 | ts5500_disable_irq(priv); | 431 | ts5500_disable_irq(priv); |
| 435 | gpiochip_remove(&priv->gpio_chip); | 432 | |
| 436 | return 0; | 433 | return 0; |
| 437 | } | 434 | } |
| 438 | 435 | ||
| @@ -100,7 +100,7 @@ static int gpo_twl6040_probe(struct platform_device *pdev) · 99 unmodified lines | |||
| 100 | twl6040gpo_chip.of_node = twl6040_core_dev->of_node; | 100 | twl6040gpo_chip.of_node = twl6040_core_dev->of_node; |
| 101 | #endif | 101 | #endif |
| 102 | 102 | ||
| 103 | ret = gpiochip_add_data(&twl6040gpo_chip, NULL); | 103 | ret = devm_gpiochip_add_data(&pdev->dev, &twl6040gpo_chip, NULL); |
| 104 | if (ret < 0) { | 104 | if (ret < 0) { |
| 105 | dev_err(&pdev->dev, "could not register gpiochip, %d\n", ret); | 105 | dev_err(&pdev->dev, "could not register gpiochip, %d\n", ret); |
| 106 | twl6040gpo_chip.ngpio = 0; | 106 | twl6040gpo_chip.ngpio = 0; |
| @@ -109,12 +109,6 @@ static int gpo_twl6040_probe(struct platform_device *pdev) · 2 unmodified lines | |||
| 109 | return ret; | 109 | return ret; |
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | static int gpo_twl6040_remove(struct platform_device *pdev) | ||
| 113 | { | ||
| 114 | gpiochip_remove(&twl6040gpo_chip); | ||
| 115 | return 0; | ||
| 116 | } | ||
| 117 | |||
| 118 | /* Note: this hardware lives inside an I2C-based multi-function device. */ | 112 | /* Note: this hardware lives inside an I2C-based multi-function device. */ |
| 119 | MODULE_ALIAS("platform:twl6040-gpo"); | 113 | MODULE_ALIAS("platform:twl6040-gpo"); |
| 120 | 114 | ||
| @@ -123,7 +117,6 @@ static struct platform_driver gpo_twl6040_driver = { · 2 unmodified lines | |||
| 123 | .name = "twl6040-gpo", | 117 | .name = "twl6040-gpo", |
| 124 | }, | 118 | }, |
| 125 | .probe = gpo_twl6040_probe, | 119 | .probe = gpo_twl6040_probe, |
| 126 | .remove = gpo_twl6040_remove, | ||
| 127 | }; | 120 | }; |
| 128 | 121 | ||
| 129 | module_platform_driver(gpo_twl6040_driver); | 122 | module_platform_driver(gpo_twl6040_driver); |
| @@ -67,7 +67,7 @@ static int ucb1400_gpio_probe(struct platform_device *dev) · 66 unmodified lines | |||
| 67 | ucb->gc.set = ucb1400_gpio_set; | 67 | ucb->gc.set = ucb1400_gpio_set; |
| 68 | ucb->gc.can_sleep = true; | 68 | ucb->gc.can_sleep = true; |
| 69 | 69 | ||
| 70 | err = gpiochip_add_data(&ucb->gc, ucb); | 70 | err = devm_gpiochip_add_data(&dev->dev, &ucb->gc, ucb); |
| 71 | if (err) | 71 | if (err) |
| 72 | goto err; | 72 | goto err; |
| 73 | 73 | ||
| @@ -90,7 +90,6 @@ static int ucb1400_gpio_remove(struct platform_device *dev) · 16 unmodified lines | |||
| 90 | return err; | 90 | return err; |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | gpiochip_remove(&ucb->gc); | ||
| 94 | return err; | 93 | return err; |
| 95 | } | 94 | } |
| 96 | 95 | ||
| @@ -410,10 +410,10 @@ static int vprbrd_gpio_probe(struct platform_device *pdev) · 409 unmodified lines | |||
| 410 | vb_gpio->gpioa.get = vprbrd_gpioa_get; | 410 | vb_gpio->gpioa.get = vprbrd_gpioa_get; |
| 411 | vb_gpio->gpioa.direction_input = vprbrd_gpioa_direction_input; | 411 | vb_gpio->gpioa.direction_input = vprbrd_gpioa_direction_input; |
| 412 | vb_gpio->gpioa.direction_output = vprbrd_gpioa_direction_output; | 412 | vb_gpio->gpioa.direction_output = vprbrd_gpioa_direction_output; |
| 413 | ret = gpiochip_add_data(&vb_gpio->gpioa, vb_gpio); | 413 | ret = devm_gpiochip_add_data(&pdev->dev, &vb_gpio->gpioa, vb_gpio); |
| 414 | if (ret < 0) { | 414 | if (ret < 0) { |
| 415 | dev_err(vb_gpio->gpioa.parent, "could not add gpio a"); | 415 | dev_err(vb_gpio->gpioa.parent, "could not add gpio a"); |
| 416 | goto err_gpioa; | 416 | return ret; |
| 417 | } | 417 | } |
| 418 | 418 | ||
| 419 | /* registering gpio b */ | 419 | /* registering gpio b */ |
| @@ -427,37 +427,21 @@ static int vprbrd_gpio_probe(struct platform_device *pdev) · 7 unmodified lines | |||
| 427 | vb_gpio->gpiob.get = vprbrd_gpiob_get; | 427 | vb_gpio->gpiob.get = vprbrd_gpiob_get; |
| 428 | vb_gpio->gpiob.direction_input = vprbrd_gpiob_direction_input; | 428 | vb_gpio->gpiob.direction_input = vprbrd_gpiob_direction_input; |
| 429 | vb_gpio->gpiob.direction_output = vprbrd_gpiob_direction_output; | 429 | vb_gpio->gpiob.direction_output = vprbrd_gpiob_direction_output; |
| 430 | ret = gpiochip_add_data(&vb_gpio->gpiob, vb_gpio); | 430 | ret = devm_gpiochip_add_data(&pdev->dev, &vb_gpio->gpiob, vb_gpio); |
| 431 | if (ret < 0) { | 431 | if (ret < 0) { |
| 432 | dev_err(vb_gpio->gpiob.parent, "could not add gpio b"); | 432 | dev_err(vb_gpio->gpiob.parent, "could not add gpio b"); |
| 433 | goto err_gpiob; | 433 | return ret; |
| 434 | } | 434 | } |
| 435 | 435 | ||
| 436 | platform_set_drvdata(pdev, vb_gpio); | 436 | platform_set_drvdata(pdev, vb_gpio); |
| 437 | 437 | ||
| 438 | return ret; | 438 | return ret; |
| 439 | |||
| 440 | err_gpiob: | ||
| 441 | gpiochip_remove(&vb_gpio->gpioa); | ||
| 442 | |||
| 443 | err_gpioa: | ||
| 444 | return ret; | ||
| 445 | } | ||
| 446 | |||
| 447 | static int vprbrd_gpio_remove(struct platform_device *pdev) | ||
| 448 | { | ||
| 449 | struct vprbrd_gpio *vb_gpio = platform_get_drvdata(pdev); | ||
| 450 | |||
| 451 | gpiochip_remove(&vb_gpio->gpiob); | ||
| 452 | |||
| 453 | return 0; | ||
| 454 | } | 439 | } |
| 455 | 440 | ||
| 456 | static struct platform_driver vprbrd_gpio_driver = { | 441 | static struct platform_driver vprbrd_gpio_driver = { |
| 457 | .driver.name = "viperboard-gpio", | 442 | .driver.name = "viperboard-gpio", |
| 458 | .driver.owner = THIS_MODULE, | 443 | .driver.owner = THIS_MODULE, |
| 459 | .probe = vprbrd_gpio_probe, | 444 | .probe = vprbrd_gpio_probe, |
| 460 | .remove = vprbrd_gpio_remove, | ||
| 461 | }; | 445 | }; |
| 462 | 446 | ||
| 463 | static int __init vprbrd_gpio_init(void) | 447 | static int __init vprbrd_gpio_init(void) |
| @@ -259,16 +259,7 @@ static int vx855gpio_probe(struct platform_device *pdev) · 258 unmodified lines | |||
| 259 | 259 | ||
| 260 | vx855gpio_gpio_setup(vg); | 260 | vx855gpio_gpio_setup(vg); |
| 261 | 261 | ||
| 262 | return gpiochip_add_data(&vg->gpio, vg); | 262 | return devm_gpiochip_add_data(&pdev->dev, &vg->gpio, vg); |
| 263 | } | ||
| 264 | |||
| 265 | static int vx855gpio_remove(struct platform_device *pdev) | ||
| 266 | { | ||
| 267 | struct vx855_gpio *vg = platform_get_drvdata(pdev); | ||
| 268 | |||
| 269 | gpiochip_remove(&vg->gpio); | ||
| 270 | |||
| 271 | return 0; | ||
| 272 | } | 263 | } |
| 273 | 264 | ||
| 274 | static struct platform_driver vx855gpio_driver = { | 265 | static struct platform_driver vx855gpio_driver = { |
| @@ -276,7 +267,6 @@ static struct platform_driver vx855gpio_driver = { · 1 unmodified line | |||
| 276 | .name = MODULE_NAME, | 267 | .name = MODULE_NAME, |
| 277 | }, | 268 | }, |
| 278 | .probe = vx855gpio_probe, | 269 | .probe = vx855gpio_probe, |
| 279 | .remove = vx855gpio_remove, | ||
| 280 | }; | 270 | }; |
| 281 | 271 | ||
| 282 | module_platform_driver(vx855gpio_driver); | 272 | module_platform_driver(vx855gpio_driver); |
| @@ -259,7 +259,8 @@ static int wm831x_gpio_probe(struct platform_device *pdev) · 258 unmodified lines | |||
| 259 | else | 259 | else |
| 260 | wm831x_gpio->gpio_chip.base = -1; | 260 | wm831x_gpio->gpio_chip.base = -1; |
| 261 | 261 | ||
| 262 | ret = gpiochip_add_data(&wm831x_gpio->gpio_chip, wm831x_gpio); | 262 | ret = devm_gpiochip_add_data(&pdev->dev, &wm831x_gpio->gpio_chip, |
| 263 | wm831x_gpio); | ||
| 263 | if (ret < 0) { | 264 | if (ret < 0) { |
| 264 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); | 265 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); |
| 265 | return ret; | 266 | return ret; |
| @@ -270,19 +271,10 @@ static int wm831x_gpio_probe(struct platform_device *pdev) · 4 unmodified lines | |||
| 270 | return ret; | 271 | return ret; |
| 271 | } | 272 | } |
| 272 | 273 | ||
| 273 | static int wm831x_gpio_remove(struct platform_device *pdev) | ||
| 274 | { | ||
| 275 | struct wm831x_gpio *wm831x_gpio = platform_get_drvdata(pdev); | ||
| 276 | |||
| 277 | gpiochip_remove(&wm831x_gpio->gpio_chip); | ||
| 278 | return 0; | ||
| 279 | } | ||
| 280 | |||
| 281 | static struct platform_driver wm831x_gpio_driver = { | 274 | static struct platform_driver wm831x_gpio_driver = { |
| 282 | .driver.name = "wm831x-gpio", | 275 | .driver.name = "wm831x-gpio", |
| 283 | .driver.owner = THIS_MODULE, | 276 | .driver.owner = THIS_MODULE, |
| 284 | .probe = wm831x_gpio_probe, | 277 | .probe = wm831x_gpio_probe, |
| 285 | .remove = wm831x_gpio_remove, | ||
| 286 | }; | 278 | }; |
| 287 | 279 | ||
| 288 | static int __init wm831x_gpio_init(void) | 280 | static int __init wm831x_gpio_init(void) |
| @@ -125,7 +125,8 @@ static int wm8350_gpio_probe(struct platform_device *pdev) · 124 unmodified lines | |||
| 125 | else | 125 | else |
| 126 | wm8350_gpio->gpio_chip.base = -1; | 126 | wm8350_gpio->gpio_chip.base = -1; |
| 127 | 127 | ||
| 128 | ret = gpiochip_add_data(&wm8350_gpio->gpio_chip, wm8350_gpio); | 128 | ret = devm_gpiochip_add_data(&pdev->dev, &wm8350_gpio->gpio_chip, |
| 129 | wm8350_gpio); | ||
| 129 | if (ret < 0) { | 130 | if (ret < 0) { |
| 130 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); | 131 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); |
| 131 | return ret; | 132 | return ret; |
| @@ -136,19 +137,10 @@ static int wm8350_gpio_probe(struct platform_device *pdev) · 4 unmodified lines | |||
| 136 | return ret; | 137 | return ret; |
| 137 | } | 138 | } |
| 138 | 139 | ||
| 139 | static int wm8350_gpio_remove(struct platform_device *pdev) | ||
| 140 | { | ||
| 141 | struct wm8350_gpio_data *wm8350_gpio = platform_get_drvdata(pdev); | ||
| 142 | |||
| 143 | gpiochip_remove(&wm8350_gpio->gpio_chip); | ||
| 144 | return 0; | ||
| 145 | } | ||
| 146 | |||
| 147 | static struct platform_driver wm8350_gpio_driver = { | 140 | static struct platform_driver wm8350_gpio_driver = { |
| 148 | .driver.name = "wm8350-gpio", | 141 | .driver.name = "wm8350-gpio", |
| 149 | .driver.owner = THIS_MODULE, | 142 | .driver.owner = THIS_MODULE, |
| 150 | .probe = wm8350_gpio_probe, | 143 | .probe = wm8350_gpio_probe, |
| 151 | .remove = wm8350_gpio_remove, | ||
| 152 | }; | 144 | }; |
| 153 | 145 | ||
| 154 | static int __init wm8350_gpio_init(void) | 146 | static int __init wm8350_gpio_init(void) |
| @@ -261,34 +261,23 @@ static int wm8994_gpio_probe(struct platform_device *pdev) · 260 unmodified lines | |||
| 261 | else | 261 | else |
| 262 | wm8994_gpio->gpio_chip.base = -1; | 262 | wm8994_gpio->gpio_chip.base = -1; |
| 263 | 263 | ||
| 264 | ret = gpiochip_add_data(&wm8994_gpio->gpio_chip, wm8994_gpio); | 264 | ret = devm_gpiochip_add_data(&pdev->dev, &wm8994_gpio->gpio_chip, |
| 265 | wm8994_gpio); | ||
| 265 | if (ret < 0) { | 266 | if (ret < 0) { |
| 266 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", | 267 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", |
| 267 | ret); | 268 | ret); |
| 268 | goto err; | 269 | return ret; |
| 269 | } | 270 | } |
| 270 | 271 | ||
| 271 | platform_set_drvdata(pdev, wm8994_gpio); | 272 | platform_set_drvdata(pdev, wm8994_gpio); |
| 272 | 273 | ||
| 273 | return ret; | 274 | return ret; |
| 274 | |||
| 275 | err: | ||
| 276 | return ret; | ||
| 277 | } | ||
| 278 | |||
| 279 | static int wm8994_gpio_remove(struct platform_device *pdev) | ||
| 280 | { | ||
| 281 | struct wm8994_gpio *wm8994_gpio = platform_get_drvdata(pdev); | ||
| 282 | |||
| 283 | gpiochip_remove(&wm8994_gpio->gpio_chip); | ||
| 284 | return 0; | ||
| 285 | } | 275 | } |
| 286 | 276 | ||
| 287 | static struct platform_driver wm8994_gpio_driver = { | 277 | static struct platform_driver wm8994_gpio_driver = { |
| 288 | .driver.name = "wm8994-gpio", | 278 | .driver.name = "wm8994-gpio", |
| 289 | .driver.owner = THIS_MODULE, | 279 | .driver.owner = THIS_MODULE, |
| 290 | .probe = wm8994_gpio_probe, | 280 | .probe = wm8994_gpio_probe, |
| 291 | .remove = wm8994_gpio_remove, | ||
| 292 | }; | 281 | }; |
| 293 | 282 | ||
| 294 | static int __init wm8994_gpio_init(void) | 283 | static int __init wm8994_gpio_init(void) |
| @@ -0,0 +1,427 @@ | |||
| 1 | /* | ||
| 2 | * GPIO driver for the WinSystems WS16C48 | ||
| 3 | * Copyright (C) 2016 William Breathitt Gray | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License, version 2, as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, but | ||
| 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 12 | * General Public License for more details. | ||
| 13 | */ | ||
| 14 | #include <linux/bitops.h> | ||
| 15 | #include <linux/device.h> | ||
| 16 | #include <linux/errno.h> | ||
| 17 | #include <linux/gpio/driver.h> | ||
| 18 | #include <linux/io.h> | ||
| 19 | #include <linux/ioport.h> | ||
| 20 | #include <linux/interrupt.h> | ||
| 21 | #include <linux/irqdesc.h> | ||
| 22 | #include <linux/kernel.h> | ||
| 23 | #include <linux/module.h> | ||
| 24 | #include <linux/moduleparam.h> | ||
| 25 | #include <linux/platform_device.h> | ||
| 26 | #include <linux/spinlock.h> | ||
| 27 | |||
| 28 | static unsigned ws16c48_base; | ||
| 29 | module_param(ws16c48_base, uint, 0); | ||
| 30 | MODULE_PARM_DESC(ws16c48_base, "WinSystems WS16C48 base address"); | ||
| 31 | static unsigned ws16c48_irq; | ||
| 32 | module_param(ws16c48_irq, uint, 0); | ||
| 33 | MODULE_PARM_DESC(ws16c48_irq, "WinSystems WS16C48 interrupt line number"); | ||
| 34 | |||
| 35 | /** | ||
| 36 | * struct ws16c48_gpio - GPIO device private data structure | ||
| 37 | * @chip: instance of the gpio_chip | ||
| 38 | * @io_state: bit I/O state (whether bit is set to input or output) | ||
| 39 | * @out_state: output bits state | ||
| 40 | * @lock: synchronization lock to prevent I/O race conditions | ||
| 41 | * @irq_mask: I/O bits affected by interrupts | ||
| 42 | * @flow_mask: IRQ flow type mask for the respective I/O bits | ||
| 43 | * @base: base port address of the GPIO device | ||
| 44 | * @irq: Interrupt line number | ||
| 45 | */ | ||
| 46 | struct ws16c48_gpio { | ||
| 47 | struct gpio_chip chip; | ||
| 48 | unsigned char io_state[6]; | ||
| 49 | unsigned char out_state[6]; | ||
| 50 | spinlock_t lock; | ||
| 51 | unsigned long irq_mask; | ||
| 52 | unsigned long flow_mask; | ||
| 53 | unsigned base; | ||
| 54 | unsigned irq; | ||
| 55 | }; | ||
| 56 | |||
| 57 | static int ws16c48_gpio_get_direction(struct gpio_chip *chip, unsigned offset) | ||
| 58 | { | ||
| 59 | struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip); | ||
| 60 | const unsigned port = offset / 8; | ||
| 61 | const unsigned mask = BIT(offset % 8); | ||
| 62 | |||
| 63 | return !!(ws16c48gpio->io_state[port] & mask); | ||
| 64 | } | ||
| 65 | |||
| 66 | static int ws16c48_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | ||
| 67 | { | ||
| 68 | struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip); | ||
| 69 | const unsigned port = offset / 8; | ||
| 70 | const unsigned mask = BIT(offset % 8); | ||
| 71 | unsigned long flags; | ||
| 72 | |||
| 73 | spin_lock_irqsave(&ws16c48gpio->lock, flags); | ||
| 74 | |||
| 75 | ws16c48gpio->io_state[port] |= mask; | ||
| 76 | ws16c48gpio->out_state[port] &= ~mask; | ||
| 77 | outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port); | ||
| 78 | |||
| 79 | spin_unlock_irqrestore(&ws16c48gpio->lock, flags); | ||
| 80 | |||
| 81 | return 0; | ||
| 82 | } | ||
| 83 | |||
| 84 | static int ws16c48_gpio_direction_output(struct gpio_chip *chip, | ||
| 85 | unsigned offset, int value) | ||
| 86 | { | ||
| 87 | struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip); | ||
| 88 | const unsigned port = offset / 8; | ||
| 89 | const unsigned mask = BIT(offset % 8); | ||
| 90 | unsigned long flags; | ||
| 91 | |||
| 92 | spin_lock_irqsave(&ws16c48gpio->lock, flags); | ||
| 93 | |||
| 94 | ws16c48gpio->io_state[port] &= ~mask; | ||
| 95 | if (value) | ||
| 96 | ws16c48gpio->out_state[port] |= mask; | ||
| 97 | else | ||
| 98 | ws16c48gpio->out_state[port] &= ~mask; | ||
| 99 | outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port); | ||
| 100 | |||
| 101 | spin_unlock_irqrestore(&ws16c48gpio->lock, flags); | ||
| 102 | |||
| 103 | return 0; | ||
| 104 | } | ||
| 105 | |||
| 106 | static int ws16c48_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
| 107 | { | ||
| 108 | struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip); | ||
| 109 | const unsigned port = offset / 8; | ||
| 110 | const unsigned mask = BIT(offset % 8); | ||
| 111 | unsigned long flags; | ||
| 112 | unsigned port_state; | ||
| 113 | |||
| 114 | spin_lock_irqsave(&ws16c48gpio->lock, flags); | ||
| 115 | |||
| 116 | /* ensure that GPIO is set for input */ | ||
| 117 | if (!(ws16c48gpio->io_state[port] & mask)) { | ||
| 118 | spin_unlock_irqrestore(&ws16c48gpio->lock, flags); | ||
| 119 | return -EINVAL; | ||
| 120 | } | ||
| 121 | |||
| 122 | port_state = inb(ws16c48gpio->base + port); | ||
| 123 | |||
| 124 | spin_unlock_irqrestore(&ws16c48gpio->lock, flags); | ||
| 125 | |||
| 126 | return !!(port_state & mask); | ||
| 127 | } | ||
| 128 | |||
| 129 | static void ws16c48_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
| 130 | { | ||
| 131 | struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip); | ||
| 132 | const unsigned port = offset / 8; | ||
| 133 | const unsigned mask = BIT(offset % 8); | ||
| 134 | unsigned long flags; | ||
| 135 | |||
| 136 | spin_lock_irqsave(&ws16c48gpio->lock, flags); | ||
| 137 | |||
| 138 | /* ensure that GPIO is set for output */ | ||
| 139 | if (ws16c48gpio->io_state[port] & mask) { | ||
| 140 | spin_unlock_irqrestore(&ws16c48gpio->lock, flags); | ||
| 141 | return; | ||
| 142 | } | ||
| 143 | |||
| 144 | if (value) | ||
| 145 | ws16c48gpio->out_state[port] |= mask; | ||
| 146 | else | ||
| 147 | ws16c48gpio->out_state[port] &= ~mask; | ||
| 148 | outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port); | ||
| 149 | |||
| 150 | spin_unlock_irqrestore(&ws16c48gpio->lock, flags); | ||
| 151 | } | ||
| 152 | |||
| 153 | static void ws16c48_irq_ack(struct irq_data *data) | ||
| 154 | { | ||
| 155 | struct gpio_chip *chip = irq_data_get_irq_chip_data(data); | ||
| 156 | struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip); | ||
| 157 | const unsigned long offset = irqd_to_hwirq(data); | ||
| 158 | const unsigned port = offset / 8; | ||
| 159 | const unsigned mask = BIT(offset % 8); | ||
| 160 | unsigned long flags; | ||
| 161 | unsigned port_state; | ||
| 162 | |||
| 163 | /* only the first 3 ports support interrupts */ | ||
| 164 | if (port > 2) | ||
| 165 | return; | ||
| 166 | |||
| 167 | spin_lock_irqsave(&ws16c48gpio->lock, flags); | ||
| 168 | |||
| 169 | port_state = ws16c48gpio->irq_mask >> (8*port); | ||
| 170 | |||
| 171 | outb(0x80, ws16c48gpio->base + 7); | ||
| 172 | outb(port_state & ~mask, ws16c48gpio->base + 8 + port); | ||
| 173 | outb(port_state | mask, ws16c48gpio->base + 8 + port); | ||
| 174 | outb(0xC0, ws16c48gpio->base + 7); | ||
| 175 | |||
| 176 | spin_unlock_irqrestore(&ws16c48gpio->lock, flags); | ||
| 177 | } | ||
| 178 | |||
| 179 | static void ws16c48_irq_mask(struct irq_data *data) | ||
| 180 | { | ||
| 181 | struct gpio_chip *chip = irq_data_get_irq_chip_data(data); | ||
| 182 | struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip); | ||
| 183 | const unsigned long offset = irqd_to_hwirq(data); | ||
| 184 | const unsigned long mask = BIT(offset); | ||
| 185 | const unsigned port = offset / 8; | ||
| 186 | unsigned long flags; | ||
| 187 | |||
| 188 | /* only the first 3 ports support interrupts */ | ||
| 189 | if (port > 2) | ||
| 190 | return; | ||
| 191 | |||
| 192 | spin_lock_irqsave(&ws16c48gpio->lock, flags); | ||
| 193 | |||
| 194 | ws16c48gpio->irq_mask &= ~mask; | ||
| 195 | |||
| 196 | outb(0x80, ws16c48gpio->base + 7); | ||
| 197 | outb(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port); | ||
| 198 | outb(0xC0, ws16c48gpio->base + 7); | ||
| 199 | |||
| 200 | spin_unlock_irqrestore(&ws16c48gpio->lock, flags); | ||
| 201 | } | ||
| 202 | |||
| 203 | static void ws16c48_irq_unmask(struct irq_data *data) | ||
| 204 | { | ||
| 205 | struct gpio_chip *chip = irq_data_get_irq_chip_data(data); | ||
| 206 | struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip); | ||
| 207 | const unsigned long offset = irqd_to_hwirq(data); | ||
| 208 | const unsigned long mask = BIT(offset); | ||
| 209 | const unsigned port = offset / 8; | ||
| 210 | unsigned long flags; | ||
| 211 | |||
| 212 | /* only the first 3 ports support interrupts */ | ||
| 213 | if (port > 2) | ||
| 214 | return; | ||
| 215 | |||
| 216 | spin_lock_irqsave(&ws16c48gpio->lock, flags); | ||
| 217 | |||
| 218 | ws16c48gpio->irq_mask |= mask; | ||
| 219 | |||
| 220 | outb(0x80, ws16c48gpio->base + 7); | ||
| 221 | outb(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port); | ||
| 222 | outb(0xC0, ws16c48gpio->base + 7); | ||
| 223 | |||
| 224 | spin_unlock_irqrestore(&ws16c48gpio->lock, flags); | ||
| 225 | } | ||
| 226 | |||
| 227 | static int ws16c48_irq_set_type(struct irq_data *data, unsigned flow_type) | ||
| 228 | { | ||
| 229 | struct gpio_chip *chip = irq_data_get_irq_chip_data(data); | ||
| 230 | struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip); | ||
| 231 | const unsigned long offset = irqd_to_hwirq(data); | ||
| 232 | const unsigned long mask = BIT(offset); | ||
| 233 | const unsigned port = offset / 8; | ||
| 234 | unsigned long flags; | ||
| 235 | |||
| 236 | /* only the first 3 ports support interrupts */ | ||
| 237 | if (port > 2) | ||
| 238 | return -EINVAL; | ||
| 239 | |||
| 240 | spin_lock_irqsave(&ws16c48gpio->lock, flags); | ||
| 241 | |||
| 242 | switch (flow_type) { | ||
| 243 | case IRQ_TYPE_NONE: | ||
| 244 | break; | ||
| 245 | case IRQ_TYPE_EDGE_RISING: | ||
| 246 | ws16c48gpio->flow_mask |= mask; | ||
| 247 | break; | ||
| 248 | case IRQ_TYPE_EDGE_FALLING: | ||
| 249 | ws16c48gpio->flow_mask &= ~mask; | ||
| 250 | break; | ||
| 251 | default: | ||
| 252 | spin_unlock_irqrestore(&ws16c48gpio->lock, flags); | ||
| 253 | return -EINVAL; | ||
| 254 | } | ||
| 255 | |||
| 256 | outb(0x40, ws16c48gpio->base + 7); | ||
| 257 | outb(ws16c48gpio->flow_mask >> (8*port), ws16c48gpio->base + 8 + port); | ||
| 258 | outb(0xC0, ws16c48gpio->base + 7); | ||
| 259 | |||
| 260 | spin_unlock_irqrestore(&ws16c48gpio->lock, flags); | ||
| 261 | |||
| 262 | return 0; | ||
| 263 | } | ||
| 264 | |||
| 265 | static struct irq_chip ws16c48_irqchip = { | ||
| 266 | .name = "ws16c48", | ||
| 267 | .irq_ack = ws16c48_irq_ack, | ||
| 268 | .irq_mask = ws16c48_irq_mask, | ||
| 269 | .irq_unmask = ws16c48_irq_unmask, | ||
| 270 | .irq_set_type = ws16c48_irq_set_type | ||
| 271 | }; | ||
| 272 | |||
| 273 | static irqreturn_t ws16c48_irq_handler(int irq, void *dev_id) | ||
| 274 | { | ||
| 275 | struct ws16c48_gpio *const ws16c48gpio = dev_id; | ||
| 276 | struct gpio_chip *const chip = &ws16c48gpio->chip; | ||
| 277 | unsigned long int_pending; | ||
| 278 | unsigned long port; | ||
| 279 | unsigned long int_id; | ||
| 280 | unsigned long gpio; | ||
| 281 | |||
| 282 | int_pending = inb(ws16c48gpio->base + 6) & 0x7; | ||
| 283 | if (!int_pending) | ||
| 284 | return IRQ_NONE; | ||
| 285 | |||
| 286 | /* loop until all pending interrupts are handled */ | ||
| 287 | do { | ||
| 288 | for_each_set_bit(port, &int_pending, 3) { | ||
| 289 | int_id = inb(ws16c48gpio->base + 8 + port); | ||
| 290 | for_each_set_bit(gpio, &int_id, 8) | ||
| 291 | generic_handle_irq(irq_find_mapping( | ||
| 292 | chip->irqdomain, gpio + 8*port)); | ||
| 293 | } | ||
| 294 | |||
| 295 | int_pending = inb(ws16c48gpio->base + 6) & 0x7; | ||
| 296 | } while (int_pending); | ||
| 297 | |||
| 298 | return IRQ_HANDLED; | ||
| 299 | } | ||
| 300 | |||
| 301 | static int __init ws16c48_probe(struct platform_device *pdev) | ||
| 302 | { | ||
| 303 | struct device *dev = &pdev->dev; | ||
| 304 | struct ws16c48_gpio *ws16c48gpio; | ||
| 305 | const unsigned base = ws16c48_base; | ||
| 306 | const unsigned extent = 16; | ||
| 307 | const char *const name = dev_name(dev); | ||
| 308 | int err; | ||
| 309 | const unsigned irq = ws16c48_irq; | ||
| 310 | |||
| 311 | ws16c48gpio = devm_kzalloc(dev, sizeof(*ws16c48gpio), GFP_KERNEL); | ||
| 312 | if (!ws16c48gpio) | ||
| 313 | return -ENOMEM; | ||
| 314 | |||
| 315 | if (!devm_request_region(dev, base, extent, name)) { | ||
| 316 | dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", | ||
| 317 | base, base + extent); | ||
| 318 | return -EBUSY; | ||
| 319 | } | ||
| 320 | |||
| 321 | ws16c48gpio->chip.label = name; | ||
| 322 | ws16c48gpio->chip.parent = dev; | ||
| 323 | ws16c48gpio->chip.owner = THIS_MODULE; | ||
| 324 | ws16c48gpio->chip.base = -1; | ||
| 325 | ws16c48gpio->chip.ngpio = 48; | ||
| 326 | ws16c48gpio->chip.get_direction = ws16c48_gpio_get_direction; | ||
| 327 | ws16c48gpio->chip.direction_input = ws16c48_gpio_direction_input; | ||
| 328 | ws16c48gpio->chip.direction_output = ws16c48_gpio_direction_output; | ||
| 329 | ws16c48gpio->chip.get = ws16c48_gpio_get; | ||
| 330 | ws16c48gpio->chip.set = ws16c48_gpio_set; | ||
| 331 | ws16c48gpio->base = base; | ||
| 332 | ws16c48gpio->irq = irq; | ||
| 333 | |||
| 334 | spin_lock_init(&ws16c48gpio->lock); | ||
| 335 | |||
| 336 | dev_set_drvdata(dev, ws16c48gpio); | ||
| 337 | |||
| 338 | err = gpiochip_add_data(&ws16c48gpio->chip, ws16c48gpio); | ||
| 339 | if (err) { | ||
| 340 | dev_err(dev, "GPIO registering failed (%d)\n", err); | ||
| 341 | return err; | ||
| 342 | } | ||
| 343 | |||
| 344 | /* Disable IRQ by default */ | ||
| 345 | outb(0x80, base + 7); | ||
| 346 | outb(0, base + 8); | ||
| 347 | outb(0, base + 9); | ||
| 348 | outb(0, base + 10); | ||
| 349 | outb(0xC0, base + 7); | ||
| 350 | |||
| 351 | err = gpiochip_irqchip_add(&ws16c48gpio->chip, &ws16c48_irqchip, 0, | ||
| 352 | handle_edge_irq, IRQ_TYPE_NONE); | ||
| 353 | if (err) { | ||
| 354 | dev_err(dev, "Could not add irqchip (%d)\n", err); | ||
| 355 | goto err_gpiochip_remove; | ||
| 356 | } | ||
| 357 | |||
| 358 | err = request_irq(irq, ws16c48_irq_handler, IRQF_SHARED, name, | ||
| 359 | ws16c48gpio); | ||
| 360 | if (err) { | ||
| 361 | dev_err(dev, "IRQ handler registering failed (%d)\n", err); | ||
| 362 | goto err_gpiochip_remove; | ||
| 363 | } | ||
| 364 | |||
| 365 | return 0; | ||
| 366 | |||
| 367 | err_gpiochip_remove: | ||
| 368 | gpiochip_remove(&ws16c48gpio->chip); | ||
| 369 | return err; | ||
| 370 | } | ||
| 371 | |||
| 372 | static int ws16c48_remove(struct platform_device *pdev) | ||
| 373 | { | ||
| 374 | struct ws16c48_gpio *const ws16c48gpio = platform_get_drvdata(pdev); | ||
| 375 | |||
| 376 | free_irq(ws16c48gpio->irq, ws16c48gpio); | ||
| 377 | gpiochip_remove(&ws16c48gpio->chip); | ||
| 378 | |||
| 379 | return 0; | ||
| 380 | } | ||
| 381 | |||
| 382 | static struct platform_device *ws16c48_device; | ||
| 383 | |||
| 384 | static struct platform_driver ws16c48_driver = { | ||
| 385 | .driver = { | ||
| 386 | .name = "ws16c48" | ||
| 387 | }, | ||
| 388 | .remove = ws16c48_remove | ||
| 389 | }; | ||
| 390 | |||
| 391 | static void __exit ws16c48_exit(void) | ||
| 392 | { | ||
| 393 | platform_device_unregister(ws16c48_device); | ||
| 394 | platform_driver_unregister(&ws16c48_driver); | ||
| 395 | } | ||
| 396 | |||
| 397 | static int __init ws16c48_init(void) | ||
| 398 | { | ||
| 399 | int err; | ||
| 400 | |||
| 401 | ws16c48_device = platform_device_alloc(ws16c48_driver.driver.name, -1); | ||
| 402 | if (!ws16c48_device) | ||
| 403 | return -ENOMEM; | ||
| 404 | |||
| 405 | err = platform_device_add(ws16c48_device); | ||
| 406 | if (err) | ||
| 407 | goto err_platform_device; | ||
| 408 | |||
| 409 | err = platform_driver_probe(&ws16c48_driver, ws16c48_probe); | ||
| 410 | if (err) | ||
| 411 | goto err_platform_driver; | ||
| 412 | |||
| 413 | return 0; | ||
| 414 | |||
| 415 | err_platform_driver: | ||
| 416 | platform_device_del(ws16c48_device); | ||
| 417 | err_platform_device: | ||
| 418 | platform_device_put(ws16c48_device); | ||
| 419 | return err; | ||
| 420 | } | ||
| 421 | |||
| 422 | module_init(ws16c48_init); | ||
| 423 | module_exit(ws16c48_exit); | ||
| 424 | |||
| 425 | MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>"); | ||
| 426 | MODULE_DESCRIPTION("WinSystems WS16C48 GPIO driver"); | ||
| 427 | MODULE_LICENSE("GPL v2"); | ||
| @@ -2,8 +2,9 @@ · 1 unmodified line | |||
| 2 | * AppliedMicro X-Gene SoC GPIO-Standby Driver | 2 | * AppliedMicro X-Gene SoC GPIO-Standby Driver |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2014, Applied Micro Circuits Corporation | 4 | * Copyright (c) 2014, Applied Micro Circuits Corporation |
| 5 | * Author: Tin Huynh <tnhuynh@apm.com>. | 5 | * Author: Tin Huynh <tnhuynh@apm.com>. |
| 6 | * Y Vo <yvo@apm.com>. | 6 | * Y Vo <yvo@apm.com>. |
| 7 | * Quan Nguyen <qnguyen@apm.com>. | ||
| 7 | * | 8 | * |
| 8 | * This program is free software; you can redistribute it and/or modify it | 9 | * 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 | * under the terms of the GNU General Public License as published by the |
| @@ -28,9 +29,14 @@ · 18 unmodified lines | |||
| 28 | 29 | ||
| 29 | #include "gpiolib.h" | 30 | #include "gpiolib.h" |
| 30 | 31 | ||
| 31 | #define XGENE_MAX_GPIO_DS 22 | 32 | /* Common property names */ |
| 32 | #define XGENE_MAX_GPIO_DS_IRQ 6 | 33 | #define XGENE_NIRQ_PROPERTY "apm,nr-irqs" |
| 34 | #define XGENE_NGPIO_PROPERTY "apm,nr-gpios" | ||
| 35 | #define XGENE_IRQ_START_PROPERTY "apm,irq-start" | ||
| 33 | 36 | ||
| 37 | #define XGENE_DFLT_MAX_NGPIO 22 | ||
| 38 | #define XGENE_DFLT_MAX_NIRQ 6 | ||
| 39 | #define XGENE_DFLT_IRQ_START_PIN 8 | ||
| 34 | #define GPIO_MASK(x) (1U << ((x) % 32)) | 40 | #define GPIO_MASK(x) (1U << ((x) % 32)) |
| 35 | 41 | ||
| 36 | #define MPA_GPIO_INT_LVL 0x0290 | 42 | #define MPA_GPIO_INT_LVL 0x0290 |
| @@ -39,19 +45,32 @@ · 2 unmodified lines | |||
| 39 | #define MPA_GPIO_IN_ADDR 0x02a4 | 45 | #define MPA_GPIO_IN_ADDR 0x02a4 |
| 40 | #define MPA_GPIO_SEL_LO 0x0294 | 46 | #define MPA_GPIO_SEL_LO 0x0294 |
| 41 | 47 | ||
| 48 | #define GPIO_INT_LEVEL_H 0x000001 | ||
| 49 | #define GPIO_INT_LEVEL_L 0x000000 | ||
| 50 | |||
| 42 | /** | 51 | /** |
| 43 | * struct xgene_gpio_sb - GPIO-Standby private data structure. | 52 | * struct xgene_gpio_sb - GPIO-Standby private data structure. |
| 44 | * @gc: memory-mapped GPIO controllers. | 53 | * @gc: memory-mapped GPIO controllers. |
| 45 | * @irq: Mapping GPIO pins and interrupt number | 54 | * @regs: GPIO register base offset |
| 46 | * nirq: Number of GPIO pins that supports interrupt | 55 | * @irq_domain: GPIO interrupt domain |
| 56 | * @irq_start: GPIO pin that start support interrupt | ||
| 57 | * @nirq: Number of GPIO pins that supports interrupt | ||
| 58 | * @parent_irq_base: Start parent HWIRQ | ||
| 47 | */ | 59 | */ |
| 48 | struct xgene_gpio_sb { | 60 | struct xgene_gpio_sb { |
| 49 | struct gpio_chip gc; | 61 | struct gpio_chip gc; |
| 50 | u32 *irq; | 62 | void __iomem *regs; |
| 51 | u32 nirq; | 63 | struct irq_domain *irq_domain; |
| 64 | u16 irq_start; | ||
| 65 | u16 nirq; | ||
| 66 | u16 parent_irq_base; | ||
| 52 | }; | 67 | }; |
| 53 | 68 | ||
| 54 | static void xgene_gpio_set_bit(struct gpio_chip *gc, void __iomem *reg, u32 gpio, int val) | 69 | #define HWIRQ_TO_GPIO(priv, hwirq) ((hwirq) + (priv)->irq_start) |
| 70 | #define GPIO_TO_HWIRQ(priv, gpio) ((gpio) - (priv)->irq_start) | ||
| 71 | |||
| 72 | static void xgene_gpio_set_bit(struct gpio_chip *gc, | ||
| 73 | void __iomem *reg, u32 gpio, int val) | ||
| 55 | { | 74 | { |
| 56 | u32 data; | 75 | u32 data; |
| 57 | 76 | ||
| @@ -63,23 +82,170 @@ static void xgene_gpio_set_bit(struct gpio_chip *gc, void __iomem *reg, u32 gpio · 5 unmodified lines | |||
| 63 | gc->write_reg(reg, data); | 82 | gc->write_reg(reg, data); |
| 64 | } | 83 | } |
| 65 | 84 | ||
| 66 | static int apm_gpio_sb_to_irq(struct gpio_chip *gc, u32 gpio) | 85 | static int xgene_gpio_sb_irq_set_type(struct irq_data *d, unsigned int type) |
| 86 | { | ||
| 87 | struct xgene_gpio_sb *priv = irq_data_get_irq_chip_data(d); | ||
| 88 | int gpio = HWIRQ_TO_GPIO(priv, d->hwirq); | ||
| 89 | int lvl_type = GPIO_INT_LEVEL_H; | ||
| 90 | |||
| 91 | switch (type & IRQ_TYPE_SENSE_MASK) { | ||
| 92 | case IRQ_TYPE_EDGE_RISING: | ||
| 93 | case IRQ_TYPE_LEVEL_HIGH: | ||
| 94 | lvl_type = GPIO_INT_LEVEL_H; | ||
| 95 | break; | ||
| 96 | case IRQ_TYPE_EDGE_FALLING: | ||
| 97 | case IRQ_TYPE_LEVEL_LOW: | ||
| 98 | lvl_type = GPIO_INT_LEVEL_L; | ||
| 99 | break; | ||
| 100 | default: | ||
| 101 | break; | ||
| 102 | } | ||
| 103 | |||
| 104 | xgene_gpio_set_bit(&priv->gc, priv->regs + MPA_GPIO_SEL_LO, | ||
| 105 | gpio * 2, 1); | ||
| 106 | xgene_gpio_set_bit(&priv->gc, priv->regs + MPA_GPIO_INT_LVL, | ||
| 107 | d->hwirq, lvl_type); | ||
| 108 | |||
| 109 | /* Propagate IRQ type setting to parent */ | ||
| 110 | if (type & IRQ_TYPE_EDGE_BOTH) | ||
| 111 | return irq_chip_set_type_parent(d, IRQ_TYPE_EDGE_RISING); | ||
| 112 | else | ||
| 113 | return irq_chip_set_type_parent(d, IRQ_TYPE_LEVEL_HIGH); | ||
| 114 | } | ||
| 115 | |||
| 116 | static struct irq_chip xgene_gpio_sb_irq_chip = { | ||
| 117 | .name = "sbgpio", | ||
| 118 | .irq_eoi = irq_chip_eoi_parent, | ||
| 119 | .irq_mask = irq_chip_mask_parent, | ||
| 120 | .irq_unmask = irq_chip_unmask_parent, | ||
| 121 | .irq_set_type = xgene_gpio_sb_irq_set_type, | ||
| 122 | }; | ||
| 123 | |||
| 124 | static int xgene_gpio_sb_to_irq(struct gpio_chip *gc, u32 gpio) | ||
| 67 | { | 125 | { |
| 68 | struct xgene_gpio_sb *priv = gpiochip_get_data(gc); | 126 | struct xgene_gpio_sb *priv = gpiochip_get_data(gc); |
| 127 | struct irq_fwspec fwspec; | ||
| 128 | |||
| 129 | if ((gpio < priv->irq_start) || | ||
| 130 | (gpio > HWIRQ_TO_GPIO(priv, priv->nirq))) | ||
| 131 | return -ENXIO; | ||
| 132 | |||
| 133 | if (gc->parent->of_node) | ||
| 134 | fwspec.fwnode = of_node_to_fwnode(gc->parent->of_node); | ||
| 135 | else | ||
| 136 | fwspec.fwnode = gc->parent->fwnode; | ||
| 137 | fwspec.param_count = 2; | ||
| 138 | fwspec.param[0] = GPIO_TO_HWIRQ(priv, gpio); | ||
| 139 | fwspec.param[1] = IRQ_TYPE_NONE; | ||
| 140 | return irq_create_fwspec_mapping(&fwspec); | ||
| 141 | } | ||
| 142 | |||
| 143 | static void xgene_gpio_sb_domain_activate(struct irq_domain *d, | ||
| 144 | struct irq_data *irq_data) | ||
| 145 | { | ||
| 146 | struct xgene_gpio_sb *priv = d->host_data; | ||
| 147 | u32 gpio = HWIRQ_TO_GPIO(priv, irq_data->hwirq); | ||
| 148 | |||
| 149 | if (gpiochip_lock_as_irq(&priv->gc, gpio)) { | ||
| 150 | dev_err(priv->gc.parent, | ||
| 151 | "Unable to configure XGene GPIO standby pin %d as IRQ\n", | ||
| 152 | gpio); | ||
| 153 | return; | ||
| 154 | } | ||
| 155 | |||
| 156 | xgene_gpio_set_bit(&priv->gc, priv->regs + MPA_GPIO_SEL_LO, | ||
| 157 | gpio * 2, 1); | ||
| 158 | } | ||
| 159 | |||
| 160 | static void xgene_gpio_sb_domain_deactivate(struct irq_domain *d, | ||
| 161 | struct irq_data *irq_data) | ||
| 162 | { | ||
| 163 | struct xgene_gpio_sb *priv = d->host_data; | ||
| 164 | u32 gpio = HWIRQ_TO_GPIO(priv, irq_data->hwirq); | ||
| 165 | |||
| 166 | gpiochip_unlock_as_irq(&priv->gc, gpio); | ||
| 167 | xgene_gpio_set_bit(&priv->gc, priv->regs + MPA_GPIO_SEL_LO, | ||
| 168 | gpio * 2, 0); | ||
| 169 | } | ||
| 170 | |||
| 171 | static int xgene_gpio_sb_domain_translate(struct irq_domain *d, | ||
| 172 | struct irq_fwspec *fwspec, | ||
| 173 | unsigned long *hwirq, | ||
| 174 | unsigned int *type) | ||
| 175 | { | ||
| 176 | struct xgene_gpio_sb *priv = d->host_data; | ||
| 177 | |||
| 178 | if ((fwspec->param_count != 2) || | ||
| 179 | (fwspec->param[0] >= priv->nirq)) | ||
| 180 | return -EINVAL; | ||
| 181 | *hwirq = fwspec->param[0]; | ||
| 182 | *type = fwspec->param[1]; | ||
| 183 | return 0; | ||
| 184 | } | ||
| 185 | |||
| 186 | static int xgene_gpio_sb_domain_alloc(struct irq_domain *domain, | ||
| 187 | unsigned int virq, | ||
| 188 | unsigned int nr_irqs, void *data) | ||
| 189 | { | ||
| 190 | struct irq_fwspec *fwspec = data; | ||
| 191 | struct irq_fwspec parent_fwspec; | ||
| 192 | struct xgene_gpio_sb *priv = domain->host_data; | ||
| 193 | irq_hw_number_t hwirq; | ||
| 194 | unsigned int i; | ||
| 195 | |||
| 196 | hwirq = fwspec->param[0]; | ||
| 197 | for (i = 0; i < nr_irqs; i++) | ||
| 198 | irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, | ||
| 199 | &xgene_gpio_sb_irq_chip, priv); | ||
| 69 | 200 | ||
| 70 | if (priv->irq[gpio]) | 201 | parent_fwspec.fwnode = domain->parent->fwnode; |
| 71 | return priv->irq[gpio]; | 202 | if (is_of_node(parent_fwspec.fwnode)) { |
| 203 | parent_fwspec.param_count = 3; | ||
| 204 | parent_fwspec.param[0] = 0;/* SPI */ | ||
| 205 | /* Skip SGIs and PPIs*/ | ||
| 206 | parent_fwspec.param[1] = hwirq + priv->parent_irq_base - 32; | ||
| 207 | parent_fwspec.param[2] = fwspec->param[1]; | ||
| 208 | } else if (is_fwnode_irqchip(parent_fwspec.fwnode)) { | ||
| 209 | parent_fwspec.param_count = 2; | ||
| 210 | parent_fwspec.param[0] = hwirq + priv->parent_irq_base; | ||
| 211 | parent_fwspec.param[1] = fwspec->param[1]; | ||
| 212 | } else | ||
| 213 | return -EINVAL; | ||
| 72 | 214 | ||
| 73 | return -ENXIO; | 215 | return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, |
| 216 | &parent_fwspec); | ||
| 74 | } | 217 | } |
| 75 | 218 | ||
| 219 | static void xgene_gpio_sb_domain_free(struct irq_domain *domain, | ||
| 220 | unsigned int virq, | ||
| 221 | unsigned int nr_irqs) | ||
| 222 | { | ||
| 223 | struct irq_data *d; | ||
| 224 | unsigned int i; | ||
| 225 | |||
| 226 | for (i = 0; i < nr_irqs; i++) { | ||
| 227 | d = irq_domain_get_irq_data(domain, virq + i); | ||
| 228 | irq_domain_reset_irq_data(d); | ||
| 229 | } | ||
| 230 | } | ||
| 231 | |||
| 232 | static const struct irq_domain_ops xgene_gpio_sb_domain_ops = { | ||
| 233 | .translate = xgene_gpio_sb_domain_translate, | ||
| 234 | .alloc = xgene_gpio_sb_domain_alloc, | ||
| 235 | .free = xgene_gpio_sb_domain_free, | ||
| 236 | .activate = xgene_gpio_sb_domain_activate, | ||
| 237 | .deactivate = xgene_gpio_sb_domain_deactivate, | ||
| 238 | }; | ||
| 239 | |||
| 76 | static int xgene_gpio_sb_probe(struct platform_device *pdev) | 240 | static int xgene_gpio_sb_probe(struct platform_device *pdev) |
| 77 | { | 241 | { |
| 78 | struct xgene_gpio_sb *priv; | 242 | struct xgene_gpio_sb *priv; |
| 79 | u32 ret, i; | 243 | int ret; |
| 80 | u32 default_lines[] = {0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D}; | ||
| 81 | struct resource *res; | 244 | struct resource *res; |
| 82 | void __iomem *regs; | 245 | void __iomem *regs; |
| 246 | struct irq_domain *parent_domain = NULL; | ||
| 247 | struct fwnode_handle *fwnode; | ||
| 248 | u32 val32; | ||
| 83 | 249 | ||
| 84 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); | 250 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); |
| 85 | if (!priv) | 251 | if (!priv) |
| @@ -90,6 +256,18 @@ static int xgene_gpio_sb_probe(struct platform_device *pdev) · 4 unmodified lines | |||
| 90 | if (IS_ERR(regs)) | 256 | if (IS_ERR(regs)) |
| 91 | return PTR_ERR(regs); | 257 | return PTR_ERR(regs); |
| 92 | 258 | ||
| 259 | priv->regs = regs; | ||
| 260 | |||
| 261 | ret = platform_get_irq(pdev, 0); | ||
| 262 | if (ret > 0) { | ||
| 263 | priv->parent_irq_base = irq_get_irq_data(ret)->hwirq; | ||
| 264 | parent_domain = irq_get_irq_data(ret)->domain; | ||
| 265 | } | ||
| 266 | if (!parent_domain) { | ||
| 267 | dev_err(&pdev->dev, "unable to obtain parent domain\n"); | ||
| 268 | return -ENODEV; | ||
| 269 | } | ||
| 270 | |||
| 93 | ret = bgpio_init(&priv->gc, &pdev->dev, 4, | 271 | ret = bgpio_init(&priv->gc, &pdev->dev, 4, |
| 94 | regs + MPA_GPIO_IN_ADDR, | 272 | regs + MPA_GPIO_IN_ADDR, |
| 95 | regs + MPA_GPIO_OUT_ADDR, NULL, | 273 | regs + MPA_GPIO_OUT_ADDR, NULL, |
| @@ -97,30 +275,51 @@ static int xgene_gpio_sb_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 97 | if (ret) | 275 | if (ret) |
| 98 | return ret; | 276 | return ret; |
| 99 | 277 | ||
| 100 | priv->gc.to_irq = apm_gpio_sb_to_irq; | 278 | priv->gc.to_irq = xgene_gpio_sb_to_irq; |
| 101 | priv->gc.ngpio = XGENE_MAX_GPIO_DS; | ||
| 102 | 279 | ||
| 103 | priv->nirq = XGENE_MAX_GPIO_DS_IRQ; | 280 | /* Retrieve start irq pin, use default if property not found */ |
| 281 | priv->irq_start = XGENE_DFLT_IRQ_START_PIN; | ||
| 282 | if (!device_property_read_u32(&pdev->dev, | ||
| 283 | XGENE_IRQ_START_PROPERTY, &val32)) | ||
| 284 | priv->irq_start = val32; | ||
| 104 | 285 | ||
| 105 | priv->irq = devm_kzalloc(&pdev->dev, sizeof(u32) * XGENE_MAX_GPIO_DS, | 286 | /* Retrieve number irqs, use default if property not found */ |
| 106 | GFP_KERNEL); | 287 | priv->nirq = XGENE_DFLT_MAX_NIRQ; |
| 107 | if (!priv->irq) | 288 | if (!device_property_read_u32(&pdev->dev, XGENE_NIRQ_PROPERTY, &val32)) |
| 108 | return -ENOMEM; | 289 | priv->nirq = val32; |
| 109 | 290 | ||
| 110 | for (i = 0; i < priv->nirq; i++) { | 291 | /* Retrieve number gpio, use default if property not found */ |
| 111 | priv->irq[default_lines[i]] = platform_get_irq(pdev, i); | 292 | priv->gc.ngpio = XGENE_DFLT_MAX_NGPIO; |
| 112 | xgene_gpio_set_bit(&priv->gc, regs + MPA_GPIO_SEL_LO, | 293 | if (!device_property_read_u32(&pdev->dev, XGENE_NGPIO_PROPERTY, &val32)) |
| 113 | default_lines[i] * 2, 1); | 294 | priv->gc.ngpio = val32; |
| 114 | xgene_gpio_set_bit(&priv->gc, regs + MPA_GPIO_INT_LVL, i, 1); | 295 | |
| 115 | } | 296 | dev_info(&pdev->dev, "Support %d gpios, %d irqs start from pin %d\n", |
| 297 | priv->gc.ngpio, priv->nirq, priv->irq_start); | ||
| 116 | 298 | ||
| 117 | platform_set_drvdata(pdev, priv); | 299 | platform_set_drvdata(pdev, priv); |
| 118 | 300 | ||
| 119 | ret = gpiochip_add_data(&priv->gc, priv); | 301 | if (pdev->dev.of_node) |
| 120 | if (ret) | 302 | fwnode = of_node_to_fwnode(pdev->dev.of_node); |
| 121 | dev_err(&pdev->dev, "failed to register X-Gene GPIO Standby driver\n"); | ||
| 122 | else | 303 | else |
| 123 | dev_info(&pdev->dev, "X-Gene GPIO Standby driver registered\n"); | 304 | fwnode = pdev->dev.fwnode; |
| 305 | |||
| 306 | priv->irq_domain = irq_domain_create_hierarchy(parent_domain, | ||
| 307 | 0, priv->nirq, fwnode, | ||
| 308 | &xgene_gpio_sb_domain_ops, priv); | ||
| 309 | if (!priv->irq_domain) | ||
| 310 | return -ENODEV; | ||
| 311 | |||
| 312 | priv->gc.irqdomain = priv->irq_domain; | ||
| 313 | |||
| 314 | ret = devm_gpiochip_add_data(&pdev->dev, &priv->gc, priv); | ||
| 315 | if (ret) { | ||
| 316 | dev_err(&pdev->dev, | ||
| 317 | "failed to register X-Gene GPIO Standby driver\n"); | ||
| 318 | irq_domain_remove(priv->irq_domain); | ||
| 319 | return ret; | ||
| 320 | } | ||
| 321 | |||
| 322 | dev_info(&pdev->dev, "X-Gene GPIO Standby driver registered\n"); | ||
| 124 | 323 | ||
| 125 | if (priv->nirq > 0) { | 324 | if (priv->nirq > 0) { |
| 126 | /* Register interrupt handlers for gpio signaled acpi events */ | 325 | /* Register interrupt handlers for gpio signaled acpi events */ |
| @@ -138,7 +337,8 @@ static int xgene_gpio_sb_remove(struct platform_device *pdev) · 11 unmodified lines | |||
| 138 | acpi_gpiochip_free_interrupts(&priv->gc); | 337 | acpi_gpiochip_free_interrupts(&priv->gc); |
| 139 | } | 338 | } |
| 140 | 339 | ||
| 141 | gpiochip_remove(&priv->gc); | 340 | irq_domain_remove(priv->irq_domain); |
| 341 | |||
| 142 | return 0; | 342 | return 0; |
| 143 | } | 343 | } |
| 144 | 344 | ||
| @@ -193,7 +193,7 @@ static int xgene_gpio_probe(struct platform_device *pdev) · 192 unmodified lines | |||
| 193 | 193 | ||
| 194 | platform_set_drvdata(pdev, gpio); | 194 | platform_set_drvdata(pdev, gpio); |
| 195 | 195 | ||
| 196 | err = gpiochip_add_data(&gpio->chip, gpio); | 196 | err = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio); |
| 197 | if (err) { | 197 | if (err) { |
| 198 | dev_err(&pdev->dev, | 198 | dev_err(&pdev->dev, |
| 199 | "failed to register gpiochip.\n"); | 199 | "failed to register gpiochip.\n"); |
| @@ -207,14 +207,6 @@ err: · 7 unmodified lines | |||
| 207 | return err; | 207 | return err; |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | static int xgene_gpio_remove(struct platform_device *pdev) | ||
| 211 | { | ||
| 212 | struct xgene_gpio *gpio = platform_get_drvdata(pdev); | ||
| 213 | |||
| 214 | gpiochip_remove(&gpio->chip); | ||
| 215 | return 0; | ||
| 216 | } | ||
| 217 | |||
| 218 | static const struct of_device_id xgene_gpio_of_match[] = { | 210 | static const struct of_device_id xgene_gpio_of_match[] = { |
| 219 | { .compatible = "apm,xgene-gpio", }, | 211 | { .compatible = "apm,xgene-gpio", }, |
| 220 | {}, | 212 | {}, |
| @@ -228,7 +220,6 @@ static struct platform_driver xgene_gpio_driver = { · 7 unmodified lines | |||
| 228 | .pm = XGENE_GPIO_PM_OPS, | 220 | .pm = XGENE_GPIO_PM_OPS, |
| 229 | }, | 221 | }, |
| 230 | .probe = xgene_gpio_probe, | 222 | .probe = xgene_gpio_probe, |
| 231 | .remove = xgene_gpio_remove, | ||
| 232 | }; | 223 | }; |
| 233 | 224 | ||
| 234 | module_platform_driver(xgene_gpio_driver); | 225 | module_platform_driver(xgene_gpio_driver); |
| @@ -71,29 +71,29 @@ static int acpi_gpiochip_find(struct gpio_chip *gc, void *data) · 70 unmodified lines | |||
| 71 | * controller uses pin controller and the mapping is not contiguous the | 71 | * controller uses pin controller and the mapping is not contiguous the |
| 72 | * offset might be different. | 72 | * offset might be different. |
| 73 | */ | 73 | */ |
| 74 | static int acpi_gpiochip_pin_to_gpio_offset(struct gpio_chip *chip, int pin) | 74 | static int acpi_gpiochip_pin_to_gpio_offset(struct gpio_device *gdev, int pin) |
| 75 | { | 75 | { |
| 76 | struct gpio_pin_range *pin_range; | 76 | struct gpio_pin_range *pin_range; |
| 77 | 77 | ||
| 78 | /* If there are no ranges in this chip, use 1:1 mapping */ | 78 | /* If there are no ranges in this chip, use 1:1 mapping */ |
| 79 | if (list_empty(&chip->pin_ranges)) | 79 | if (list_empty(&gdev->pin_ranges)) |
| 80 | return pin; | 80 | return pin; |
| 81 | 81 | ||
| 82 | list_for_each_entry(pin_range, &chip->pin_ranges, node) { | 82 | list_for_each_entry(pin_range, &gdev->pin_ranges, node) { |
| 83 | const struct pinctrl_gpio_range *range = &pin_range->range; | 83 | const struct pinctrl_gpio_range *range = &pin_range->range; |
| 84 | int i; | 84 | int i; |
| 85 | 85 | ||
| 86 | if (range->pins) { | 86 | if (range->pins) { |
| 87 | for (i = 0; i < range->npins; i++) { | 87 | for (i = 0; i < range->npins; i++) { |
| 88 | if (range->pins[i] == pin) | 88 | if (range->pins[i] == pin) |
| 89 | return range->base + i - chip->base; | 89 | return range->base + i - gdev->base; |
| 90 | } | 90 | } |
| 91 | } else { | 91 | } else { |
| 92 | if (pin >= range->pin_base && | 92 | if (pin >= range->pin_base && |
| 93 | pin < range->pin_base + range->npins) { | 93 | pin < range->pin_base + range->npins) { |
| 94 | unsigned gpio_base; | 94 | unsigned gpio_base; |
| 95 | 95 | ||
| 96 | gpio_base = range->base - chip->base; | 96 | gpio_base = range->base - gdev->base; |
| 97 | return gpio_base + pin - range->pin_base; | 97 | return gpio_base + pin - range->pin_base; |
| 98 | } | 98 | } |
| 99 | } | 99 | } |
| @@ -102,7 +102,7 @@ static int acpi_gpiochip_pin_to_gpio_offset(struct gpio_chip *chip, int pin) · 2 unmodified lines | |||
| 102 | return -EINVAL; | 102 | return -EINVAL; |
| 103 | } | 103 | } |
| 104 | #else | 104 | #else |
| 105 | static inline int acpi_gpiochip_pin_to_gpio_offset(struct gpio_chip *chip, | 105 | static inline int acpi_gpiochip_pin_to_gpio_offset(struct gpio_device *gdev, |
| 106 | int pin) | 106 | int pin) |
| 107 | { | 107 | { |
| 108 | return pin; | 108 | return pin; |
| @@ -134,7 +134,7 @@ static struct gpio_desc *acpi_get_gpiod(char *path, int pin) · 25 unmodified lines | |||
| 134 | if (!chip) | 134 | if (!chip) |
| 135 | return ERR_PTR(-EPROBE_DEFER); | 135 | return ERR_PTR(-EPROBE_DEFER); |
| 136 | 136 | ||
| 137 | offset = acpi_gpiochip_pin_to_gpio_offset(chip, pin); | 137 | offset = acpi_gpiochip_pin_to_gpio_offset(chip->gpiodev, pin); |
| 138 | if (offset < 0) | 138 | if (offset < 0) |
| 139 | return ERR_PTR(offset); | 139 | return ERR_PTR(offset); |
| 140 | 140 | ||
| @@ -202,7 +202,7 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares, · 61 unmodified lines | |||
| 202 | if (!handler) | 202 | if (!handler) |
| 203 | return AE_BAD_PARAMETER; | 203 | return AE_BAD_PARAMETER; |
| 204 | 204 | ||
| 205 | pin = acpi_gpiochip_pin_to_gpio_offset(chip, pin); | 205 | pin = acpi_gpiochip_pin_to_gpio_offset(chip->gpiodev, pin); |
| 206 | if (pin < 0) | 206 | if (pin < 0) |
| 207 | return AE_BAD_PARAMETER; | 207 | return AE_BAD_PARAMETER; |
| 208 | 208 | ||
| @@ -673,7 +673,7 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address, · 464 unmodified lines | |||
| 673 | struct gpio_desc *desc; | 673 | struct gpio_desc *desc; |
| 674 | bool found; | 674 | bool found; |
| 675 | 675 | ||
| 676 | pin = acpi_gpiochip_pin_to_gpio_offset(chip, pin); | 676 | pin = acpi_gpiochip_pin_to_gpio_offset(chip->gpiodev, pin); |
| 677 | if (pin < 0) { | 677 | if (pin < 0) { |
| 678 | status = AE_BAD_PARAMETER; | 678 | status = AE_BAD_PARAMETER; |
| 679 | goto out; | 679 | goto out; |
| @@ -180,7 +180,7 @@ static int gpio_sysfs_request_irq(struct device *dev, unsigned char flags) · 179 unmodified lines | |||
| 180 | * Remove this redundant call (along with the corresponding | 180 | * Remove this redundant call (along with the corresponding |
| 181 | * unlock) when those drivers have been fixed. | 181 | * unlock) when those drivers have been fixed. |
| 182 | */ | 182 | */ |
| 183 | ret = gpiochip_lock_as_irq(desc->chip, gpio_chip_hwgpio(desc)); | 183 | ret = gpiochip_lock_as_irq(desc->gdev->chip, gpio_chip_hwgpio(desc)); |
| 184 | if (ret < 0) | 184 | if (ret < 0) |
| 185 | goto err_put_kn; | 185 | goto err_put_kn; |
| 186 | 186 | ||
| @@ -194,7 +194,7 @@ static int gpio_sysfs_request_irq(struct device *dev, unsigned char flags) · 7 unmodified lines | |||
| 194 | return 0; | 194 | return 0; |
| 195 | 195 | ||
| 196 | err_unlock: | 196 | err_unlock: |
| 197 | gpiochip_unlock_as_irq(desc->chip, gpio_chip_hwgpio(desc)); | 197 | gpiochip_unlock_as_irq(desc->gdev->chip, gpio_chip_hwgpio(desc)); |
| 198 | err_put_kn: | 198 | err_put_kn: |
| 199 | sysfs_put(data->value_kn); | 199 | sysfs_put(data->value_kn); |
| 200 | 200 | ||
| @@ -212,7 +212,7 @@ static void gpio_sysfs_free_irq(struct device *dev) · 11 unmodified lines | |||
| 212 | 212 | ||
| 213 | data->irq_flags = 0; | 213 | data->irq_flags = 0; |
| 214 | free_irq(data->irq, data); | 214 | free_irq(data->irq, data); |
| 215 | gpiochip_unlock_as_irq(desc->chip, gpio_chip_hwgpio(desc)); | 215 | gpiochip_unlock_as_irq(desc->gdev->chip, gpio_chip_hwgpio(desc)); |
| 216 | sysfs_put(data->value_kn); | 216 | sysfs_put(data->value_kn); |
| 217 | } | 217 | } |
| 218 | 218 | ||
| @@ -547,6 +547,7 @@ static struct class gpio_class = { · 328 unmodified lines | |||
| 547 | int gpiod_export(struct gpio_desc *desc, bool direction_may_change) | 547 | int gpiod_export(struct gpio_desc *desc, bool direction_may_change) |
| 548 | { | 548 | { |
| 549 | struct gpio_chip *chip; | 549 | struct gpio_chip *chip; |
| 550 | struct gpio_device *gdev; | ||
| 550 | struct gpiod_data *data; | 551 | struct gpiod_data *data; |
| 551 | unsigned long flags; | 552 | unsigned long flags; |
| 552 | int status; | 553 | int status; |
| @@ -565,12 +566,13 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change) · 12 unmodified lines | |||
| 565 | return -EINVAL; | 566 | return -EINVAL; |
| 566 | } | 567 | } |
| 567 | 568 | ||
| 568 | chip = desc->chip; | 569 | gdev = desc->gdev; |
| 570 | chip = gdev->chip; | ||
| 569 | 571 | ||
| 570 | mutex_lock(&sysfs_lock); | 572 | mutex_lock(&sysfs_lock); |
| 571 | 573 | ||
| 572 | /* check if chip is being removed */ | 574 | /* check if chip is being removed */ |
| 573 | if (!chip || !chip->cdev) { | 575 | if (!chip || !gdev->mockdev) { |
| 574 | status = -ENODEV; | 576 | status = -ENODEV; |
| 575 | goto err_unlock; | 577 | goto err_unlock; |
| 576 | } | 578 | } |
| @@ -605,7 +607,7 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change) · 28 unmodified lines | |||
| 605 | if (chip->names && chip->names[offset]) | 607 | if (chip->names && chip->names[offset]) |
| 606 | ioname = chip->names[offset]; | 608 | ioname = chip->names[offset]; |
| 607 | 609 | ||
| 608 | dev = device_create_with_groups(&gpio_class, chip->parent, | 610 | dev = device_create_with_groups(&gpio_class, &gdev->dev, |
| 609 | MKDEV(0, 0), data, gpio_groups, | 611 | MKDEV(0, 0), data, gpio_groups, |
| 610 | ioname ? ioname : "gpio%u", | 612 | ioname ? ioname : "gpio%u", |
| 611 | desc_to_gpio(desc)); | 613 | desc_to_gpio(desc)); |
| @@ -716,9 +718,11 @@ err_unlock: · 104 unmodified lines | |||
| 716 | } | 718 | } |
| 717 | EXPORT_SYMBOL_GPL(gpiod_unexport); | 719 | EXPORT_SYMBOL_GPL(gpiod_unexport); |
| 718 | 720 | ||
| 719 | int gpiochip_sysfs_register(struct gpio_chip *chip) | 721 | int gpiochip_sysfs_register(struct gpio_device *gdev) |
| 720 | { | 722 | { |
| 721 | struct device *dev; | 723 | struct device *dev; |
| 724 | struct device *parent; | ||
| 725 | struct gpio_chip *chip = gdev->chip; | ||
| 722 | 726 | ||
| 723 | /* | 727 | /* |
| 724 | * Many systems add gpio chips for SOC support very early, | 728 | * Many systems add gpio chips for SOC support very early, |
| @@ -729,8 +733,17 @@ int gpiochip_sysfs_register(struct gpio_chip *chip) · 4 unmodified lines | |||
| 729 | if (!gpio_class.p) | 733 | if (!gpio_class.p) |
| 730 | return 0; | 734 | return 0; |
| 731 | 735 | ||
| 736 | /* | ||
| 737 | * For sysfs backward compatibility we need to preserve this | ||
| 738 | * preferred parenting to the gpio_chip parent field, if set. | ||
| 739 | */ | ||
| 740 | if (chip->parent) | ||
| 741 | parent = chip->parent; | ||
| 742 | else | ||
| 743 | parent = &gdev->dev; | ||
| 744 | |||
| 732 | /* use chip->base for the ID; it's already known to be unique */ | 745 | /* use chip->base for the ID; it's already known to be unique */ |
| 733 | dev = device_create_with_groups(&gpio_class, chip->parent, | 746 | dev = device_create_with_groups(&gpio_class, parent, |
| 734 | MKDEV(0, 0), | 747 | MKDEV(0, 0), |
| 735 | chip, gpiochip_groups, | 748 | chip, gpiochip_groups, |
| 736 | "gpiochip%d", chip->base); | 749 | "gpiochip%d", chip->base); |
| @@ -738,30 +751,31 @@ int gpiochip_sysfs_register(struct gpio_chip *chip) · 1 unmodified line | |||
| 738 | return PTR_ERR(dev); | 751 | return PTR_ERR(dev); |
| 739 | 752 | ||
| 740 | mutex_lock(&sysfs_lock); | 753 | mutex_lock(&sysfs_lock); |
| 741 | chip->cdev = dev; | 754 | gdev->mockdev = dev; |
| 742 | mutex_unlock(&sysfs_lock); | 755 | mutex_unlock(&sysfs_lock); |
| 743 | 756 | ||
| 744 | return 0; | 757 | return 0; |
| 745 | } | 758 | } |
| 746 | 759 | ||
| 747 | void gpiochip_sysfs_unregister(struct gpio_chip *chip) | 760 | void gpiochip_sysfs_unregister(struct gpio_device *gdev) |
| 748 | { | 761 | { |
| 749 | struct gpio_desc *desc; | 762 | struct gpio_desc *desc; |
| 763 | struct gpio_chip *chip = gdev->chip; | ||
| 750 | unsigned int i; | 764 | unsigned int i; |
| 751 | 765 | ||
| 752 | if (!chip->cdev) | 766 | if (!gdev->mockdev) |
| 753 | return; | 767 | return; |
| 754 | 768 | ||
| 755 | device_unregister(chip->cdev); | 769 | device_unregister(gdev->mockdev); |
| 756 | 770 | ||
| 757 | /* prevent further gpiod exports */ | 771 | /* prevent further gpiod exports */ |
| 758 | mutex_lock(&sysfs_lock); | 772 | mutex_lock(&sysfs_lock); |
| 759 | chip->cdev = NULL; | 773 | gdev->mockdev = NULL; |
| 760 | mutex_unlock(&sysfs_lock); | 774 | mutex_unlock(&sysfs_lock); |
| 761 | 775 | ||
| 762 | /* unregister gpiod class devices owned by sysfs */ | 776 | /* unregister gpiod class devices owned by sysfs */ |
| 763 | for (i = 0; i < chip->ngpio; i++) { | 777 | for (i = 0; i < chip->ngpio; i++) { |
| 764 | desc = &chip->desc[i]; | 778 | desc = &gdev->descs[i]; |
| 765 | if (test_and_clear_bit(FLAG_SYSFS, &desc->flags)) | 779 | if (test_and_clear_bit(FLAG_SYSFS, &desc->flags)) |
| 766 | gpiod_free(desc); | 780 | gpiod_free(desc); |
| 767 | } | 781 | } |
| @@ -771,7 +785,7 @@ static int __init gpiolib_sysfs_init(void) · 3 unmodified lines | |||
| 771 | { | 785 | { |
| 772 | int status; | 786 | int status; |
| 773 | unsigned long flags; | 787 | unsigned long flags; |
| 774 | struct gpio_chip *chip; | 788 | struct gpio_device *gdev; |
| 775 | 789 | ||
| 776 | status = class_register(&gpio_class); | 790 | status = class_register(&gpio_class); |
| 777 | if (status < 0) | 791 | if (status < 0) |
| @@ -784,8 +798,8 @@ static int __init gpiolib_sysfs_init(void) · 6 unmodified lines | |||
| 784 | * registered, and so arch_initcall() can always gpio_export(). | 798 | * registered, and so arch_initcall() can always gpio_export(). |
| 785 | */ | 799 | */ |
| 786 | spin_lock_irqsave(&gpio_lock, flags); | 800 | spin_lock_irqsave(&gpio_lock, flags); |
| 787 | list_for_each_entry(chip, &gpio_chips, list) { | 801 | list_for_each_entry(gdev, &gpio_devices, list) { |
| 788 | if (chip->cdev) | 802 | if (gdev->mockdev) |
| 789 | continue; | 803 | continue; |
| 790 | 804 | ||
| 791 | /* | 805 | /* |
| @@ -798,12 +812,11 @@ static int __init gpiolib_sysfs_init(void) · 6 unmodified lines | |||
| 798 | * gpio_lock prevents us from doing this. | 812 | * gpio_lock prevents us from doing this. |
| 799 | */ | 813 | */ |
| 800 | spin_unlock_irqrestore(&gpio_lock, flags); | 814 | spin_unlock_irqrestore(&gpio_lock, flags); |
| 801 | status = gpiochip_sysfs_register(chip); | 815 | status = gpiochip_sysfs_register(gdev); |
| 802 | spin_lock_irqsave(&gpio_lock, flags); | 816 | spin_lock_irqsave(&gpio_lock, flags); |
| 803 | } | 817 | } |
| 804 | spin_unlock_irqrestore(&gpio_lock, flags); | 818 | spin_unlock_irqrestore(&gpio_lock, flags); |
| 805 | 819 | ||
| 806 | |||
| 807 | return status; | 820 | return status; |
| 808 | } | 821 | } |
| 809 | postcore_initcall(gpiolib_sysfs_init); | 822 | postcore_initcall(gpiolib_sysfs_init); |
| @@ -16,6 +16,11 @@ · 15 unmodified lines | |||
| 16 | #include <linux/gpio/driver.h> | 16 | #include <linux/gpio/driver.h> |
| 17 | #include <linux/gpio/machine.h> | 17 | #include <linux/gpio/machine.h> |
| 18 | #include <linux/pinctrl/consumer.h> | 18 | #include <linux/pinctrl/consumer.h> |
| 19 | #include <linux/idr.h> | ||
| 20 | #include <linux/cdev.h> | ||
| 21 | #include <linux/fs.h> | ||
| 22 | #include <linux/uaccess.h> | ||
| 23 | #include <uapi/linux/gpio.h> | ||
| 19 | 24 | ||
| 20 | #include "gpiolib.h" | 25 | #include "gpiolib.h" |
| 21 | 26 | ||
| @@ -42,6 +47,14 @@ · 20 unmodified lines | |||
| 42 | #define extra_checks 0 | 47 | #define extra_checks 0 |
| 43 | #endif | 48 | #endif |
| 44 | 49 | ||
| 50 | /* Device and char device-related information */ | ||
| 51 | static DEFINE_IDA(gpio_ida); | ||
| 52 | static dev_t gpio_devt; | ||
| 53 | #define GPIO_DEV_MAX 256 /* 256 GPIO chip devices supported */ | ||
| 54 | static struct bus_type gpio_bus_type = { | ||
| 55 | .name = "gpio", | ||
| 56 | }; | ||
| 57 | |||
| 45 | /* gpio_lock prevents conflicts during gpio_desc[] table updates. | 58 | /* gpio_lock prevents conflicts during gpio_desc[] table updates. |
| 46 | * While any GPIO is requested, its gpio_chip is not removable; | 59 | * While any GPIO is requested, its gpio_chip is not removable; |
| 47 | * each GPIO's "requested" flag serves as a lock and refcount. | 60 | * each GPIO's "requested" flag serves as a lock and refcount. |
| @@ -50,8 +63,7 @@ DEFINE_SPINLOCK(gpio_lock); · 2 unmodified lines | |||
| 50 | 63 | ||
| 51 | static DEFINE_MUTEX(gpio_lookup_lock); | 64 | static DEFINE_MUTEX(gpio_lookup_lock); |
| 52 | static LIST_HEAD(gpio_lookup_list); | 65 | static LIST_HEAD(gpio_lookup_list); |
| 53 | LIST_HEAD(gpio_chips); | 66 | LIST_HEAD(gpio_devices); |
| 54 | |||
| 55 | 67 | ||
| 56 | static void gpiochip_free_hogs(struct gpio_chip *chip); | 68 | static void gpiochip_free_hogs(struct gpio_chip *chip); |
| 57 | static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip); | 69 | static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip); |
| @@ -67,15 +79,16 @@ static inline void desc_set_label(struct gpio_desc *d, const char *label) · 9 unmodified lines | |||
| 67 | */ | 79 | */ |
| 68 | struct gpio_desc *gpio_to_desc(unsigned gpio) | 80 | struct gpio_desc *gpio_to_desc(unsigned gpio) |
| 69 | { | 81 | { |
| 70 | struct gpio_chip *chip; | 82 | struct gpio_device *gdev; |
| 71 | unsigned long flags; | 83 | unsigned long flags; |
| 72 | 84 | ||
| 73 | spin_lock_irqsave(&gpio_lock, flags); | 85 | spin_lock_irqsave(&gpio_lock, flags); |
| 74 | 86 | ||
| 75 | list_for_each_entry(chip, &gpio_chips, list) { | 87 | list_for_each_entry(gdev, &gpio_devices, list) { |
| 76 | if (chip->base <= gpio && chip->base + chip->ngpio > gpio) { | 88 | if (gdev->base <= gpio && |
| 89 | gdev->base + gdev->ngpio > gpio) { | ||
| 77 | spin_unlock_irqrestore(&gpio_lock, flags); | 90 | spin_unlock_irqrestore(&gpio_lock, flags); |
| 78 | return &chip->desc[gpio - chip->base]; | 91 | return &gdev->descs[gpio - gdev->base]; |
| 79 | } | 92 | } |
| 80 | } | 93 | } |
| 81 | 94 | ||
| @@ -94,10 +107,12 @@ EXPORT_SYMBOL_GPL(gpio_to_desc); · 12 unmodified lines | |||
| 94 | struct gpio_desc *gpiochip_get_desc(struct gpio_chip *chip, | 107 | struct gpio_desc *gpiochip_get_desc(struct gpio_chip *chip, |
| 95 | u16 hwnum) | 108 | u16 hwnum) |
| 96 | { | 109 | { |
| 97 | if (hwnum >= chip->ngpio) | 110 | struct gpio_device *gdev = chip->gpiodev; |
| 111 | |||
| 112 | if (hwnum >= gdev->ngpio) | ||
| 98 | return ERR_PTR(-EINVAL); | 113 | return ERR_PTR(-EINVAL); |
| 99 | 114 | ||
| 100 | return &chip->desc[hwnum]; | 115 | return &gdev->descs[hwnum]; |
| 101 | } | 116 | } |
| 102 | 117 | ||
| 103 | /** | 118 | /** |
| @@ -107,7 +122,7 @@ struct gpio_desc *gpiochip_get_desc(struct gpio_chip *chip, · 3 unmodified lines | |||
| 107 | */ | 122 | */ |
| 108 | int desc_to_gpio(const struct gpio_desc *desc) | 123 | int desc_to_gpio(const struct gpio_desc *desc) |
| 109 | { | 124 | { |
| 110 | return desc->chip->base + (desc - &desc->chip->desc[0]); | 125 | return desc->gdev->base + (desc - &desc->gdev->descs[0]); |
| 111 | } | 126 | } |
| 112 | EXPORT_SYMBOL_GPL(desc_to_gpio); | 127 | EXPORT_SYMBOL_GPL(desc_to_gpio); |
| 113 | 128 | ||
| @@ -118,23 +133,25 @@ EXPORT_SYMBOL_GPL(desc_to_gpio); · 4 unmodified lines | |||
| 118 | */ | 133 | */ |
| 119 | struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc) | 134 | struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc) |
| 120 | { | 135 | { |
| 121 | return desc ? desc->chip : NULL; | 136 | if (!desc || !desc->gdev || !desc->gdev->chip) |
| 137 | return NULL; | ||
| 138 | return desc->gdev->chip; | ||
| 122 | } | 139 | } |
| 123 | EXPORT_SYMBOL_GPL(gpiod_to_chip); | 140 | EXPORT_SYMBOL_GPL(gpiod_to_chip); |
| 124 | 141 | ||
| 125 | /* dynamic allocation of GPIOs, e.g. on a hotplugged device */ | 142 | /* dynamic allocation of GPIOs, e.g. on a hotplugged device */ |
| 126 | static int gpiochip_find_base(int ngpio) | 143 | static int gpiochip_find_base(int ngpio) |
| 127 | { | 144 | { |
| 128 | struct gpio_chip *chip; | 145 | struct gpio_device *gdev; |
| 129 | int base = ARCH_NR_GPIOS - ngpio; | 146 | int base = ARCH_NR_GPIOS - ngpio; |
| 130 | 147 | ||
| 131 | list_for_each_entry_reverse(chip, &gpio_chips, list) { | 148 | list_for_each_entry_reverse(gdev, &gpio_devices, list) { |
| 132 | /* found a free space? */ | 149 | /* found a free space? */ |
| 133 | if (chip->base + chip->ngpio <= base) | 150 | if (gdev->base + gdev->ngpio <= base) |
| 134 | break; | 151 | break; |
| 135 | else | 152 | else |
| 136 | /* nope, check the space right before the chip */ | 153 | /* nope, check the space right before the chip */ |
| 137 | base = chip->base - ngpio; | 154 | base = gdev->base - ngpio; |
| 138 | } | 155 | } |
| 139 | 156 | ||
| 140 | if (gpio_is_valid(base)) { | 157 | if (gpio_is_valid(base)) { |
| @@ -187,57 +204,45 @@ EXPORT_SYMBOL_GPL(gpiod_get_direction); · 46 unmodified lines | |||
| 187 | * Return -EBUSY if the new chip overlaps with some other chip's integer | 204 | * Return -EBUSY if the new chip overlaps with some other chip's integer |
| 188 | * space. | 205 | * space. |
| 189 | */ | 206 | */ |
| 190 | static int gpiochip_add_to_list(struct gpio_chip *chip) | 207 | static int gpiodev_add_to_list(struct gpio_device *gdev) |
| 191 | { | 208 | { |
| 192 | struct gpio_chip *iterator; | 209 | struct gpio_device *prev, *next; |
| 193 | struct gpio_chip *previous = NULL; | ||
| 194 | 210 | ||
| 195 | if (list_empty(&gpio_chips)) { | 211 | if (list_empty(&gpio_devices)) { |
| 196 | list_add_tail(&chip->list, &gpio_chips); | 212 | /* initial entry in list */ |
| 213 | list_add_tail(&gdev->list, &gpio_devices); | ||
| 197 | return 0; | 214 | return 0; |
| 198 | } | 215 | } |
| 199 | 216 | ||
| 200 | list_for_each_entry(iterator, &gpio_chips, list) { | 217 | next = list_entry(gpio_devices.next, struct gpio_device, list); |
| 201 | if (iterator->base >= chip->base + chip->ngpio) { | 218 | if (gdev->base + gdev->ngpio <= next->base) { |
| 202 | /* | 219 | /* add before first entry */ |
| 203 | * Iterator is the first GPIO chip so there is no | 220 | list_add(&gdev->list, &gpio_devices); |
| 204 | * previous one | 221 | return 0; |
| 205 | */ | ||
| 206 | if (!previous) { | ||
| 207 | goto found; | ||
| 208 | } else { | ||
| 209 | /* | ||
| 210 | * We found a valid range(means | ||
| 211 | * [base, base + ngpio - 1]) between previous | ||
| 212 | * and iterator chip. | ||
| 213 | */ | ||
| 214 | if (previous->base + previous->ngpio | ||
| 215 | <= chip->base) | ||
| 216 | goto found; | ||
| 217 | } | ||
| 218 | } | ||
| 219 | previous = iterator; | ||
| 220 | } | 222 | } |
| 221 | 223 | ||
| 222 | /* | 224 | prev = list_entry(gpio_devices.prev, struct gpio_device, list); |
| 223 | * We are beyond the last chip in the list and iterator now | 225 | if (prev->base + prev->ngpio <= gdev->base) { |
| 224 | * points to the head. | 226 | /* add behind last entry */ |
| 225 | * Let iterator point to the last chip in the list. | 227 | list_add_tail(&gdev->list, &gpio_devices); |
| 226 | */ | ||
| 227 | |||
| 228 | iterator = list_last_entry(&gpio_chips, struct gpio_chip, list); | ||
| 229 | if (iterator->base + iterator->ngpio <= chip->base) { | ||
| 230 | list_add(&chip->list, &iterator->list); | ||
| 231 | return 0; | 228 | return 0; |
| 232 | } | 229 | } |
| 233 | 230 | ||
| 234 | dev_err(chip->parent, | 231 | list_for_each_entry_safe(prev, next, &gpio_devices, list) { |
| 235 | "GPIO integer space overlap, cannot add chip\n"); | 232 | /* at the end of the list */ |
| 236 | return -EBUSY; | 233 | if (&next->list == &gpio_devices) |
| 234 | break; | ||
| 237 | 235 | ||
| 238 | found: | 236 | /* add between prev and next */ |
| 239 | list_add_tail(&chip->list, &iterator->list); | 237 | if (prev->base + prev->ngpio <= gdev->base |
| 240 | return 0; | 238 | && gdev->base + gdev->ngpio <= next->base) { |
| 239 | list_add(&gdev->list, &prev->list); | ||
| 240 | return 0; | ||
| 241 | } | ||
| 242 | } | ||
| 243 | |||
| 244 | dev_err(&gdev->dev, "GPIO integer space overlap, cannot add chip\n"); | ||
| 245 | return -EBUSY; | ||
| 241 | } | 246 | } |
| 242 | 247 | ||
| 243 | /** | 248 | /** |
| @@ -245,23 +250,23 @@ found: · 1 unmodified line | |||
| 245 | */ | 250 | */ |
| 246 | static struct gpio_desc *gpio_name_to_desc(const char * const name) | 251 | static struct gpio_desc *gpio_name_to_desc(const char * const name) |
| 247 | { | 252 | { |
| 248 | struct gpio_chip *chip; | 253 | struct gpio_device *gdev; |
| 249 | unsigned long flags; | 254 | unsigned long flags; |
| 250 | 255 | ||
| 251 | spin_lock_irqsave(&gpio_lock, flags); | 256 | spin_lock_irqsave(&gpio_lock, flags); |
| 252 | 257 | ||
| 253 | list_for_each_entry(chip, &gpio_chips, list) { | 258 | list_for_each_entry(gdev, &gpio_devices, list) { |
| 254 | int i; | 259 | int i; |
| 255 | 260 | ||
| 256 | for (i = 0; i != chip->ngpio; ++i) { | 261 | for (i = 0; i != gdev->ngpio; ++i) { |
| 257 | struct gpio_desc *gpio = &chip->desc[i]; | 262 | struct gpio_desc *desc = &gdev->descs[i]; |
| 258 | 263 | ||
| 259 | if (!gpio->name || !name) | 264 | if (!desc->name || !name) |
| 260 | continue; | 265 | continue; |
| 261 | 266 | ||
| 262 | if (!strcmp(gpio->name, name)) { | 267 | if (!strcmp(desc->name, name)) { |
| 263 | spin_unlock_irqrestore(&gpio_lock, flags); | 268 | spin_unlock_irqrestore(&gpio_lock, flags); |
| 264 | return gpio; | 269 | return desc; |
| 265 | } | 270 | } |
| 266 | } | 271 | } |
| 267 | } | 272 | } |
| @@ -279,6 +284,7 @@ static struct gpio_desc *gpio_name_to_desc(const char * const name) · 11 unmodified lines | |||
| 279 | */ | 284 | */ |
| 280 | static int gpiochip_set_desc_names(struct gpio_chip *gc) | 285 | static int gpiochip_set_desc_names(struct gpio_chip *gc) |
| 281 | { | 286 | { |
| 287 | struct gpio_device *gdev = gc->gpiodev; | ||
| 282 | int i; | 288 | int i; |
| 283 | 289 | ||
| 284 | if (!gc->names) | 290 | if (!gc->names) |
| @@ -290,18 +296,153 @@ static int gpiochip_set_desc_names(struct gpio_chip *gc) · 5 unmodified lines | |||
| 290 | 296 | ||
| 291 | gpio = gpio_name_to_desc(gc->names[i]); | 297 | gpio = gpio_name_to_desc(gc->names[i]); |
| 292 | if (gpio) | 298 | if (gpio) |
| 293 | dev_warn(gc->parent, "Detected name collision for " | 299 | dev_warn(&gdev->dev, |
| 294 | "GPIO name '%s'\n", | 300 | "Detected name collision for GPIO name '%s'\n", |
| 295 | gc->names[i]); | 301 | gc->names[i]); |
| 296 | } | 302 | } |
| 297 | 303 | ||
| 298 | /* Then add all names to the GPIO descriptors */ | 304 | /* Then add all names to the GPIO descriptors */ |
| 299 | for (i = 0; i != gc->ngpio; ++i) | 305 | for (i = 0; i != gc->ngpio; ++i) |
| 300 | gc->desc[i].name = gc->names[i]; | 306 | gdev->descs[i].name = gc->names[i]; |
| 307 | |||
| 308 | return 0; | ||
| 309 | } | ||
| 310 | |||
| 311 | /** | ||
| 312 | * gpio_ioctl() - ioctl handler for the GPIO chardev | ||
| 313 | */ | ||
| 314 | static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | ||
| 315 | { | ||
| 316 | struct gpio_device *gdev = filp->private_data; | ||
| 317 | struct gpio_chip *chip = gdev->chip; | ||
| 318 | int __user *ip = (int __user *)arg; | ||
| 319 | |||
| 320 | /* We fail any subsequent ioctl():s when the chip is gone */ | ||
| 321 | if (!chip) | ||
| 322 | return -ENODEV; | ||
| 323 | |||
| 324 | /* Fill in the struct and pass to userspace */ | ||
| 325 | if (cmd == GPIO_GET_CHIPINFO_IOCTL) { | ||
| 326 | struct gpiochip_info chipinfo; | ||
| 327 | |||
| 328 | strncpy(chipinfo.name, dev_name(&gdev->dev), | ||
| 329 | sizeof(chipinfo.name)); | ||
| 330 | chipinfo.name[sizeof(chipinfo.name)-1] = '\0'; | ||
| 331 | strncpy(chipinfo.label, gdev->label, | ||
| 332 | sizeof(chipinfo.label)); | ||
| 333 | chipinfo.label[sizeof(chipinfo.label)-1] = '\0'; | ||
| 334 | chipinfo.lines = gdev->ngpio; | ||
| 335 | if (copy_to_user(ip, &chipinfo, sizeof(chipinfo))) | ||
| 336 | return -EFAULT; | ||
| 337 | return 0; | ||
| 338 | } else if (cmd == GPIO_GET_LINEINFO_IOCTL) { | ||
| 339 | struct gpioline_info lineinfo; | ||
| 340 | struct gpio_desc *desc; | ||
| 341 | |||
| 342 | if (copy_from_user(&lineinfo, ip, sizeof(lineinfo))) | ||
| 343 | return -EFAULT; | ||
| 344 | if (lineinfo.line_offset > gdev->ngpio) | ||
| 345 | return -EINVAL; | ||
| 346 | |||
| 347 | desc = &gdev->descs[lineinfo.line_offset]; | ||
| 348 | if (desc->name) { | ||
| 349 | strncpy(lineinfo.name, desc->name, | ||
| 350 | sizeof(lineinfo.name)); | ||
| 351 | lineinfo.name[sizeof(lineinfo.name)-1] = '\0'; | ||
| 352 | } else { | ||
| 353 | lineinfo.name[0] = '\0'; | ||
| 354 | } | ||
| 355 | if (desc->label) { | ||
| 356 | strncpy(lineinfo.consumer, desc->label, | ||
| 357 | sizeof(lineinfo.consumer)); | ||
| 358 | lineinfo.consumer[sizeof(lineinfo.consumer)-1] = '\0'; | ||
| 359 | } else { | ||
| 360 | lineinfo.consumer[0] = '\0'; | ||
| 361 | } | ||
| 362 | |||
| 363 | /* | ||
| 364 | * Userspace only need to know that the kernel is using | ||
| 365 | * this GPIO so it can't use it. | ||
| 366 | */ | ||
| 367 | lineinfo.flags = 0; | ||
| 368 | if (test_bit(FLAG_REQUESTED, &desc->flags) || | ||
| 369 | test_bit(FLAG_IS_HOGGED, &desc->flags) || | ||
| 370 | test_bit(FLAG_USED_AS_IRQ, &desc->flags) || | ||
| 371 | test_bit(FLAG_EXPORT, &desc->flags) || | ||
| 372 | test_bit(FLAG_SYSFS, &desc->flags)) | ||
| 373 | lineinfo.flags |= GPIOLINE_FLAG_KERNEL; | ||
| 374 | if (test_bit(FLAG_IS_OUT, &desc->flags)) | ||
| 375 | lineinfo.flags |= GPIOLINE_FLAG_IS_OUT; | ||
| 376 | if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) | ||
| 377 | lineinfo.flags |= GPIOLINE_FLAG_ACTIVE_LOW; | ||
| 378 | if (test_bit(FLAG_OPEN_DRAIN, &desc->flags)) | ||
| 379 | lineinfo.flags |= GPIOLINE_FLAG_OPEN_DRAIN; | ||
| 380 | if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) | ||
| 381 | lineinfo.flags |= GPIOLINE_FLAG_OPEN_SOURCE; | ||
| 382 | |||
| 383 | if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) | ||
| 384 | return -EFAULT; | ||
| 385 | return 0; | ||
| 386 | } | ||
| 387 | return -EINVAL; | ||
| 388 | } | ||
| 389 | |||
| 390 | /** | ||
| 391 | * gpio_chrdev_open() - open the chardev for ioctl operations | ||
| 392 | * @inode: inode for this chardev | ||
| 393 | * @filp: file struct for storing private data | ||
| 394 | * Returns 0 on success | ||
| 395 | */ | ||
| 396 | static int gpio_chrdev_open(struct inode *inode, struct file *filp) | ||
| 397 | { | ||
| 398 | struct gpio_device *gdev = container_of(inode->i_cdev, | ||
| 399 | struct gpio_device, chrdev); | ||
| 400 | |||
| 401 | /* Fail on open if the backing gpiochip is gone */ | ||
| 402 | if (!gdev || !gdev->chip) | ||
| 403 | return -ENODEV; | ||
| 404 | get_device(&gdev->dev); | ||
| 405 | filp->private_data = gdev; | ||
| 406 | return 0; | ||
| 407 | } | ||
| 301 | 408 | ||
| 409 | /** | ||
| 410 | * gpio_chrdev_release() - close chardev after ioctl operations | ||
| 411 | * @inode: inode for this chardev | ||
| 412 | * @filp: file struct for storing private data | ||
| 413 | * Returns 0 on success | ||
| 414 | */ | ||
| 415 | static int gpio_chrdev_release(struct inode *inode, struct file *filp) | ||
| 416 | { | ||
| 417 | struct gpio_device *gdev = container_of(inode->i_cdev, | ||
| 418 | struct gpio_device, chrdev); | ||
| 419 | |||
| 420 | if (!gdev) | ||
| 421 | return -ENODEV; | ||
| 422 | put_device(&gdev->dev); | ||
| 302 | return 0; | 423 | return 0; |
| 303 | } | 424 | } |
| 304 | 425 | ||
| 426 | |||
| 427 | static const struct file_operations gpio_fileops = { | ||
| 428 | .release = gpio_chrdev_release, | ||
| 429 | .open = gpio_chrdev_open, | ||
| 430 | .owner = THIS_MODULE, | ||
| 431 | .llseek = noop_llseek, | ||
| 432 | .unlocked_ioctl = gpio_ioctl, | ||
| 433 | .compat_ioctl = gpio_ioctl, | ||
| 434 | }; | ||
| 435 | |||
| 436 | static void gpiodevice_release(struct device *dev) | ||
| 437 | { | ||
| 438 | struct gpio_device *gdev = dev_get_drvdata(dev); | ||
| 439 | |||
| 440 | cdev_del(&gdev->chrdev); | ||
| 441 | list_del(&gdev->list); | ||
| 442 | ida_simple_remove(&gpio_ida, gdev->id); | ||
| 443 | kfree(gdev); | ||
| 444 | } | ||
| 445 | |||
| 305 | /** | 446 | /** |
| 306 | * gpiochip_add_data() - register a gpio_chip | 447 | * gpiochip_add_data() - register a gpio_chip |
| 307 | * @chip: the chip to register, with chip->base initialized | 448 | * @chip: the chip to register, with chip->base initialized |
| @@ -323,43 +464,107 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data) · 15 unmodified lines | |||
| 323 | { | 464 | { |
| 324 | unsigned long flags; | 465 | unsigned long flags; |
| 325 | int status = 0; | 466 | int status = 0; |
| 326 | unsigned id; | 467 | unsigned i; |
| 327 | int base = chip->base; | 468 | int base = chip->base; |
| 328 | struct gpio_desc *descs; | 469 | struct gpio_device *gdev; |
| 329 | 470 | ||
| 330 | descs = kcalloc(chip->ngpio, sizeof(descs[0]), GFP_KERNEL); | 471 | /* |
| 331 | if (!descs) | 472 | * First: allocate and populate the internal stat container, and |
| 473 | * set up the struct device. | ||
| 474 | */ | ||
| 475 | gdev = kzalloc(sizeof(*gdev), GFP_KERNEL); | ||
| 476 | if (!gdev) | ||
| 332 | return -ENOMEM; | 477 | return -ENOMEM; |
| 478 | gdev->dev.bus = &gpio_bus_type; | ||
| 479 | gdev->chip = chip; | ||
| 480 | chip->gpiodev = gdev; | ||
| 481 | if (chip->parent) { | ||
| 482 | gdev->dev.parent = chip->parent; | ||
| 483 | gdev->dev.of_node = chip->parent->of_node; | ||
| 484 | } else { | ||
| 485 | #ifdef CONFIG_OF_GPIO | ||
| 486 | /* If the gpiochip has an assigned OF node this takes precedence */ | ||
| 487 | if (chip->of_node) | ||
| 488 | gdev->dev.of_node = chip->of_node; | ||
| 489 | #endif | ||
| 490 | } | ||
| 491 | gdev->id = ida_simple_get(&gpio_ida, 0, 0, GFP_KERNEL); | ||
| 492 | if (gdev->id < 0) { | ||
| 493 | status = gdev->id; | ||
| 494 | goto err_free_gdev; | ||
| 495 | } | ||
| 496 | dev_set_name(&gdev->dev, "gpiochip%d", gdev->id); | ||
| 497 | device_initialize(&gdev->dev); | ||
| 498 | dev_set_drvdata(&gdev->dev, gdev); | ||
| 499 | if (chip->parent && chip->parent->driver) | ||
| 500 | gdev->owner = chip->parent->driver->owner; | ||
| 501 | else if (chip->owner) | ||
| 502 | /* TODO: remove chip->owner */ | ||
| 503 | gdev->owner = chip->owner; | ||
| 504 | else | ||
| 505 | gdev->owner = THIS_MODULE; | ||
| 333 | 506 | ||
| 334 | chip->data = data; | 507 | gdev->descs = devm_kcalloc(&gdev->dev, chip->ngpio, |
| 508 | sizeof(gdev->descs[0]), GFP_KERNEL); | ||
| 509 | if (!gdev->descs) { | ||
| 510 | status = -ENOMEM; | ||
| 511 | goto err_free_gdev; | ||
| 512 | } | ||
| 335 | 513 | ||
| 336 | if (chip->ngpio == 0) { | 514 | if (chip->ngpio == 0) { |
| 337 | chip_err(chip, "tried to insert a GPIO chip with zero lines\n"); | 515 | chip_err(chip, "tried to insert a GPIO chip with zero lines\n"); |
| 338 | return -EINVAL; | 516 | status = -EINVAL; |
| 517 | goto err_free_gdev; | ||
| 339 | } | 518 | } |
| 340 | 519 | ||
| 520 | if (chip->label) | ||
| 521 | gdev->label = devm_kstrdup(&gdev->dev, chip->label, GFP_KERNEL); | ||
| 522 | else | ||
| 523 | gdev->label = devm_kstrdup(&gdev->dev, "unknown", GFP_KERNEL); | ||
| 524 | if (!gdev->label) { | ||
| 525 | status = -ENOMEM; | ||
| 526 | goto err_free_gdev; | ||
| 527 | } | ||
| 528 | |||
| 529 | gdev->ngpio = chip->ngpio; | ||
| 530 | gdev->data = data; | ||
| 531 | |||
| 341 | spin_lock_irqsave(&gpio_lock, flags); | 532 | spin_lock_irqsave(&gpio_lock, flags); |
| 342 | 533 | ||
| 534 | /* | ||
| 535 | * TODO: this allocates a Linux GPIO number base in the global | ||
| 536 | * GPIO numberspace for this chip. In the long run we want to | ||
| 537 | * get *rid* of this numberspace and use only descriptors, but | ||
| 538 | * it may be a pipe dream. It will not happen before we get rid | ||
| 539 | * of the sysfs interface anyways. | ||
| 540 | */ | ||
| 343 | if (base < 0) { | 541 | if (base < 0) { |
| 344 | base = gpiochip_find_base(chip->ngpio); | 542 | base = gpiochip_find_base(chip->ngpio); |
| 345 | if (base < 0) { | 543 | if (base < 0) { |
| 346 | status = base; | 544 | status = base; |
| 347 | spin_unlock_irqrestore(&gpio_lock, flags); | 545 | spin_unlock_irqrestore(&gpio_lock, flags); |
| 348 | goto err_free_descs; | 546 | goto err_free_gdev; |
| 349 | } | 547 | } |
| 548 | /* | ||
| 549 | * TODO: it should not be necessary to reflect the assigned | ||
| 550 | * base outside of the GPIO subsystem. Go over drivers and | ||
| 551 | * see if anyone makes use of this, else drop this and assign | ||
| 552 | * a poison instead. | ||
| 553 | */ | ||
| 350 | chip->base = base; | 554 | chip->base = base; |
| 351 | } | 555 | } |
| 556 | gdev->base = base; | ||
| 352 | 557 | ||
| 353 | status = gpiochip_add_to_list(chip); | 558 | status = gpiodev_add_to_list(gdev); |
| 354 | if (status) { | 559 | if (status) { |
| 355 | spin_unlock_irqrestore(&gpio_lock, flags); | 560 | spin_unlock_irqrestore(&gpio_lock, flags); |
| 356 | goto err_free_descs; | 561 | goto err_free_gdev; |
| 357 | } | 562 | } |
| 358 | 563 | ||
| 359 | for (id = 0; id < chip->ngpio; id++) { | 564 | for (i = 0; i < chip->ngpio; i++) { |
| 360 | struct gpio_desc *desc = &descs[id]; | 565 | struct gpio_desc *desc = &gdev->descs[i]; |
| 361 | 566 | ||
| 362 | desc->chip = chip; | 567 | desc->gdev = gdev; |
| 363 | 568 | ||
| 364 | /* REVISIT: most hardware initializes GPIOs as inputs (often | 569 | /* REVISIT: most hardware initializes GPIOs as inputs (often |
| 365 | * with pullups enabled) so power usage is minimized. Linux | 570 | * with pullups enabled) so power usage is minimized. Linux |
| @@ -370,17 +575,12 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data) · 4 unmodified lines | |||
| 370 | desc->flags = !chip->direction_input ? (1 << FLAG_IS_OUT) : 0; | 575 | desc->flags = !chip->direction_input ? (1 << FLAG_IS_OUT) : 0; |
| 371 | } | 576 | } |
| 372 | 577 | ||
| 373 | chip->desc = descs; | ||
| 374 | |||
| 375 | spin_unlock_irqrestore(&gpio_lock, flags); | 578 | spin_unlock_irqrestore(&gpio_lock, flags); |
| 376 | 579 | ||
| 377 | #ifdef CONFIG_PINCTRL | 580 | #ifdef CONFIG_PINCTRL |
| 378 | INIT_LIST_HEAD(&chip->pin_ranges); | 581 | INIT_LIST_HEAD(&gdev->pin_ranges); |
| 379 | #endif | 582 | #endif |
| 380 | 583 | ||
| 381 | if (!chip->owner && chip->parent && chip->parent->driver) | ||
| 382 | chip->owner = chip->parent->driver->owner; | ||
| 383 | |||
| 384 | status = gpiochip_set_desc_names(chip); | 584 | status = gpiochip_set_desc_names(chip); |
| 385 | if (status) | 585 | if (status) |
| 386 | goto err_remove_from_list; | 586 | goto err_remove_from_list; |
| @@ -391,36 +591,72 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data) · 4 unmodified lines | |||
| 391 | 591 | ||
| 392 | acpi_gpiochip_add(chip); | 592 | acpi_gpiochip_add(chip); |
| 393 | 593 | ||
| 394 | status = gpiochip_sysfs_register(chip); | 594 | /* |
| 595 | * By first adding the chardev, and then adding the device, | ||
| 596 | * we get a device node entry in sysfs under | ||
| 597 | * /sys/bus/gpio/devices/gpiochipN/dev that can be used for | ||
| 598 | * coldplug of device nodes and other udev business. | ||
| 599 | */ | ||
| 600 | cdev_init(&gdev->chrdev, &gpio_fileops); | ||
| 601 | gdev->chrdev.owner = THIS_MODULE; | ||
| 602 | gdev->chrdev.kobj.parent = &gdev->dev.kobj; | ||
| 603 | gdev->dev.devt = MKDEV(MAJOR(gpio_devt), gdev->id); | ||
| 604 | status = cdev_add(&gdev->chrdev, gdev->dev.devt, 1); | ||
| 605 | if (status < 0) | ||
| 606 | chip_warn(chip, "failed to add char device %d:%d\n", | ||
| 607 | MAJOR(gpio_devt), gdev->id); | ||
| 608 | else | ||
| 609 | chip_dbg(chip, "added GPIO chardev (%d:%d)\n", | ||
| 610 | MAJOR(gpio_devt), gdev->id); | ||
| 611 | status = device_add(&gdev->dev); | ||
| 395 | if (status) | 612 | if (status) |
| 396 | goto err_remove_chip; | 613 | goto err_remove_chardev; |
| 614 | |||
| 615 | status = gpiochip_sysfs_register(gdev); | ||
| 616 | if (status) | ||
| 617 | goto err_remove_device; | ||
| 397 | 618 | ||
| 398 | pr_debug("%s: registered GPIOs %d to %d on device: %s\n", __func__, | 619 | /* From this point, the .release() function cleans up gpio_device */ |
| 399 | chip->base, chip->base + chip->ngpio - 1, | 620 | gdev->dev.release = gpiodevice_release; |
| 400 | chip->label ? : "generic"); | 621 | get_device(&gdev->dev); |
| 622 | pr_debug("%s: registered GPIOs %d to %d on device: %s (%s)\n", | ||
| 623 | __func__, gdev->base, gdev->base + gdev->ngpio - 1, | ||
| 624 | dev_name(&gdev->dev), chip->label ? : "generic"); | ||
| 401 | 625 | ||
| 402 | return 0; | 626 | return 0; |
| 403 | 627 | ||
| 628 | err_remove_device: | ||
| 629 | device_del(&gdev->dev); | ||
| 630 | err_remove_chardev: | ||
| 631 | cdev_del(&gdev->chrdev); | ||
| 404 | err_remove_chip: | 632 | err_remove_chip: |
| 405 | acpi_gpiochip_remove(chip); | 633 | acpi_gpiochip_remove(chip); |
| 406 | gpiochip_free_hogs(chip); | 634 | gpiochip_free_hogs(chip); |
| 407 | of_gpiochip_remove(chip); | 635 | of_gpiochip_remove(chip); |
| 408 | err_remove_from_list: | 636 | err_remove_from_list: |
| 409 | spin_lock_irqsave(&gpio_lock, flags); | 637 | spin_lock_irqsave(&gpio_lock, flags); |
| 410 | list_del(&chip->list); | 638 | list_del(&gdev->list); |
| 411 | spin_unlock_irqrestore(&gpio_lock, flags); | 639 | spin_unlock_irqrestore(&gpio_lock, flags); |
| 412 | chip->desc = NULL; | 640 | err_free_gdev: |
| 413 | err_free_descs: | 641 | ida_simple_remove(&gpio_ida, gdev->id); |
| 414 | kfree(descs); | ||
| 415 | |||
| 416 | /* failures here can mean systems won't boot... */ | 642 | /* failures here can mean systems won't boot... */ |
| 417 | pr_err("%s: GPIOs %d..%d (%s) failed to register\n", __func__, | 643 | pr_err("%s: GPIOs %d..%d (%s) failed to register\n", __func__, |
| 418 | chip->base, chip->base + chip->ngpio - 1, | 644 | gdev->base, gdev->base + gdev->ngpio - 1, |
| 419 | chip->label ? : "generic"); | 645 | chip->label ? : "generic"); |
| 646 | kfree(gdev); | ||
| 420 | return status; | 647 | return status; |
| 421 | } | 648 | } |
| 422 | EXPORT_SYMBOL_GPL(gpiochip_add_data); | 649 | EXPORT_SYMBOL_GPL(gpiochip_add_data); |
| 423 | 650 | ||
| 651 | /** | ||
| 652 | * gpiochip_get_data() - get per-subdriver data for the chip | ||
| 653 | */ | ||
| 654 | void *gpiochip_get_data(struct gpio_chip *chip) | ||
| 655 | { | ||
| 656 | return chip->gpiodev->data; | ||
| 657 | } | ||
| 658 | EXPORT_SYMBOL_GPL(gpiochip_get_data); | ||
| 659 | |||
| 424 | /** | 660 | /** |
| 425 | * gpiochip_remove() - unregister a gpio_chip | 661 | * gpiochip_remove() - unregister a gpio_chip |
| 426 | * @chip: the chip to unregister | 662 | * @chip: the chip to unregister |
| @@ -429,39 +665,123 @@ EXPORT_SYMBOL_GPL(gpiochip_add_data); · 2 unmodified lines | |||
| 429 | */ | 665 | */ |
| 430 | void gpiochip_remove(struct gpio_chip *chip) | 666 | void gpiochip_remove(struct gpio_chip *chip) |
| 431 | { | 667 | { |
| 668 | struct gpio_device *gdev = chip->gpiodev; | ||
| 432 | struct gpio_desc *desc; | 669 | struct gpio_desc *desc; |
| 433 | unsigned long flags; | 670 | unsigned long flags; |
| 434 | unsigned id; | 671 | unsigned i; |
| 435 | bool requested = false; | 672 | bool requested = false; |
| 436 | 673 | ||
| 437 | gpiochip_sysfs_unregister(chip); | 674 | /* FIXME: should the legacy sysfs handling be moved to gpio_device? */ |
| 438 | 675 | gpiochip_sysfs_unregister(gdev); | |
| 676 | /* Numb the device, cancelling all outstanding operations */ | ||
| 677 | gdev->chip = NULL; | ||
| 439 | gpiochip_irqchip_remove(chip); | 678 | gpiochip_irqchip_remove(chip); |
| 440 | |||
| 441 | acpi_gpiochip_remove(chip); | 679 | acpi_gpiochip_remove(chip); |
| 442 | gpiochip_remove_pin_ranges(chip); | 680 | gpiochip_remove_pin_ranges(chip); |
| 443 | gpiochip_free_hogs(chip); | 681 | gpiochip_free_hogs(chip); |
| 444 | of_gpiochip_remove(chip); | 682 | of_gpiochip_remove(chip); |
| 683 | /* | ||
| 684 | * We accept no more calls into the driver from this point, so | ||
| 685 | * NULL the driver data pointer | ||
| 686 | */ | ||
| 687 | gdev->data = NULL; | ||
| 445 | 688 | ||
| 446 | spin_lock_irqsave(&gpio_lock, flags); | 689 | spin_lock_irqsave(&gpio_lock, flags); |
| 447 | for (id = 0; id < chip->ngpio; id++) { | 690 | for (i = 0; i < gdev->ngpio; i++) { |
| 448 | desc = &chip->desc[id]; | 691 | desc = &gdev->descs[i]; |
| 449 | desc->chip = NULL; | ||
| 450 | if (test_bit(FLAG_REQUESTED, &desc->flags)) | 692 | if (test_bit(FLAG_REQUESTED, &desc->flags)) |
| 451 | requested = true; | 693 | requested = true; |
| 452 | } | 694 | } |
| 453 | list_del(&chip->list); | ||
| 454 | spin_unlock_irqrestore(&gpio_lock, flags); | 695 | spin_unlock_irqrestore(&gpio_lock, flags); |
| 455 | 696 | ||
| 456 | if (requested) | 697 | if (requested) |
| 457 | dev_crit(chip->parent, | 698 | dev_crit(&gdev->dev, |
| 458 | "REMOVING GPIOCHIP WITH GPIOS STILL REQUESTED\n"); | 699 | "REMOVING GPIOCHIP WITH GPIOS STILL REQUESTED\n"); |
| 459 | 700 | ||
| 460 | kfree(chip->desc); | 701 | /* |
| 461 | chip->desc = NULL; | 702 | * The gpiochip side puts its use of the device to rest here: |
| 703 | * if there are no userspace clients, the chardev and device will | ||
| 704 | * be removed, else it will be dangling until the last user is | ||
| 705 | * gone. | ||
| 706 | */ | ||
| 707 | put_device(&gdev->dev); | ||
| 462 | } | 708 | } |
| 463 | EXPORT_SYMBOL_GPL(gpiochip_remove); | 709 | EXPORT_SYMBOL_GPL(gpiochip_remove); |
| 464 | 710 | ||
| 711 | static void devm_gpio_chip_release(struct device *dev, void *res) | ||
| 712 | { | ||
| 713 | struct gpio_chip *chip = *(struct gpio_chip **)res; | ||
| 714 | |||
| 715 | gpiochip_remove(chip); | ||
| 716 | } | ||
| 717 | |||
| 718 | static int devm_gpio_chip_match(struct device *dev, void *res, void *data) | ||
| 719 | |||
| 720 | { | ||
| 721 | struct gpio_chip **r = res; | ||
| 722 | |||
| 723 | if (!r || !*r) { | ||
| 724 | WARN_ON(!r || !*r); | ||
| 725 | return 0; | ||
| 726 | } | ||
| 727 | |||
| 728 | return *r == data; | ||
| 729 | } | ||
| 730 | |||
| 731 | /** | ||
| 732 | * devm_gpiochip_add_data() - Resource manager piochip_add_data() | ||
| 733 | * @dev: the device pointer on which irq_chip belongs to. | ||
| 734 | * @chip: the chip to register, with chip->base initialized | ||
| 735 | * Context: potentially before irqs will work | ||
| 736 | * | ||
| 737 | * Returns a negative errno if the chip can't be registered, such as | ||
| 738 | * because the chip->base is invalid or already associated with a | ||
| 739 | * different chip. Otherwise it returns zero as a success code. | ||
| 740 | * | ||
| 741 | * The gpio chip automatically be released when the device is unbound. | ||
| 742 | */ | ||
| 743 | int devm_gpiochip_add_data(struct device *dev, struct gpio_chip *chip, | ||
| 744 | void *data) | ||
| 745 | { | ||
| 746 | struct gpio_chip **ptr; | ||
| 747 | int ret; | ||
| 748 | |||
| 749 | ptr = devres_alloc(devm_gpio_chip_release, sizeof(*ptr), | ||
| 750 | GFP_KERNEL); | ||
| 751 | if (!ptr) | ||
| 752 | return -ENOMEM; | ||
| 753 | |||
| 754 | ret = gpiochip_add_data(chip, data); | ||
| 755 | if (ret < 0) { | ||
| 756 | devres_free(ptr); | ||
| 757 | return ret; | ||
| 758 | } | ||
| 759 | |||
| 760 | *ptr = chip; | ||
| 761 | devres_add(dev, ptr); | ||
| 762 | |||
| 763 | return 0; | ||
| 764 | } | ||
| 765 | EXPORT_SYMBOL_GPL(devm_gpiochip_add_data); | ||
| 766 | |||
| 767 | /** | ||
| 768 | * devm_gpiochip_remove() - Resource manager of gpiochip_remove() | ||
| 769 | * @dev: device for which which resource was allocated | ||
| 770 | * @chip: the chip to remove | ||
| 771 | * | ||
| 772 | * A gpio_chip with any GPIOs still requested may not be removed. | ||
| 773 | */ | ||
| 774 | void devm_gpiochip_remove(struct device *dev, struct gpio_chip *chip) | ||
| 775 | { | ||
| 776 | int ret; | ||
| 777 | |||
| 778 | ret = devres_release(dev, devm_gpio_chip_release, | ||
| 779 | devm_gpio_chip_match, chip); | ||
| 780 | if (!ret) | ||
| 781 | WARN_ON(ret); | ||
| 782 | } | ||
| 783 | EXPORT_SYMBOL_GPL(devm_gpiochip_remove); | ||
| 784 | |||
| 465 | /** | 785 | /** |
| 466 | * gpiochip_find() - iterator for locating a specific gpio_chip | 786 | * gpiochip_find() - iterator for locating a specific gpio_chip |
| 467 | * @data: data to pass to match function | 787 | * @data: data to pass to match function |
| @@ -477,17 +797,21 @@ struct gpio_chip *gpiochip_find(void *data, · 9 unmodified lines | |||
| 477 | int (*match)(struct gpio_chip *chip, | 797 | int (*match)(struct gpio_chip *chip, |
| 478 | void *data)) | 798 | void *data)) |
| 479 | { | 799 | { |
| 800 | struct gpio_device *gdev; | ||
| 480 | struct gpio_chip *chip; | 801 | struct gpio_chip *chip; |
| 481 | unsigned long flags; | 802 | unsigned long flags; |
| 482 | 803 | ||
| 483 | spin_lock_irqsave(&gpio_lock, flags); | 804 | spin_lock_irqsave(&gpio_lock, flags); |
| 484 | list_for_each_entry(chip, &gpio_chips, list) | 805 | list_for_each_entry(gdev, &gpio_devices, list) |
| 485 | if (match(chip, data)) | 806 | if (match(gdev->chip, data)) |
| 486 | break; | 807 | break; |
| 487 | 808 | ||
| 488 | /* No match? */ | 809 | /* No match? */ |
| 489 | if (&chip->list == &gpio_chips) | 810 | if (&gdev->list == &gpio_devices) |
| 490 | chip = NULL; | 811 | chip = NULL; |
| 812 | else | ||
| 813 | chip = gdev->chip; | ||
| 814 | |||
| 491 | spin_unlock_irqrestore(&gpio_lock, flags); | 815 | spin_unlock_irqrestore(&gpio_lock, flags); |
| 492 | 816 | ||
| 493 | return chip; | 817 | return chip; |
| @@ -617,14 +941,14 @@ static int gpiochip_irq_reqres(struct irq_data *d) · 123 unmodified lines | |||
| 617 | { | 941 | { |
| 618 | struct gpio_chip *chip = irq_data_get_irq_chip_data(d); | 942 | struct gpio_chip *chip = irq_data_get_irq_chip_data(d); |
| 619 | 943 | ||
| 620 | if (!try_module_get(chip->owner)) | 944 | if (!try_module_get(chip->gpiodev->owner)) |
| 621 | return -ENODEV; | 945 | return -ENODEV; |
| 622 | 946 | ||
| 623 | if (gpiochip_lock_as_irq(chip, d->hwirq)) { | 947 | if (gpiochip_lock_as_irq(chip, d->hwirq)) { |
| 624 | chip_err(chip, | 948 | chip_err(chip, |
| 625 | "unable to lock HW IRQ %lu for IRQ\n", | 949 | "unable to lock HW IRQ %lu for IRQ\n", |
| 626 | d->hwirq); | 950 | d->hwirq); |
| 627 | module_put(chip->owner); | 951 | module_put(chip->gpiodev->owner); |
| 628 | return -EINVAL; | 952 | return -EINVAL; |
| 629 | } | 953 | } |
| 630 | return 0; | 954 | return 0; |
| @@ -635,7 +959,7 @@ static void gpiochip_irq_relres(struct irq_data *d) · 4 unmodified lines | |||
| 635 | struct gpio_chip *chip = irq_data_get_irq_chip_data(d); | 959 | struct gpio_chip *chip = irq_data_get_irq_chip_data(d); |
| 636 | 960 | ||
| 637 | gpiochip_unlock_as_irq(chip, d->hwirq); | 961 | gpiochip_unlock_as_irq(chip, d->hwirq); |
| 638 | module_put(chip->owner); | 962 | module_put(chip->gpiodev->owner); |
| 639 | } | 963 | } |
| 640 | 964 | ||
| 641 | static int gpiochip_to_irq(struct gpio_chip *chip, unsigned offset) | 965 | static int gpiochip_to_irq(struct gpio_chip *chip, unsigned offset) |
| @@ -785,7 +1109,7 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip) {} · 143 unmodified lines | |||
| 785 | */ | 1109 | */ |
| 786 | int gpiochip_generic_request(struct gpio_chip *chip, unsigned offset) | 1110 | int gpiochip_generic_request(struct gpio_chip *chip, unsigned offset) |
| 787 | { | 1111 | { |
| 788 | return pinctrl_request_gpio(chip->base + offset); | 1112 | return pinctrl_request_gpio(chip->gpiodev->base + offset); |
| 789 | } | 1113 | } |
| 790 | EXPORT_SYMBOL_GPL(gpiochip_generic_request); | 1114 | EXPORT_SYMBOL_GPL(gpiochip_generic_request); |
| 791 | 1115 | ||
| @@ -796,7 +1120,7 @@ EXPORT_SYMBOL_GPL(gpiochip_generic_request); · 4 unmodified lines | |||
| 796 | */ | 1120 | */ |
| 797 | void gpiochip_generic_free(struct gpio_chip *chip, unsigned offset) | 1121 | void gpiochip_generic_free(struct gpio_chip *chip, unsigned offset) |
| 798 | { | 1122 | { |
| 799 | pinctrl_free_gpio(chip->base + offset); | 1123 | pinctrl_free_gpio(chip->gpiodev->base + offset); |
| 800 | } | 1124 | } |
| 801 | EXPORT_SYMBOL_GPL(gpiochip_generic_free); | 1125 | EXPORT_SYMBOL_GPL(gpiochip_generic_free); |
| 802 | 1126 | ||
| @@ -814,6 +1138,7 @@ int gpiochip_add_pingroup_range(struct gpio_chip *chip, · 11 unmodified lines | |||
| 814 | unsigned int gpio_offset, const char *pin_group) | 1138 | unsigned int gpio_offset, const char *pin_group) |
| 815 | { | 1139 | { |
| 816 | struct gpio_pin_range *pin_range; | 1140 | struct gpio_pin_range *pin_range; |
| 1141 | struct gpio_device *gdev = chip->gpiodev; | ||
| 817 | int ret; | 1142 | int ret; |
| 818 | 1143 | ||
| 819 | pin_range = kzalloc(sizeof(*pin_range), GFP_KERNEL); | 1144 | pin_range = kzalloc(sizeof(*pin_range), GFP_KERNEL); |
| @@ -826,7 +1151,7 @@ int gpiochip_add_pingroup_range(struct gpio_chip *chip, · 6 unmodified lines | |||
| 826 | pin_range->range.id = gpio_offset; | 1151 | pin_range->range.id = gpio_offset; |
| 827 | pin_range->range.gc = chip; | 1152 | pin_range->range.gc = chip; |
| 828 | pin_range->range.name = chip->label; | 1153 | pin_range->range.name = chip->label; |
| 829 | pin_range->range.base = chip->base + gpio_offset; | 1154 | pin_range->range.base = gdev->base + gpio_offset; |
| 830 | pin_range->pctldev = pctldev; | 1155 | pin_range->pctldev = pctldev; |
| 831 | 1156 | ||
| 832 | ret = pinctrl_get_group_pins(pctldev, pin_group, | 1157 | ret = pinctrl_get_group_pins(pctldev, pin_group, |
| @@ -843,7 +1168,7 @@ int gpiochip_add_pingroup_range(struct gpio_chip *chip, · 10 unmodified lines | |||
| 843 | gpio_offset, gpio_offset + pin_range->range.npins - 1, | 1168 | gpio_offset, gpio_offset + pin_range->range.npins - 1, |
| 844 | pinctrl_dev_get_devname(pctldev), pin_group); | 1169 | pinctrl_dev_get_devname(pctldev), pin_group); |
| 845 | 1170 | ||
| 846 | list_add_tail(&pin_range->node, &chip->pin_ranges); | 1171 | list_add_tail(&pin_range->node, &gdev->pin_ranges); |
| 847 | 1172 | ||
| 848 | return 0; | 1173 | return 0; |
| 849 | } | 1174 | } |
| @@ -863,6 +1188,7 @@ int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, · 13 unmodified lines | |||
| 863 | unsigned int npins) | 1188 | unsigned int npins) |
| 864 | { | 1189 | { |
| 865 | struct gpio_pin_range *pin_range; | 1190 | struct gpio_pin_range *pin_range; |
| 1191 | struct gpio_device *gdev = chip->gpiodev; | ||
| 866 | int ret; | 1192 | int ret; |
| 867 | 1193 | ||
| 868 | pin_range = kzalloc(sizeof(*pin_range), GFP_KERNEL); | 1194 | pin_range = kzalloc(sizeof(*pin_range), GFP_KERNEL); |
| @@ -875,7 +1201,7 @@ int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, · 6 unmodified lines | |||
| 875 | pin_range->range.id = gpio_offset; | 1201 | pin_range->range.id = gpio_offset; |
| 876 | pin_range->range.gc = chip; | 1202 | pin_range->range.gc = chip; |
| 877 | pin_range->range.name = chip->label; | 1203 | pin_range->range.name = chip->label; |
| 878 | pin_range->range.base = chip->base + gpio_offset; | 1204 | pin_range->range.base = gdev->base + gpio_offset; |
| 879 | pin_range->range.pin_base = pin_offset; | 1205 | pin_range->range.pin_base = pin_offset; |
| 880 | pin_range->range.npins = npins; | 1206 | pin_range->range.npins = npins; |
| 881 | pin_range->pctldev = pinctrl_find_and_add_gpio_range(pinctl_name, | 1207 | pin_range->pctldev = pinctrl_find_and_add_gpio_range(pinctl_name, |
| @@ -891,7 +1217,7 @@ int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, · 9 unmodified lines | |||
| 891 | pinctl_name, | 1217 | pinctl_name, |
| 892 | pin_offset, pin_offset + npins - 1); | 1218 | pin_offset, pin_offset + npins - 1); |
| 893 | 1219 | ||
| 894 | list_add_tail(&pin_range->node, &chip->pin_ranges); | 1220 | list_add_tail(&pin_range->node, &gdev->pin_ranges); |
| 895 | 1221 | ||
| 896 | return 0; | 1222 | return 0; |
| 897 | } | 1223 | } |
| @@ -904,8 +1230,9 @@ EXPORT_SYMBOL_GPL(gpiochip_add_pin_range); · 6 unmodified lines | |||
| 904 | void gpiochip_remove_pin_ranges(struct gpio_chip *chip) | 1230 | void gpiochip_remove_pin_ranges(struct gpio_chip *chip) |
| 905 | { | 1231 | { |
| 906 | struct gpio_pin_range *pin_range, *tmp; | 1232 | struct gpio_pin_range *pin_range, *tmp; |
| 1233 | struct gpio_device *gdev = chip->gpiodev; | ||
| 907 | 1234 | ||
| 908 | list_for_each_entry_safe(pin_range, tmp, &chip->pin_ranges, node) { | 1235 | list_for_each_entry_safe(pin_range, tmp, &gdev->pin_ranges, node) { |
| 909 | list_del(&pin_range->node); | 1236 | list_del(&pin_range->node); |
| 910 | pinctrl_remove_gpio_range(pin_range->pctldev, | 1237 | pinctrl_remove_gpio_range(pin_range->pctldev, |
| 911 | &pin_range->range); | 1238 | &pin_range->range); |
| @@ -922,7 +1249,7 @@ EXPORT_SYMBOL_GPL(gpiochip_remove_pin_ranges); · 10 unmodified lines | |||
| 922 | */ | 1249 | */ |
| 923 | static int __gpiod_request(struct gpio_desc *desc, const char *label) | 1250 | static int __gpiod_request(struct gpio_desc *desc, const char *label) |
| 924 | { | 1251 | { |
| 925 | struct gpio_chip *chip = desc->chip; | 1252 | struct gpio_chip *chip = desc->gdev->chip; |
| 926 | int status; | 1253 | int status; |
| 927 | unsigned long flags; | 1254 | unsigned long flags; |
| 928 | 1255 | ||
| @@ -971,27 +1298,50 @@ done: · 42 unmodified lines | |||
| 971 | return status; | 1298 | return status; |
| 972 | } | 1299 | } |
| 973 | 1300 | ||
| 1301 | /* | ||
| 1302 | * This descriptor validation needs to be inserted verbatim into each | ||
| 1303 | * function taking a descriptor, so we need to use a preprocessor | ||
| 1304 | * macro to avoid endless duplication. | ||
| 1305 | */ | ||
| 1306 | #define VALIDATE_DESC(desc) do { \ | ||
| 1307 | if (!desc || !desc->gdev) { \ | ||
| 1308 | pr_warn("%s: invalid GPIO\n", __func__); \ | ||
| 1309 | return -EINVAL; \ | ||
| 1310 | } \ | ||
| 1311 | if ( !desc->gdev->chip ) { \ | ||
| 1312 | dev_warn(&desc->gdev->dev, \ | ||
| 1313 | "%s: backing chip is gone\n", __func__); \ | ||
| 1314 | return 0; \ | ||
| 1315 | } } while (0) | ||
| 1316 | |||
| 1317 | #define VALIDATE_DESC_VOID(desc) do { \ | ||
| 1318 | if (!desc || !desc->gdev) { \ | ||
| 1319 | pr_warn("%s: invalid GPIO\n", __func__); \ | ||
| 1320 | return; \ | ||
| 1321 | } \ | ||
| 1322 | if (!desc->gdev->chip) { \ | ||
| 1323 | dev_warn(&desc->gdev->dev, \ | ||
| 1324 | "%s: backing chip is gone\n", __func__); \ | ||
| 1325 | return; \ | ||
| 1326 | } } while (0) | ||
| 1327 | |||
| 1328 | |||
| 974 | int gpiod_request(struct gpio_desc *desc, const char *label) | 1329 | int gpiod_request(struct gpio_desc *desc, const char *label) |
| 975 | { | 1330 | { |
| 976 | int status = -EPROBE_DEFER; | 1331 | int status = -EPROBE_DEFER; |
| 977 | struct gpio_chip *chip; | 1332 | struct gpio_device *gdev; |
| 978 | 1333 | ||
| 979 | if (!desc) { | 1334 | VALIDATE_DESC(desc); |
| 980 | pr_warn("%s: invalid GPIO\n", __func__); | 1335 | gdev = desc->gdev; |
| 981 | return -EINVAL; | ||
| 982 | } | ||
| 983 | 1336 | ||
| 984 | chip = desc->chip; | 1337 | if (try_module_get(gdev->owner)) { |
| 985 | if (!chip) | ||
| 986 | goto done; | ||
| 987 | |||
| 988 | if (try_module_get(chip->owner)) { | ||
| 989 | status = __gpiod_request(desc, label); | 1338 | status = __gpiod_request(desc, label); |
| 990 | if (status < 0) | 1339 | if (status < 0) |
| 991 | module_put(chip->owner); | 1340 | module_put(gdev->owner); |
| 1341 | else | ||
| 1342 | get_device(&gdev->dev); | ||
| 992 | } | 1343 | } |
| 993 | 1344 | ||
| 994 | done: | ||
| 995 | if (status) | 1345 | if (status) |
| 996 | gpiod_dbg(desc, "%s: status %d\n", __func__, status); | 1346 | gpiod_dbg(desc, "%s: status %d\n", __func__, status); |
| 997 | 1347 | ||
| @@ -1010,7 +1360,7 @@ static bool __gpiod_free(struct gpio_desc *desc) · 12 unmodified lines | |||
| 1010 | 1360 | ||
| 1011 | spin_lock_irqsave(&gpio_lock, flags); | 1361 | spin_lock_irqsave(&gpio_lock, flags); |
| 1012 | 1362 | ||
| 1013 | chip = desc->chip; | 1363 | chip = desc->gdev->chip; |
| 1014 | if (chip && test_bit(FLAG_REQUESTED, &desc->flags)) { | 1364 | if (chip && test_bit(FLAG_REQUESTED, &desc->flags)) { |
| 1015 | if (chip->free) { | 1365 | if (chip->free) { |
| 1016 | spin_unlock_irqrestore(&gpio_lock, flags); | 1366 | spin_unlock_irqrestore(&gpio_lock, flags); |
| @@ -1033,10 +1383,12 @@ static bool __gpiod_free(struct gpio_desc *desc) · 16 unmodified lines | |||
| 1033 | 1383 | ||
| 1034 | void gpiod_free(struct gpio_desc *desc) | 1384 | void gpiod_free(struct gpio_desc *desc) |
| 1035 | { | 1385 | { |
| 1036 | if (desc && __gpiod_free(desc)) | 1386 | if (desc && desc->gdev && __gpiod_free(desc)) { |
| 1037 | module_put(desc->chip->owner); | 1387 | module_put(desc->gdev->owner); |
| 1038 | else | 1388 | put_device(&desc->gdev->dev); |
| 1389 | } else { | ||
| 1039 | WARN_ON(extra_checks); | 1390 | WARN_ON(extra_checks); |
| 1391 | } | ||
| 1040 | } | 1392 | } |
| 1041 | 1393 | ||
| 1042 | /** | 1394 | /** |
| @@ -1059,7 +1411,7 @@ const char *gpiochip_is_requested(struct gpio_chip *chip, unsigned offset) · 16 unmodified lines | |||
| 1059 | if (offset >= chip->ngpio) | 1411 | if (offset >= chip->ngpio) |
| 1060 | return NULL; | 1412 | return NULL; |
| 1061 | 1413 | ||
| 1062 | desc = &chip->desc[offset]; | 1414 | desc = &chip->gpiodev->descs[offset]; |
| 1063 | 1415 | ||
| 1064 | if (test_bit(FLAG_REQUESTED, &desc->flags) == 0) | 1416 | if (test_bit(FLAG_REQUESTED, &desc->flags) == 0) |
| 1065 | return NULL; | 1417 | return NULL; |
| @@ -1111,7 +1463,8 @@ void gpiochip_free_own_desc(struct gpio_desc *desc) · 45 unmodified lines | |||
| 1111 | } | 1463 | } |
| 1112 | EXPORT_SYMBOL_GPL(gpiochip_free_own_desc); | 1464 | EXPORT_SYMBOL_GPL(gpiochip_free_own_desc); |
| 1113 | 1465 | ||
| 1114 | /* Drivers MUST set GPIO direction before making get/set calls. In | 1466 | /* |
| 1467 | * Drivers MUST set GPIO direction before making get/set calls. In | ||
| 1115 | * some cases this is done in early boot, before IRQs are enabled. | 1468 | * some cases this is done in early boot, before IRQs are enabled. |
| 1116 | * | 1469 | * |
| 1117 | * As a rule these aren't called more than once (except for drivers | 1470 | * As a rule these aren't called more than once (except for drivers |
| @@ -1134,12 +1487,9 @@ int gpiod_direction_input(struct gpio_desc *desc) · 16 unmodified lines | |||
| 1134 | struct gpio_chip *chip; | 1487 | struct gpio_chip *chip; |
| 1135 | int status = -EINVAL; | 1488 | int status = -EINVAL; |
| 1136 | 1489 | ||
| 1137 | if (!desc || !desc->chip) { | 1490 | VALIDATE_DESC(desc); |
| 1138 | pr_warn("%s: invalid GPIO\n", __func__); | 1491 | chip = desc->gdev->chip; |
| 1139 | return -EINVAL; | ||
| 1140 | } | ||
| 1141 | 1492 | ||
| 1142 | chip = desc->chip; | ||
| 1143 | if (!chip->get || !chip->direction_input) { | 1493 | if (!chip->get || !chip->direction_input) { |
| 1144 | gpiod_warn(desc, | 1494 | gpiod_warn(desc, |
| 1145 | "%s: missing get() or direction_input() operations\n", | 1495 | "%s: missing get() or direction_input() operations\n", |
| @@ -1178,7 +1528,7 @@ static int _gpiod_direction_output_raw(struct gpio_desc *desc, int value) · 32 unmodified lines | |||
| 1178 | if (!value && test_bit(FLAG_OPEN_SOURCE, &desc->flags)) | 1528 | if (!value && test_bit(FLAG_OPEN_SOURCE, &desc->flags)) |
| 1179 | return gpiod_direction_input(desc); | 1529 | return gpiod_direction_input(desc); |
| 1180 | 1530 | ||
| 1181 | chip = desc->chip; | 1531 | chip = desc->gdev->chip; |
| 1182 | if (!chip->set || !chip->direction_output) { | 1532 | if (!chip->set || !chip->direction_output) { |
| 1183 | gpiod_warn(desc, | 1533 | gpiod_warn(desc, |
| 1184 | "%s: missing set() or direction_output() operations\n", | 1534 | "%s: missing set() or direction_output() operations\n", |
| @@ -1207,10 +1557,7 @@ static int _gpiod_direction_output_raw(struct gpio_desc *desc, int value) · 22 unmodified lines | |||
| 1207 | */ | 1557 | */ |
| 1208 | int gpiod_direction_output_raw(struct gpio_desc *desc, int value) | 1558 | int gpiod_direction_output_raw(struct gpio_desc *desc, int value) |
| 1209 | { | 1559 | { |
| 1210 | if (!desc || !desc->chip) { | 1560 | VALIDATE_DESC(desc); |
| 1211 | pr_warn("%s: invalid GPIO\n", __func__); | ||
| 1212 | return -EINVAL; | ||
| 1213 | } | ||
| 1214 | return _gpiod_direction_output_raw(desc, value); | 1561 | return _gpiod_direction_output_raw(desc, value); |
| 1215 | } | 1562 | } |
| 1216 | EXPORT_SYMBOL_GPL(gpiod_direction_output_raw); | 1563 | EXPORT_SYMBOL_GPL(gpiod_direction_output_raw); |
| @@ -1229,10 +1576,7 @@ EXPORT_SYMBOL_GPL(gpiod_direction_output_raw); · 12 unmodified lines | |||
| 1229 | */ | 1576 | */ |
| 1230 | int gpiod_direction_output(struct gpio_desc *desc, int value) | 1577 | int gpiod_direction_output(struct gpio_desc *desc, int value) |
| 1231 | { | 1578 | { |
| 1232 | if (!desc || !desc->chip) { | 1579 | VALIDATE_DESC(desc); |
| 1233 | pr_warn("%s: invalid GPIO\n", __func__); | ||
| 1234 | return -EINVAL; | ||
| 1235 | } | ||
| 1236 | if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) | 1580 | if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) |
| 1237 | value = !value; | 1581 | value = !value; |
| 1238 | return _gpiod_direction_output_raw(desc, value); | 1582 | return _gpiod_direction_output_raw(desc, value); |
| @@ -1251,12 +1595,8 @@ int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce) · 12 unmodified lines | |||
| 1251 | { | 1595 | { |
| 1252 | struct gpio_chip *chip; | 1596 | struct gpio_chip *chip; |
| 1253 | 1597 | ||
| 1254 | if (!desc || !desc->chip) { | 1598 | VALIDATE_DESC(desc); |
| 1255 | pr_warn("%s: invalid GPIO\n", __func__); | 1599 | chip = desc->gdev->chip; |
| 1256 | return -EINVAL; | ||
| 1257 | } | ||
| 1258 | |||
| 1259 | chip = desc->chip; | ||
| 1260 | if (!chip->set || !chip->set_debounce) { | 1600 | if (!chip->set || !chip->set_debounce) { |
| 1261 | gpiod_dbg(desc, | 1601 | gpiod_dbg(desc, |
| 1262 | "%s: missing set() or set_debounce() operations\n", | 1602 | "%s: missing set() or set_debounce() operations\n", |
| @@ -1276,6 +1616,7 @@ EXPORT_SYMBOL_GPL(gpiod_set_debounce); · 13 unmodified lines | |||
| 1276 | */ | 1616 | */ |
| 1277 | int gpiod_is_active_low(const struct gpio_desc *desc) | 1617 | int gpiod_is_active_low(const struct gpio_desc *desc) |
| 1278 | { | 1618 | { |
| 1619 | VALIDATE_DESC(desc); | ||
| 1279 | return test_bit(FLAG_ACTIVE_LOW, &desc->flags); | 1620 | return test_bit(FLAG_ACTIVE_LOW, &desc->flags); |
| 1280 | } | 1621 | } |
| 1281 | EXPORT_SYMBOL_GPL(gpiod_is_active_low); | 1622 | EXPORT_SYMBOL_GPL(gpiod_is_active_low); |
| @@ -1308,7 +1649,7 @@ static int _gpiod_get_raw_value(const struct gpio_desc *desc) · 26 unmodified lines | |||
| 1308 | int offset; | 1649 | int offset; |
| 1309 | int value; | 1650 | int value; |
| 1310 | 1651 | ||
| 1311 | chip = desc->chip; | 1652 | chip = desc->gdev->chip; |
| 1312 | offset = gpio_chip_hwgpio(desc); | 1653 | offset = gpio_chip_hwgpio(desc); |
| 1313 | value = chip->get ? chip->get(chip, offset) : -EIO; | 1654 | value = chip->get ? chip->get(chip, offset) : -EIO; |
| 1314 | value = value < 0 ? value : !!value; | 1655 | value = value < 0 ? value : !!value; |
| @@ -1328,10 +1669,9 @@ static int _gpiod_get_raw_value(const struct gpio_desc *desc) · 13 unmodified lines | |||
| 1328 | */ | 1669 | */ |
| 1329 | int gpiod_get_raw_value(const struct gpio_desc *desc) | 1670 | int gpiod_get_raw_value(const struct gpio_desc *desc) |
| 1330 | { | 1671 | { |
| 1331 | if (!desc) | 1672 | VALIDATE_DESC(desc); |
| 1332 | return 0; | ||
| 1333 | /* Should be using gpio_get_value_cansleep() */ | 1673 | /* Should be using gpio_get_value_cansleep() */ |
| 1334 | WARN_ON(desc->chip->can_sleep); | 1674 | WARN_ON(desc->gdev->chip->can_sleep); |
| 1335 | return _gpiod_get_raw_value(desc); | 1675 | return _gpiod_get_raw_value(desc); |
| 1336 | } | 1676 | } |
| 1337 | EXPORT_SYMBOL_GPL(gpiod_get_raw_value); | 1677 | EXPORT_SYMBOL_GPL(gpiod_get_raw_value); |
| @@ -1349,10 +1689,10 @@ EXPORT_SYMBOL_GPL(gpiod_get_raw_value); · 11 unmodified lines | |||
| 1349 | int gpiod_get_value(const struct gpio_desc *desc) | 1689 | int gpiod_get_value(const struct gpio_desc *desc) |
| 1350 | { | 1690 | { |
| 1351 | int value; | 1691 | int value; |
| 1352 | if (!desc) | 1692 | |
| 1353 | return 0; | 1693 | VALIDATE_DESC(desc); |
| 1354 | /* Should be using gpio_get_value_cansleep() */ | 1694 | /* Should be using gpio_get_value_cansleep() */ |
| 1355 | WARN_ON(desc->chip->can_sleep); | 1695 | WARN_ON(desc->gdev->chip->can_sleep); |
| 1356 | 1696 | ||
| 1357 | value = _gpiod_get_raw_value(desc); | 1697 | value = _gpiod_get_raw_value(desc); |
| 1358 | if (value < 0) | 1698 | if (value < 0) |
| @@ -1373,7 +1713,7 @@ EXPORT_SYMBOL_GPL(gpiod_get_value); · 14 unmodified lines | |||
| 1373 | static void _gpio_set_open_drain_value(struct gpio_desc *desc, bool value) | 1713 | static void _gpio_set_open_drain_value(struct gpio_desc *desc, bool value) |
| 1374 | { | 1714 | { |
| 1375 | int err = 0; | 1715 | int err = 0; |
| 1376 | struct gpio_chip *chip = desc->chip; | 1716 | struct gpio_chip *chip = desc->gdev->chip; |
| 1377 | int offset = gpio_chip_hwgpio(desc); | 1717 | int offset = gpio_chip_hwgpio(desc); |
| 1378 | 1718 | ||
| 1379 | if (value) { | 1719 | if (value) { |
| @@ -1400,7 +1740,7 @@ static void _gpio_set_open_drain_value(struct gpio_desc *desc, bool value) · 20 unmodified lines | |||
| 1400 | static void _gpio_set_open_source_value(struct gpio_desc *desc, bool value) | 1740 | static void _gpio_set_open_source_value(struct gpio_desc *desc, bool value) |
| 1401 | { | 1741 | { |
| 1402 | int err = 0; | 1742 | int err = 0; |
| 1403 | struct gpio_chip *chip = desc->chip; | 1743 | struct gpio_chip *chip = desc->gdev->chip; |
| 1404 | int offset = gpio_chip_hwgpio(desc); | 1744 | int offset = gpio_chip_hwgpio(desc); |
| 1405 | 1745 | ||
| 1406 | if (value) { | 1746 | if (value) { |
| @@ -1423,7 +1763,7 @@ static void _gpiod_set_raw_value(struct gpio_desc *desc, bool value) · 16 unmodified lines | |||
| 1423 | { | 1763 | { |
| 1424 | struct gpio_chip *chip; | 1764 | struct gpio_chip *chip; |
| 1425 | 1765 | ||
| 1426 | chip = desc->chip; | 1766 | chip = desc->gdev->chip; |
| 1427 | trace_gpio_value(desc_to_gpio(desc), 0, value); | 1767 | trace_gpio_value(desc_to_gpio(desc), 0, value); |
| 1428 | if (test_bit(FLAG_OPEN_DRAIN, &desc->flags)) | 1768 | if (test_bit(FLAG_OPEN_DRAIN, &desc->flags)) |
| 1429 | _gpio_set_open_drain_value(desc, value); | 1769 | _gpio_set_open_drain_value(desc, value); |
| @@ -1471,7 +1811,7 @@ static void gpiod_set_array_value_priv(bool raw, bool can_sleep, · 41 unmodified lines | |||
| 1471 | int i = 0; | 1811 | int i = 0; |
| 1472 | 1812 | ||
| 1473 | while (i < array_size) { | 1813 | while (i < array_size) { |
| 1474 | struct gpio_chip *chip = desc_array[i]->chip; | 1814 | struct gpio_chip *chip = desc_array[i]->gdev->chip; |
| 1475 | unsigned long mask[BITS_TO_LONGS(chip->ngpio)]; | 1815 | unsigned long mask[BITS_TO_LONGS(chip->ngpio)]; |
| 1476 | unsigned long bits[BITS_TO_LONGS(chip->ngpio)]; | 1816 | unsigned long bits[BITS_TO_LONGS(chip->ngpio)]; |
| 1477 | int count = 0; | 1817 | int count = 0; |
| @@ -1505,7 +1845,8 @@ static void gpiod_set_array_value_priv(bool raw, bool can_sleep, · 27 unmodified lines | |||
| 1505 | count++; | 1845 | count++; |
| 1506 | } | 1846 | } |
| 1507 | i++; | 1847 | i++; |
| 1508 | } while ((i < array_size) && (desc_array[i]->chip == chip)); | 1848 | } while ((i < array_size) && |
| 1849 | (desc_array[i]->gdev->chip == chip)); | ||
| 1509 | /* push collected bits to outputs */ | 1850 | /* push collected bits to outputs */ |
| 1510 | if (count != 0) | 1851 | if (count != 0) |
| 1511 | gpio_chip_set_multiple(chip, mask, bits); | 1852 | gpio_chip_set_multiple(chip, mask, bits); |
| @@ -1525,10 +1866,9 @@ static void gpiod_set_array_value_priv(bool raw, bool can_sleep, · 13 unmodified lines | |||
| 1525 | */ | 1866 | */ |
| 1526 | void gpiod_set_raw_value(struct gpio_desc *desc, int value) | 1867 | void gpiod_set_raw_value(struct gpio_desc *desc, int value) |
| 1527 | { | 1868 | { |
| 1528 | if (!desc) | 1869 | VALIDATE_DESC_VOID(desc); |
| 1529 | return; | 1870 | /* Should be using gpiod_set_value_cansleep() */ |
| 1530 | /* Should be using gpio_set_value_cansleep() */ | 1871 | WARN_ON(desc->gdev->chip->can_sleep); |
| 1531 | WARN_ON(desc->chip->can_sleep); | ||
| 1532 | _gpiod_set_raw_value(desc, value); | 1872 | _gpiod_set_raw_value(desc, value); |
| 1533 | } | 1873 | } |
| 1534 | EXPORT_SYMBOL_GPL(gpiod_set_raw_value); | 1874 | EXPORT_SYMBOL_GPL(gpiod_set_raw_value); |
| @@ -1546,10 +1886,9 @@ EXPORT_SYMBOL_GPL(gpiod_set_raw_value); · 11 unmodified lines | |||
| 1546 | */ | 1886 | */ |
| 1547 | void gpiod_set_value(struct gpio_desc *desc, int value) | 1887 | void gpiod_set_value(struct gpio_desc *desc, int value) |
| 1548 | { | 1888 | { |
| 1549 | if (!desc) | 1889 | VALIDATE_DESC_VOID(desc); |
| 1550 | return; | 1890 | /* Should be using gpiod_set_value_cansleep() */ |
| 1551 | /* Should be using gpio_set_value_cansleep() */ | 1891 | WARN_ON(desc->gdev->chip->can_sleep); |
| 1552 | WARN_ON(desc->chip->can_sleep); | ||
| 1553 | if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) | 1892 | if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) |
| 1554 | value = !value; | 1893 | value = !value; |
| 1555 | _gpiod_set_raw_value(desc, value); | 1894 | _gpiod_set_raw_value(desc, value); |
| @@ -1607,9 +1946,8 @@ EXPORT_SYMBOL_GPL(gpiod_set_array_value); · 51 unmodified lines | |||
| 1607 | */ | 1946 | */ |
| 1608 | int gpiod_cansleep(const struct gpio_desc *desc) | 1947 | int gpiod_cansleep(const struct gpio_desc *desc) |
| 1609 | { | 1948 | { |
| 1610 | if (!desc) | 1949 | VALIDATE_DESC(desc); |
| 1611 | return 0; | 1950 | return desc->gdev->chip->can_sleep; |
| 1612 | return desc->chip->can_sleep; | ||
| 1613 | } | 1951 | } |
| 1614 | EXPORT_SYMBOL_GPL(gpiod_cansleep); | 1952 | EXPORT_SYMBOL_GPL(gpiod_cansleep); |
| 1615 | 1953 | ||
| @@ -1625,9 +1963,8 @@ int gpiod_to_irq(const struct gpio_desc *desc) · 9 unmodified lines | |||
| 1625 | struct gpio_chip *chip; | 1963 | struct gpio_chip *chip; |
| 1626 | int offset; | 1964 | int offset; |
| 1627 | 1965 | ||
| 1628 | if (!desc) | 1966 | VALIDATE_DESC(desc); |
| 1629 | return -EINVAL; | 1967 | chip = desc->gdev->chip; |
| 1630 | chip = desc->chip; | ||
| 1631 | offset = gpio_chip_hwgpio(desc); | 1968 | offset = gpio_chip_hwgpio(desc); |
| 1632 | return chip->to_irq ? chip->to_irq(chip, offset) : -ENXIO; | 1969 | return chip->to_irq ? chip->to_irq(chip, offset) : -ENXIO; |
| 1633 | } | 1970 | } |
| @@ -1646,14 +1983,14 @@ int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset) · 12 unmodified lines | |||
| 1646 | if (offset >= chip->ngpio) | 1983 | if (offset >= chip->ngpio) |
| 1647 | return -EINVAL; | 1984 | return -EINVAL; |
| 1648 | 1985 | ||
| 1649 | if (test_bit(FLAG_IS_OUT, &chip->desc[offset].flags)) { | 1986 | if (test_bit(FLAG_IS_OUT, &chip->gpiodev->descs[offset].flags)) { |
| 1650 | chip_err(chip, | 1987 | chip_err(chip, |
| 1651 | "%s: tried to flag a GPIO set as output for IRQ\n", | 1988 | "%s: tried to flag a GPIO set as output for IRQ\n", |
| 1652 | __func__); | 1989 | __func__); |
| 1653 | return -EIO; | 1990 | return -EIO; |
| 1654 | } | 1991 | } |
| 1655 | 1992 | ||
| 1656 | set_bit(FLAG_USED_AS_IRQ, &chip->desc[offset].flags); | 1993 | set_bit(FLAG_USED_AS_IRQ, &chip->gpiodev->descs[offset].flags); |
| 1657 | return 0; | 1994 | return 0; |
| 1658 | } | 1995 | } |
| 1659 | EXPORT_SYMBOL_GPL(gpiochip_lock_as_irq); | 1996 | EXPORT_SYMBOL_GPL(gpiochip_lock_as_irq); |
| @@ -1671,10 +2008,37 @@ void gpiochip_unlock_as_irq(struct gpio_chip *chip, unsigned int offset) · 11 unmodified lines | |||
| 1671 | if (offset >= chip->ngpio) | 2008 | if (offset >= chip->ngpio) |
| 1672 | return; | 2009 | return; |
| 1673 | 2010 | ||
| 1674 | clear_bit(FLAG_USED_AS_IRQ, &chip->desc[offset].flags); | 2011 | clear_bit(FLAG_USED_AS_IRQ, &chip->gpiodev->descs[offset].flags); |
| 1675 | } | 2012 | } |
| 1676 | EXPORT_SYMBOL_GPL(gpiochip_unlock_as_irq); | 2013 | EXPORT_SYMBOL_GPL(gpiochip_unlock_as_irq); |
| 1677 | 2014 | ||
| 2015 | bool gpiochip_line_is_irq(struct gpio_chip *chip, unsigned int offset) | ||
| 2016 | { | ||
| 2017 | if (offset >= chip->ngpio) | ||
| 2018 | return false; | ||
| 2019 | |||
| 2020 | return test_bit(FLAG_USED_AS_IRQ, &chip->gpiodev->descs[offset].flags); | ||
| 2021 | } | ||
| 2022 | EXPORT_SYMBOL_GPL(gpiochip_line_is_irq); | ||
| 2023 | |||
| 2024 | bool gpiochip_line_is_open_drain(struct gpio_chip *chip, unsigned int offset) | ||
| 2025 | { | ||
| 2026 | if (offset >= chip->ngpio) | ||
| 2027 | return false; | ||
| 2028 | |||
| 2029 | return test_bit(FLAG_OPEN_DRAIN, &chip->gpiodev->descs[offset].flags); | ||
| 2030 | } | ||
| 2031 | EXPORT_SYMBOL_GPL(gpiochip_line_is_open_drain); | ||
| 2032 | |||
| 2033 | bool gpiochip_line_is_open_source(struct gpio_chip *chip, unsigned int offset) | ||
| 2034 | { | ||
| 2035 | if (offset >= chip->ngpio) | ||
| 2036 | return false; | ||
| 2037 | |||
| 2038 | return test_bit(FLAG_OPEN_SOURCE, &chip->gpiodev->descs[offset].flags); | ||
| 2039 | } | ||
| 2040 | EXPORT_SYMBOL_GPL(gpiochip_line_is_open_source); | ||
| 2041 | |||
| 1678 | /** | 2042 | /** |
| 1679 | * gpiod_get_raw_value_cansleep() - return a gpio's raw value | 2043 | * gpiod_get_raw_value_cansleep() - return a gpio's raw value |
| 1680 | * @desc: gpio whose value will be returned | 2044 | * @desc: gpio whose value will be returned |
| @@ -1687,8 +2051,7 @@ EXPORT_SYMBOL_GPL(gpiochip_unlock_as_irq); · 6 unmodified lines | |||
| 1687 | int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc) | 2051 | int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc) |
| 1688 | { | 2052 | { |
| 1689 | might_sleep_if(extra_checks); | 2053 | might_sleep_if(extra_checks); |
| 1690 | if (!desc) | 2054 | VALIDATE_DESC(desc); |
| 1691 | return 0; | ||
| 1692 | return _gpiod_get_raw_value(desc); | 2055 | return _gpiod_get_raw_value(desc); |
| 1693 | } | 2056 | } |
| 1694 | EXPORT_SYMBOL_GPL(gpiod_get_raw_value_cansleep); | 2057 | EXPORT_SYMBOL_GPL(gpiod_get_raw_value_cansleep); |
| @@ -1707,9 +2070,7 @@ int gpiod_get_value_cansleep(const struct gpio_desc *desc) · 12 unmodified lines | |||
| 1707 | int value; | 2070 | int value; |
| 1708 | 2071 | ||
| 1709 | might_sleep_if(extra_checks); | 2072 | might_sleep_if(extra_checks); |
| 1710 | if (!desc) | 2073 | VALIDATE_DESC(desc); |
| 1711 | return 0; | ||
| 1712 | |||
| 1713 | value = _gpiod_get_raw_value(desc); | 2074 | value = _gpiod_get_raw_value(desc); |
| 1714 | if (value < 0) | 2075 | if (value < 0) |
| 1715 | return value; | 2076 | return value; |
| @@ -1734,8 +2095,7 @@ EXPORT_SYMBOL_GPL(gpiod_get_value_cansleep); · 18 unmodified lines | |||
| 1734 | void gpiod_set_raw_value_cansleep(struct gpio_desc *desc, int value) | 2095 | void gpiod_set_raw_value_cansleep(struct gpio_desc *desc, int value) |
| 1735 | { | 2096 | { |
| 1736 | might_sleep_if(extra_checks); | 2097 | might_sleep_if(extra_checks); |
| 1737 | if (!desc) | 2098 | VALIDATE_DESC_VOID(desc); |
| 1738 | return; | ||
| 1739 | _gpiod_set_raw_value(desc, value); | 2099 | _gpiod_set_raw_value(desc, value); |
| 1740 | } | 2100 | } |
| 1741 | EXPORT_SYMBOL_GPL(gpiod_set_raw_value_cansleep); | 2101 | EXPORT_SYMBOL_GPL(gpiod_set_raw_value_cansleep); |
| @@ -1753,9 +2113,7 @@ EXPORT_SYMBOL_GPL(gpiod_set_raw_value_cansleep); · 11 unmodified lines | |||
| 1753 | void gpiod_set_value_cansleep(struct gpio_desc *desc, int value) | 2113 | void gpiod_set_value_cansleep(struct gpio_desc *desc, int value) |
| 1754 | { | 2114 | { |
| 1755 | might_sleep_if(extra_checks); | 2115 | might_sleep_if(extra_checks); |
| 1756 | if (!desc) | 2116 | VALIDATE_DESC_VOID(desc); |
| 1757 | return; | ||
| 1758 | |||
| 1759 | if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) | 2117 | if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) |
| 1760 | value = !value; | 2118 | value = !value; |
| 1761 | _gpiod_set_raw_value(desc, value); | 2119 | _gpiod_set_raw_value(desc, value); |
| @@ -2358,8 +2716,8 @@ static void gpiochip_free_hogs(struct gpio_chip *chip) · 596 unmodified lines | |||
| 2358 | int id; | 2716 | int id; |
| 2359 | 2717 | ||
| 2360 | for (id = 0; id < chip->ngpio; id++) { | 2718 | for (id = 0; id < chip->ngpio; id++) { |
| 2361 | if (test_bit(FLAG_IS_HOGGED, &chip->desc[id].flags)) | 2719 | if (test_bit(FLAG_IS_HOGGED, &chip->gpiodev->descs[id].flags)) |
| 2362 | gpiochip_free_own_desc(&chip->desc[id]); | 2720 | gpiochip_free_own_desc(&chip->gpiodev->descs[id]); |
| 2363 | } | 2721 | } |
| 2364 | } | 2722 | } |
| 2365 | 2723 | ||
| @@ -2456,17 +2814,38 @@ void gpiod_put_array(struct gpio_descs *descs) · 90 unmodified lines | |||
| 2456 | } | 2814 | } |
| 2457 | EXPORT_SYMBOL_GPL(gpiod_put_array); | 2815 | EXPORT_SYMBOL_GPL(gpiod_put_array); |
| 2458 | 2816 | ||
| 2817 | static int __init gpiolib_dev_init(void) | ||
| 2818 | { | ||
| 2819 | int ret; | ||
| 2820 | |||
| 2821 | /* Register GPIO sysfs bus */ | ||
| 2822 | ret = bus_register(&gpio_bus_type); | ||
| 2823 | if (ret < 0) { | ||
| 2824 | pr_err("gpiolib: could not register GPIO bus type\n"); | ||
| 2825 | return ret; | ||
| 2826 | } | ||
| 2827 | |||
| 2828 | ret = alloc_chrdev_region(&gpio_devt, 0, GPIO_DEV_MAX, "gpiochip"); | ||
| 2829 | if (ret < 0) { | ||
| 2830 | pr_err("gpiolib: failed to allocate char dev region\n"); | ||
| 2831 | bus_unregister(&gpio_bus_type); | ||
| 2832 | } | ||
| 2833 | return ret; | ||
| 2834 | } | ||
| 2835 | core_initcall(gpiolib_dev_init); | ||
| 2836 | |||
| 2459 | #ifdef CONFIG_DEBUG_FS | 2837 | #ifdef CONFIG_DEBUG_FS |
| 2460 | 2838 | ||
| 2461 | static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) | 2839 | static void gpiolib_dbg_show(struct seq_file *s, struct gpio_device *gdev) |
| 2462 | { | 2840 | { |
| 2463 | unsigned i; | 2841 | unsigned i; |
| 2464 | unsigned gpio = chip->base; | 2842 | struct gpio_chip *chip = gdev->chip; |
| 2465 | struct gpio_desc *gdesc = &chip->desc[0]; | 2843 | unsigned gpio = gdev->base; |
| 2844 | struct gpio_desc *gdesc = &gdev->descs[0]; | ||
| 2466 | int is_out; | 2845 | int is_out; |
| 2467 | int is_irq; | 2846 | int is_irq; |
| 2468 | 2847 | ||
| 2469 | for (i = 0; i < chip->ngpio; i++, gpio++, gdesc++) { | 2848 | for (i = 0; i < gdev->ngpio; i++, gpio++, gdesc++) { |
| 2470 | if (!test_bit(FLAG_REQUESTED, &gdesc->flags)) { | 2849 | if (!test_bit(FLAG_REQUESTED, &gdesc->flags)) { |
| 2471 | if (gdesc->name) { | 2850 | if (gdesc->name) { |
| 2472 | seq_printf(s, " gpio-%-3d (%-20.20s)\n", | 2851 | seq_printf(s, " gpio-%-3d (%-20.20s)\n", |
| @@ -2492,16 +2871,16 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) · 19 unmodified lines | |||
| 2492 | static void *gpiolib_seq_start(struct seq_file *s, loff_t *pos) | 2871 | static void *gpiolib_seq_start(struct seq_file *s, loff_t *pos) |
| 2493 | { | 2872 | { |
| 2494 | unsigned long flags; | 2873 | unsigned long flags; |
| 2495 | struct gpio_chip *chip = NULL; | 2874 | struct gpio_device *gdev = NULL; |
| 2496 | loff_t index = *pos; | 2875 | loff_t index = *pos; |
| 2497 | 2876 | ||
| 2498 | s->private = ""; | 2877 | s->private = ""; |
| 2499 | 2878 | ||
| 2500 | spin_lock_irqsave(&gpio_lock, flags); | 2879 | spin_lock_irqsave(&gpio_lock, flags); |
| 2501 | list_for_each_entry(chip, &gpio_chips, list) | 2880 | list_for_each_entry(gdev, &gpio_devices, list) |
| 2502 | if (index-- == 0) { | 2881 | if (index-- == 0) { |
| 2503 | spin_unlock_irqrestore(&gpio_lock, flags); | 2882 | spin_unlock_irqrestore(&gpio_lock, flags); |
| 2504 | return chip; | 2883 | return gdev; |
| 2505 | } | 2884 | } |
| 2506 | spin_unlock_irqrestore(&gpio_lock, flags); | 2885 | spin_unlock_irqrestore(&gpio_lock, flags); |
| 2507 | 2886 | ||
| @@ -2511,14 +2890,14 @@ static void *gpiolib_seq_start(struct seq_file *s, loff_t *pos) · 3 unmodified lines | |||
| 2511 | static void *gpiolib_seq_next(struct seq_file *s, void *v, loff_t *pos) | 2890 | static void *gpiolib_seq_next(struct seq_file *s, void *v, loff_t *pos) |
| 2512 | { | 2891 | { |
| 2513 | unsigned long flags; | 2892 | unsigned long flags; |
| 2514 | struct gpio_chip *chip = v; | 2893 | struct gpio_device *gdev = v; |
| 2515 | void *ret = NULL; | 2894 | void *ret = NULL; |
| 2516 | 2895 | ||
| 2517 | spin_lock_irqsave(&gpio_lock, flags); | 2896 | spin_lock_irqsave(&gpio_lock, flags); |
| 2518 | if (list_is_last(&chip->list, &gpio_chips)) | 2897 | if (list_is_last(&gdev->list, &gpio_devices)) |
| 2519 | ret = NULL; | 2898 | ret = NULL; |
| 2520 | else | 2899 | else |
| 2521 | ret = list_entry(chip->list.next, struct gpio_chip, list); | 2900 | ret = list_entry(gdev->list.next, struct gpio_device, list); |
| 2522 | spin_unlock_irqrestore(&gpio_lock, flags); | 2901 | spin_unlock_irqrestore(&gpio_lock, flags); |
| 2523 | 2902 | ||
| 2524 | s->private = "\n"; | 2903 | s->private = "\n"; |
| @@ -2533,15 +2912,24 @@ static void gpiolib_seq_stop(struct seq_file *s, void *v) · 8 unmodified lines | |||
| 2533 | 2912 | ||
| 2534 | static int gpiolib_seq_show(struct seq_file *s, void *v) | 2913 | static int gpiolib_seq_show(struct seq_file *s, void *v) |
| 2535 | { | 2914 | { |
| 2536 | struct gpio_chip *chip = v; | 2915 | struct gpio_device *gdev = v; |
| 2537 | struct device *dev; | 2916 | struct gpio_chip *chip = gdev->chip; |
| 2917 | struct device *parent; | ||
| 2918 | |||
| 2919 | if (!chip) { | ||
| 2920 | seq_printf(s, "%s%s: (dangling chip)", (char *)s->private, | ||
| 2921 | dev_name(&gdev->dev)); | ||
| 2922 | return 0; | ||
| 2923 | } | ||
| 2538 | 2924 | ||
| 2539 | seq_printf(s, "%sGPIOs %d-%d", (char *)s->private, | 2925 | seq_printf(s, "%s%s: GPIOs %d-%d", (char *)s->private, |
| 2540 | chip->base, chip->base + chip->ngpio - 1); | 2926 | dev_name(&gdev->dev), |
| 2541 | dev = chip->parent; | 2927 | gdev->base, gdev->base + gdev->ngpio - 1); |
| 2542 | if (dev) | 2928 | parent = chip->parent; |
| 2543 | seq_printf(s, ", %s/%s", dev->bus ? dev->bus->name : "no-bus", | 2929 | if (parent) |
| 2544 | dev_name(dev)); | 2930 | seq_printf(s, ", parent: %s/%s", |
| 2931 | parent->bus ? parent->bus->name : "no-bus", | ||
| 2932 | dev_name(parent)); | ||
| 2545 | if (chip->label) | 2933 | if (chip->label) |
| 2546 | seq_printf(s, ", %s", chip->label); | 2934 | seq_printf(s, ", %s", chip->label); |
| 2547 | if (chip->can_sleep) | 2935 | if (chip->can_sleep) |
| @@ -2551,7 +2939,7 @@ static int gpiolib_seq_show(struct seq_file *s, void *v) · 3 unmodified lines | |||
| 2551 | if (chip->dbg_show) | 2939 | if (chip->dbg_show) |
| 2552 | chip->dbg_show(s, chip); | 2940 | chip->dbg_show(s, chip); |
| 2553 | else | 2941 | else |
| 2554 | gpiolib_dbg_show(s, chip); | 2942 | gpiolib_dbg_show(s, gdev); |
| 2555 | 2943 | ||
| 2556 | return 0; | 2944 | return 0; |
| 2557 | } | 2945 | } |
| @@ -12,13 +12,66 @@ · 11 unmodified lines | |||
| 12 | #ifndef GPIOLIB_H | 12 | #ifndef GPIOLIB_H |
| 13 | #define GPIOLIB_H | 13 | #define GPIOLIB_H |
| 14 | 14 | ||
| 15 | #include <linux/gpio/driver.h> | ||
| 15 | #include <linux/err.h> | 16 | #include <linux/err.h> |
| 16 | #include <linux/device.h> | 17 | #include <linux/device.h> |
| 18 | #include <linux/module.h> | ||
| 19 | #include <linux/cdev.h> | ||
| 17 | 20 | ||
| 18 | enum of_gpio_flags; | 21 | enum of_gpio_flags; |
| 19 | enum gpiod_flags; | 22 | enum gpiod_flags; |
| 20 | struct acpi_device; | 23 | struct acpi_device; |
| 21 | 24 | ||
| 25 | /** | ||
| 26 | * struct gpio_device - internal state container for GPIO devices | ||
| 27 | * @id: numerical ID number for the GPIO chip | ||
| 28 | * @dev: the GPIO device struct | ||
| 29 | * @chrdev: character device for the GPIO device | ||
| 30 | * @mockdev: class device used by the deprecated sysfs interface (may be | ||
| 31 | * NULL) | ||
| 32 | * @owner: helps prevent removal of modules exporting active GPIOs | ||
| 33 | * @chip: pointer to the corresponding gpiochip, holding static | ||
| 34 | * data for this device | ||
| 35 | * @descs: array of ngpio descriptors. | ||
| 36 | * @ngpio: the number of GPIO lines on this GPIO device, equal to the size | ||
| 37 | * of the @descs array. | ||
| 38 | * @base: GPIO base in the DEPRECATED global Linux GPIO numberspace, assigned | ||
| 39 | * at device creation time. | ||
| 40 | * @label: a descriptive name for the GPIO device, such as the part number | ||
| 41 | * or name of the IP component in a System on Chip. | ||
| 42 | * @data: per-instance data assigned by the driver | ||
| 43 | * @list: links gpio_device:s together for traversal | ||
| 44 | * | ||
| 45 | * This state container holds most of the runtime variable data | ||
| 46 | * for a GPIO device and can hold references and live on after the | ||
| 47 | * GPIO chip has been removed, if it is still being used from | ||
| 48 | * userspace. | ||
| 49 | */ | ||
| 50 | struct gpio_device { | ||
| 51 | int id; | ||
| 52 | struct device dev; | ||
| 53 | struct cdev chrdev; | ||
| 54 | struct device *mockdev; | ||
| 55 | struct module *owner; | ||
| 56 | struct gpio_chip *chip; | ||
| 57 | struct gpio_desc *descs; | ||
| 58 | int base; | ||
| 59 | u16 ngpio; | ||
| 60 | char *label; | ||
| 61 | void *data; | ||
| 62 | struct list_head list; | ||
| 63 | |||
| 64 | #ifdef CONFIG_PINCTRL | ||
| 65 | /* | ||
| 66 | * If CONFIG_PINCTRL is enabled, then gpio controllers can optionally | ||
| 67 | * describe the actual pin range which they serve in an SoC. This | ||
| 68 | * information would be used by pinctrl subsystem to configure | ||
| 69 | * corresponding pins for gpio usage. | ||
| 70 | */ | ||
| 71 | struct list_head pin_ranges; | ||
| 72 | #endif | ||
| 73 | }; | ||
| 74 | |||
| 22 | /** | 75 | /** |
| 23 | * struct acpi_gpio_info - ACPI GPIO specific information | 76 | * struct acpi_gpio_info - ACPI GPIO specific information |
| 24 | * @gpioint: if %true this GPIO is of type GpioInt otherwise type is GpioIo | 77 | * @gpioint: if %true this GPIO is of type GpioInt otherwise type is GpioIo |
| @@ -90,10 +143,10 @@ struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np, · 65 unmodified lines | |||
| 90 | struct gpio_desc *gpiochip_get_desc(struct gpio_chip *chip, u16 hwnum); | 143 | struct gpio_desc *gpiochip_get_desc(struct gpio_chip *chip, u16 hwnum); |
| 91 | 144 | ||
| 92 | extern struct spinlock gpio_lock; | 145 | extern struct spinlock gpio_lock; |
| 93 | extern struct list_head gpio_chips; | 146 | extern struct list_head gpio_devices; |
| 94 | 147 | ||
| 95 | struct gpio_desc { | 148 | struct gpio_desc { |
| 96 | struct gpio_chip *chip; | 149 | struct gpio_device *gdev; |
| 97 | unsigned long flags; | 150 | unsigned long flags; |
| 98 | /* flag symbols are bit numbers */ | 151 | /* flag symbols are bit numbers */ |
| 99 | #define FLAG_REQUESTED 0 | 152 | #define FLAG_REQUESTED 0 |
| @@ -122,7 +175,7 @@ int gpiod_hog(struct gpio_desc *desc, const char *name, · 22 unmodified lines | |||
| 122 | */ | 175 | */ |
| 123 | static int __maybe_unused gpio_chip_hwgpio(const struct gpio_desc *desc) | 176 | static int __maybe_unused gpio_chip_hwgpio(const struct gpio_desc *desc) |
| 124 | { | 177 | { |
| 125 | return desc - &desc->chip->desc[0]; | 178 | return desc - &desc->gdev->descs[0]; |
| 126 | } | 179 | } |
| 127 | 180 | ||
| 128 | /* With descriptor prefix */ | 181 | /* With descriptor prefix */ |
| @@ -149,31 +202,31 @@ static int __maybe_unused gpio_chip_hwgpio(const struct gpio_desc *desc) · 20 unmodified lines | |||
| 149 | /* With chip prefix */ | 202 | /* With chip prefix */ |
| 150 | 203 | ||
| 151 | #define chip_emerg(chip, fmt, ...) \ | 204 | #define chip_emerg(chip, fmt, ...) \ |
| 152 | pr_emerg("GPIO chip %s: " fmt, chip->label, ##__VA_ARGS__) | 205 | dev_emerg(&chip->gpiodev->dev, "(%s): " fmt, chip->label, ##__VA_ARGS__) |
| 153 | #define chip_crit(chip, fmt, ...) \ | 206 | #define chip_crit(chip, fmt, ...) \ |
| 154 | pr_crit("GPIO chip %s: " fmt, chip->label, ##__VA_ARGS__) | 207 | dev_crit(&chip->gpiodev->dev, "(%s): " fmt, chip->label, ##__VA_ARGS__) |
| 155 | #define chip_err(chip, fmt, ...) \ | 208 | #define chip_err(chip, fmt, ...) \ |
| 156 | pr_err("GPIO chip %s: " fmt, chip->label, ##__VA_ARGS__) | 209 | dev_err(&chip->gpiodev->dev, "(%s): " fmt, chip->label, ##__VA_ARGS__) |
| 157 | #define chip_warn(chip, fmt, ...) \ | 210 | #define chip_warn(chip, fmt, ...) \ |
| 158 | pr_warn("GPIO chip %s: " fmt, chip->label, ##__VA_ARGS__) | 211 | dev_warn(&chip->gpiodev->dev, "(%s): " fmt, chip->label, ##__VA_ARGS__) |
| 159 | #define chip_info(chip, fmt, ...) \ | 212 | #define chip_info(chip, fmt, ...) \ |
| 160 | pr_info("GPIO chip %s: " fmt, chip->label, ##__VA_ARGS__) | 213 | dev_info(&chip->gpiodev->dev, "(%s): " fmt, chip->label, ##__VA_ARGS__) |
| 161 | #define chip_dbg(chip, fmt, ...) \ | 214 | #define chip_dbg(chip, fmt, ...) \ |
| 162 | pr_debug("GPIO chip %s: " fmt, chip->label, ##__VA_ARGS__) | 215 | dev_dbg(&chip->gpiodev->dev, "(%s): " fmt, chip->label, ##__VA_ARGS__) |
| 163 | 216 | ||
| 164 | #ifdef CONFIG_GPIO_SYSFS | 217 | #ifdef CONFIG_GPIO_SYSFS |
| 165 | 218 | ||
| 166 | int gpiochip_sysfs_register(struct gpio_chip *chip); | 219 | int gpiochip_sysfs_register(struct gpio_device *gdev); |
| 167 | void gpiochip_sysfs_unregister(struct gpio_chip *chip); | 220 | void gpiochip_sysfs_unregister(struct gpio_device *gdev); |
| 168 | 221 | ||
| 169 | #else | 222 | #else |
| 170 | 223 | ||
| 171 | static inline int gpiochip_sysfs_register(struct gpio_chip *chip) | 224 | static inline int gpiochip_sysfs_register(struct gpio_device *gdev) |
| 172 | { | 225 | { |
| 173 | return 0; | 226 | return 0; |
| 174 | } | 227 | } |
| 175 | 228 | ||
| 176 | static inline void gpiochip_sysfs_unregister(struct gpio_chip *chip) | 229 | static inline void gpiochip_sysfs_unregister(struct gpio_device *gdev) |
| 177 | { | 230 | { |
| 178 | } | 231 | } |
| 179 | 232 | ||
| @@ -1181,27 +1181,25 @@ config MFD_TPS65910 · 1180 unmodified lines | |||
| 1181 | Power Management chips. | 1181 | Power Management chips. |
| 1182 | 1182 | ||
| 1183 | config MFD_TPS65912 | 1183 | config MFD_TPS65912 |
| 1184 | bool "TI TPS65912 Power Management chip" | 1184 | tristate |
| 1185 | depends on GPIOLIB | ||
| 1186 | select MFD_CORE | 1185 | select MFD_CORE |
| 1187 | help | 1186 | select REGMAP |
| 1188 | If you say yes here you get support for the TPS65912 series of | 1187 | select REGMAP_IRQ |
| 1189 | PM chips. | ||
| 1190 | 1188 | ||
| 1191 | config MFD_TPS65912_I2C | 1189 | config MFD_TPS65912_I2C |
| 1192 | bool "TI TPS65912 Power Management chip with I2C" | 1190 | tristate "TI TPS65912 Power Management chip with I2C" |
| 1193 | select MFD_CORE | ||
| 1194 | select MFD_TPS65912 | 1191 | select MFD_TPS65912 |
| 1195 | depends on I2C=y && GPIOLIB | 1192 | select REGMAP_I2C |
| 1193 | depends on I2C | ||
| 1196 | help | 1194 | help |
| 1197 | If you say yes here you get support for the TPS65912 series of | 1195 | If you say yes here you get support for the TPS65912 series of |
| 1198 | PM chips with I2C interface. | 1196 | PM chips with I2C interface. |
| 1199 | 1197 | ||
| 1200 | config MFD_TPS65912_SPI | 1198 | config MFD_TPS65912_SPI |
| 1201 | bool "TI TPS65912 Power Management chip with SPI" | 1199 | tristate "TI TPS65912 Power Management chip with SPI" |
| 1202 | select MFD_CORE | ||
| 1203 | select MFD_TPS65912 | 1200 | select MFD_TPS65912 |
| 1204 | depends on SPI_MASTER && GPIOLIB | 1201 | select REGMAP_SPI |
| 1202 | depends on SPI_MASTER | ||
| 1205 | help | 1203 | help |
| 1206 | If you say yes here you get support for the TPS65912 series of | 1204 | If you say yes here you get support for the TPS65912 series of |
| 1207 | PM chips with SPI interface. | 1205 | PM chips with SPI interface. |
| @@ -73,8 +73,7 @@ obj-$(CONFIG_TPS6507X) += tps6507x.o · 72 unmodified lines | |||
| 73 | obj-$(CONFIG_MFD_TPS65217) += tps65217.o | 73 | obj-$(CONFIG_MFD_TPS65217) += tps65217.o |
| 74 | obj-$(CONFIG_MFD_TPS65218) += tps65218.o | 74 | obj-$(CONFIG_MFD_TPS65218) += tps65218.o |
| 75 | obj-$(CONFIG_MFD_TPS65910) += tps65910.o | 75 | obj-$(CONFIG_MFD_TPS65910) += tps65910.o |
| 76 | tps65912-objs := tps65912-core.o tps65912-irq.o | 76 | obj-$(CONFIG_MFD_TPS65912) += tps65912-core.o |
| 77 | obj-$(CONFIG_MFD_TPS65912) += tps65912.o | ||
| 78 | obj-$(CONFIG_MFD_TPS65912_I2C) += tps65912-i2c.o | 77 | obj-$(CONFIG_MFD_TPS65912_I2C) += tps65912-i2c.o |
| 79 | obj-$(CONFIG_MFD_TPS65912_SPI) += tps65912-spi.o | 78 | obj-$(CONFIG_MFD_TPS65912_SPI) += tps65912-spi.o |
| 80 | obj-$(CONFIG_MFD_TPS80031) += tps80031.o | 79 | obj-$(CONFIG_MFD_TPS80031) += tps80031.o |
| @@ -42,10 +42,10 @@ · 41 unmodified lines | |||
| 42 | #include <linux/bcd.h> | 42 | #include <linux/bcd.h> |
| 43 | #include <linux/slab.h> | 43 | #include <linux/slab.h> |
| 44 | #include <linux/mfd/menelaus.h> | 44 | #include <linux/mfd/menelaus.h> |
| 45 | #include <linux/gpio.h> | ||
| 45 | 46 | ||
| 46 | #include <asm/mach/irq.h> | 47 | #include <asm/mach/irq.h> |
| 47 | 48 | ||
| 48 | #include <asm/gpio.h> | ||
| 49 | 49 | ||
| 50 | #define DRIVER_NAME "menelaus" | 50 | #define DRIVER_NAME "menelaus" |
| 51 | 51 | ||
| @@ -1,175 +1,111 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * tps65912-core.c -- TI TPS65912x | 2 | * Core functions for TI TPS65912x PMICs |
| 3 | * | 3 | * |
| 4 | * Copyright 2011 Texas Instruments Inc. | 4 | * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ |
| 5 | * Andrew F. Davis <afd@ti.com> | ||
| 5 | * | 6 | * |
| 6 | * Author: Margarita Olaya Cabrera <magi@slimlogic.co.uk> | 7 | * This program is free software; you can redistribute it and/or |
| 8 | * modify it under the terms of the GNU General Public License version 2 as | ||
| 9 | * published by the Free Software Foundation. | ||
| 7 | * | 10 | * |
| 8 | * This program is free software; you can redistribute it and/or modify it | 11 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any |
| 9 | * under the terms of the GNU General Public License as published by the | 12 | * kind, whether expressed or implied; without even the implied warranty |
| 10 | * Free Software Foundation; either version 2 of the License, or (at your | 13 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 11 | * option) any later version. | 14 | * GNU General Public License version 2 for more details. |
| 12 | * | 15 | * |
| 13 | * This driver is based on wm8350 implementation. | 16 | * Based on the TPS65218 driver and the previous TPS65912 driver by |
| 17 | * Margarita Olaya Cabrera <magi@slimlogic.co.uk> | ||
| 14 | */ | 18 | */ |
| 15 | 19 | ||
| 16 | #include <linux/module.h> | 20 | #include <linux/interrupt.h> |
| 17 | #include <linux/moduleparam.h> | ||
| 18 | #include <linux/slab.h> | ||
| 19 | #include <linux/gpio.h> | ||
| 20 | #include <linux/mfd/core.h> | 21 | #include <linux/mfd/core.h> |
| 22 | #include <linux/module.h> | ||
| 23 | |||
| 21 | #include <linux/mfd/tps65912.h> | 24 | #include <linux/mfd/tps65912.h> |
| 22 | 25 | ||
| 23 | static const struct mfd_cell tps65912s[] = { | 26 | static const struct mfd_cell tps65912_cells[] = { |
| 24 | { | 27 | { .name = "tps65912-regulator", }, |
| 25 | .name = "tps65912-pmic", | 28 | { .name = "tps65912-gpio", }, |
| 26 | }, | ||
| 27 | }; | 29 | }; |
| 28 | 30 | ||
| 29 | int tps65912_set_bits(struct tps65912 *tps65912, u8 reg, u8 mask) | 31 | static const struct regmap_irq tps65912_irqs[] = { |
| 30 | { | 32 | /* INT_STS IRQs */ |
| 31 | u8 data; | 33 | REGMAP_IRQ_REG(TPS65912_IRQ_PWRHOLD_F, 0, TPS65912_INT_STS_PWRHOLD_F), |
| 32 | int err; | 34 | REGMAP_IRQ_REG(TPS65912_IRQ_VMON, 0, TPS65912_INT_STS_VMON), |
| 33 | 35 | REGMAP_IRQ_REG(TPS65912_IRQ_PWRON, 0, TPS65912_INT_STS_PWRON), | |
| 34 | mutex_lock(&tps65912->io_mutex); | 36 | REGMAP_IRQ_REG(TPS65912_IRQ_PWRON_LP, 0, TPS65912_INT_STS_PWRON_LP), |
| 35 | 37 | REGMAP_IRQ_REG(TPS65912_IRQ_PWRHOLD_R, 0, TPS65912_INT_STS_PWRHOLD_R), | |
| 36 | err = tps65912->read(tps65912, reg, 1, &data); | 38 | REGMAP_IRQ_REG(TPS65912_IRQ_HOTDIE, 0, TPS65912_INT_STS_HOTDIE), |
| 37 | if (err) { | 39 | REGMAP_IRQ_REG(TPS65912_IRQ_GPIO1_R, 0, TPS65912_INT_STS_GPIO1_R), |
| 38 | dev_err(tps65912->dev, "Read from reg 0x%x failed\n", reg); | 40 | REGMAP_IRQ_REG(TPS65912_IRQ_GPIO1_F, 0, TPS65912_INT_STS_GPIO1_F), |
| 39 | goto out; | 41 | /* INT_STS2 IRQs */ |
| 40 | } | 42 | REGMAP_IRQ_REG(TPS65912_IRQ_GPIO2_R, 1, TPS65912_INT_STS2_GPIO2_R), |
| 41 | 43 | REGMAP_IRQ_REG(TPS65912_IRQ_GPIO2_F, 1, TPS65912_INT_STS2_GPIO2_F), | |
| 42 | data |= mask; | 44 | REGMAP_IRQ_REG(TPS65912_IRQ_GPIO3_R, 1, TPS65912_INT_STS2_GPIO3_R), |
| 43 | err = tps65912->write(tps65912, reg, 1, &data); | 45 | REGMAP_IRQ_REG(TPS65912_IRQ_GPIO3_F, 1, TPS65912_INT_STS2_GPIO3_F), |
| 44 | if (err) | 46 | REGMAP_IRQ_REG(TPS65912_IRQ_GPIO4_R, 1, TPS65912_INT_STS2_GPIO4_R), |
| 45 | dev_err(tps65912->dev, "Write to reg 0x%x failed\n", reg); | 47 | REGMAP_IRQ_REG(TPS65912_IRQ_GPIO4_F, 1, TPS65912_INT_STS2_GPIO4_F), |
| 48 | REGMAP_IRQ_REG(TPS65912_IRQ_GPIO5_R, 1, TPS65912_INT_STS2_GPIO5_R), | ||
| 49 | REGMAP_IRQ_REG(TPS65912_IRQ_GPIO5_F, 1, TPS65912_INT_STS2_GPIO5_F), | ||
| 50 | /* INT_STS3 IRQs */ | ||
| 51 | REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_DCDC1, 2, TPS65912_INT_STS3_PGOOD_DCDC1), | ||
| 52 | REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_DCDC2, 2, TPS65912_INT_STS3_PGOOD_DCDC2), | ||
| 53 | REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_DCDC3, 2, TPS65912_INT_STS3_PGOOD_DCDC3), | ||
| 54 | REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_DCDC4, 2, TPS65912_INT_STS3_PGOOD_DCDC4), | ||
| 55 | REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_LDO1, 2, TPS65912_INT_STS3_PGOOD_LDO1), | ||
| 56 | REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_LDO2, 2, TPS65912_INT_STS3_PGOOD_LDO2), | ||
| 57 | REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_LDO3, 2, TPS65912_INT_STS3_PGOOD_LDO3), | ||
| 58 | REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_LDO4, 2, TPS65912_INT_STS3_PGOOD_LDO4), | ||
| 59 | /* INT_STS4 IRQs */ | ||
| 60 | REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_LDO5, 3, TPS65912_INT_STS4_PGOOD_LDO5), | ||
| 61 | REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_LDO6, 3, TPS65912_INT_STS4_PGOOD_LDO6), | ||
| 62 | REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_LDO7, 3, TPS65912_INT_STS4_PGOOD_LDO7), | ||
| 63 | REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_LDO8, 3, TPS65912_INT_STS4_PGOOD_LDO8), | ||
| 64 | REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_LDO9, 3, TPS65912_INT_STS4_PGOOD_LDO9), | ||
| 65 | REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_LDO10, 3, TPS65912_INT_STS4_PGOOD_LDO10), | ||
| 66 | }; | ||
| 46 | 67 | ||
| 47 | out: | 68 | static struct regmap_irq_chip tps65912_irq_chip = { |
| 48 | mutex_unlock(&tps65912->io_mutex); | 69 | .name = "tps65912", |
| 49 | return err; | 70 | .irqs = tps65912_irqs, |
| 50 | } | 71 | .num_irqs = ARRAY_SIZE(tps65912_irqs), |
| 51 | EXPORT_SYMBOL_GPL(tps65912_set_bits); | 72 | .num_regs = 4, |
| 73 | .irq_reg_stride = 2, | ||
| 74 | .mask_base = TPS65912_INT_MSK, | ||
| 75 | .status_base = TPS65912_INT_STS, | ||
| 76 | .ack_base = TPS65912_INT_STS, | ||
| 77 | .init_ack_masked = true, | ||
| 78 | }; | ||
| 52 | 79 | ||
| 53 | int tps65912_clear_bits(struct tps65912 *tps65912, u8 reg, u8 mask) | 80 | int tps65912_device_init(struct tps65912 *tps) |
| 54 | { | 81 | { |
| 55 | u8 data; | 82 | int ret; |
| 56 | int err; | 83 | |
| 57 | 84 | ret = regmap_add_irq_chip(tps->regmap, tps->irq, IRQF_ONESHOT, 0, | |
| 58 | mutex_lock(&tps65912->io_mutex); | 85 | &tps65912_irq_chip, &tps->irq_data); |
| 59 | err = tps65912->read(tps65912, reg, 1, &data); | 86 | if (ret) |
| 60 | if (err) { | 87 | return ret; |
| 61 | dev_err(tps65912->dev, "Read from reg 0x%x failed\n", reg); | 88 | |
| 62 | goto out; | 89 | ret = mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO, tps65912_cells, |
| 90 | ARRAY_SIZE(tps65912_cells), NULL, 0, | ||
| 91 | regmap_irq_get_domain(tps->irq_data)); | ||
| 92 | if (ret) { | ||
| 93 | regmap_del_irq_chip(tps->irq, tps->irq_data); | ||
| 94 | return ret; | ||
| 63 | } | 95 | } |
| 64 | 96 | ||
| 65 | data &= ~mask; | 97 | return 0; |
| 66 | err = tps65912->write(tps65912, reg, 1, &data); | ||
| 67 | if (err) | ||
| 68 | dev_err(tps65912->dev, "Write to reg 0x%x failed\n", reg); | ||
| 69 | |||
| 70 | out: | ||
| 71 | mutex_unlock(&tps65912->io_mutex); | ||
| 72 | return err; | ||
| 73 | } | 98 | } |
| 74 | EXPORT_SYMBOL_GPL(tps65912_clear_bits); | 99 | EXPORT_SYMBOL_GPL(tps65912_device_init); |
| 75 | 100 | ||
| 76 | static inline int tps65912_read(struct tps65912 *tps65912, u8 reg) | 101 | int tps65912_device_exit(struct tps65912 *tps) |
| 77 | { | 102 | { |
| 78 | u8 val; | 103 | regmap_del_irq_chip(tps->irq, tps->irq_data); |
| 79 | int err; | ||
| 80 | |||
| 81 | err = tps65912->read(tps65912, reg, 1, &val); | ||
| 82 | if (err < 0) | ||
| 83 | return err; | ||
| 84 | |||
| 85 | return val; | ||
| 86 | } | ||
| 87 | |||
| 88 | static inline int tps65912_write(struct tps65912 *tps65912, u8 reg, u8 val) | ||
| 89 | { | ||
| 90 | return tps65912->write(tps65912, reg, 1, &val); | ||
| 91 | } | ||
| 92 | |||
| 93 | int tps65912_reg_read(struct tps65912 *tps65912, u8 reg) | ||
| 94 | { | ||
| 95 | int data; | ||
| 96 | |||
| 97 | mutex_lock(&tps65912->io_mutex); | ||
| 98 | 104 | ||
| 99 | data = tps65912_read(tps65912, reg); | 105 | return 0; |
| 100 | if (data < 0) | ||
| 101 | dev_err(tps65912->dev, "Read from reg 0x%x failed\n", reg); | ||
| 102 | |||
| 103 | mutex_unlock(&tps65912->io_mutex); | ||
| 104 | return data; | ||
| 105 | } | ||
| 106 | EXPORT_SYMBOL_GPL(tps65912_reg_read); | ||
| 107 | |||
| 108 | int tps65912_reg_write(struct tps65912 *tps65912, u8 reg, u8 val) | ||
| 109 | { | ||
| 110 | int err; | ||
| 111 | |||
| 112 | mutex_lock(&tps65912->io_mutex); | ||
| 113 | |||
| 114 | err = tps65912_write(tps65912, reg, val); | ||
| 115 | if (err < 0) | ||
| 116 | dev_err(tps65912->dev, "Write for reg 0x%x failed\n", reg); | ||
| 117 | |||
| 118 | mutex_unlock(&tps65912->io_mutex); | ||
| 119 | return err; | ||
| 120 | } | ||
| 121 | EXPORT_SYMBOL_GPL(tps65912_reg_write); | ||
| 122 | |||
| 123 | int tps65912_device_init(struct tps65912 *tps65912) | ||
| 124 | { | ||
| 125 | struct tps65912_board *pmic_plat_data = dev_get_platdata(tps65912->dev); | ||
| 126 | struct tps65912_platform_data *init_data; | ||
| 127 | int ret, dcdc_avs, value; | ||
| 128 | |||
| 129 | init_data = kzalloc(sizeof(struct tps65912_platform_data), GFP_KERNEL); | ||
| 130 | if (init_data == NULL) | ||
| 131 | return -ENOMEM; | ||
| 132 | |||
| 133 | mutex_init(&tps65912->io_mutex); | ||
| 134 | dev_set_drvdata(tps65912->dev, tps65912); | ||
| 135 | |||
| 136 | dcdc_avs = (pmic_plat_data->is_dcdc1_avs << 0 | | ||
| 137 | pmic_plat_data->is_dcdc2_avs << 1 | | ||
| 138 | pmic_plat_data->is_dcdc3_avs << 2 | | ||
| 139 | pmic_plat_data->is_dcdc4_avs << 3); | ||
| 140 | if (dcdc_avs) { | ||
| 141 | tps65912->read(tps65912, TPS65912_I2C_SPI_CFG, 1, &value); | ||
| 142 | dcdc_avs |= value; | ||
| 143 | tps65912->write(tps65912, TPS65912_I2C_SPI_CFG, 1, &dcdc_avs); | ||
| 144 | } | ||
| 145 | |||
| 146 | ret = mfd_add_devices(tps65912->dev, -1, | ||
| 147 | tps65912s, ARRAY_SIZE(tps65912s), | ||
| 148 | NULL, 0, NULL); | ||
| 149 | if (ret < 0) | ||
| 150 | goto err; | ||
| 151 | |||
| 152 | init_data->irq = pmic_plat_data->irq; | ||
| 153 | init_data->irq_base = pmic_plat_data->irq_base; | ||
| 154 | ret = tps65912_irq_init(tps65912, init_data->irq, init_data); | ||
| 155 | if (ret < 0) | ||
| 156 | goto err; | ||
| 157 | |||
| 158 | kfree(init_data); | ||
| 159 | return ret; | ||
| 160 | |||
| 161 | err: | ||
| 162 | kfree(init_data); | ||
| 163 | mfd_remove_devices(tps65912->dev); | ||
| 164 | return ret; | ||
| 165 | } | ||
| 166 | |||
| 167 | void tps65912_device_exit(struct tps65912 *tps65912) | ||
| 168 | { | ||
| 169 | mfd_remove_devices(tps65912->dev); | ||
| 170 | tps65912_irq_exit(tps65912); | ||
| 171 | } | 106 | } |
| 107 | EXPORT_SYMBOL_GPL(tps65912_device_exit); | ||
| 172 | 108 | ||
| 173 | MODULE_AUTHOR("Margarita Olaya <magi@slimlogic.co.uk>"); | 109 | MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>"); |
| 174 | MODULE_DESCRIPTION("TPS65912x chip family multi-function driver"); | 110 | MODULE_DESCRIPTION("TPS65912x MFD Driver"); |
| 175 | MODULE_LICENSE("GPL"); | 111 | MODULE_LICENSE("GPL v2"); |
| @@ -1,139 +1,79 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * tps65912-i2c.c -- I2C access for TI TPS65912x PMIC | 2 | * I2C access driver for TI TPS65912x PMICs |
| 3 | * | 3 | * |
| 4 | * Copyright 2011 Texas Instruments Inc. | 4 | * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ |
| 5 | * Andrew F. Davis <afd@ti.com> | ||
| 5 | * | 6 | * |
| 6 | * Author: Margarita Olaya Cabrera <magi@slimlogic.co.uk> | 7 | * This program is free software; you can redistribute it and/or |
| 8 | * modify it under the terms of the GNU General Public License version 2 as | ||
| 9 | * published by the Free Software Foundation. | ||
| 7 | * | 10 | * |
| 8 | * This program is free software; you can redistribute it and/or modify it | 11 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any |
| 9 | * under the terms of the GNU General Public License as published by the | 12 | * kind, whether expressed or implied; without even the implied warranty |
| 10 | * Free Software Foundation; either version 2 of the License, or (at your | 13 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 11 | * option) any later version. | 14 | * GNU General Public License version 2 for more details. |
| 12 | * | 15 | * |
| 13 | * This driver is based on wm8350 implementation. | 16 | * Based on the TPS65218 driver and the previous TPS65912 driver by |
| 17 | * Margarita Olaya Cabrera <magi@slimlogic.co.uk> | ||
| 14 | */ | 18 | */ |
| 15 | 19 | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/moduleparam.h> | ||
| 18 | #include <linux/init.h> | ||
| 19 | #include <linux/slab.h> | ||
| 20 | #include <linux/gpio.h> | ||
| 21 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
| 22 | #include <linux/mfd/core.h> | 21 | #include <linux/module.h> |
| 23 | #include <linux/mfd/tps65912.h> | 22 | #include <linux/regmap.h> |
| 24 | |||
| 25 | static int tps65912_i2c_read(struct tps65912 *tps65912, u8 reg, | ||
| 26 | int bytes, void *dest) | ||
| 27 | { | ||
| 28 | struct i2c_client *i2c = tps65912->control_data; | ||
| 29 | struct i2c_msg xfer[2]; | ||
| 30 | int ret; | ||
| 31 | |||
| 32 | /* Write register */ | ||
| 33 | xfer[0].addr = i2c->addr; | ||
| 34 | xfer[0].flags = 0; | ||
| 35 | xfer[0].len = 1; | ||
| 36 | xfer[0].buf = ® | ||
| 37 | |||
| 38 | /* Read data */ | ||
| 39 | xfer[1].addr = i2c->addr; | ||
| 40 | xfer[1].flags = I2C_M_RD; | ||
| 41 | xfer[1].len = bytes; | ||
| 42 | xfer[1].buf = dest; | ||
| 43 | |||
| 44 | ret = i2c_transfer(i2c->adapter, xfer, 2); | ||
| 45 | if (ret == 2) | ||
| 46 | ret = 0; | ||
| 47 | else if (ret >= 0) | ||
| 48 | ret = -EIO; | ||
| 49 | return ret; | ||
| 50 | } | ||
| 51 | |||
| 52 | static int tps65912_i2c_write(struct tps65912 *tps65912, u8 reg, | ||
| 53 | int bytes, void *src) | ||
| 54 | { | ||
| 55 | struct i2c_client *i2c = tps65912->control_data; | ||
| 56 | /* we add 1 byte for device register */ | ||
| 57 | u8 msg[TPS6591X_MAX_REGISTER + 1]; | ||
| 58 | int ret; | ||
| 59 | |||
| 60 | if (bytes > TPS6591X_MAX_REGISTER) | ||
| 61 | return -EINVAL; | ||
| 62 | |||
| 63 | msg[0] = reg; | ||
| 64 | memcpy(&msg[1], src, bytes); | ||
| 65 | 23 | ||
| 66 | ret = i2c_master_send(i2c, msg, bytes + 1); | 24 | #include <linux/mfd/tps65912.h> |
| 67 | if (ret < 0) | ||
| 68 | return ret; | ||
| 69 | if (ret != bytes + 1) | ||
| 70 | return -EIO; | ||
| 71 | 25 | ||
| 72 | return 0; | 26 | static const struct of_device_id tps65912_i2c_of_match_table[] = { |
| 73 | } | 27 | { .compatible = "ti,tps65912", }, |
| 28 | { /* sentinel */ } | ||
| 29 | }; | ||
| 74 | 30 | ||
| 75 | static int tps65912_i2c_probe(struct i2c_client *i2c, | 31 | static int tps65912_i2c_probe(struct i2c_client *client, |
| 76 | const struct i2c_device_id *id) | 32 | const struct i2c_device_id *ids) |
| 77 | { | 33 | { |
| 78 | struct tps65912 *tps65912; | 34 | struct tps65912 *tps; |
| 79 | 35 | ||
| 80 | tps65912 = devm_kzalloc(&i2c->dev, | 36 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); |
| 81 | sizeof(struct tps65912), GFP_KERNEL); | 37 | if (!tps) |
| 82 | if (tps65912 == NULL) | ||
| 83 | return -ENOMEM; | 38 | return -ENOMEM; |
| 84 | 39 | ||
| 85 | i2c_set_clientdata(i2c, tps65912); | 40 | i2c_set_clientdata(client, tps); |
| 86 | tps65912->dev = &i2c->dev; | 41 | tps->dev = &client->dev; |
| 87 | tps65912->control_data = i2c; | 42 | tps->irq = client->irq; |
| 88 | tps65912->read = tps65912_i2c_read; | 43 | |
| 89 | tps65912->write = tps65912_i2c_write; | 44 | tps->regmap = devm_regmap_init_i2c(client, &tps65912_regmap_config); |
| 45 | if (IS_ERR(tps->regmap)) { | ||
| 46 | dev_err(tps->dev, "Failed to initialize register map\n"); | ||
| 47 | return PTR_ERR(tps->regmap); | ||
| 48 | } | ||
| 90 | 49 | ||
| 91 | return tps65912_device_init(tps65912); | 50 | return tps65912_device_init(tps); |
| 92 | } | 51 | } |
| 93 | 52 | ||
| 94 | static int tps65912_i2c_remove(struct i2c_client *i2c) | 53 | static int tps65912_i2c_remove(struct i2c_client *client) |
| 95 | { | 54 | { |
| 96 | struct tps65912 *tps65912 = i2c_get_clientdata(i2c); | 55 | struct tps65912 *tps = i2c_get_clientdata(client); |
| 97 | 56 | ||
| 98 | tps65912_device_exit(tps65912); | 57 | return tps65912_device_exit(tps); |
| 99 | |||
| 100 | return 0; | ||
| 101 | } | 58 | } |
| 102 | 59 | ||
| 103 | static const struct i2c_device_id tps65912_i2c_id[] = { | 60 | static const struct i2c_device_id tps65912_i2c_id_table[] = { |
| 104 | {"tps65912", 0 }, | 61 | { "tps65912", 0 }, |
| 105 | { } | 62 | { /* sentinel */ } |
| 106 | }; | 63 | }; |
| 107 | MODULE_DEVICE_TABLE(i2c, tps65912_i2c_id); | 64 | MODULE_DEVICE_TABLE(i2c, tps65912_i2c_id_table); |
| 108 | 65 | ||
| 109 | static struct i2c_driver tps65912_i2c_driver = { | 66 | static struct i2c_driver tps65912_i2c_driver = { |
| 110 | .driver = { | 67 | .driver = { |
| 111 | .name = "tps65912", | 68 | .name = "tps65912", |
| 69 | .of_match_table = tps65912_i2c_of_match_table, | ||
| 112 | }, | 70 | }, |
| 113 | .probe = tps65912_i2c_probe, | 71 | .probe = tps65912_i2c_probe, |
| 114 | .remove = tps65912_i2c_remove, | 72 | .remove = tps65912_i2c_remove, |
| 115 | .id_table = tps65912_i2c_id, | 73 | .id_table = tps65912_i2c_id_table, |
| 116 | }; | 74 | }; |
| 75 | module_i2c_driver(tps65912_i2c_driver); | ||
| 117 | 76 | ||
| 118 | static int __init tps65912_i2c_init(void) | 77 | MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>"); |
| 119 | { | 78 | MODULE_DESCRIPTION("TPS65912x I2C Interface Driver"); |
| 120 | int ret; | 79 | MODULE_LICENSE("GPL v2"); |
| 121 | |||
| 122 | ret = i2c_add_driver(&tps65912_i2c_driver); | ||
| 123 | if (ret != 0) | ||
| 124 | pr_err("Failed to register TPS65912 I2C driver: %d\n", ret); | ||
| 125 | |||
| 126 | return ret; | ||
| 127 | } | ||
| 128 | /* init early so consumer devices can complete system boot */ | ||
| 129 | subsys_initcall(tps65912_i2c_init); | ||
| 130 | |||
| 131 | static void __exit tps65912_i2c_exit(void) | ||
| 132 | { | ||
| 133 | i2c_del_driver(&tps65912_i2c_driver); | ||
| 134 | } | ||
| 135 | module_exit(tps65912_i2c_exit); | ||
| 136 | |||
| 137 | MODULE_AUTHOR("Margarita Olaya <magi@slimlogic.co.uk>"); | ||
| 138 | MODULE_DESCRIPTION("TPS6591x chip family multi-function driver"); | ||
| 139 | MODULE_LICENSE("GPL"); | ||
| @@ -1,217 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * tps65912-irq.c -- TI TPS6591x | ||
| 3 | * | ||
| 4 | * Copyright 2011 Texas Instruments Inc. | ||
| 5 | * | ||
| 6 | * Author: Margarita Olaya <magi@slimlogic.co.uk> | ||
| 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 | * This driver is based on wm8350 implementation. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/module.h> | ||
| 18 | #include <linux/bug.h> | ||
| 19 | #include <linux/device.h> | ||
| 20 | #include <linux/interrupt.h> | ||
| 21 | #include <linux/irq.h> | ||
| 22 | #include <linux/gpio.h> | ||
| 23 | #include <linux/mfd/tps65912.h> | ||
| 24 | |||
| 25 | static inline int irq_to_tps65912_irq(struct tps65912 *tps65912, | ||
| 26 | int irq) | ||
| 27 | { | ||
| 28 | return irq - tps65912->irq_base; | ||
| 29 | } | ||
| 30 | |||
| 31 | /* | ||
| 32 | * This is a threaded IRQ handler so can access I2C/SPI. Since the | ||
| 33 | * IRQ handler explicitly clears the IRQ it handles the IRQ line | ||
| 34 | * will be reasserted and the physical IRQ will be handled again if | ||
| 35 | * another interrupt is asserted while we run - in the normal course | ||
| 36 | * of events this is a rare occurrence so we save I2C/SPI reads. We're | ||
| 37 | * also assuming that it's rare to get lots of interrupts firing | ||
| 38 | * simultaneously so try to minimise I/O. | ||
| 39 | */ | ||
| 40 | static irqreturn_t tps65912_irq(int irq, void *irq_data) | ||
| 41 | { | ||
| 42 | struct tps65912 *tps65912 = irq_data; | ||
| 43 | u32 irq_sts; | ||
| 44 | u32 irq_mask; | ||
| 45 | u8 reg; | ||
| 46 | int i; | ||
| 47 | |||
| 48 | |||
| 49 | tps65912->read(tps65912, TPS65912_INT_STS, 1, ®); | ||
| 50 | irq_sts = reg; | ||
| 51 | tps65912->read(tps65912, TPS65912_INT_STS2, 1, ®); | ||
| 52 | irq_sts |= reg << 8; | ||
| 53 | tps65912->read(tps65912, TPS65912_INT_STS3, 1, ®); | ||
| 54 | irq_sts |= reg << 16; | ||
| 55 | tps65912->read(tps65912, TPS65912_INT_STS4, 1, ®); | ||
| 56 | irq_sts |= reg << 24; | ||
| 57 | |||
| 58 | tps65912->read(tps65912, TPS65912_INT_MSK, 1, ®); | ||
| 59 | irq_mask = reg; | ||
| 60 | tps65912->read(tps65912, TPS65912_INT_MSK2, 1, ®); | ||
| 61 | irq_mask |= reg << 8; | ||
| 62 | tps65912->read(tps65912, TPS65912_INT_MSK3, 1, ®); | ||
| 63 | irq_mask |= reg << 16; | ||
| 64 | tps65912->read(tps65912, TPS65912_INT_MSK4, 1, ®); | ||
| 65 | irq_mask |= reg << 24; | ||
| 66 | |||
| 67 | irq_sts &= ~irq_mask; | ||
| 68 | if (!irq_sts) | ||
| 69 | return IRQ_NONE; | ||
| 70 | |||
| 71 | for (i = 0; i < tps65912->irq_num; i++) { | ||
| 72 | if (!(irq_sts & (1 << i))) | ||
| 73 | continue; | ||
| 74 | |||
| 75 | handle_nested_irq(tps65912->irq_base + i); | ||
| 76 | } | ||
| 77 | |||
| 78 | /* Write the STS register back to clear IRQs we handled */ | ||
| 79 | reg = irq_sts & 0xFF; | ||
| 80 | irq_sts >>= 8; | ||
| 81 | if (reg) | ||
| 82 | tps65912->write(tps65912, TPS65912_INT_STS, 1, ®); | ||
| 83 | reg = irq_sts & 0xFF; | ||
| 84 | irq_sts >>= 8; | ||
| 85 | if (reg) | ||
| 86 | tps65912->write(tps65912, TPS65912_INT_STS2, 1, ®); | ||
| 87 | reg = irq_sts & 0xFF; | ||
| 88 | irq_sts >>= 8; | ||
| 89 | if (reg) | ||
| 90 | tps65912->write(tps65912, TPS65912_INT_STS3, 1, ®); | ||
| 91 | reg = irq_sts & 0xFF; | ||
| 92 | if (reg) | ||
| 93 | tps65912->write(tps65912, TPS65912_INT_STS4, 1, ®); | ||
| 94 | |||
| 95 | return IRQ_HANDLED; | ||
| 96 | } | ||
| 97 | |||
| 98 | static void tps65912_irq_lock(struct irq_data *data) | ||
| 99 | { | ||
| 100 | struct tps65912 *tps65912 = irq_data_get_irq_chip_data(data); | ||
| 101 | |||
| 102 | mutex_lock(&tps65912->irq_lock); | ||
| 103 | } | ||
| 104 | |||
| 105 | static void tps65912_irq_sync_unlock(struct irq_data *data) | ||
| 106 | { | ||
| 107 | struct tps65912 *tps65912 = irq_data_get_irq_chip_data(data); | ||
| 108 | u32 reg_mask; | ||
| 109 | u8 reg; | ||
| 110 | |||
| 111 | tps65912->read(tps65912, TPS65912_INT_MSK, 1, ®); | ||
| 112 | reg_mask = reg; | ||
| 113 | tps65912->read(tps65912, TPS65912_INT_MSK2, 1, ®); | ||
| 114 | reg_mask |= reg << 8; | ||
| 115 | tps65912->read(tps65912, TPS65912_INT_MSK3, 1, ®); | ||
| 116 | reg_mask |= reg << 16; | ||
| 117 | tps65912->read(tps65912, TPS65912_INT_MSK4, 1, ®); | ||
| 118 | reg_mask |= reg << 24; | ||
| 119 | |||
| 120 | if (tps65912->irq_mask != reg_mask) { | ||
| 121 | reg = tps65912->irq_mask & 0xFF; | ||
| 122 | tps65912->write(tps65912, TPS65912_INT_MSK, 1, ®); | ||
| 123 | reg = tps65912->irq_mask >> 8 & 0xFF; | ||
| 124 | tps65912->write(tps65912, TPS65912_INT_MSK2, 1, ®); | ||
| 125 | reg = tps65912->irq_mask >> 16 & 0xFF; | ||
| 126 | tps65912->write(tps65912, TPS65912_INT_MSK3, 1, ®); | ||
| 127 | reg = tps65912->irq_mask >> 24 & 0xFF; | ||
| 128 | tps65912->write(tps65912, TPS65912_INT_MSK4, 1, ®); | ||
| 129 | } | ||
| 130 | |||
| 131 | mutex_unlock(&tps65912->irq_lock); | ||
| 132 | } | ||
| 133 | |||
| 134 | static void tps65912_irq_enable(struct irq_data *data) | ||
| 135 | { | ||
| 136 | struct tps65912 *tps65912 = irq_data_get_irq_chip_data(data); | ||
| 137 | |||
| 138 | tps65912->irq_mask &= ~(1 << irq_to_tps65912_irq(tps65912, data->irq)); | ||
| 139 | } | ||
| 140 | |||
| 141 | static void tps65912_irq_disable(struct irq_data *data) | ||
| 142 | { | ||
| 143 | struct tps65912 *tps65912 = irq_data_get_irq_chip_data(data); | ||
| 144 | |||
| 145 | tps65912->irq_mask |= (1 << irq_to_tps65912_irq(tps65912, data->irq)); | ||
| 146 | } | ||
| 147 | |||
| 148 | static struct irq_chip tps65912_irq_chip = { | ||
| 149 | .name = "tps65912", | ||
| 150 | .irq_bus_lock = tps65912_irq_lock, | ||
| 151 | .irq_bus_sync_unlock = tps65912_irq_sync_unlock, | ||
| 152 | .irq_disable = tps65912_irq_disable, | ||
| 153 | .irq_enable = tps65912_irq_enable, | ||
| 154 | }; | ||
| 155 | |||
| 156 | int tps65912_irq_init(struct tps65912 *tps65912, int irq, | ||
| 157 | struct tps65912_platform_data *pdata) | ||
| 158 | { | ||
| 159 | int ret, cur_irq; | ||
| 160 | int flags = IRQF_ONESHOT; | ||
| 161 | u8 reg; | ||
| 162 | |||
| 163 | if (!irq) { | ||
| 164 | dev_warn(tps65912->dev, "No interrupt support, no core IRQ\n"); | ||
| 165 | return 0; | ||
| 166 | } | ||
| 167 | |||
| 168 | if (!pdata || !pdata->irq_base) { | ||
| 169 | dev_warn(tps65912->dev, "No interrupt support, no IRQ base\n"); | ||
| 170 | return 0; | ||
| 171 | } | ||
| 172 | |||
| 173 | /* Clear unattended interrupts */ | ||
| 174 | tps65912->read(tps65912, TPS65912_INT_STS, 1, ®); | ||
| 175 | tps65912->write(tps65912, TPS65912_INT_STS, 1, ®); | ||
| 176 | tps65912->read(tps65912, TPS65912_INT_STS2, 1, ®); | ||
| 177 | tps65912->write(tps65912, TPS65912_INT_STS2, 1, ®); | ||
| 178 | tps65912->read(tps65912, TPS65912_INT_STS3, 1, ®); | ||
| 179 | tps65912->write(tps65912, TPS65912_INT_STS3, 1, ®); | ||
| 180 | tps65912->read(tps65912, TPS65912_INT_STS4, 1, ®); | ||
| 181 | tps65912->write(tps65912, TPS65912_INT_STS4, 1, ®); | ||
| 182 | |||
| 183 | /* Mask top level interrupts */ | ||
| 184 | tps65912->irq_mask = 0xFFFFFFFF; | ||
| 185 | |||
| 186 | mutex_init(&tps65912->irq_lock); | ||
| 187 | tps65912->chip_irq = irq; | ||
| 188 | tps65912->irq_base = pdata->irq_base; | ||
| 189 | |||
| 190 | tps65912->irq_num = TPS65912_NUM_IRQ; | ||
| 191 | |||
| 192 | /* Register with genirq */ | ||
| 193 | for (cur_irq = tps65912->irq_base; | ||
| 194 | cur_irq < tps65912->irq_num + tps65912->irq_base; | ||
| 195 | cur_irq++) { | ||
| 196 | irq_set_chip_data(cur_irq, tps65912); | ||
| 197 | irq_set_chip_and_handler(cur_irq, &tps65912_irq_chip, | ||
| 198 | handle_edge_irq); | ||
| 199 | irq_set_nested_thread(cur_irq, 1); | ||
| 200 | irq_clear_status_flags(cur_irq, IRQ_NOREQUEST | IRQ_NOPROBE); | ||
| 201 | } | ||
| 202 | |||
| 203 | ret = request_threaded_irq(irq, NULL, tps65912_irq, flags, | ||
| 204 | "tps65912", tps65912); | ||
| 205 | |||
| 206 | irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW); | ||
| 207 | if (ret != 0) | ||
| 208 | dev_err(tps65912->dev, "Failed to request IRQ: %d\n", ret); | ||
| 209 | |||
| 210 | return ret; | ||
| 211 | } | ||
| 212 | |||
| 213 | int tps65912_irq_exit(struct tps65912 *tps65912) | ||
| 214 | { | ||
| 215 | free_irq(tps65912->chip_irq, tps65912); | ||
| 216 | return 0; | ||
| 217 | } | ||
| @@ -1,140 +1,78 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * tps65912-spi.c -- SPI access for TI TPS65912x PMIC | 2 | * SPI access driver for TI TPS65912x PMICs |
| 3 | * | 3 | * |
| 4 | * Copyright 2011 Texas Instruments Inc. | 4 | * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ |
| 5 | * Andrew F. Davis <afd@ti.com> | ||
| 5 | * | 6 | * |
| 6 | * Author: Margarita Olaya Cabrera <magi@slimlogic.co.uk> | 7 | * This program is free software; you can redistribute it and/or |
| 8 | * modify it under the terms of the GNU General Public License version 2 as | ||
| 9 | * published by the Free Software Foundation. | ||
| 7 | * | 10 | * |
| 8 | * This program is free software; you can redistribute it and/or modify it | 11 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any |
| 9 | * under the terms of the GNU General Public License as published by the | 12 | * kind, whether expressed or implied; without even the implied warranty |
| 10 | * Free Software Foundation; either version 2 of the License, or (at your | 13 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 11 | * option) any later version. | 14 | * GNU General Public License version 2 for more details. |
| 12 | * | 15 | * |
| 13 | * This driver is based on wm8350 implementation. | 16 | * Based on the TPS65218 driver and the previous TPS65912 driver by |
| 17 | * Margarita Olaya Cabrera <magi@slimlogic.co.uk> | ||
| 14 | */ | 18 | */ |
| 15 | 19 | ||
| 16 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 17 | #include <linux/moduleparam.h> | 21 | #include <linux/regmap.h> |
| 18 | #include <linux/init.h> | ||
| 19 | #include <linux/slab.h> | ||
| 20 | #include <linux/gpio.h> | ||
| 21 | #include <linux/spi/spi.h> | 22 | #include <linux/spi/spi.h> |
| 22 | #include <linux/mfd/core.h> | ||
| 23 | #include <linux/mfd/tps65912.h> | ||
| 24 | |||
| 25 | static int tps65912_spi_write(struct tps65912 *tps65912, u8 addr, | ||
| 26 | int bytes, void *src) | ||
| 27 | { | ||
| 28 | struct spi_device *spi = tps65912->control_data; | ||
| 29 | u8 *data = (u8 *) src; | ||
| 30 | int ret; | ||
| 31 | /* bit 23 is the read/write bit */ | ||
| 32 | unsigned long spi_data = 1 << 23 | addr << 15 | *data; | ||
| 33 | struct spi_transfer xfer; | ||
| 34 | struct spi_message msg; | ||
| 35 | u32 tx_buf; | ||
| 36 | |||
| 37 | tx_buf = spi_data; | ||
| 38 | |||
| 39 | xfer.tx_buf = &tx_buf; | ||
| 40 | xfer.rx_buf = NULL; | ||
| 41 | xfer.len = sizeof(unsigned long); | ||
| 42 | xfer.bits_per_word = 24; | ||
| 43 | |||
| 44 | spi_message_init(&msg); | ||
| 45 | spi_message_add_tail(&xfer, &msg); | ||
| 46 | |||
| 47 | ret = spi_sync(spi, &msg); | ||
| 48 | return ret; | ||
| 49 | } | ||
| 50 | |||
| 51 | static int tps65912_spi_read(struct tps65912 *tps65912, u8 addr, | ||
| 52 | int bytes, void *dest) | ||
| 53 | { | ||
| 54 | struct spi_device *spi = tps65912->control_data; | ||
| 55 | /* bit 23 is the read/write bit */ | ||
| 56 | unsigned long spi_data = 0 << 23 | addr << 15; | ||
| 57 | struct spi_transfer xfer; | ||
| 58 | struct spi_message msg; | ||
| 59 | int ret; | ||
| 60 | u8 *data = (u8 *) dest; | ||
| 61 | u32 tx_buf, rx_buf; | ||
| 62 | |||
| 63 | tx_buf = spi_data; | ||
| 64 | rx_buf = 0; | ||
| 65 | 23 | ||
| 66 | xfer.tx_buf = &tx_buf; | 24 | #include <linux/mfd/tps65912.h> |
| 67 | xfer.rx_buf = &rx_buf; | ||
| 68 | xfer.len = sizeof(unsigned long); | ||
| 69 | xfer.bits_per_word = 24; | ||
| 70 | |||
| 71 | spi_message_init(&msg); | ||
| 72 | spi_message_add_tail(&xfer, &msg); | ||
| 73 | |||
| 74 | if (spi == NULL) | ||
| 75 | return 0; | ||
| 76 | 25 | ||
| 77 | ret = spi_sync(spi, &msg); | 26 | static const struct of_device_id tps65912_spi_of_match_table[] = { |
| 78 | if (ret == 0) | 27 | { .compatible = "ti,tps65912", }, |
| 79 | *data = (u8) (rx_buf & 0xFF); | 28 | { /* sentinel */ } |
| 80 | return ret; | 29 | }; |
| 81 | } | ||
| 82 | 30 | ||
| 83 | static int tps65912_spi_probe(struct spi_device *spi) | 31 | static int tps65912_spi_probe(struct spi_device *spi) |
| 84 | { | 32 | { |
| 85 | struct tps65912 *tps65912; | 33 | struct tps65912 *tps; |
| 86 | 34 | ||
| 87 | tps65912 = devm_kzalloc(&spi->dev, | 35 | tps = devm_kzalloc(&spi->dev, sizeof(*tps), GFP_KERNEL); |
| 88 | sizeof(struct tps65912), GFP_KERNEL); | 36 | if (!tps) |
| 89 | if (tps65912 == NULL) | ||
| 90 | return -ENOMEM; | 37 | return -ENOMEM; |
| 91 | 38 | ||
| 92 | tps65912->dev = &spi->dev; | 39 | spi_set_drvdata(spi, tps); |
| 93 | tps65912->control_data = spi; | 40 | tps->dev = &spi->dev; |
| 94 | tps65912->read = tps65912_spi_read; | 41 | tps->irq = spi->irq; |
| 95 | tps65912->write = tps65912_spi_write; | ||
| 96 | 42 | ||
| 97 | spi_set_drvdata(spi, tps65912); | 43 | tps->regmap = devm_regmap_init_spi(spi, &tps65912_regmap_config); |
| 44 | if (IS_ERR(tps->regmap)) { | ||
| 45 | dev_err(tps->dev, "Failed to initialize register map\n"); | ||
| 46 | return PTR_ERR(tps->regmap); | ||
| 47 | } | ||
| 98 | 48 | ||
| 99 | return tps65912_device_init(tps65912); | 49 | return tps65912_device_init(tps); |
| 100 | } | 50 | } |
| 101 | 51 | ||
| 102 | static int tps65912_spi_remove(struct spi_device *spi) | 52 | static int tps65912_spi_remove(struct spi_device *client) |
| 103 | { | 53 | { |
| 104 | struct tps65912 *tps65912 = spi_get_drvdata(spi); | 54 | struct tps65912 *tps = spi_get_drvdata(client); |
| 105 | 55 | ||
| 106 | tps65912_device_exit(tps65912); | 56 | return tps65912_device_exit(tps); |
| 107 | |||
| 108 | return 0; | ||
| 109 | } | 57 | } |
| 110 | 58 | ||
| 59 | static const struct spi_device_id tps65912_spi_id_table[] = { | ||
| 60 | { "tps65912", 0 }, | ||
| 61 | { /* sentinel */ } | ||
| 62 | }; | ||
| 63 | MODULE_DEVICE_TABLE(spi, tps65912_spi_id_table); | ||
| 64 | |||
| 111 | static struct spi_driver tps65912_spi_driver = { | 65 | static struct spi_driver tps65912_spi_driver = { |
| 112 | .driver = { | 66 | .driver = { |
| 113 | .name = "tps65912", | 67 | .name = "tps65912", |
| 68 | .of_match_table = tps65912_spi_of_match_table, | ||
| 114 | }, | 69 | }, |
| 115 | .probe = tps65912_spi_probe, | 70 | .probe = tps65912_spi_probe, |
| 116 | .remove = tps65912_spi_remove, | 71 | .remove = tps65912_spi_remove, |
| 72 | .id_table = tps65912_spi_id_table, | ||
| 117 | }; | 73 | }; |
| 74 | module_spi_driver(tps65912_spi_driver); | ||
| 118 | 75 | ||
| 119 | static int __init tps65912_spi_init(void) | 76 | MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>"); |
| 120 | { | 77 | MODULE_DESCRIPTION("TPS65912x SPI Interface Driver"); |
| 121 | int ret; | 78 | MODULE_LICENSE("GPL v2"); |
| 122 | |||
| 123 | ret = spi_register_driver(&tps65912_spi_driver); | ||
| 124 | if (ret != 0) | ||
| 125 | pr_err("Failed to register TPS65912 SPI driver: %d\n", ret); | ||
| 126 | |||
| 127 | return 0; | ||
| 128 | } | ||
| 129 | /* init early so consumer devices can complete system boot */ | ||
| 130 | subsys_initcall(tps65912_spi_init); | ||
| 131 | |||
| 132 | static void __exit tps65912_spi_exit(void) | ||
| 133 | { | ||
| 134 | spi_unregister_driver(&tps65912_spi_driver); | ||
| 135 | } | ||
| 136 | module_exit(tps65912_spi_exit); | ||
| 137 | |||
| 138 | MODULE_AUTHOR("Margarita Olaya <magi@slimlogic.co.uk>"); | ||
| 139 | MODULE_DESCRIPTION("SPI support for TPS65912 chip family mfd"); | ||
| 140 | MODULE_LICENSE("GPL"); | ||
| @@ -35,10 +35,10 @@ · 34 unmodified lines | |||
| 35 | #include <linux/io.h> | 35 | #include <linux/io.h> |
| 36 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
| 37 | #include <linux/regulator/consumer.h> | 37 | #include <linux/regulator/consumer.h> |
| 38 | #include <linux/gpio.h> | ||
| 38 | 39 | ||
| 39 | #include <asm/mach/flash.h> | 40 | #include <asm/mach/flash.h> |
| 40 | #include <linux/platform_data/mtd-onenand-omap2.h> | 41 | #include <linux/platform_data/mtd-onenand-omap2.h> |
| 41 | #include <asm/gpio.h> | ||
| 42 | 42 | ||
| 43 | #include <linux/omap-dma.h> | 43 | #include <linux/omap-dma.h> |
| 44 | 44 | ||
| @@ -36,10 +36,10 @@ · 35 unmodified lines | |||
| 36 | #include <linux/interrupt.h> | 36 | #include <linux/interrupt.h> |
| 37 | #include <linux/irq.h> | 37 | #include <linux/irq.h> |
| 38 | #include <linux/io.h> | 38 | #include <linux/io.h> |
| 39 | #include <linux/gpio.h> | ||
| 39 | 40 | ||
| 40 | #include <pcmcia/ss.h> | 41 | #include <pcmcia/ss.h> |
| 41 | #include <pcmcia/cisreg.h> | 42 | #include <pcmcia/cisreg.h> |
| 42 | #include <asm/gpio.h> | ||
| 43 | 43 | ||
| 44 | #define SZ_1K 0x00000400 | 44 | #define SZ_1K 0x00000400 |
| 45 | #define SZ_8K 0x00002000 | 45 | #define SZ_8K 0x00002000 |
| @@ -17,7 +17,6 @@ · 16 unmodified lines | |||
| 17 | 17 | ||
| 18 | #include <asm/mach-types.h> | 18 | #include <asm/mach-types.h> |
| 19 | 19 | ||
| 20 | #include <asm/gpio.h> | ||
| 21 | #include <mach/vpac270.h> | 20 | #include <mach/vpac270.h> |
| 22 | 21 | ||
| 23 | #include "soc_common.h" | 22 | #include "soc_common.h" |
| @@ -26,7 +26,7 @@ · 25 unmodified lines | |||
| 26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
| 27 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
| 28 | #include <linux/io.h> | 28 | #include <linux/io.h> |
| 29 | #include <linux/gpio.h> | 29 | #include <linux/gpio/driver.h> |
| 30 | #include <linux/ioport.h> | 30 | #include <linux/ioport.h> |
| 31 | #include <linux/of_device.h> | 31 | #include <linux/of_device.h> |
| 32 | #include <linux/of_irq.h> | 32 | #include <linux/of_irq.h> |
| @@ -98,11 +98,6 @@ struct iproc_gpio { · 65 unmodified lines | |||
| 98 | struct pinctrl_desc pctldesc; | 98 | struct pinctrl_desc pctldesc; |
| 99 | }; | 99 | }; |
| 100 | 100 | ||
| 101 | static inline struct iproc_gpio *to_iproc_gpio(struct gpio_chip *gc) | ||
| 102 | { | ||
| 103 | return container_of(gc, struct iproc_gpio, gc); | ||
| 104 | } | ||
| 105 | |||
| 106 | /* | 101 | /* |
| 107 | * Mapping from PINCONF pins to GPIO pins is 1-to-1 | 102 | * Mapping from PINCONF pins to GPIO pins is 1-to-1 |
| 108 | */ | 103 | */ |
| @@ -147,7 +142,7 @@ static inline bool iproc_get_bit(struct iproc_gpio *chip, unsigned int reg, · 38 unmodified lines | |||
| 147 | static void iproc_gpio_irq_handler(struct irq_desc *desc) | 142 | static void iproc_gpio_irq_handler(struct irq_desc *desc) |
| 148 | { | 143 | { |
| 149 | struct gpio_chip *gc = irq_desc_get_handler_data(desc); | 144 | struct gpio_chip *gc = irq_desc_get_handler_data(desc); |
| 150 | struct iproc_gpio *chip = to_iproc_gpio(gc); | 145 | struct iproc_gpio *chip = gpiochip_get_data(gc); |
| 151 | struct irq_chip *irq_chip = irq_desc_get_chip(desc); | 146 | struct irq_chip *irq_chip = irq_desc_get_chip(desc); |
| 152 | int i, bit; | 147 | int i, bit; |
| 153 | 148 | ||
| @@ -180,7 +175,7 @@ static void iproc_gpio_irq_handler(struct irq_desc *desc) · 26 unmodified lines | |||
| 180 | static void iproc_gpio_irq_ack(struct irq_data *d) | 175 | static void iproc_gpio_irq_ack(struct irq_data *d) |
| 181 | { | 176 | { |
| 182 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | 177 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
| 183 | struct iproc_gpio *chip = to_iproc_gpio(gc); | 178 | struct iproc_gpio *chip = gpiochip_get_data(gc); |
| 184 | unsigned gpio = d->hwirq; | 179 | unsigned gpio = d->hwirq; |
| 185 | unsigned int offset = IPROC_GPIO_REG(gpio, | 180 | unsigned int offset = IPROC_GPIO_REG(gpio, |
| 186 | IPROC_GPIO_INT_CLR_OFFSET); | 181 | IPROC_GPIO_INT_CLR_OFFSET); |
| @@ -199,7 +194,7 @@ static void iproc_gpio_irq_ack(struct irq_data *d) · 12 unmodified lines | |||
| 199 | static void iproc_gpio_irq_set_mask(struct irq_data *d, bool unmask) | 194 | static void iproc_gpio_irq_set_mask(struct irq_data *d, bool unmask) |
| 200 | { | 195 | { |
| 201 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | 196 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
| 202 | struct iproc_gpio *chip = to_iproc_gpio(gc); | 197 | struct iproc_gpio *chip = gpiochip_get_data(gc); |
| 203 | unsigned gpio = d->hwirq; | 198 | unsigned gpio = d->hwirq; |
| 204 | 199 | ||
| 205 | iproc_set_bit(chip, IPROC_GPIO_INT_MSK_OFFSET, gpio, unmask); | 200 | iproc_set_bit(chip, IPROC_GPIO_INT_MSK_OFFSET, gpio, unmask); |
| @@ -208,7 +203,7 @@ static void iproc_gpio_irq_set_mask(struct irq_data *d, bool unmask) · 2 unmodified lines | |||
| 208 | static void iproc_gpio_irq_mask(struct irq_data *d) | 203 | static void iproc_gpio_irq_mask(struct irq_data *d) |
| 209 | { | 204 | { |
| 210 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | 205 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
| 211 | struct iproc_gpio *chip = to_iproc_gpio(gc); | 206 | struct iproc_gpio *chip = gpiochip_get_data(gc); |
| 212 | unsigned long flags; | 207 | unsigned long flags; |
| 213 | 208 | ||
| 214 | spin_lock_irqsave(&chip->lock, flags); | 209 | spin_lock_irqsave(&chip->lock, flags); |
| @@ -219,7 +214,7 @@ static void iproc_gpio_irq_mask(struct irq_data *d) · 4 unmodified lines | |||
| 219 | static void iproc_gpio_irq_unmask(struct irq_data *d) | 214 | static void iproc_gpio_irq_unmask(struct irq_data *d) |
| 220 | { | 215 | { |
| 221 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | 216 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
| 222 | struct iproc_gpio *chip = to_iproc_gpio(gc); | 217 | struct iproc_gpio *chip = gpiochip_get_data(gc); |
| 223 | unsigned long flags; | 218 | unsigned long flags; |
| 224 | 219 | ||
| 225 | spin_lock_irqsave(&chip->lock, flags); | 220 | spin_lock_irqsave(&chip->lock, flags); |
| @@ -230,7 +225,7 @@ static void iproc_gpio_irq_unmask(struct irq_data *d) · 4 unmodified lines | |||
| 230 | static int iproc_gpio_irq_set_type(struct irq_data *d, unsigned int type) | 225 | static int iproc_gpio_irq_set_type(struct irq_data *d, unsigned int type) |
| 231 | { | 226 | { |
| 232 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | 227 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
| 233 | struct iproc_gpio *chip = to_iproc_gpio(gc); | 228 | struct iproc_gpio *chip = gpiochip_get_data(gc); |
| 234 | unsigned gpio = d->hwirq; | 229 | unsigned gpio = d->hwirq; |
| 235 | bool level_triggered = false; | 230 | bool level_triggered = false; |
| 236 | bool dual_edge = false; | 231 | bool dual_edge = false; |
| @@ -292,7 +287,7 @@ static struct irq_chip iproc_gpio_irq_chip = { · 55 unmodified lines | |||
| 292 | */ | 287 | */ |
| 293 | static int iproc_gpio_request(struct gpio_chip *gc, unsigned offset) | 288 | static int iproc_gpio_request(struct gpio_chip *gc, unsigned offset) |
| 294 | { | 289 | { |
| 295 | struct iproc_gpio *chip = to_iproc_gpio(gc); | 290 | struct iproc_gpio *chip = gpiochip_get_data(gc); |
| 296 | unsigned gpio = gc->base + offset; | 291 | unsigned gpio = gc->base + offset; |
| 297 | 292 | ||
| 298 | /* not all Iproc GPIO pins can be muxed individually */ | 293 | /* not all Iproc GPIO pins can be muxed individually */ |
| @@ -304,7 +299,7 @@ static int iproc_gpio_request(struct gpio_chip *gc, unsigned offset) · 5 unmodified lines | |||
| 304 | 299 | ||
| 305 | static void iproc_gpio_free(struct gpio_chip *gc, unsigned offset) | 300 | static void iproc_gpio_free(struct gpio_chip *gc, unsigned offset) |
| 306 | { | 301 | { |
| 307 | struct iproc_gpio *chip = to_iproc_gpio(gc); | 302 | struct iproc_gpio *chip = gpiochip_get_data(gc); |
| 308 | unsigned gpio = gc->base + offset; | 303 | unsigned gpio = gc->base + offset; |
| 309 | 304 | ||
| 310 | if (!chip->pinmux_is_supported) | 305 | if (!chip->pinmux_is_supported) |
| @@ -315,7 +310,7 @@ static void iproc_gpio_free(struct gpio_chip *gc, unsigned offset) · 4 unmodified lines | |||
| 315 | 310 | ||
| 316 | static int iproc_gpio_direction_input(struct gpio_chip *gc, unsigned gpio) | 311 | static int iproc_gpio_direction_input(struct gpio_chip *gc, unsigned gpio) |
| 317 | { | 312 | { |
| 318 | struct iproc_gpio *chip = to_iproc_gpio(gc); | 313 | struct iproc_gpio *chip = gpiochip_get_data(gc); |
| 319 | unsigned long flags; | 314 | unsigned long flags; |
| 320 | 315 | ||
| 321 | spin_lock_irqsave(&chip->lock, flags); | 316 | spin_lock_irqsave(&chip->lock, flags); |
| @@ -330,7 +325,7 @@ static int iproc_gpio_direction_input(struct gpio_chip *gc, unsigned gpio) · 8 unmodified lines | |||
| 330 | static int iproc_gpio_direction_output(struct gpio_chip *gc, unsigned gpio, | 325 | static int iproc_gpio_direction_output(struct gpio_chip *gc, unsigned gpio, |
| 331 | int val) | 326 | int val) |
| 332 | { | 327 | { |
| 333 | struct iproc_gpio *chip = to_iproc_gpio(gc); | 328 | struct iproc_gpio *chip = gpiochip_get_data(gc); |
| 334 | unsigned long flags; | 329 | unsigned long flags; |
| 335 | 330 | ||
| 336 | spin_lock_irqsave(&chip->lock, flags); | 331 | spin_lock_irqsave(&chip->lock, flags); |
| @@ -345,7 +340,7 @@ static int iproc_gpio_direction_output(struct gpio_chip *gc, unsigned gpio, · 8 unmodified lines | |||
| 345 | 340 | ||
| 346 | static void iproc_gpio_set(struct gpio_chip *gc, unsigned gpio, int val) | 341 | static void iproc_gpio_set(struct gpio_chip *gc, unsigned gpio, int val) |
| 347 | { | 342 | { |
| 348 | struct iproc_gpio *chip = to_iproc_gpio(gc); | 343 | struct iproc_gpio *chip = gpiochip_get_data(gc); |
| 349 | unsigned long flags; | 344 | unsigned long flags; |
| 350 | 345 | ||
| 351 | spin_lock_irqsave(&chip->lock, flags); | 346 | spin_lock_irqsave(&chip->lock, flags); |
| @@ -357,7 +352,7 @@ static void iproc_gpio_set(struct gpio_chip *gc, unsigned gpio, int val) · 5 unmodified lines | |||
| 357 | 352 | ||
| 358 | static int iproc_gpio_get(struct gpio_chip *gc, unsigned gpio) | 353 | static int iproc_gpio_get(struct gpio_chip *gc, unsigned gpio) |
| 359 | { | 354 | { |
| 360 | struct iproc_gpio *chip = to_iproc_gpio(gc); | 355 | struct iproc_gpio *chip = gpiochip_get_data(gc); |
| 361 | unsigned int offset = IPROC_GPIO_REG(gpio, | 356 | unsigned int offset = IPROC_GPIO_REG(gpio, |
| 362 | IPROC_GPIO_DATA_IN_OFFSET); | 357 | IPROC_GPIO_DATA_IN_OFFSET); |
| 363 | unsigned int shift = IPROC_GPIO_SHIFT(gpio); | 358 | unsigned int shift = IPROC_GPIO_SHIFT(gpio); |
| @@ -706,7 +701,7 @@ static int iproc_gpio_probe(struct platform_device *pdev) · 342 unmodified lines | |||
| 706 | chip->pinmux_is_supported = of_property_read_bool(dev->of_node, | 701 | chip->pinmux_is_supported = of_property_read_bool(dev->of_node, |
| 707 | "gpio-ranges"); | 702 | "gpio-ranges"); |
| 708 | 703 | ||
| 709 | ret = gpiochip_add(gc); | 704 | ret = gpiochip_add_data(gc, chip); |
| 710 | if (ret < 0) { | 705 | if (ret < 0) { |
| 711 | dev_err(dev, "unable to add GPIO chip\n"); | 706 | dev_err(dev, "unable to add GPIO chip\n"); |
| 712 | return ret; | 707 | return ret; |
| @@ -338,7 +338,6 @@ struct atlas7_pinctrl_data { · 337 unmodified lines | |||
| 338 | #define ATLAS7_GPIO_CTL_DATAIN_MASK BIT(7) | 338 | #define ATLAS7_GPIO_CTL_DATAIN_MASK BIT(7) |
| 339 | 339 | ||
| 340 | struct atlas7_gpio_bank { | 340 | struct atlas7_gpio_bank { |
| 341 | struct pinctrl_dev *pctldev; | ||
| 342 | int id; | 341 | int id; |
| 343 | int irq; | 342 | int irq; |
| 344 | void __iomem *base; | 343 | void __iomem *base; |
| @@ -6070,7 +6069,6 @@ static int atlas7_gpio_probe(struct platform_device *pdev) · 5725 unmodified lines | |||
| 6070 | } | 6069 | } |
| 6071 | 6070 | ||
| 6072 | for (idx = 0; idx < nbank; idx++) { | 6071 | for (idx = 0; idx < nbank; idx++) { |
| 6073 | struct gpio_pin_range *pin_range; | ||
| 6074 | struct atlas7_gpio_bank *bank; | 6072 | struct atlas7_gpio_bank *bank; |
| 6075 | 6073 | ||
| 6076 | bank = &a7gc->banks[idx]; | 6074 | bank = &a7gc->banks[idx]; |
| @@ -6088,22 +6086,6 @@ static int atlas7_gpio_probe(struct platform_device *pdev) · 11 unmodified lines | |||
| 6088 | 6086 | ||
| 6089 | gpiochip_set_chained_irqchip(chip, &atlas7_gpio_irq_chip, | 6087 | gpiochip_set_chained_irqchip(chip, &atlas7_gpio_irq_chip, |
| 6090 | bank->irq, atlas7_gpio_handle_irq); | 6088 | bank->irq, atlas7_gpio_handle_irq); |
| 6091 | |||
| 6092 | /* Records gpio_pin_range to a7gc */ | ||
| 6093 | list_for_each_entry(pin_range, &chip->pin_ranges, node) { | ||
| 6094 | struct pinctrl_gpio_range *range; | ||
| 6095 | |||
| 6096 | range = &pin_range->range; | ||
| 6097 | if (range->id == NGPIO_OF_BANK * idx) { | ||
| 6098 | bank->gpio_offset = range->id; | ||
| 6099 | bank->ngpio = range->npins; | ||
| 6100 | bank->gpio_pins = range->pins; | ||
| 6101 | bank->pctldev = pin_range->pctldev; | ||
| 6102 | break; | ||
| 6103 | } | ||
| 6104 | } | ||
| 6105 | |||
| 6106 | BUG_ON(!bank->pctldev); | ||
| 6107 | } | 6089 | } |
| 6108 | 6090 | ||
| 6109 | platform_set_drvdata(pdev, a7gc); | 6091 | platform_set_drvdata(pdev, a7gc); |
| @@ -457,8 +457,8 @@ static int sunxi_pinctrl_gpio_get(struct gpio_chip *chip, unsigned offset) · 456 unmodified lines | |||
| 457 | struct sunxi_pinctrl *pctl = gpiochip_get_data(chip); | 457 | struct sunxi_pinctrl *pctl = gpiochip_get_data(chip); |
| 458 | u32 reg = sunxi_data_reg(offset); | 458 | u32 reg = sunxi_data_reg(offset); |
| 459 | u8 index = sunxi_data_offset(offset); | 459 | u8 index = sunxi_data_offset(offset); |
| 460 | u32 set_mux = pctl->desc->irq_read_needs_mux && | 460 | bool set_mux = pctl->desc->irq_read_needs_mux && |
| 461 | test_bit(FLAG_USED_AS_IRQ, &chip->desc[offset].flags); | 461 | gpiochip_line_is_irq(chip, offset); |
| 462 | u32 pin = offset + chip->base; | 462 | u32 pin = offset + chip->base; |
| 463 | u32 val; | 463 | u32 val; |
| 464 | 464 | ||
| @@ -788,7 +788,7 @@ config REGULATOR_TPS65910 · 787 unmodified lines | |||
| 788 | 788 | ||
| 789 | config REGULATOR_TPS65912 | 789 | config REGULATOR_TPS65912 |
| 790 | tristate "TI TPS65912 Power regulator" | 790 | tristate "TI TPS65912 Power regulator" |
| 791 | depends on (MFD_TPS65912_I2C || MFD_TPS65912_SPI) | 791 | depends on MFD_TPS65912 |
| 792 | help | 792 | help |
| 793 | This driver supports TPS65912 voltage regulator chip. | 793 | This driver supports TPS65912 voltage regulator chip. |
| 794 | 794 | ||
| @@ -1,541 +1,168 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * tps65912.c -- TI tps65912 | 2 | * Regulator driver for TI TPS65912x PMICs |
| 3 | * | 3 | * |
| 4 | * Copyright 2011 Texas Instruments Inc. | 4 | * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ |
| 5 | * Andrew F. Davis <afd@ti.com> | ||
| 5 | * | 6 | * |
| 6 | * Author: Margarita Olaya Cabrera <magi@slimlogic.co.uk> | 7 | * This program is free software; you can redistribute it and/or |
| 8 | * modify it under the terms of the GNU General Public License version 2 as | ||
| 9 | * published by the Free Software Foundation. | ||
| 7 | * | 10 | * |
| 8 | * This program is free software; you can redistribute it and/or modify it | 11 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any |
| 9 | * under the terms of the GNU General Public License as published by the | 12 | * kind, whether expressed or implied; without even the implied warranty |
| 10 | * Free Software Foundation; either version 2 of the License, or (at your | 13 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 11 | * option) any later version. | 14 | * GNU General Public License version 2 for more details. |
| 12 | * | 15 | * |
| 13 | * This driver is based on wm8350 implementation. | 16 | * Based on the TPS65218 driver and the previous TPS65912 driver by |
| 17 | * Margarita Olaya Cabrera <magi@slimlogic.co.uk> | ||
| 14 | */ | 18 | */ |
| 15 | 19 | ||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 18 | #include <linux/init.h> | ||
| 19 | #include <linux/err.h> | ||
| 20 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
| 21 | #include <linux/regulator/driver.h> | 22 | #include <linux/regulator/driver.h> |
| 22 | #include <linux/regulator/machine.h> | ||
| 23 | #include <linux/slab.h> | ||
| 24 | #include <linux/gpio.h> | ||
| 25 | #include <linux/mfd/tps65912.h> | ||
| 26 | |||
| 27 | /* DCDC's */ | ||
| 28 | #define TPS65912_REG_DCDC1 0 | ||
| 29 | #define TPS65912_REG_DCDC2 1 | ||
| 30 | #define TPS65912_REG_DCDC3 2 | ||
| 31 | #define TPS65912_REG_DCDC4 3 | ||
| 32 | |||
| 33 | /* LDOs */ | ||
| 34 | #define TPS65912_REG_LDO1 4 | ||
| 35 | #define TPS65912_REG_LDO2 5 | ||
| 36 | #define TPS65912_REG_LDO3 6 | ||
| 37 | #define TPS65912_REG_LDO4 7 | ||
| 38 | #define TPS65912_REG_LDO5 8 | ||
| 39 | #define TPS65912_REG_LDO6 9 | ||
| 40 | #define TPS65912_REG_LDO7 10 | ||
| 41 | #define TPS65912_REG_LDO8 11 | ||
| 42 | #define TPS65912_REG_LDO9 12 | ||
| 43 | #define TPS65912_REG_LDO10 13 | ||
| 44 | |||
| 45 | /* Number of step-down converters available */ | ||
| 46 | #define TPS65912_NUM_DCDC 4 | ||
| 47 | |||
| 48 | /* Number of LDO voltage regulators available */ | ||
| 49 | #define TPS65912_NUM_LDO 10 | ||
| 50 | 23 | ||
| 51 | /* Number of total regulators available */ | 24 | #include <linux/mfd/tps65912.h> |
| 52 | #define TPS65912_NUM_REGULATOR (TPS65912_NUM_DCDC + TPS65912_NUM_LDO) | ||
| 53 | |||
| 54 | #define TPS65912_REG_ENABLED 0x80 | ||
| 55 | #define OP_SELREG_MASK 0x40 | ||
| 56 | #define OP_SELREG_SHIFT 6 | ||
| 57 | |||
| 58 | struct tps_info { | ||
| 59 | const char *name; | ||
| 60 | }; | ||
| 61 | 25 | ||
| 62 | static struct tps_info tps65912_regs[] = { | 26 | enum tps65912_regulators { DCDC1, DCDC2, DCDC3, DCDC4, LDO1, LDO2, LDO3, |
| 63 | { | 27 | LDO4, LDO5, LDO6, LDO7, LDO8, LDO9, LDO10 }; |
| 64 | .name = "DCDC1", | 28 | |
| 65 | }, | 29 | #define TPS65912_REGULATOR(_name, _id, _of_match, _ops, _vr, _er, _lr) \ |
| 66 | { | 30 | [_id] = { \ |
| 67 | .name = "DCDC2", | 31 | .name = _name, \ |
| 68 | }, | 32 | .of_match = _of_match, \ |
| 69 | { | 33 | .regulators_node = "regulators", \ |
| 70 | .name = "DCDC3", | 34 | .id = _id, \ |
| 71 | }, | 35 | .ops = &_ops, \ |
| 72 | { | 36 | .n_voltages = 64, \ |
| 73 | .name = "DCDC4", | 37 | .type = REGULATOR_VOLTAGE, \ |
| 74 | }, | 38 | .owner = THIS_MODULE, \ |
| 75 | { | 39 | .vsel_reg = _vr, \ |
| 76 | .name = "LDO1", | 40 | .vsel_mask = 0x3f, \ |
| 77 | }, | 41 | .enable_reg = _er, \ |
| 78 | { | 42 | .enable_mask = BIT(7), \ |
| 79 | .name = "LDO2", | 43 | .volt_table = NULL, \ |
| 80 | }, | 44 | .linear_ranges = _lr, \ |
| 81 | { | 45 | .n_linear_ranges = ARRAY_SIZE(_lr), \ |
| 82 | .name = "LDO3", | 46 | } |
| 83 | }, | ||
| 84 | { | ||
| 85 | .name = "LDO4", | ||
| 86 | }, | ||
| 87 | { | ||
| 88 | .name = "LDO5", | ||
| 89 | }, | ||
| 90 | { | ||
| 91 | .name = "LDO6", | ||
| 92 | }, | ||
| 93 | { | ||
| 94 | .name = "LDO7", | ||
| 95 | }, | ||
| 96 | { | ||
| 97 | .name = "LDO8", | ||
| 98 | }, | ||
| 99 | { | ||
| 100 | .name = "LDO9", | ||
| 101 | }, | ||
| 102 | { | ||
| 103 | .name = "LDO10", | ||
| 104 | }, | ||
| 105 | }; | ||
| 106 | 47 | ||
| 107 | struct tps65912_reg { | 48 | static const struct regulator_linear_range tps65912_dcdc_ranges[] = { |
| 108 | struct regulator_desc desc[TPS65912_NUM_REGULATOR]; | 49 | REGULATOR_LINEAR_RANGE(500000, 0x0, 0x3f, 50000), |
| 109 | struct tps65912 *mfd; | ||
| 110 | struct regulator_dev *rdev[TPS65912_NUM_REGULATOR]; | ||
| 111 | struct tps_info *info[TPS65912_NUM_REGULATOR]; | ||
| 112 | /* for read/write access */ | ||
| 113 | struct mutex io_lock; | ||
| 114 | int mode; | ||
| 115 | int (*get_ctrl_reg)(int); | ||
| 116 | int dcdc_range[TPS65912_NUM_DCDC]; | ||
| 117 | int pwm_mode_reg; | ||
| 118 | int eco_reg; | ||
| 119 | }; | 50 | }; |
| 120 | 51 | ||
| 121 | static const struct regulator_linear_range tps65912_ldo_ranges[] = { | 52 | static const struct regulator_linear_range tps65912_ldo_ranges[] = { |
| 122 | REGULATOR_LINEAR_RANGE(800000, 0, 32, 25000), | 53 | REGULATOR_LINEAR_RANGE(800000, 0x0, 0x20, 25000), |
| 123 | REGULATOR_LINEAR_RANGE(1650000, 33, 60, 50000), | 54 | REGULATOR_LINEAR_RANGE(1650000, 0x21, 0x3c, 50000), |
| 124 | REGULATOR_LINEAR_RANGE(3100000, 61, 63, 100000), | 55 | REGULATOR_LINEAR_RANGE(3100000, 0x3d, 0x3f, 100000), |
| 125 | }; | 56 | }; |
| 126 | 57 | ||
| 127 | static int tps65912_get_range(struct tps65912_reg *pmic, int id) | ||
| 128 | { | ||
| 129 | struct tps65912 *mfd = pmic->mfd; | ||
| 130 | int range; | ||
| 131 | |||
| 132 | switch (id) { | ||
| 133 | case TPS65912_REG_DCDC1: | ||
| 134 | range = tps65912_reg_read(mfd, TPS65912_DCDC1_LIMIT); | ||
| 135 | break; | ||
| 136 | case TPS65912_REG_DCDC2: | ||
| 137 | range = tps65912_reg_read(mfd, TPS65912_DCDC2_LIMIT); | ||
| 138 | break; | ||
| 139 | case TPS65912_REG_DCDC3: | ||
| 140 | range = tps65912_reg_read(mfd, TPS65912_DCDC3_LIMIT); | ||
| 141 | break; | ||
| 142 | case TPS65912_REG_DCDC4: | ||
| 143 | range = tps65912_reg_read(mfd, TPS65912_DCDC4_LIMIT); | ||
| 144 | break; | ||
| 145 | default: | ||
| 146 | return 0; | ||
| 147 | } | ||
| 148 | |||
| 149 | if (range >= 0) | ||
| 150 | range = (range & DCDC_LIMIT_RANGE_MASK) | ||
| 151 | >> DCDC_LIMIT_RANGE_SHIFT; | ||
| 152 | |||
| 153 | pmic->dcdc_range[id] = range; | ||
| 154 | return range; | ||
| 155 | } | ||
| 156 | |||
| 157 | static unsigned long tps65912_vsel_to_uv_range0(u8 vsel) | ||
| 158 | { | ||
| 159 | unsigned long uv; | ||
| 160 | |||
| 161 | uv = ((vsel * 12500) + 500000); | ||
| 162 | return uv; | ||
| 163 | } | ||
| 164 | |||
| 165 | static unsigned long tps65912_vsel_to_uv_range1(u8 vsel) | ||
| 166 | { | ||
| 167 | unsigned long uv; | ||
| 168 | |||
| 169 | uv = ((vsel * 12500) + 700000); | ||
| 170 | return uv; | ||
| 171 | } | ||
| 172 | |||
| 173 | static unsigned long tps65912_vsel_to_uv_range2(u8 vsel) | ||
| 174 | { | ||
| 175 | unsigned long uv; | ||
| 176 | |||
| 177 | uv = ((vsel * 25000) + 500000); | ||
| 178 | return uv; | ||
| 179 | } | ||
| 180 | |||
| 181 | static unsigned long tps65912_vsel_to_uv_range3(u8 vsel) | ||
| 182 | { | ||
| 183 | unsigned long uv; | ||
| 184 | |||
| 185 | if (vsel == 0x3f) | ||
| 186 | uv = 3800000; | ||
| 187 | else | ||
| 188 | uv = ((vsel * 50000) + 500000); | ||
| 189 | |||
| 190 | return uv; | ||
| 191 | } | ||
| 192 | |||
| 193 | static int tps65912_get_ctrl_register(int id) | ||
| 194 | { | ||
| 195 | if (id >= TPS65912_REG_DCDC1 && id <= TPS65912_REG_LDO4) | ||
| 196 | return id * 3 + TPS65912_DCDC1_AVS; | ||
| 197 | else if (id >= TPS65912_REG_LDO5 && id <= TPS65912_REG_LDO10) | ||
| 198 | return id - TPS65912_REG_LDO5 + TPS65912_LDO5; | ||
| 199 | else | ||
| 200 | return -EINVAL; | ||
| 201 | } | ||
| 202 | |||
| 203 | static int tps65912_get_sel_register(struct tps65912_reg *pmic, int id) | ||
| 204 | { | ||
| 205 | struct tps65912 *mfd = pmic->mfd; | ||
| 206 | int opvsel; | ||
| 207 | u8 reg = 0; | ||
| 208 | |||
| 209 | if (id >= TPS65912_REG_DCDC1 && id <= TPS65912_REG_LDO4) { | ||
| 210 | opvsel = tps65912_reg_read(mfd, id * 3 + TPS65912_DCDC1_OP); | ||
| 211 | if (opvsel & OP_SELREG_MASK) | ||
| 212 | reg = id * 3 + TPS65912_DCDC1_AVS; | ||
| 213 | else | ||
| 214 | reg = id * 3 + TPS65912_DCDC1_OP; | ||
| 215 | } else if (id >= TPS65912_REG_LDO5 && id <= TPS65912_REG_LDO10) { | ||
| 216 | reg = id - TPS65912_REG_LDO5 + TPS65912_LDO5; | ||
| 217 | } else { | ||
| 218 | return -EINVAL; | ||
| 219 | } | ||
| 220 | |||
| 221 | return reg; | ||
| 222 | } | ||
| 223 | |||
| 224 | static int tps65912_get_mode_regiters(struct tps65912_reg *pmic, int id) | ||
| 225 | { | ||
| 226 | switch (id) { | ||
| 227 | case TPS65912_REG_DCDC1: | ||
| 228 | pmic->pwm_mode_reg = TPS65912_DCDC1_CTRL; | ||
| 229 | pmic->eco_reg = TPS65912_DCDC1_AVS; | ||
| 230 | break; | ||
| 231 | case TPS65912_REG_DCDC2: | ||
| 232 | pmic->pwm_mode_reg = TPS65912_DCDC2_CTRL; | ||
| 233 | pmic->eco_reg = TPS65912_DCDC2_AVS; | ||
| 234 | break; | ||
| 235 | case TPS65912_REG_DCDC3: | ||
| 236 | pmic->pwm_mode_reg = TPS65912_DCDC3_CTRL; | ||
| 237 | pmic->eco_reg = TPS65912_DCDC3_AVS; | ||
| 238 | break; | ||
| 239 | case TPS65912_REG_DCDC4: | ||
| 240 | pmic->pwm_mode_reg = TPS65912_DCDC4_CTRL; | ||
| 241 | pmic->eco_reg = TPS65912_DCDC4_AVS; | ||
| 242 | break; | ||
| 243 | default: | ||
| 244 | return -EINVAL; | ||
| 245 | } | ||
| 246 | |||
| 247 | return 0; | ||
| 248 | } | ||
| 249 | |||
| 250 | static int tps65912_reg_is_enabled(struct regulator_dev *dev) | ||
| 251 | { | ||
| 252 | struct tps65912_reg *pmic = rdev_get_drvdata(dev); | ||
| 253 | struct tps65912 *mfd = pmic->mfd; | ||
| 254 | int reg, value, id = rdev_get_id(dev); | ||
| 255 | |||
| 256 | if (id < TPS65912_REG_DCDC1 || id > TPS65912_REG_LDO10) | ||
| 257 | return -EINVAL; | ||
| 258 | |||
| 259 | reg = pmic->get_ctrl_reg(id); | ||
| 260 | if (reg < 0) | ||
| 261 | return reg; | ||
| 262 | |||
| 263 | value = tps65912_reg_read(mfd, reg); | ||
| 264 | if (value < 0) | ||
| 265 | return value; | ||
| 266 | |||
| 267 | return value & TPS65912_REG_ENABLED; | ||
| 268 | } | ||
| 269 | |||
| 270 | static int tps65912_reg_enable(struct regulator_dev *dev) | ||
| 271 | { | ||
| 272 | struct tps65912_reg *pmic = rdev_get_drvdata(dev); | ||
| 273 | struct tps65912 *mfd = pmic->mfd; | ||
| 274 | int id = rdev_get_id(dev); | ||
| 275 | int reg; | ||
| 276 | |||
| 277 | if (id < TPS65912_REG_DCDC1 || id > TPS65912_REG_LDO10) | ||
| 278 | return -EINVAL; | ||
| 279 | |||
| 280 | reg = pmic->get_ctrl_reg(id); | ||
| 281 | if (reg < 0) | ||
| 282 | return reg; | ||
| 283 | |||
| 284 | return tps65912_set_bits(mfd, reg, TPS65912_REG_ENABLED); | ||
| 285 | } | ||
| 286 | |||
| 287 | static int tps65912_reg_disable(struct regulator_dev *dev) | ||
| 288 | { | ||
| 289 | struct tps65912_reg *pmic = rdev_get_drvdata(dev); | ||
| 290 | struct tps65912 *mfd = pmic->mfd; | ||
| 291 | int id = rdev_get_id(dev), reg; | ||
| 292 | |||
| 293 | reg = pmic->get_ctrl_reg(id); | ||
| 294 | if (reg < 0) | ||
| 295 | return reg; | ||
| 296 | |||
| 297 | return tps65912_clear_bits(mfd, reg, TPS65912_REG_ENABLED); | ||
| 298 | } | ||
| 299 | |||
| 300 | static int tps65912_set_mode(struct regulator_dev *dev, unsigned int mode) | ||
| 301 | { | ||
| 302 | struct tps65912_reg *pmic = rdev_get_drvdata(dev); | ||
| 303 | struct tps65912 *mfd = pmic->mfd; | ||
| 304 | int pwm_mode, eco, id = rdev_get_id(dev); | ||
| 305 | |||
| 306 | tps65912_get_mode_regiters(pmic, id); | ||
| 307 | |||
| 308 | pwm_mode = tps65912_reg_read(mfd, pmic->pwm_mode_reg); | ||
| 309 | eco = tps65912_reg_read(mfd, pmic->eco_reg); | ||
| 310 | |||
| 311 | pwm_mode &= DCDCCTRL_DCDC_MODE_MASK; | ||
| 312 | eco &= DCDC_AVS_ECO_MASK; | ||
| 313 | |||
| 314 | switch (mode) { | ||
| 315 | case REGULATOR_MODE_FAST: | ||
| 316 | /* Verify if mode alredy set */ | ||
| 317 | if (pwm_mode && !eco) | ||
| 318 | break; | ||
| 319 | tps65912_set_bits(mfd, pmic->pwm_mode_reg, DCDCCTRL_DCDC_MODE_MASK); | ||
| 320 | tps65912_clear_bits(mfd, pmic->eco_reg, DCDC_AVS_ECO_MASK); | ||
| 321 | break; | ||
| 322 | case REGULATOR_MODE_NORMAL: | ||
| 323 | case REGULATOR_MODE_IDLE: | ||
| 324 | if (!pwm_mode && !eco) | ||
| 325 | break; | ||
| 326 | tps65912_clear_bits(mfd, pmic->pwm_mode_reg, DCDCCTRL_DCDC_MODE_MASK); | ||
| 327 | tps65912_clear_bits(mfd, pmic->eco_reg, DCDC_AVS_ECO_MASK); | ||
| 328 | break; | ||
| 329 | case REGULATOR_MODE_STANDBY: | ||
| 330 | if (!pwm_mode && eco) | ||
| 331 | break; | ||
| 332 | tps65912_clear_bits(mfd, pmic->pwm_mode_reg, DCDCCTRL_DCDC_MODE_MASK); | ||
| 333 | tps65912_set_bits(mfd, pmic->eco_reg, DCDC_AVS_ECO_MASK); | ||
| 334 | break; | ||
| 335 | default: | ||
| 336 | return -EINVAL; | ||
| 337 | } | ||
| 338 | |||
| 339 | return 0; | ||
| 340 | } | ||
| 341 | |||
| 342 | static unsigned int tps65912_get_mode(struct regulator_dev *dev) | ||
| 343 | { | ||
| 344 | struct tps65912_reg *pmic = rdev_get_drvdata(dev); | ||
| 345 | struct tps65912 *mfd = pmic->mfd; | ||
| 346 | int pwm_mode, eco, mode = 0, id = rdev_get_id(dev); | ||
| 347 | |||
| 348 | tps65912_get_mode_regiters(pmic, id); | ||
| 349 | |||
| 350 | pwm_mode = tps65912_reg_read(mfd, pmic->pwm_mode_reg); | ||
| 351 | eco = tps65912_reg_read(mfd, pmic->eco_reg); | ||
| 352 | |||
| 353 | pwm_mode &= DCDCCTRL_DCDC_MODE_MASK; | ||
| 354 | eco &= DCDC_AVS_ECO_MASK; | ||
| 355 | |||
| 356 | if (pwm_mode && !eco) | ||
| 357 | mode = REGULATOR_MODE_FAST; | ||
| 358 | else if (!pwm_mode && !eco) | ||
| 359 | mode = REGULATOR_MODE_NORMAL; | ||
| 360 | else if (!pwm_mode && eco) | ||
| 361 | mode = REGULATOR_MODE_STANDBY; | ||
| 362 | |||
| 363 | return mode; | ||
| 364 | } | ||
| 365 | |||
| 366 | static int tps65912_list_voltage(struct regulator_dev *dev, unsigned selector) | ||
| 367 | { | ||
| 368 | struct tps65912_reg *pmic = rdev_get_drvdata(dev); | ||
| 369 | int range, voltage = 0, id = rdev_get_id(dev); | ||
| 370 | |||
| 371 | if (id > TPS65912_REG_DCDC4) | ||
| 372 | return -EINVAL; | ||
| 373 | |||
| 374 | range = pmic->dcdc_range[id]; | ||
| 375 | |||
| 376 | switch (range) { | ||
| 377 | case 0: | ||
| 378 | /* 0.5 - 1.2875V in 12.5mV steps */ | ||
| 379 | voltage = tps65912_vsel_to_uv_range0(selector); | ||
| 380 | break; | ||
| 381 | case 1: | ||
| 382 | /* 0.7 - 1.4875V in 12.5mV steps */ | ||
| 383 | voltage = tps65912_vsel_to_uv_range1(selector); | ||
| 384 | break; | ||
| 385 | case 2: | ||
| 386 | /* 0.5 - 2.075V in 25mV steps */ | ||
| 387 | voltage = tps65912_vsel_to_uv_range2(selector); | ||
| 388 | break; | ||
| 389 | case 3: | ||
| 390 | /* 0.5 - 3.8V in 50mV steps */ | ||
| 391 | voltage = tps65912_vsel_to_uv_range3(selector); | ||
| 392 | break; | ||
| 393 | } | ||
| 394 | return voltage; | ||
| 395 | } | ||
| 396 | |||
| 397 | static int tps65912_get_voltage_sel(struct regulator_dev *dev) | ||
| 398 | { | ||
| 399 | struct tps65912_reg *pmic = rdev_get_drvdata(dev); | ||
| 400 | struct tps65912 *mfd = pmic->mfd; | ||
| 401 | int id = rdev_get_id(dev); | ||
| 402 | int reg, vsel; | ||
| 403 | |||
| 404 | reg = tps65912_get_sel_register(pmic, id); | ||
| 405 | if (reg < 0) | ||
| 406 | return reg; | ||
| 407 | |||
| 408 | vsel = tps65912_reg_read(mfd, reg); | ||
| 409 | vsel &= 0x3F; | ||
| 410 | |||
| 411 | return vsel; | ||
| 412 | } | ||
| 413 | |||
| 414 | static int tps65912_set_voltage_sel(struct regulator_dev *dev, | ||
| 415 | unsigned selector) | ||
| 416 | { | ||
| 417 | struct tps65912_reg *pmic = rdev_get_drvdata(dev); | ||
| 418 | struct tps65912 *mfd = pmic->mfd; | ||
| 419 | int id = rdev_get_id(dev); | ||
| 420 | int value; | ||
| 421 | u8 reg; | ||
| 422 | |||
| 423 | reg = tps65912_get_sel_register(pmic, id); | ||
| 424 | value = tps65912_reg_read(mfd, reg); | ||
| 425 | value &= 0xC0; | ||
| 426 | return tps65912_reg_write(mfd, reg, selector | value); | ||
| 427 | } | ||
| 428 | |||
| 429 | /* Operations permitted on DCDCx */ | 58 | /* Operations permitted on DCDCx */ |
| 430 | static struct regulator_ops tps65912_ops_dcdc = { | 59 | static struct regulator_ops tps65912_ops_dcdc = { |
| 431 | .is_enabled = tps65912_reg_is_enabled, | 60 | .is_enabled = regulator_is_enabled_regmap, |
| 432 | .enable = tps65912_reg_enable, | 61 | .enable = regulator_enable_regmap, |
| 433 | .disable = tps65912_reg_disable, | 62 | .disable = regulator_disable_regmap, |
| 434 | .set_mode = tps65912_set_mode, | 63 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
| 435 | .get_mode = tps65912_get_mode, | 64 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
| 436 | .get_voltage_sel = tps65912_get_voltage_sel, | 65 | .list_voltage = regulator_list_voltage_linear_range, |
| 437 | .set_voltage_sel = tps65912_set_voltage_sel, | ||
| 438 | .list_voltage = tps65912_list_voltage, | ||
| 439 | }; | 66 | }; |
| 440 | 67 | ||
| 441 | /* Operations permitted on LDOx */ | 68 | /* Operations permitted on LDOx */ |
| 442 | static struct regulator_ops tps65912_ops_ldo = { | 69 | static struct regulator_ops tps65912_ops_ldo = { |
| 443 | .is_enabled = tps65912_reg_is_enabled, | 70 | .is_enabled = regulator_is_enabled_regmap, |
| 444 | .enable = tps65912_reg_enable, | 71 | .enable = regulator_enable_regmap, |
| 445 | .disable = tps65912_reg_disable, | 72 | .disable = regulator_disable_regmap, |
| 446 | .get_voltage_sel = tps65912_get_voltage_sel, | 73 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
| 447 | .set_voltage_sel = tps65912_set_voltage_sel, | 74 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
| 448 | .list_voltage = regulator_list_voltage_linear_range, | 75 | .list_voltage = regulator_list_voltage_linear_range, |
| 449 | .map_voltage = regulator_map_voltage_linear_range, | 76 | .map_voltage = regulator_map_voltage_linear_range, |
| 77 | }; | ||
| 78 | |||
| 79 | static const struct regulator_desc regulators[] = { | ||
| 80 | TPS65912_REGULATOR("DCDC1", DCDC1, "dcdc1", tps65912_ops_dcdc, | ||
| 81 | TPS65912_DCDC1_OP, TPS65912_DCDC1_CTRL, | ||
| 82 | tps65912_dcdc_ranges), | ||
| 83 | TPS65912_REGULATOR("DCDC2", DCDC2, "dcdc2", tps65912_ops_dcdc, | ||
| 84 | TPS65912_DCDC2_OP, TPS65912_DCDC2_CTRL, | ||
| 85 | tps65912_dcdc_ranges), | ||
| 86 | TPS65912_REGULATOR("DCDC3", DCDC3, "dcdc3", tps65912_ops_dcdc, | ||
| 87 | TPS65912_DCDC3_OP, TPS65912_DCDC3_CTRL, | ||
| 88 | tps65912_dcdc_ranges), | ||
| 89 | TPS65912_REGULATOR("DCDC4", DCDC4, "dcdc4", tps65912_ops_dcdc, | ||
| 90 | TPS65912_DCDC4_OP, TPS65912_DCDC4_CTRL, | ||
| 91 | tps65912_dcdc_ranges), | ||
| 92 | TPS65912_REGULATOR("LDO1", LDO1, "ldo1", tps65912_ops_ldo, | ||
| 93 | TPS65912_LDO1_OP, TPS65912_LDO1_AVS, | ||
| 94 | tps65912_ldo_ranges), | ||
| 95 | TPS65912_REGULATOR("LDO2", LDO2, "ldo2", tps65912_ops_ldo, | ||
| 96 | TPS65912_LDO2_OP, TPS65912_LDO2_AVS, | ||
| 97 | tps65912_ldo_ranges), | ||
| 98 | TPS65912_REGULATOR("LDO3", LDO3, "ldo3", tps65912_ops_ldo, | ||
| 99 | TPS65912_LDO3_OP, TPS65912_LDO3_AVS, | ||
| 100 | tps65912_ldo_ranges), | ||
| 101 | TPS65912_REGULATOR("LDO4", LDO4, "ldo4", tps65912_ops_ldo, | ||
| 102 | TPS65912_LDO4_OP, TPS65912_LDO4_AVS, | ||
| 103 | tps65912_ldo_ranges), | ||
| 104 | TPS65912_REGULATOR("LDO5", LDO5, "ldo5", tps65912_ops_ldo, | ||
| 105 | TPS65912_LDO5, TPS65912_LDO5, | ||
| 106 | tps65912_ldo_ranges), | ||
| 107 | TPS65912_REGULATOR("LDO6", LDO6, "ldo6", tps65912_ops_ldo, | ||
| 108 | TPS65912_LDO6, TPS65912_LDO6, | ||
| 109 | tps65912_ldo_ranges), | ||
| 110 | TPS65912_REGULATOR("LDO7", LDO7, "ldo7", tps65912_ops_ldo, | ||
| 111 | TPS65912_LDO7, TPS65912_LDO7, | ||
| 112 | tps65912_ldo_ranges), | ||
| 113 | TPS65912_REGULATOR("LDO8", LDO8, "ldo8", tps65912_ops_ldo, | ||
| 114 | TPS65912_LDO8, TPS65912_LDO8, | ||
| 115 | tps65912_ldo_ranges), | ||
| 116 | TPS65912_REGULATOR("LDO9", LDO9, "ldo9", tps65912_ops_ldo, | ||
| 117 | TPS65912_LDO9, TPS65912_LDO9, | ||
| 118 | tps65912_ldo_ranges), | ||
| 119 | TPS65912_REGULATOR("LDO10", LDO10, "ldo10", tps65912_ops_ldo, | ||
| 120 | TPS65912_LDO10, TPS65912_LDO10, | ||
| 121 | tps65912_ldo_ranges), | ||
| 450 | }; | 122 | }; |
| 451 | 123 | ||
| 452 | static int tps65912_probe(struct platform_device *pdev) | 124 | static int tps65912_regulator_probe(struct platform_device *pdev) |
| 453 | { | 125 | { |
| 454 | struct tps65912 *tps65912 = dev_get_drvdata(pdev->dev.parent); | 126 | struct tps65912 *tps = dev_get_drvdata(pdev->dev.parent); |
| 455 | struct regulator_config config = { }; | 127 | struct regulator_config config = { }; |
| 456 | struct tps_info *info; | ||
| 457 | struct regulator_init_data *reg_data; | ||
| 458 | struct regulator_dev *rdev; | 128 | struct regulator_dev *rdev; |
| 459 | struct tps65912_reg *pmic; | ||
| 460 | struct tps65912_board *pmic_plat_data; | ||
| 461 | int i; | 129 | int i; |
| 462 | 130 | ||
| 463 | pmic_plat_data = dev_get_platdata(tps65912->dev); | 131 | platform_set_drvdata(pdev, tps); |
| 464 | if (!pmic_plat_data) | ||
| 465 | return -EINVAL; | ||
| 466 | 132 | ||
| 467 | reg_data = pmic_plat_data->tps65912_pmic_init_data; | 133 | config.dev = &pdev->dev; |
| 134 | config.driver_data = tps; | ||
| 135 | config.dev->of_node = tps->dev->of_node; | ||
| 136 | config.regmap = tps->regmap; | ||
| 468 | 137 | ||
| 469 | pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); | 138 | for (i = 0; i < ARRAY_SIZE(regulators); i++) { |
| 470 | if (!pmic) | 139 | rdev = devm_regulator_register(&pdev->dev, ®ulators[i], |
| 471 | return -ENOMEM; | ||
| 472 | |||
| 473 | mutex_init(&pmic->io_lock); | ||
| 474 | pmic->mfd = tps65912; | ||
| 475 | platform_set_drvdata(pdev, pmic); | ||
| 476 | |||
| 477 | pmic->get_ctrl_reg = &tps65912_get_ctrl_register; | ||
| 478 | info = tps65912_regs; | ||
| 479 | |||
| 480 | for (i = 0; i < TPS65912_NUM_REGULATOR; i++, info++, reg_data++) { | ||
| 481 | int range = 0; | ||
| 482 | /* Register the regulators */ | ||
| 483 | pmic->info[i] = info; | ||
| 484 | |||
| 485 | pmic->desc[i].name = info->name; | ||
| 486 | pmic->desc[i].id = i; | ||
| 487 | pmic->desc[i].n_voltages = 64; | ||
| 488 | if (i > TPS65912_REG_DCDC4) { | ||
| 489 | pmic->desc[i].ops = &tps65912_ops_ldo; | ||
| 490 | pmic->desc[i].linear_ranges = tps65912_ldo_ranges; | ||
| 491 | pmic->desc[i].n_linear_ranges = | ||
| 492 | ARRAY_SIZE(tps65912_ldo_ranges); | ||
| 493 | } else { | ||
| 494 | pmic->desc[i].ops = &tps65912_ops_dcdc; | ||
| 495 | } | ||
| 496 | pmic->desc[i].type = REGULATOR_VOLTAGE; | ||
| 497 | pmic->desc[i].owner = THIS_MODULE; | ||
| 498 | range = tps65912_get_range(pmic, i); | ||
| 499 | |||
| 500 | config.dev = tps65912->dev; | ||
| 501 | config.init_data = reg_data; | ||
| 502 | config.driver_data = pmic; | ||
| 503 | |||
| 504 | rdev = devm_regulator_register(&pdev->dev, &pmic->desc[i], | ||
| 505 | &config); | 140 | &config); |
| 506 | if (IS_ERR(rdev)) { | 141 | if (IS_ERR(rdev)) { |
| 507 | dev_err(tps65912->dev, | 142 | dev_err(tps->dev, "failed to register %s regulator\n", |
| 508 | "failed to register %s regulator\n", | ||
| 509 | pdev->name); | 143 | pdev->name); |
| 510 | return PTR_ERR(rdev); | 144 | return PTR_ERR(rdev); |
| 511 | } | 145 | } |
| 512 | |||
| 513 | /* Save regulator for cleanup */ | ||
| 514 | pmic->rdev[i] = rdev; | ||
| 515 | } | 146 | } |
| 147 | |||
| 516 | return 0; | 148 | return 0; |
| 517 | } | 149 | } |
| 518 | 150 | ||
| 519 | static struct platform_driver tps65912_driver = { | 151 | static const struct platform_device_id tps65912_regulator_id_table[] = { |
| 152 | { "tps65912-regulator", }, | ||
| 153 | { /* sentinel */ } | ||
| 154 | }; | ||
| 155 | MODULE_DEVICE_TABLE(platform, tps65912_regulator_id_table); | ||
| 156 | |||
| 157 | static struct platform_driver tps65912_regulator_driver = { | ||
| 520 | .driver = { | 158 | .driver = { |
| 521 | .name = "tps65912-pmic", | 159 | .name = "tps65912-regulator", |
| 522 | }, | 160 | }, |
| 523 | .probe = tps65912_probe, | 161 | .probe = tps65912_regulator_probe, |
| 162 | .id_table = tps65912_regulator_id_table, | ||
| 524 | }; | 163 | }; |
| 164 | module_platform_driver(tps65912_regulator_driver); | ||
| 525 | 165 | ||
| 526 | static int __init tps65912_init(void) | 166 | MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>"); |
| 527 | { | ||
| 528 | return platform_driver_register(&tps65912_driver); | ||
| 529 | } | ||
| 530 | subsys_initcall(tps65912_init); | ||
| 531 | |||
| 532 | static void __exit tps65912_cleanup(void) | ||
| 533 | { | ||
| 534 | platform_driver_unregister(&tps65912_driver); | ||
| 535 | } | ||
| 536 | module_exit(tps65912_cleanup); | ||
| 537 | |||
| 538 | MODULE_AUTHOR("Margarita Olaya Cabrera <magi@slimlogic.co.uk>"); | ||
| 539 | MODULE_DESCRIPTION("TPS65912 voltage regulator driver"); | 167 | MODULE_DESCRIPTION("TPS65912 voltage regulator driver"); |
| 540 | MODULE_LICENSE("GPL v2"); | 168 | MODULE_LICENSE("GPL v2"); |
| 541 | MODULE_ALIAS("platform:tps65912-pmic"); | ||
| @@ -63,7 +63,7 @@ static int qe_gpio_get(struct gpio_chip *gc, unsigned int gpio) · 62 unmodified lines | |||
| 63 | struct qe_pio_regs __iomem *regs = mm_gc->regs; | 63 | struct qe_pio_regs __iomem *regs = mm_gc->regs; |
| 64 | u32 pin_mask = 1 << (QE_PIO_PINS - 1 - gpio); | 64 | u32 pin_mask = 1 << (QE_PIO_PINS - 1 - gpio); |
| 65 | 65 | ||
| 66 | return in_be32(®s->cpdata) & pin_mask; | 66 | return !!(in_be32(®s->cpdata) & pin_mask); |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | static void qe_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) | 69 | static void qe_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) |
| @@ -25,8 +25,6 @@ · 24 unmodified lines | |||
| 25 | #include <linux/of.h> | 25 | #include <linux/of.h> |
| 26 | #include <linux/of_gpio.h> | 26 | #include <linux/of_gpio.h> |
| 27 | 27 | ||
| 28 | #include <asm/gpio.h> | ||
| 29 | |||
| 30 | #include "atmel_usba_udc.h" | 28 | #include "atmel_usba_udc.h" |
| 31 | 29 | ||
| 32 | #ifdef CONFIG_USB_GADGET_DEBUG_FS | 30 | #ifdef CONFIG_USB_GADGET_DEBUG_FS |
| @@ -24,8 +24,6 @@ · 23 unmodified lines | |||
| 24 | #include <linux/usb.h> | 24 | #include <linux/usb.h> |
| 25 | #include <linux/usb/hcd.h> | 25 | #include <linux/usb/hcd.h> |
| 26 | 26 | ||
| 27 | #include <asm/gpio.h> | ||
| 28 | |||
| 29 | #include "ohci.h" | 27 | #include "ohci.h" |
| 30 | 28 | ||
| 31 | #define valid_port(index) ((index) >= 0 && (index) < AT91_MAX_USBH_PORTS) | 29 | #define valid_port(index) ((index) >= 0 && (index) < AT91_MAX_USBH_PORTS) |
| @@ -26,8 +26,6 @@ · 25 unmodified lines | |||
| 26 | #include <linux/regulator/consumer.h> | 26 | #include <linux/regulator/consumer.h> |
| 27 | #include <video/videomode.h> | 27 | #include <video/videomode.h> |
| 28 | 28 | ||
| 29 | #include <asm/gpio.h> | ||
| 30 | |||
| 31 | #include <video/atmel_lcdc.h> | 29 | #include <video/atmel_lcdc.h> |
| 32 | 30 | ||
| 33 | struct atmel_lcdfb_config { | 31 | struct atmel_lcdfb_config { |
| @@ -22,8 +22,8 @@ · 21 unmodified lines | |||
| 22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
| 23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
| 24 | #include <linux/i2c/tps65010.h> | 24 | #include <linux/i2c/tps65010.h> |
| 25 | #include <linux/gpio.h> | ||
| 25 | 26 | ||
| 26 | #include <asm/gpio.h> | ||
| 27 | #include "omapfb.h" | 27 | #include "omapfb.h" |
| 28 | 28 | ||
| 29 | #define MODULE_NAME "omapfb-lcd_h3" | 29 | #define MODULE_NAME "omapfb-lcd_h3" |
| @@ -22,8 +22,7 @@ · 21 unmodified lines | |||
| 22 | 22 | ||
| 23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
| 24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
| 25 | 25 | #include <linux/gpio.h> | |
| 26 | #include <asm/gpio.h> | ||
| 27 | 26 | ||
| 28 | #include <mach/hardware.h> | 27 | #include <mach/hardware.h> |
| 29 | #include <mach/mux.h> | 28 | #include <mach/mux.h> |
| @@ -28,8 +28,8 @@ GPIO13 - screen blanking · 27 unmodified lines | |||
| 28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
| 29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
| 30 | #include <linux/io.h> | 30 | #include <linux/io.h> |
| 31 | #include <linux/gpio.h> | ||
| 31 | 32 | ||
| 32 | #include <asm/gpio.h> | ||
| 33 | #include "omapfb.h" | 33 | #include "omapfb.h" |
| 34 | 34 | ||
| 35 | static int palmtt_panel_init(struct lcd_panel *panel, | 35 | static int palmtt_panel_init(struct lcd_panel *panel, |
| @@ -26,8 +26,12 @@ · 25 unmodified lines | |||
| 26 | */ | 26 | */ |
| 27 | 27 | ||
| 28 | #ifndef ARCH_NR_GPIOS | 28 | #ifndef ARCH_NR_GPIOS |
| 29 | #if defined(CONFIG_ARCH_NR_GPIO) && CONFIG_ARCH_NR_GPIO > 0 | ||
| 30 | #define ARCH_NR_GPIOS CONFIG_ARCH_NR_GPIO | ||
| 31 | #else | ||
| 29 | #define ARCH_NR_GPIOS 512 | 32 | #define ARCH_NR_GPIOS 512 |
| 30 | #endif | 33 | #endif |
| 34 | #endif | ||
| 31 | 35 | ||
| 32 | /* | 36 | /* |
| 33 | * "valid" GPIO numbers are nonnegative and may be passed to | 37 | * "valid" GPIO numbers are nonnegative and may be passed to |
| @@ -1,6 +1,7 @@ | |||
| 1 | #ifndef __LINUX_GPIO_DRIVER_H | 1 | #ifndef __LINUX_GPIO_DRIVER_H |
| 2 | #define __LINUX_GPIO_DRIVER_H | 2 | #define __LINUX_GPIO_DRIVER_H |
| 3 | 3 | ||
| 4 | #include <linux/device.h> | ||
| 4 | #include <linux/types.h> | 5 | #include <linux/types.h> |
| 5 | #include <linux/module.h> | 6 | #include <linux/module.h> |
| 6 | #include <linux/irq.h> | 7 | #include <linux/irq.h> |
| @@ -10,22 +11,21 @@ · 3 unmodified lines | |||
| 10 | #include <linux/pinctrl/pinctrl.h> | 11 | #include <linux/pinctrl/pinctrl.h> |
| 11 | #include <linux/kconfig.h> | 12 | #include <linux/kconfig.h> |
| 12 | 13 | ||
| 13 | struct device; | ||
| 14 | struct gpio_desc; | 14 | struct gpio_desc; |
| 15 | struct of_phandle_args; | 15 | struct of_phandle_args; |
| 16 | struct device_node; | 16 | struct device_node; |
| 17 | struct seq_file; | 17 | struct seq_file; |
| 18 | struct gpio_device; | ||
| 18 | 19 | ||
| 19 | #ifdef CONFIG_GPIOLIB | 20 | #ifdef CONFIG_GPIOLIB |
| 20 | 21 | ||
| 21 | /** | 22 | /** |
| 22 | * struct gpio_chip - abstract a GPIO controller | 23 | * struct gpio_chip - abstract a GPIO controller |
| 23 | * @label: for diagnostics | 24 | * @label: a functional name for the GPIO device, such as a part |
| 25 | * number or the name of the SoC IP-block implementing it. | ||
| 26 | * @gpiodev: the internal state holder, opaque struct | ||
| 24 | * @parent: optional parent device providing the GPIOs | 27 | * @parent: optional parent device providing the GPIOs |
| 25 | * @cdev: class device used by sysfs interface (may be NULL) | ||
| 26 | * @owner: helps prevent removal of modules exporting active GPIOs | 28 | * @owner: helps prevent removal of modules exporting active GPIOs |
| 27 | * @data: per-instance data assigned by the driver | ||
| 28 | * @list: links gpio_chips together for traversal | ||
| 29 | * @request: optional hook for chip-specific activation, such as | 29 | * @request: optional hook for chip-specific activation, such as |
| 30 | * enabling module power and clock; may sleep | 30 | * enabling module power and clock; may sleep |
| 31 | * @free: optional hook for chip-specific deactivation, such as | 31 | * @free: optional hook for chip-specific deactivation, such as |
| @@ -52,7 +52,6 @@ struct seq_file; · 20 unmodified lines | |||
| 52 | * get rid of the static GPIO number space in the long run. | 52 | * get rid of the static GPIO number space in the long run. |
| 53 | * @ngpio: the number of GPIOs handled by this controller; the last GPIO | 53 | * @ngpio: the number of GPIOs handled by this controller; the last GPIO |
| 54 | * handled is (base + ngpio - 1). | 54 | * handled is (base + ngpio - 1). |
| 55 | * @desc: array of ngpio descriptors. Private. | ||
| 56 | * @names: if set, must be an array of strings to use as alternative | 55 | * @names: if set, must be an array of strings to use as alternative |
| 57 | * names for the GPIOs in this chip. Any entry in the array | 56 | * names for the GPIOs in this chip. Any entry in the array |
| 58 | * may be NULL if there is no alias for the GPIO, however the | 57 | * may be NULL if there is no alias for the GPIO, however the |
| @@ -107,11 +106,9 @@ struct seq_file; · 48 unmodified lines | |||
| 107 | */ | 106 | */ |
| 108 | struct gpio_chip { | 107 | struct gpio_chip { |
| 109 | const char *label; | 108 | const char *label; |
| 109 | struct gpio_device *gpiodev; | ||
| 110 | struct device *parent; | 110 | struct device *parent; |
| 111 | struct device *cdev; | ||
| 112 | struct module *owner; | 111 | struct module *owner; |
| 113 | void *data; | ||
| 114 | struct list_head list; | ||
| 115 | 112 | ||
| 116 | int (*request)(struct gpio_chip *chip, | 113 | int (*request)(struct gpio_chip *chip, |
| 117 | unsigned offset); | 114 | unsigned offset); |
| @@ -141,7 +138,6 @@ struct gpio_chip { · 23 unmodified lines | |||
| 141 | struct gpio_chip *chip); | 138 | struct gpio_chip *chip); |
| 142 | int base; | 139 | int base; |
| 143 | u16 ngpio; | 140 | u16 ngpio; |
| 144 | struct gpio_desc *desc; | ||
| 145 | const char *const *names; | 141 | const char *const *names; |
| 146 | bool can_sleep; | 142 | bool can_sleep; |
| 147 | bool irq_not_threaded; | 143 | bool irq_not_threaded; |
| @@ -184,15 +180,6 @@ struct gpio_chip { · 36 unmodified lines | |||
| 184 | int (*of_xlate)(struct gpio_chip *gc, | 180 | int (*of_xlate)(struct gpio_chip *gc, |
| 185 | const struct of_phandle_args *gpiospec, u32 *flags); | 181 | const struct of_phandle_args *gpiospec, u32 *flags); |
| 186 | #endif | 182 | #endif |
| 187 | #ifdef CONFIG_PINCTRL | ||
| 188 | /* | ||
| 189 | * If CONFIG_PINCTRL is enabled, then gpio controllers can optionally | ||
| 190 | * describe the actual pin range which they serve in an SoC. This | ||
| 191 | * information would be used by pinctrl subsystem to configure | ||
| 192 | * corresponding pins for gpio usage. | ||
| 193 | */ | ||
| 194 | struct list_head pin_ranges; | ||
| 195 | #endif | ||
| 196 | }; | 183 | }; |
| 197 | 184 | ||
| 198 | extern const char *gpiochip_is_requested(struct gpio_chip *chip, | 185 | extern const char *gpiochip_is_requested(struct gpio_chip *chip, |
| @@ -205,18 +192,24 @@ static inline int gpiochip_add(struct gpio_chip *chip) · 6 unmodified lines | |||
| 205 | return gpiochip_add_data(chip, NULL); | 192 | return gpiochip_add_data(chip, NULL); |
| 206 | } | 193 | } |
| 207 | extern void gpiochip_remove(struct gpio_chip *chip); | 194 | extern void gpiochip_remove(struct gpio_chip *chip); |
| 195 | extern int devm_gpiochip_add_data(struct device *dev, struct gpio_chip *chip, | ||
| 196 | void *data); | ||
| 197 | extern void devm_gpiochip_remove(struct device *dev, struct gpio_chip *chip); | ||
| 198 | |||
| 208 | extern struct gpio_chip *gpiochip_find(void *data, | 199 | extern struct gpio_chip *gpiochip_find(void *data, |
| 209 | int (*match)(struct gpio_chip *chip, void *data)); | 200 | int (*match)(struct gpio_chip *chip, void *data)); |
| 210 | 201 | ||
| 211 | /* lock/unlock as IRQ */ | 202 | /* lock/unlock as IRQ */ |
| 212 | int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset); | 203 | int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset); |
| 213 | void gpiochip_unlock_as_irq(struct gpio_chip *chip, unsigned int offset); | 204 | void gpiochip_unlock_as_irq(struct gpio_chip *chip, unsigned int offset); |
| 205 | bool gpiochip_line_is_irq(struct gpio_chip *chip, unsigned int offset); | ||
| 206 | |||
| 207 | /* Line status inquiry for drivers */ | ||
| 208 | bool gpiochip_line_is_open_drain(struct gpio_chip *chip, unsigned int offset); | ||
| 209 | bool gpiochip_line_is_open_source(struct gpio_chip *chip, unsigned int offset); | ||
| 214 | 210 | ||
| 215 | /* get driver data */ | 211 | /* get driver data */ |
| 216 | static inline void *gpiochip_get_data(struct gpio_chip *chip) | 212 | void *gpiochip_get_data(struct gpio_chip *chip); |
| 217 | { | ||
| 218 | return chip->data; | ||
| 219 | } | ||
| 220 | 213 | ||
| 221 | struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc); | 214 | struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc); |
| 222 | 215 | ||
| @@ -1,28 +1,27 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * tps65912.h -- TI TPS6591x | 2 | * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ |
| 3 | * Andrew F. Davis <afd@ti.com> | ||
| 3 | * | 4 | * |
| 4 | * Copyright 2011 Texas Instruments Inc. | 5 | * This program is free software; you can redistribute it and/or |
| 6 | * modify it under the terms of the GNU General Public License version 2 as | ||
| 7 | * published by the Free Software Foundation. | ||
| 5 | * | 8 | * |
| 6 | * Author: Margarita Olaya <magi@slimlogic.co.uk> | 9 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any |
| 7 | * | 10 | * kind, whether expressed or implied; without even the implied warranty |
| 8 | * This program is free software; you can redistribute it and/or modify it | 11 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 9 | * under the terms of the GNU General Public License as published by the | 12 | * GNU General Public License version 2 for more details. |
| 10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 11 | * option) any later version. | ||
| 12 | * | 13 | * |
| 14 | * Based on the TPS65218 driver and the previous TPS65912 driver by | ||
| 15 | * Margarita Olaya Cabrera <magi@slimlogic.co.uk> | ||
| 13 | */ | 16 | */ |
| 14 | 17 | ||
| 15 | #ifndef __LINUX_MFD_TPS65912_H | 18 | #ifndef __LINUX_MFD_TPS65912_H |
| 16 | #define __LINUX_MFD_TPS65912_H | 19 | #define __LINUX_MFD_TPS65912_H |
| 17 | 20 | ||
| 18 | /* TPS regulator type list */ | 21 | #include <linux/device.h> |
| 19 | #define REGULATOR_LDO 0 | 22 | #include <linux/regmap.h> |
| 20 | #define REGULATOR_DCDC 1 | ||
| 21 | |||
| 22 | /* | ||
| 23 | * List of registers for TPS65912 | ||
| 24 | */ | ||
| 25 | 23 | ||
| 24 | /* List of registers for TPS65912 */ | ||
| 26 | #define TPS65912_DCDC1_CTRL 0x00 | 25 | #define TPS65912_DCDC1_CTRL 0x00 |
| 27 | #define TPS65912_DCDC2_CTRL 0x01 | 26 | #define TPS65912_DCDC2_CTRL 0x01 |
| 28 | #define TPS65912_DCDC3_CTRL 0x02 | 27 | #define TPS65912_DCDC3_CTRL 0x02 |
| @@ -126,41 +125,45 @@ · 97 unmodified lines | |||
| 126 | #define TPS65912_VERNUM 0x64 | 125 | #define TPS65912_VERNUM 0x64 |
| 127 | #define TPS6591X_MAX_REGISTER 0x64 | 126 | #define TPS6591X_MAX_REGISTER 0x64 |
| 128 | 127 | ||
| 129 | /* IRQ Definitions */ | 128 | /* INT_STS Register field definitions */ |
| 130 | #define TPS65912_IRQ_PWRHOLD_F 0 | 129 | #define TPS65912_INT_STS_PWRHOLD_F BIT(0) |
| 131 | #define TPS65912_IRQ_VMON 1 | 130 | #define TPS65912_INT_STS_VMON BIT(1) |
| 132 | #define TPS65912_IRQ_PWRON 2 | 131 | #define TPS65912_INT_STS_PWRON BIT(2) |
| 133 | #define TPS65912_IRQ_PWRON_LP 3 | 132 | #define TPS65912_INT_STS_PWRON_LP BIT(3) |
| 134 | #define TPS65912_IRQ_PWRHOLD_R 4 | 133 | #define TPS65912_INT_STS_PWRHOLD_R BIT(4) |
| 135 | #define TPS65912_IRQ_HOTDIE 5 | 134 | #define TPS65912_INT_STS_HOTDIE BIT(5) |
| 136 | #define TPS65912_IRQ_GPIO1_R 6 | 135 | #define TPS65912_INT_STS_GPIO1_R BIT(6) |
| 137 | #define TPS65912_IRQ_GPIO1_F 7 | 136 | #define TPS65912_INT_STS_GPIO1_F BIT(7) |
| 138 | #define TPS65912_IRQ_GPIO2_R 8 | 137 | |
| 139 | #define TPS65912_IRQ_GPIO2_F 9 | 138 | /* INT_STS Register field definitions */ |
| 140 | #define TPS65912_IRQ_GPIO3_R 10 | 139 | #define TPS65912_INT_STS2_GPIO2_R BIT(0) |
| 141 | #define TPS65912_IRQ_GPIO3_F 11 | 140 | #define TPS65912_INT_STS2_GPIO2_F BIT(1) |
| 142 | #define TPS65912_IRQ_GPIO4_R 12 | 141 | #define TPS65912_INT_STS2_GPIO3_R BIT(2) |
| 143 | #define TPS65912_IRQ_GPIO4_F 13 | 142 | #define TPS65912_INT_STS2_GPIO3_F BIT(3) |
| 144 | #define TPS65912_IRQ_GPIO5_R 14 | 143 | #define TPS65912_INT_STS2_GPIO4_R BIT(4) |
| 145 | #define TPS65912_IRQ_GPIO5_F 15 | 144 | #define TPS65912_INT_STS2_GPIO4_F BIT(5) |
| 146 | #define TPS65912_IRQ_PGOOD_DCDC1 16 | 145 | #define TPS65912_INT_STS2_GPIO5_R BIT(6) |
| 147 | #define TPS65912_IRQ_PGOOD_DCDC2 17 | 146 | #define TPS65912_INT_STS2_GPIO5_F BIT(7) |
| 148 | #define TPS65912_IRQ_PGOOD_DCDC3 18 | ||
| 149 | #define TPS65912_IRQ_PGOOD_DCDC4 19 | ||
| 150 | #define TPS65912_IRQ_PGOOD_LDO1 20 | ||
| 151 | #define TPS65912_IRQ_PGOOD_LDO2 21 | ||
| 152 | #define TPS65912_IRQ_PGOOD_LDO3 22 | ||
| 153 | #define TPS65912_IRQ_PGOOD_LDO4 23 | ||
| 154 | #define TPS65912_IRQ_PGOOD_LDO5 24 | ||
| 155 | #define TPS65912_IRQ_PGOOD_LDO6 25 | ||
| 156 | #define TPS65912_IRQ_PGOOD_LDO7 26 | ||
| 157 | #define TPS65912_IRQ_PGOOD_LD08 27 | ||
| 158 | #define TPS65912_IRQ_PGOOD_LDO9 28 | ||
| 159 | #define TPS65912_IRQ_PGOOD_LDO10 29 | ||
| 160 | 147 | ||
| 161 | #define TPS65912_NUM_IRQ 30 | 148 | /* INT_STS Register field definitions */ |
| 149 | #define TPS65912_INT_STS3_PGOOD_DCDC1 BIT(0) | ||
| 150 | #define TPS65912_INT_STS3_PGOOD_DCDC2 BIT(1) | ||
| 151 | #define TPS65912_INT_STS3_PGOOD_DCDC3 BIT(2) | ||
| 152 | #define TPS65912_INT_STS3_PGOOD_DCDC4 BIT(3) | ||
| 153 | #define TPS65912_INT_STS3_PGOOD_LDO1 BIT(4) | ||
| 154 | #define TPS65912_INT_STS3_PGOOD_LDO2 BIT(5) | ||
| 155 | #define TPS65912_INT_STS3_PGOOD_LDO3 BIT(6) | ||
| 156 | #define TPS65912_INT_STS3_PGOOD_LDO4 BIT(7) | ||
| 162 | 157 | ||
| 163 | /* GPIO 1 and 2 Register Definitions */ | 158 | /* INT_STS Register field definitions */ |
| 159 | #define TPS65912_INT_STS4_PGOOD_LDO5 BIT(0) | ||
| 160 | #define TPS65912_INT_STS4_PGOOD_LDO6 BIT(1) | ||
| 161 | #define TPS65912_INT_STS4_PGOOD_LDO7 BIT(2) | ||
| 162 | #define TPS65912_INT_STS4_PGOOD_LDO8 BIT(3) | ||
| 163 | #define TPS65912_INT_STS4_PGOOD_LDO9 BIT(4) | ||
| 164 | #define TPS65912_INT_STS4_PGOOD_LDO10 BIT(5) | ||
| 165 | |||
| 166 | /* GPIO 1 and 2 Register field definitions */ | ||
| 164 | #define GPIO_SLEEP_MASK 0x80 | 167 | #define GPIO_SLEEP_MASK 0x80 |
| 165 | #define GPIO_SLEEP_SHIFT 7 | 168 | #define GPIO_SLEEP_SHIFT 7 |
| 166 | #define GPIO_DEB_MASK 0x10 | 169 | #define GPIO_DEB_MASK 0x10 |
| @@ -172,7 +175,7 @@ · 5 unmodified lines | |||
| 172 | #define GPIO_SET_MASK 0x01 | 175 | #define GPIO_SET_MASK 0x01 |
| 173 | #define GPIO_SET_SHIFT 0 | 176 | #define GPIO_SET_SHIFT 0 |
| 174 | 177 | ||
| 175 | /* GPIO 3 Register Definitions */ | 178 | /* GPIO 3 Register field definitions */ |
| 176 | #define GPIO3_SLEEP_MASK 0x80 | 179 | #define GPIO3_SLEEP_MASK 0x80 |
| 177 | #define GPIO3_SLEEP_SHIFT 7 | 180 | #define GPIO3_SLEEP_SHIFT 7 |
| 178 | #define GPIO3_SEL_MASK 0x40 | 181 | #define GPIO3_SEL_MASK 0x40 |
| @@ -190,7 +193,7 @@ · 11 unmodified lines | |||
| 190 | #define GPIO3_SET_MASK 0x01 | 193 | #define GPIO3_SET_MASK 0x01 |
| 191 | #define GPIO3_SET_SHIFT 0 | 194 | #define GPIO3_SET_SHIFT 0 |
| 192 | 195 | ||
| 193 | /* GPIO 4 Register Definitions */ | 196 | /* GPIO 4 Register field definitions */ |
| 194 | #define GPIO4_SLEEP_MASK 0x80 | 197 | #define GPIO4_SLEEP_MASK 0x80 |
| 195 | #define GPIO4_SLEEP_SHIFT 7 | 198 | #define GPIO4_SLEEP_SHIFT 7 |
| 196 | #define GPIO4_SEL_MASK 0x40 | 199 | #define GPIO4_SEL_MASK 0x40 |
| @@ -264,65 +267,75 @@ · 67 unmodified lines | |||
| 264 | #define DCDC_LIMIT_MAX_SEL_MASK 0x3F | 267 | #define DCDC_LIMIT_MAX_SEL_MASK 0x3F |
| 265 | #define DCDC_LIMIT_MAX_SEL_SHIFT 0 | 268 | #define DCDC_LIMIT_MAX_SEL_SHIFT 0 |
| 266 | 269 | ||
| 267 | /** | 270 | /* Define the TPS65912 IRQ numbers */ |
| 268 | * struct tps65912_board | 271 | enum tps65912_irqs { |
| 269 | * Board platform dat may be used to initialize regulators. | 272 | /* INT_STS registers */ |
| 270 | */ | 273 | TPS65912_IRQ_PWRHOLD_F, |
| 271 | struct tps65912_board { | 274 | TPS65912_IRQ_VMON, |
| 272 | int is_dcdc1_avs; | 275 | TPS65912_IRQ_PWRON, |
| 273 | int is_dcdc2_avs; | 276 | TPS65912_IRQ_PWRON_LP, |
| 274 | int is_dcdc3_avs; | 277 | TPS65912_IRQ_PWRHOLD_R, |
| 275 | int is_dcdc4_avs; | 278 | TPS65912_IRQ_HOTDIE, |
| 276 | int irq; | 279 | TPS65912_IRQ_GPIO1_R, |
| 277 | int irq_base; | 280 | TPS65912_IRQ_GPIO1_F, |
| 278 | int gpio_base; | 281 | /* INT_STS2 registers */ |
| 279 | struct regulator_init_data *tps65912_pmic_init_data; | 282 | TPS65912_IRQ_GPIO2_R, |
| 283 | TPS65912_IRQ_GPIO2_F, | ||
| 284 | TPS65912_IRQ_GPIO3_R, | ||
| 285 | TPS65912_IRQ_GPIO3_F, | ||
| 286 | TPS65912_IRQ_GPIO4_R, | ||
| 287 | TPS65912_IRQ_GPIO4_F, | ||
| 288 | TPS65912_IRQ_GPIO5_R, | ||
| 289 | TPS65912_IRQ_GPIO5_F, | ||
| 290 | /* INT_STS3 registers */ | ||
| 291 | TPS65912_IRQ_PGOOD_DCDC1, | ||
| 292 | TPS65912_IRQ_PGOOD_DCDC2, | ||
| 293 | TPS65912_IRQ_PGOOD_DCDC3, | ||
| 294 | TPS65912_IRQ_PGOOD_DCDC4, | ||
| 295 | TPS65912_IRQ_PGOOD_LDO1, | ||
| 296 | TPS65912_IRQ_PGOOD_LDO2, | ||
| 297 | TPS65912_IRQ_PGOOD_LDO3, | ||
| 298 | TPS65912_IRQ_PGOOD_LDO4, | ||
| 299 | /* INT_STS4 registers */ | ||
| 300 | TPS65912_IRQ_PGOOD_LDO5, | ||
| 301 | TPS65912_IRQ_PGOOD_LDO6, | ||
| 302 | TPS65912_IRQ_PGOOD_LDO7, | ||
| 303 | TPS65912_IRQ_PGOOD_LDO8, | ||
| 304 | TPS65912_IRQ_PGOOD_LDO9, | ||
| 305 | TPS65912_IRQ_PGOOD_LDO10, | ||
| 280 | }; | 306 | }; |
| 281 | 307 | ||
| 282 | /** | 308 | /* |
| 283 | * struct tps65912 - tps65912 sub-driver chip access routines | 309 | * struct tps65912 - state holder for the tps65912 driver |
| 310 | * | ||
| 311 | * Device data may be used to access the TPS65912 chip | ||
| 284 | */ | 312 | */ |
| 285 | |||
| 286 | struct tps65912 { | 313 | struct tps65912 { |
| 287 | struct device *dev; | 314 | struct device *dev; |
| 288 | /* for read/write acces */ | 315 | struct regmap *regmap; |
| 289 | struct mutex io_mutex; | ||
| 290 | |||
| 291 | /* For device IO interfaces: I2C or SPI */ | ||
| 292 | void *control_data; | ||
| 293 | |||
| 294 | int (*read)(struct tps65912 *tps65912, u8 reg, int size, void *dest); | ||
| 295 | int (*write)(struct tps65912 *tps65912, u8 reg, int size, void *src); | ||
| 296 | |||
| 297 | /* Client devices */ | ||
| 298 | struct tps65912_pmic *pmic; | ||
| 299 | 316 | ||
| 300 | /* GPIO Handling */ | 317 | /* IRQ Data */ |
| 301 | struct gpio_chip gpio; | 318 | int irq; |
| 319 | struct regmap_irq_chip_data *irq_data; | ||
| 320 | }; | ||
| 302 | 321 | ||
| 303 | /* IRQ Handling */ | 322 | static const struct regmap_range tps65912_yes_ranges[] = { |
| 304 | struct mutex irq_lock; | 323 | regmap_reg_range(TPS65912_INT_STS, TPS65912_GPIO5), |
| 305 | int chip_irq; | ||
| 306 | int irq_base; | ||
| 307 | int irq_num; | ||
| 308 | u32 irq_mask; | ||
| 309 | }; | 324 | }; |
| 310 | 325 | ||
| 311 | struct tps65912_platform_data { | 326 | static const struct regmap_access_table tps65912_volatile_table = { |
| 312 | int irq; | 327 | .yes_ranges = tps65912_yes_ranges, |
| 313 | int irq_base; | 328 | .n_yes_ranges = ARRAY_SIZE(tps65912_yes_ranges), |
| 314 | }; | 329 | }; |
| 315 | 330 | ||
| 316 | unsigned int tps_chip(void); | 331 | static const struct regmap_config tps65912_regmap_config = { |
| 332 | .reg_bits = 8, | ||
| 333 | .val_bits = 8, | ||
| 334 | .cache_type = REGCACHE_RBTREE, | ||
| 335 | .volatile_table = &tps65912_volatile_table, | ||
| 336 | }; | ||
| 317 | 337 | ||
| 318 | int tps65912_set_bits(struct tps65912 *tps65912, u8 reg, u8 mask); | 338 | int tps65912_device_init(struct tps65912 *tps); |
| 319 | int tps65912_clear_bits(struct tps65912 *tps65912, u8 reg, u8 mask); | 339 | int tps65912_device_exit(struct tps65912 *tps); |
| 320 | int tps65912_reg_read(struct tps65912 *tps65912, u8 reg); | ||
| 321 | int tps65912_reg_write(struct tps65912 *tps65912, u8 reg, u8 val); | ||
| 322 | int tps65912_device_init(struct tps65912 *tps65912); | ||
| 323 | void tps65912_device_exit(struct tps65912 *tps65912); | ||
| 324 | int tps65912_irq_init(struct tps65912 *tps65912, int irq, | ||
| 325 | struct tps65912_platform_data *pdata); | ||
| 326 | int tps65912_irq_exit(struct tps65912 *tps65912); | ||
| 327 | 340 | ||
| 328 | #endif /* __LINUX_MFD_TPS65912_H */ | 341 | #endif /* __LINUX_MFD_TPS65912_H */ |
| @@ -138,6 +138,7 @@ header-y += genetlink.h · 137 unmodified lines | |||
| 138 | header-y += gen_stats.h | 138 | header-y += gen_stats.h |
| 139 | header-y += gfs2_ondisk.h | 139 | header-y += gfs2_ondisk.h |
| 140 | header-y += gigaset_dev.h | 140 | header-y += gigaset_dev.h |
| 141 | header-y += gpio.h | ||
| 141 | header-y += gsmmux.h | 142 | header-y += gsmmux.h |
| 142 | header-y += hdlcdrv.h | 143 | header-y += hdlcdrv.h |
| 143 | header-y += hdlc.h | 144 | header-y += hdlc.h |
| @@ -0,0 +1,58 @@ | |||
| 1 | /* | ||
| 2 | * <linux/gpio.h> - userspace ABI for the GPIO character devices | ||
| 3 | * | ||
| 4 | * Copyright (C) 2015 Linus Walleij | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms of the GNU General Public License version 2 as published by | ||
| 8 | * the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | #ifndef _UAPI_GPIO_H_ | ||
| 11 | #define _UAPI_GPIO_H_ | ||
| 12 | |||
| 13 | #include <linux/ioctl.h> | ||
| 14 | #include <linux/types.h> | ||
| 15 | |||
| 16 | /** | ||
| 17 | * struct gpiochip_info - Information about a certain GPIO chip | ||
| 18 | * @name: the Linux kernel name of this GPIO chip | ||
| 19 | * @label: a functional name for this GPIO chip, such as a product | ||
| 20 | * number, may be NULL | ||
| 21 | * @lines: number of GPIO lines on this chip | ||
| 22 | */ | ||
| 23 | struct gpiochip_info { | ||
| 24 | char name[32]; | ||
| 25 | char label[32]; | ||
| 26 | __u32 lines; | ||
| 27 | }; | ||
| 28 | |||
| 29 | /* Line is in use by the kernel */ | ||
| 30 | #define GPIOLINE_FLAG_KERNEL (1UL << 0) | ||
| 31 | #define GPIOLINE_FLAG_IS_OUT (1UL << 1) | ||
| 32 | #define GPIOLINE_FLAG_ACTIVE_LOW (1UL << 2) | ||
| 33 | #define GPIOLINE_FLAG_OPEN_DRAIN (1UL << 3) | ||
| 34 | #define GPIOLINE_FLAG_OPEN_SOURCE (1UL << 4) | ||
| 35 | |||
| 36 | /** | ||
| 37 | * struct gpioline_info - Information about a certain GPIO line | ||
| 38 | * @line_offset: the local offset on this GPIO device, fill this in when | ||
| 39 | * requesting the line information from the kernel | ||
| 40 | * @flags: various flags for this line | ||
| 41 | * @name: the name of this GPIO line, such as the output pin of the line on the | ||
| 42 | * chip, a rail or a pin header name on a board, as specified by the gpio | ||
| 43 | * chip, may be NULL | ||
| 44 | * @consumer: a functional name for the consumer of this GPIO line as set by | ||
| 45 | * whatever is using it, will be NULL if there is no current user but may | ||
| 46 | * also be NULL if the consumer doesn't set this up | ||
| 47 | */ | ||
| 48 | struct gpioline_info { | ||
| 49 | __u32 line_offset; | ||
| 50 | __u32 flags; | ||
| 51 | char name[32]; | ||
| 52 | char consumer[32]; | ||
| 53 | }; | ||
| 54 | |||
| 55 | #define GPIO_GET_CHIPINFO_IOCTL _IOR(0xB4, 0x01, struct gpiochip_info) | ||
| 56 | #define GPIO_GET_LINEINFO_IOCTL _IOWR(0xB4, 0x02, struct gpioline_info) | ||
| 57 | |||
| 58 | #endif /* _UAPI_GPIO_H_ */ | ||
| @@ -13,6 +13,7 @@ help: · 12 unmodified lines | |||
| 13 | @echo ' cpupower - a tool for all things x86 CPU power' | 13 | @echo ' cpupower - a tool for all things x86 CPU power' |
| 14 | @echo ' firewire - the userspace part of nosy, an IEEE-1394 traffic sniffer' | 14 | @echo ' firewire - the userspace part of nosy, an IEEE-1394 traffic sniffer' |
| 15 | @echo ' freefall - laptop accelerometer program for disk protection' | 15 | @echo ' freefall - laptop accelerometer program for disk protection' |
| 16 | @echo ' gpio - GPIO tools' | ||
| 16 | @echo ' hv - tools used when in Hyper-V clients' | 17 | @echo ' hv - tools used when in Hyper-V clients' |
| 17 | @echo ' iio - IIO tools' | 18 | @echo ' iio - IIO tools' |
| 18 | @echo ' lguest - a minimal 32-bit x86 hypervisor' | 19 | @echo ' lguest - a minimal 32-bit x86 hypervisor' |
| @@ -53,7 +54,7 @@ acpi: FORCE · 34 unmodified lines | |||
| 53 | cpupower: FORCE | 54 | cpupower: FORCE |
| 54 | $(call descend,power/$@) | 55 | $(call descend,power/$@) |
| 55 | 56 | ||
| 56 | cgroup firewire hv guest spi usb virtio vm net iio: FORCE | 57 | cgroup firewire hv guest spi usb virtio vm net iio gpio: FORCE |
| 57 | $(call descend,$@) | 58 | $(call descend,$@) |
| 58 | 59 | ||
| 59 | liblockdep: FORCE | 60 | liblockdep: FORCE |
| @@ -119,7 +120,7 @@ acpi_clean: · 59 unmodified lines | |||
| 119 | cpupower_clean: | 120 | cpupower_clean: |
| 120 | $(call descend,power/cpupower,clean) | 121 | $(call descend,power/cpupower,clean) |
| 121 | 122 | ||
| 122 | cgroup_clean hv_clean firewire_clean lguest_clean spi_clean usb_clean virtio_clean vm_clean net_clean iio_clean: | 123 | cgroup_clean hv_clean firewire_clean lguest_clean spi_clean usb_clean virtio_clean vm_clean net_clean iio_clean gpio_clean: |
| 123 | $(call descend,$(@:_clean=),clean) | 124 | $(call descend,$(@:_clean=),clean) |
| 124 | 125 | ||
| 125 | liblockdep_clean: | 126 | liblockdep_clean: |
| @@ -155,6 +156,7 @@ build_clean: · 29 unmodified lines | |||
| 155 | clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean lguest_clean \ | 156 | clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean lguest_clean \ |
| 156 | perf_clean selftests_clean turbostat_clean spi_clean usb_clean virtio_clean \ | 157 | perf_clean selftests_clean turbostat_clean spi_clean usb_clean virtio_clean \ |
| 157 | vm_clean net_clean iio_clean x86_energy_perf_policy_clean tmon_clean \ | 158 | vm_clean net_clean iio_clean x86_energy_perf_policy_clean tmon_clean \ |
| 158 | freefall_clean build_clean libbpf_clean libsubcmd_clean liblockdep_clean | 159 | freefall_clean build_clean libbpf_clean libsubcmd_clean liblockdep_clean \ |
| 160 | gpio_clean | ||
| 159 | 161 | ||
| 160 | .PHONY: FORCE | 162 | .PHONY: FORCE |
| @@ -0,0 +1,12 @@ | |||
| 1 | CC = $(CROSS_COMPILE)gcc | ||
| 2 | CFLAGS += -Wall -g -D_GNU_SOURCE | ||
| 3 | |||
| 4 | all: lsgpio | ||
| 5 | |||
| 6 | lsgpio: lsgpio.o gpio-utils.o | ||
| 7 | |||
| 8 | %.o: %.c gpio-utils.h | ||
| 9 | |||
| 10 | .PHONY: clean | ||
| 11 | clean: | ||
| 12 | rm -f *.o lsgpio | ||
| @@ -0,0 +1,11 @@ | |||
| 1 | /* | ||
| 2 | * GPIO tools - helpers library for the GPIO tools | ||
| 3 | * | ||
| 4 | * Copyright (C) 2015 Linus Walleij | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms of the GNU General Public License version 2 as published by | ||
| 8 | * the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include "gpio-utils.h" | ||
| @@ -0,0 +1,27 @@ | |||
| 1 | /* | ||
| 2 | * GPIO tools - utility helpers library for the GPIO tools | ||
| 3 | * | ||
| 4 | * Copyright (C) 2015 Linus Walleij | ||
| 5 | * | ||
| 6 | * Portions copied from iio_utils and lssio: | ||
| 7 | * Copyright (c) 2010 Manuel Stahl <manuel.stahl@iis.fraunhofer.de> | ||
| 8 | * Copyright (c) 2008 Jonathan Cameron | ||
| 9 | * * | ||
| 10 | * This program is free software; you can redistribute it and/or modify it | ||
| 11 | * under the terms of the GNU General Public License version 2 as published by | ||
| 12 | * the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | #ifndef _GPIO_UTILS_H_ | ||
| 15 | #define _GPIO_UTILS_H_ | ||
| 16 | |||
| 17 | #include <string.h> | ||
| 18 | |||
| 19 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) | ||
| 20 | |||
| 21 | static inline int check_prefix(const char *str, const char *prefix) | ||
| 22 | { | ||
| 23 | return strlen(str) > strlen(prefix) && | ||
| 24 | strncmp(str, prefix, strlen(prefix)) == 0; | ||
| 25 | } | ||
| 26 | |||
| 27 | #endif /* _GPIO_UTILS_H_ */ | ||
| @@ -0,0 +1,195 @@ | |||
| 1 | /* | ||
| 2 | * lsgpio - example on how to list the GPIO lines on a system | ||
| 3 | * | ||
| 4 | * Copyright (C) 2015 Linus Walleij | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms of the GNU General Public License version 2 as published by | ||
| 8 | * the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * Usage: | ||
| 11 | * lsgpio <-n device-name> | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <unistd.h> | ||
| 15 | #include <stdlib.h> | ||
| 16 | #include <stdbool.h> | ||
| 17 | #include <stdio.h> | ||
| 18 | #include <dirent.h> | ||
| 19 | #include <errno.h> | ||
| 20 | #include <string.h> | ||
| 21 | #include <poll.h> | ||
| 22 | #include <fcntl.h> | ||
| 23 | #include <getopt.h> | ||
| 24 | #include <sys/ioctl.h> | ||
| 25 | #include <linux/gpio.h> | ||
| 26 | |||
| 27 | #include "gpio-utils.h" | ||
| 28 | |||
| 29 | struct gpio_flag { | ||
| 30 | char *name; | ||
| 31 | unsigned long mask; | ||
| 32 | }; | ||
| 33 | |||
| 34 | struct gpio_flag flagnames[] = { | ||
| 35 | { | ||
| 36 | .name = "kernel", | ||
| 37 | .mask = GPIOLINE_FLAG_KERNEL, | ||
| 38 | }, | ||
| 39 | { | ||
| 40 | .name = "output", | ||
| 41 | .mask = GPIOLINE_FLAG_IS_OUT, | ||
| 42 | }, | ||
| 43 | { | ||
| 44 | .name = "active-low", | ||
| 45 | .mask = GPIOLINE_FLAG_ACTIVE_LOW, | ||
| 46 | }, | ||
| 47 | { | ||
| 48 | .name = "open-drain", | ||
| 49 | .mask = GPIOLINE_FLAG_OPEN_DRAIN, | ||
| 50 | }, | ||
| 51 | { | ||
| 52 | .name = "open-source", | ||
| 53 | .mask = GPIOLINE_FLAG_OPEN_SOURCE, | ||
| 54 | }, | ||
| 55 | }; | ||
| 56 | |||
| 57 | void print_flags(unsigned long flags) | ||
| 58 | { | ||
| 59 | int i; | ||
| 60 | int printed = 0; | ||
| 61 | |||
| 62 | for (i = 0; i < ARRAY_SIZE(flagnames); i++) { | ||
| 63 | if (flags & flagnames[i].mask) { | ||
| 64 | if (printed) | ||
| 65 | fprintf(stdout, " "); | ||
| 66 | fprintf(stdout, "%s", flagnames[i].name); | ||
| 67 | printed++; | ||
| 68 | } | ||
| 69 | } | ||
| 70 | } | ||
| 71 | |||
| 72 | int list_device(const char *device_name) | ||
| 73 | { | ||
| 74 | struct gpiochip_info cinfo; | ||
| 75 | char *chrdev_name; | ||
| 76 | int fd; | ||
| 77 | int ret; | ||
| 78 | int i; | ||
| 79 | |||
| 80 | ret = asprintf(&chrdev_name, "/dev/%s", device_name); | ||
| 81 | if (ret < 0) | ||
| 82 | return -ENOMEM; | ||
| 83 | |||
| 84 | fd = open(chrdev_name, 0); | ||
| 85 | if (fd == -1) { | ||
| 86 | ret = -errno; | ||
| 87 | fprintf(stderr, "Failed to open %s\n", chrdev_name); | ||
| 88 | goto exit_close_error; | ||
| 89 | } | ||
| 90 | |||
| 91 | /* Inspect this GPIO chip */ | ||
| 92 | ret = ioctl(fd, GPIO_GET_CHIPINFO_IOCTL, &cinfo); | ||
| 93 | if (ret == -1) { | ||
| 94 | ret = -errno; | ||
| 95 | perror("Failed to issue CHIPINFO IOCTL\n"); | ||
| 96 | goto exit_close_error; | ||
| 97 | } | ||
| 98 | fprintf(stdout, "GPIO chip: %s, \"%s\", %u GPIO lines\n", | ||
| 99 | cinfo.name, cinfo.label, cinfo.lines); | ||
| 100 | |||
| 101 | /* Loop over the lines and print info */ | ||
| 102 | for (i = 0; i < cinfo.lines; i++) { | ||
| 103 | struct gpioline_info linfo; | ||
| 104 | |||
| 105 | memset(&linfo, 0, sizeof(linfo)); | ||
| 106 | linfo.line_offset = i; | ||
| 107 | |||
| 108 | ret = ioctl(fd, GPIO_GET_LINEINFO_IOCTL, &linfo); | ||
| 109 | if (ret == -1) { | ||
| 110 | ret = -errno; | ||
| 111 | perror("Failed to issue LINEINFO IOCTL\n"); | ||
| 112 | goto exit_close_error; | ||
| 113 | } | ||
| 114 | fprintf(stdout, "\tline %2d:", linfo.line_offset); | ||
| 115 | if (linfo.name[0]) | ||
| 116 | fprintf(stdout, " \"%s\"", linfo.name); | ||
| 117 | else | ||
| 118 | fprintf(stdout, " unnamed"); | ||
| 119 | if (linfo.consumer[0]) | ||
| 120 | fprintf(stdout, " \"%s\"", linfo.consumer); | ||
| 121 | else | ||
| 122 | fprintf(stdout, " unused"); | ||
| 123 | if (linfo.flags) { | ||
| 124 | fprintf(stdout, " ["); | ||
| 125 | print_flags(linfo.flags); | ||
| 126 | fprintf(stdout, "]"); | ||
| 127 | } | ||
| 128 | fprintf(stdout, "\n"); | ||
| 129 | |||
| 130 | } | ||
| 131 | |||
| 132 | exit_close_error: | ||
| 133 | if (close(fd) == -1) | ||
| 134 | perror("Failed to close GPIO character device file"); | ||
| 135 | free(chrdev_name); | ||
| 136 | return ret; | ||
| 137 | } | ||
| 138 | |||
| 139 | void print_usage(void) | ||
| 140 | { | ||
| 141 | fprintf(stderr, "Usage: lsgpio [options]...\n" | ||
| 142 | "List GPIO chips, lines and states\n" | ||
| 143 | " -n <name> List GPIOs on a named device\n" | ||
| 144 | " -? This helptext\n" | ||
| 145 | ); | ||
| 146 | } | ||
| 147 | |||
| 148 | int main(int argc, char **argv) | ||
| 149 | { | ||
| 150 | const char *device_name; | ||
| 151 | int ret; | ||
| 152 | int c; | ||
| 153 | |||
| 154 | while ((c = getopt(argc, argv, "n:")) != -1) { | ||
| 155 | switch (c) { | ||
| 156 | case 'n': | ||
| 157 | device_name = optarg; | ||
| 158 | break; | ||
| 159 | case '?': | ||
| 160 | print_usage(); | ||
| 161 | return -1; | ||
| 162 | } | ||
| 163 | } | ||
| 164 | |||
| 165 | if (device_name) | ||
| 166 | ret = list_device(device_name); | ||
| 167 | else { | ||
| 168 | const struct dirent *ent; | ||
| 169 | DIR *dp; | ||
| 170 | |||
| 171 | /* List all GPIO devices one at a time */ | ||
| 172 | dp = opendir("/dev"); | ||
| 173 | if (!dp) { | ||
| 174 | ret = -errno; | ||
| 175 | goto error_out; | ||
| 176 | } | ||
| 177 | |||
| 178 | ret = -ENOENT; | ||
| 179 | while (ent = readdir(dp), ent) { | ||
| 180 | if (check_prefix(ent->d_name, "gpiochip")) { | ||
| 181 | ret = list_device(ent->d_name); | ||
| 182 | if (ret) | ||
| 183 | break; | ||
| 184 | } | ||
| 185 | } | ||
| 186 | |||
| 187 | ret = 0; | ||
| 188 | if (closedir(dp) == -1) { | ||
| 189 | perror("scanning devices: Failed to close directory"); | ||
| 190 | ret = -errno; | ||
| 191 | } | ||
| 192 | } | ||
| 193 | error_out: | ||
| 194 | return ret; | ||
| 195 | } | ||