gpio: updates for v5.14

- new driver for the IDT 79RC3243x GPIO controller
 - device tree bindings coversion to YAML for the following drivers:
   gpio-rk3328-grf, gpio-omap, gpio-davinci, gpio-zynq, gpio-stp, gpio-pcf857x
 - cleanup of probe functions in many drivers from Alexandru Ardelean, mostly
   dropping unnecessary calls to platform_set_drvdata() and removing error
   messages where none are needed (handled by the subsystem already)
 - several improvements to the core gpiolib and the sysfs interface code from
   Andy Shevchenko
 - conversion of the gpio-xilinx driver to using the bitmap API + improvements
   of suspend/resume handling + minor tweaks
 - convert the gpio-stmpe to using devres helpers exclusively in probe for
   improved robustness
 - updates for the generic gpio-regmap driver
 - updates for the gpio-dwapb driver
 - support for a new model in gpio-pca953x
 - cleanups in gpio-tegra186, gpio-104-idio-16, gpio-mxs & gpio-xgene
 - slight code refactoring of the gpio-zynq driver
 - documentation fixes from Mauro Carvalho Chehab
 - a bunch of minor tweaks and improvements all over the place
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEFp3rbAvDxGAT0sefEacuoBRx13IFAmDiz88ACgkQEacuoBRx
 13JIaxAAhM0kWMBCs14BT79ZteLQj+QvtA/EvNvC3yfAkrlzCc75yHP4ocV21O9E
 BIdbBqvA5RdOcL8akdL8V895wjM3CdUlFpjfkdVGeN7wZzagVEpb9z8j7Ba1YwSu
 dUzrvuPsiDigxDCMGDwHybrNxis54J61HV9mAw0LxXPERHQwbCUMdx4pbdBLUKcu
 qVX+mK2hzzgORkt9ntlnYQSKsnSiWan8g4q8zntdQOjJAVN473WySXmhfONlXkAV
 OH88/moDBk7Y3QdtUNAB7h/fu23F7Y++NoiStN2uilgrJ38/3PWi0eASK4XWx1jr
 LOx5PIRTRQNU+AHQ+EVP23XFH/1EKjPXGyZwcpprS5BkpJaBnUVCMnhoHdLX4LqV
 axxbszaMATxpTNt7lcLrklvzVb0D/zvvNtwuMyjWvPZ/GMLDyPfaVMFUqSGcFwQ+
 ufdHAeIPAwU/AA9tF3OjiijsGWV+nnOWunfh2TdioHRzFM6LTM5lkcruoFmqjQxp
 2IMTNGbhsr8xv6y64x3Cq/03k7hV5lwgn/J4CJL7LGa9VHI+VgGEKMluoINRxfc/
 qIN9MT1iVu81ttCwTokSL08Le6ijqpP3LC8hMTRSCJpxZBna5KWbMm8gppYrXE1r
 EAGnEpnihM36Px9hPj4zJQYU/Ly8SIpYB4BHWs4F8eMOxgFKuWo=
 =IF0T
 -----END PGP SIGNATURE-----

Merge tag 'gpio-updates-for-v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux

Pull gpio updates from Bartosz Golaszewski:
 "One new driver, support for new models in existing ones, dt-bindings
  conversions for several modules and improvements all over the place.

  Summary:

   - new driver for the IDT 79RC3243x GPIO controller

   - device tree bindings coversion to YAML for the following drivers:
     gpio-rk3328-grf, gpio-omap, gpio-davinci, gpio-zynq, gpio-stp,
     gpio-pcf857x

   - cleanup of probe functions in many drivers from Alexandru Ardelean,
     mostly dropping unnecessary calls to platform_set_drvdata() and
     removing error messages where none are needed (handled by the
     subsystem already)

   - several improvements to the core gpiolib and the sysfs interface
     code from Andy Shevchenko

   - conversion of the gpio-xilinx driver to using the bitmap API +
     improvements of suspend/resume handling + minor tweaks

   - convert the gpio-stmpe to using devres helpers exclusively in probe
     for improved robustness

   - updates for the generic gpio-regmap driver

   - updates for the gpio-dwapb driver

   - support for a new model in gpio-pca953x

   - cleanups in gpio-tegra186, gpio-104-idio-16, gpio-mxs & gpio-xgene

   - slight code refactoring of the gpio-zynq driver

   - documentation fixes from Mauro Carvalho Chehab

   - a bunch of minor tweaks and improvements all over the place"

* tag 'gpio-updates-for-v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux: (57 commits)
  docs: driver-api: gpio: using-gpio.rst: avoid using ReST :doc:`foo` markup
  dt-bindings: gpio: pcf857x: Convert to json-schema
  gpio: mxs: Prefer unsigned int to bare use of unsigned
  dt-bindings: gpio: stp: convert to json-schema
  dt-bindings: gpio: zynq: convert bindings to YAML
  dt-bindings: gpio: gpio-davinci: Convert to json-schema
  gpio: pca953x: Add support for the On Semi pca9655
  gpio: gpio-xilinx: update on suspend and resume calls
  gpio: zynq: Check return value of irq_get_irq_data
  gpio: zynq: Check return value of pm_runtime_get_sync
  gpio: zynq: use module_platform_driver to simplify the code
  gpio: idt3243x: Fix return value check in idt_gpio_probe()
  MAINTAINERS: update ti,omap-gpio.yaml reference
  dt-bindings: gpio: Add devicetree binding for IDT 79RC32434 GPIO controller
  gpio: Add support for IDT 79RC3243x GPIO controller
  gpio: regmap: move drvdata to config data
  gpio-dwapb: Drop unused headers and sort the rest
  gpio: gpio-regmap: Use devm_add_action_or_reset()
  gpio: dwapb: Switch to use fwnode_irq_get()
  gpio: dwapb: Drop redundant check in dwapb_irq_set_type()
  ...
This commit is contained in:
Linus Torvalds 2021-07-05 11:48:14 -07:00
commit b805259942
52 changed files with 1242 additions and 944 deletions

View File

@ -1,167 +0,0 @@
Davinci/Keystone GPIO controller bindings
Required Properties:
- compatible: should be "ti,dm6441-gpio": for Davinci da850 SoCs
"ti,keystone-gpio": for Keystone 2 66AK2H/K, 66AK2L,
66AK2E SoCs
"ti,k2g-gpio", "ti,keystone-gpio": for 66AK2G
"ti,am654-gpio", "ti,keystone-gpio": for TI K3 AM654
"ti,j721e-gpio", "ti,keystone-gpio": for J721E SoCs
"ti,am64-gpio", "ti,keystone-gpio": for AM64 SoCs
- reg: Physical base address of the controller and the size of memory mapped
registers.
- gpio-controller : Marks the device node as a gpio controller.
- #gpio-cells : Should be two.
- first cell is the pin number
- second cell is used to specify optional parameters (unused)
- interrupts: Array of GPIO interrupt number. Only banked or unbanked IRQs are
supported at a time.
- ti,ngpio: The number of GPIO pins supported.
- ti,davinci-gpio-unbanked: The number of GPIOs that have an individual interrupt
line to processor.
- clocks: Should contain the device's input clock, and should be defined as per
the appropriate clock bindings consumer usage in,
Documentation/devicetree/bindings/clock/keystone-gate.txt
for 66AK2HK/66AK2L/66AK2E SoCs or,
Documentation/devicetree/bindings/clock/ti,sci-clk.yaml
for 66AK2G SoCs
- clock-names: Name should be "gpio";
Currently clock-names and clocks are needed for all keystone 2 platforms
Davinci platforms do not have DT clocks as of now.
The GPIO controller also acts as an interrupt controller. It uses the default
two cells specifier as described in Documentation/devicetree/bindings/
interrupt-controller/interrupts.txt.
Example:
gpio: gpio@1e26000 {
compatible = "ti,dm6441-gpio";
gpio-controller;
#gpio-cells = <2>;
reg = <0x226000 0x1000>;
interrupt-parent = <&intc>;
interrupts = <42 IRQ_TYPE_EDGE_BOTH 43 IRQ_TYPE_EDGE_BOTH
44 IRQ_TYPE_EDGE_BOTH 45 IRQ_TYPE_EDGE_BOTH
46 IRQ_TYPE_EDGE_BOTH 47 IRQ_TYPE_EDGE_BOTH
48 IRQ_TYPE_EDGE_BOTH 49 IRQ_TYPE_EDGE_BOTH
50 IRQ_TYPE_EDGE_BOTH>;
ti,ngpio = <144>;
ti,davinci-gpio-unbanked = <0>;
interrupt-controller;
#interrupt-cells = <2>;
};
leds {
compatible = "gpio-leds";
led1 {
label = "davinci:green:usr1";
gpios = <&gpio 10 GPIO_ACTIVE_HIGH>;
...
};
led2 {
label = "davinci:red:debug1";
gpios = <&gpio 11 GPIO_ACTIVE_HIGH>;
...
};
};
Example for 66AK2G:
gpio0: gpio@2603000 {
compatible = "ti,k2g-gpio", "ti,keystone-gpio";
reg = <0x02603000 0x100>;
gpio-controller;
#gpio-cells = <2>;
interrupts = <GIC_SPI 432 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 433 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 434 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 435 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 436 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 437 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 438 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 439 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 440 IRQ_TYPE_EDGE_RISING>;
interrupt-controller;
#interrupt-cells = <2>;
ti,ngpio = <144>;
ti,davinci-gpio-unbanked = <0>;
clocks = <&k2g_clks 0x001b 0x0>;
clock-names = "gpio";
};
Example for 66AK2HK/66AK2L/66AK2E:
gpio0: gpio@260bf00 {
compatible = "ti,keystone-gpio";
reg = <0x0260bf00 0x100>;
gpio-controller;
#gpio-cells = <2>;
/* HW Interrupts mapped to GPIO pins */
interrupts = <GIC_SPI 120 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 121 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 122 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 123 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 124 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 125 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 126 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 127 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 128 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 129 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 130 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 131 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 132 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 133 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 134 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 135 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 136 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 137 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 138 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 139 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 140 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 141 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 142 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 143 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 144 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 145 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 146 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 147 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 148 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 149 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 150 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 151 IRQ_TYPE_EDGE_RISING>;
clocks = <&clkgpio>;
clock-names = "gpio";
ti,ngpio = <32>;
ti,davinci-gpio-unbanked = <32>;
};
Example for K3 AM654:
wkup_gpio0: wkup_gpio0@42110000 {
compatible = "ti,am654-gpio", "ti,keystone-gpio";
reg = <0x42110000 0x100>;
gpio-controller;
#gpio-cells = <2>;
interrupt-parent = <&intr_wkup_gpio>;
interrupts = <59 128>, <59 129>, <59 130>, <59 131>;
interrupt-controller;
#interrupt-cells = <2>;
ti,ngpio = <56>;
ti,davinci-gpio-unbanked = <0>;
clocks = <&k3_clks 59 0>;
clock-names = "gpio";
};

View File

@ -0,0 +1,185 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/gpio/gpio-davinci.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: GPIO controller for Davinci and keystone devices
maintainers:
- Keerthy <j-keerthy@ti.com>
properties:
compatible:
oneOf:
- items:
- enum:
- ti,k2g-gpio
- ti,am654-gpio
- ti,j721e-gpio
- ti,am64-gpio
- const: ti,keystone-gpio
- items:
- enum:
- ti,dm6441-gpio
- ti,keystone-gpio
reg:
maxItems: 1
gpio-controller: true
gpio-ranges: true
gpio-line-names:
description: strings describing the names of each gpio line.
minItems: 1
maxItems: 100
"#gpio-cells":
const: 2
description:
first cell is the pin number and second cell is used to specify optional parameters (unused).
interrupts:
description:
The interrupts are specified as per the interrupt parent. Only banked
or unbanked IRQs are supported at a time. If the interrupts are
banked then provide list of interrupts corresponding to each bank, else
provide the list of interrupts for each gpio.
minItems: 1
maxItems: 100
ti,ngpio:
$ref: /schemas/types.yaml#/definitions/uint32
description: The number of GPIO pins supported consecutively.
minimum: 1
ti,davinci-gpio-unbanked:
$ref: /schemas/types.yaml#/definitions/uint32
description: The number of GPIOs that have an individual interrupt line to processor.
minimum: 0
clocks:
maxItems: 1
clock-names:
const: gpio
interrupt-controller: true
power-domains:
maxItems: 1
"#interrupt-cells":
const: 2
patternProperties:
"^(.+-hog(-[0-9]+)?)$":
type: object
required:
- gpio-hog
required:
- compatible
- reg
- gpio-controller
- "#gpio-cells"
- interrupts
- ti,ngpio
- ti,davinci-gpio-unbanked
- clocks
- clock-names
additionalProperties: false
examples:
- |
#include<dt-bindings/interrupt-controller/arm-gic.h>
gpio0: gpio@2603000 {
compatible = "ti,k2g-gpio", "ti,keystone-gpio";
reg = <0x02603000 0x100>;
gpio-controller;
#gpio-cells = <2>;
interrupts = <GIC_SPI 432 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 433 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 434 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 435 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 436 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 437 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 438 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 439 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 440 IRQ_TYPE_EDGE_RISING>;
interrupt-controller;
#interrupt-cells = <2>;
ti,ngpio = <144>;
ti,davinci-gpio-unbanked = <0>;
clocks = <&k2g_clks 0x001b 0x0>;
clock-names = "gpio";
};
- |
#include<dt-bindings/interrupt-controller/arm-gic.h>
gpio1: gpio@260bf00 {
compatible = "ti,keystone-gpio";
reg = <0x0260bf00 0x100>;
gpio-controller;
#gpio-cells = <2>;
/* HW Interrupts mapped to GPIO pins */
interrupts = <GIC_SPI 120 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 121 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 122 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 123 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 124 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 125 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 126 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 127 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 128 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 129 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 130 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 131 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 132 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 133 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 134 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 135 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 136 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 137 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 138 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 139 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 140 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 141 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 142 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 143 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 144 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 145 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 146 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 147 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 148 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 149 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 150 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 151 IRQ_TYPE_EDGE_RISING>;
clocks = <&clkgpio>;
clock-names = "gpio";
ti,ngpio = <32>;
ti,davinci-gpio-unbanked = <32>;
};
- |
wkup_gpio0: gpio0@42110000 {
compatible = "ti,am654-gpio", "ti,keystone-gpio";
reg = <0x42110000 0x100>;
gpio-controller;
#gpio-cells = <2>;
interrupt-parent = <&intr_wkup_gpio>;
interrupts = <60>, <61>, <62>, <63>;
interrupt-controller;
#interrupt-cells = <2>;
ti,ngpio = <56>;
ti,davinci-gpio-unbanked = <0>;
clocks = <&k3_clks 59 0>;
clock-names = "gpio";
};

View File

@ -1,45 +0,0 @@
OMAP GPIO controller bindings
Required properties:
- compatible:
- "ti,omap2-gpio" for OMAP2 controllers
- "ti,omap3-gpio" for OMAP3 controllers
- "ti,omap4-gpio" for OMAP4 controllers
- reg : Physical base address of the controller and length of memory mapped
region.
- gpio-controller : Marks the device node as a GPIO controller.
- #gpio-cells : Should be two.
- first cell is the pin number
- second cell is used to specify optional parameters (unused)
- interrupt-controller: Mark the device node as an interrupt controller.
- #interrupt-cells : Should be 2.
The first cell is the GPIO number.
The second cell is used to specify flags:
bits[3:0] trigger type and level flags:
1 = low-to-high edge triggered.
2 = high-to-low edge triggered.
4 = active high level-sensitive.
8 = active low level-sensitive.
- interrupts : The interrupt the controller is rising as output when an
interrupt occures
OMAP specific properties:
- ti,hwmods: Name of the hwmod associated to the GPIO:
"gpio<X>", <X> being the 1-based instance number
from the HW spec.
- ti,gpio-always-on: Indicates if a GPIO bank is always powered and
so will never lose its logic state.
Example:
gpio0: gpio@44e07000 {
compatible = "ti,omap4-gpio";
reg = <0x44e07000 0x1000>;
ti,hwmods = "gpio1";
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <96>;
};

View File

@ -1,69 +0,0 @@
* PCF857x-compatible I/O expanders
The PCF857x-compatible chips have "quasi-bidirectional" I/O lines that can be
driven high by a pull-up current source or driven low to ground. This combines
the direction and output level into a single bit per line, which can't be read
back. We can't actually know at initialization time whether a line is configured
(a) as output and driving the signal low/high, or (b) as input and reporting a
low/high value, without knowing the last value written since the chip came out
of reset (if any). The only reliable solution for setting up line direction is
thus to do it explicitly.
Required Properties:
- compatible: should be one of the following.
- "maxim,max7328": For the Maxim MAX7378
- "maxim,max7329": For the Maxim MAX7329
- "nxp,pca8574": For the NXP PCA8574
- "nxp,pca8575": For the NXP PCA8575
- "nxp,pca9670": For the NXP PCA9670
- "nxp,pca9671": For the NXP PCA9671
- "nxp,pca9672": For the NXP PCA9672
- "nxp,pca9673": For the NXP PCA9673
- "nxp,pca9674": For the NXP PCA9674
- "nxp,pca9675": For the NXP PCA9675
- "nxp,pcf8574": For the NXP PCF8574
- "nxp,pcf8574a": For the NXP PCF8574A
- "nxp,pcf8575": For the NXP PCF8575
- reg: I2C slave address.
- gpio-controller: Marks the device node as a gpio controller.
- #gpio-cells: Should be 2. The first cell is the GPIO number and the second
cell specifies GPIO flags, as defined in <dt-bindings/gpio/gpio.h>. Only the
GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags are supported.
Optional Properties:
- lines-initial-states: Bitmask that specifies the initial state of each
line. When a bit is set to zero, the corresponding line will be initialized to
the input (pulled-up) state. When the bit is set to one, the line will be
initialized the low-level output state. If the property is not specified
all lines will be initialized to the input state.
The I/O expander can detect input state changes, and thus optionally act as
an interrupt controller. When the expander interrupt line is connected all the
following properties must be set. For more information please see the
interrupt controller device tree bindings documentation available at
Documentation/devicetree/bindings/interrupt-controller/interrupts.txt.
- interrupt-controller: Identifies the node as an interrupt controller.
- #interrupt-cells: Number of cells to encode an interrupt source, shall be 2.
- interrupts: Interrupt specifier for the controllers interrupt.
Please refer to gpio.txt in this directory for details of the common GPIO
bindings used by client devices.
Example: PCF8575 I/O expander node
pcf8575: gpio@20 {
compatible = "nxp,pcf8575";
reg = <0x20>;
interrupt-parent = <&irqpin2>;
interrupts = <3 0>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};

View File

@ -1,42 +0,0 @@
Lantiq SoC Serial To Parallel (STP) GPIO controller
The Serial To Parallel (STP) is found on MIPS based Lantiq socs. It is a
peripheral controller used to drive external shift register cascades. At most
3 groups of 8 bits can be driven. The hardware is able to allow the DSL modem
to drive the 2 LSBs of the cascade automatically.
Required properties:
- compatible : Should be "lantiq,gpio-stp-xway"
- reg : Address and length of the register set for the device
- #gpio-cells : Should be two. The first cell is the pin number and
the second cell is used to specify optional parameters (currently
unused).
- gpio-controller : Marks the device node as a gpio controller.
Optional properties:
- lantiq,shadow : The default value that we shall assume as already set on the
shift register cascade.
- lantiq,groups : Set the 3 bit mask to select which of the 3 groups are enabled
in the shift register cascade.
- lantiq,dsl : The dsl core can control the 2 LSBs of the gpio cascade. This 2 bit
property can enable this feature.
- lantiq,phy1 : The gphy1 core can control 3 bits of the gpio cascade.
- lantiq,phy2 : The gphy2 core can control 3 bits of the gpio cascade.
- lantiq,rising : use rising instead of falling edge for the shift register
Example:
gpio1: stp@e100bb0 {
compatible = "lantiq,gpio-stp-xway";
reg = <0xE100BB0 0x40>;
#gpio-cells = <2>;
gpio-controller;
lantiq,shadow = <0xffff>;
lantiq,groups = <0x7>;
lantiq,dsl = <0x3>;
lantiq,phy1 = <0x7>;
lantiq,phy2 = <0x7>;
/* lantiq,rising; */
};

View File

@ -0,0 +1,99 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/gpio/gpio-stp-xway.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Lantiq SoC Serial To Parallel (STP) GPIO controller
description: |
The Serial To Parallel (STP) is found on MIPS based Lantiq socs. It is a
peripheral controller used to drive external shift register cascades. At most
3 groups of 8 bits can be driven. The hardware is able to allow the DSL modem
and Ethernet PHYs to drive some bytes of the cascade automatically.
maintainers:
- John Crispin <john@phrozen.org>
properties:
$nodename:
pattern: "^gpio@[0-9a-f]+$"
compatible:
const: lantiq,gpio-stp-xway
reg:
maxItems: 1
gpio-controller: true
"#gpio-cells":
description:
The first cell is the pin number and the second cell is used to specify
consumer flags.
const: 2
lantiq,shadow:
description:
The default value that we shall assume as already set on the
shift register cascade.
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0x000000
maximum: 0xffffff
lantiq,groups:
description:
Set the 3 bit mask to select which of the 3 groups are enabled
in the shift register cascade.
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0x0
maximum: 0x7
lantiq,dsl:
description:
The dsl core can control the 2 LSBs of the gpio cascade. This 2 bit
property can enable this feature.
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0x0
maximum: 0x3
lantiq,rising:
description:
Use rising instead of falling edge for the shift register.
type: boolean
patternProperties:
"^lantiq,phy[1-4]$":
description:
The gphy core can control 3 bits of the gpio cascade. In the xRX200 family
phy[1-2] are available, in xRX330 phy[1-3] and in XRX330 phy[1-4].
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0x0
maximum: 0x7
required:
- compatible
- reg
- gpio-controller
- "#gpio-cells"
additionalProperties: false
examples:
- |
gpio@e100bb0 {
compatible = "lantiq,gpio-stp-xway";
reg = <0xE100BB0 0x40>;
#gpio-cells = <2>;
gpio-controller;
pinctrl-0 = <&stp_pins>;
pinctrl-names = "default";
lantiq,shadow = <0xffffff>;
lantiq,groups = <0x7>;
lantiq,dsl = <0x3>;
lantiq,phy1 = <0x7>;
lantiq,phy2 = <0x7>;
};
...

View File

@ -1,36 +0,0 @@
Xilinx Zynq GPIO controller Device Tree Bindings
-------------------------------------------
Required properties:
- #gpio-cells : Should be two
- First cell is the GPIO line number
- Second cell is used to specify optional
parameters (unused)
- compatible : Should be "xlnx,zynq-gpio-1.0" or
"xlnx,zynqmp-gpio-1.0" or "xlnx,versal-gpio-1.0
or "xlnx,pmc-gpio-1.0
- clocks : Clock specifier (see clock bindings for details)
- gpio-controller : Marks the device node as a GPIO controller.
- interrupts : Interrupt specifier (see interrupt bindings for
details)
- interrupt-controller : Marks the device node as an interrupt controller.
- #interrupt-cells : Should be 2. The first cell is the GPIO number.
The second cell bits[3:0] is used to specify trigger type and level flags:
1 = low-to-high edge triggered.
2 = high-to-low edge triggered.
4 = active high level-sensitive.
8 = active low level-sensitive.
- reg : Address and length of the register set for the device
Example:
gpio@e000a000 {
#gpio-cells = <2>;
compatible = "xlnx,zynq-gpio-1.0";
clocks = <&clkc 42>;
gpio-controller;
interrupt-parent = <&intc>;
interrupts = <0 20 4>;
interrupt-controller;
#interrupt-cells = <2>;
reg = <0xe000a000 0x1000>;
};

View File

@ -0,0 +1,59 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/gpio/gpio-zynq.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Xilinx Zynq GPIO controller Device Tree Bindings
maintainers:
- Michal Simek <michal.simek@xilinx.com>
properties:
compatible:
const: xlnx,zynq-gpio-1.0
reg:
maxItems: 1
"#gpio-cells":
const: 2
interrupts:
maxItems: 1
gpio-controller: true
interrupt-controller: true
"#interrupt-cells":
const: 2
clocks:
maxItems: 1
required:
- compatible
- reg
- "#gpio-cells"
- interrupts
- gpio-controller
- interrupt-controller
- "#interrupt-cells"
- clocks
additionalProperties: false
examples:
- |
gpio@e000a000 {
#gpio-cells = <2>;
compatible = "xlnx,zynq-gpio-1.0";
clocks = <&clkc 42>;
gpio-controller;
interrupt-parent = <&intc>;
interrupts = <0 20 4>;
interrupt-controller;
#interrupt-cells = <2>;
reg = <0xe000a000 0x1000>;
};

View File

@ -0,0 +1,67 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/gpio/idt,32434-gpio.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: IDT 79RC32434 GPIO controller
maintainers:
- Thomas Bogendoerfer <tsbogend@alpha.franken.de>
properties:
compatible:
const: idt,32434-gpio
reg:
maxItems: 2
reg-names:
items:
- const: gpio
- const: pic
gpio-controller: true
"#gpio-cells":
const: 2
ngpios:
minimum: 1
maximum: 32
interrupt-controller: true
"#interrupt-cells":
const: 2
interrupts:
maxItems: 1
required:
- compatible
- reg
- reg-names
- gpio-controller
- "#gpio-cells"
additionalProperties: false
examples:
- |
gpio0: gpio@50004 {
compatible = "idt,32434-gpio";
reg = <0x50004 0x10>, <0x38030 0x0c>;
reg-names = "gpio", "pic";
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&cpuintc>;
interrupts = <6>;
gpio-controller;
#gpio-cells = <2>;
ngpios = <14>;
};

View File

@ -0,0 +1,103 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/gpio/nxp,pcf8575.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: PCF857x-compatible I/O expanders
maintainers:
- Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
description:
The PCF857x-compatible chips have "quasi-bidirectional" I/O lines that can be
driven high by a pull-up current source or driven low to ground. This
combines the direction and output level into a single bit per line, which
can't be read back. We can't actually know at initialization time whether a
line is configured (a) as output and driving the signal low/high, or (b) as
input and reporting a low/high value, without knowing the last value written
since the chip came out of reset (if any). The only reliable solution for
setting up line direction is thus to do it explicitly.
properties:
compatible:
enum:
- maxim,max7328
- maxim,max7329
- nxp,pca8574
- nxp,pca8575
- nxp,pca9670
- nxp,pca9671
- nxp,pca9672
- nxp,pca9673
- nxp,pca9674
- nxp,pca9675
- nxp,pcf8574
- nxp,pcf8574a
- nxp,pcf8575
reg:
maxItems: 1
gpio-controller: true
'#gpio-cells':
const: 2
description:
The first cell is the GPIO number and the second cell specifies GPIO
flags, as defined in <dt-bindings/gpio/gpio.h>. Only the GPIO_ACTIVE_HIGH
and GPIO_ACTIVE_LOW flags are supported.
lines-initial-states:
$ref: /schemas/types.yaml#/definitions/uint32
description:
Bitmask that specifies the initial state of each line.
When a bit is set to zero, the corresponding line will be initialized to
the input (pulled-up) state.
When the bit is set to one, the line will be initialized to the
low-level output state.
If the property is not specified all lines will be initialized to the
input state.
interrupts:
maxItems: 1
interrupt-controller: true
'#interrupt-cells':
const: 2
wakeup-source: true
patternProperties:
"^(.+-hog(-[0-9]+)?)$":
type: object
required:
- gpio-hog
required:
- compatible
- reg
- gpio-controller
- '#gpio-cells'
additionalProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
pcf8575: gpio@20 {
compatible = "nxp,pcf8575";
reg = <0x20>;
interrupt-parent = <&irqpin2>;
interrupts = <3 0>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
};

View File

@ -1,32 +0,0 @@
Rockchip RK3328 GRF (General Register Files) GPIO controller.
In Rockchip RK3328, the output only GPIO_MUTE pin, originally for codec mute
control, can also be used for general purpose. It is manipulated by the
GRF_SOC_CON10 register in GRF. Aside from the GPIO_MUTE pin, the HDMI pins can
also be set in the same way.
Currently this GPIO controller only supports the mute pin. If needed in the
future, the HDMI pins support can also be added.
Required properties:
- compatible: Should contain "rockchip,rk3328-grf-gpio".
- gpio-controller: Marks the device node as a gpio controller.
- #gpio-cells: Should be 2. The first cell is the pin number and
the second cell is used to specify the gpio polarity:
0 = Active high,
1 = Active low.
Example:
grf: syscon@ff100000 {
compatible = "rockchip,rk3328-grf", "syscon", "simple-mfd";
grf_gpio: grf-gpio {
compatible = "rockchip,rk3328-grf-gpio";
gpio-controller;
#gpio-cells = <2>;
};
};
Note: The grf_gpio node should be declared as the child of the GRF (General
Register File) node. The GPIO_MUTE pin is referred to as <&grf_gpio 0>.

View File

@ -0,0 +1,50 @@
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/gpio/rockchip,rk3328-grf-gpio.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Rockchip RK3328 General Register Files GPIO controller
description:
The Rockchip RK3328 General Register File (GRF) outputs only the
GPIO_MUTE pin, originally for codec mute control, but it can also be used
for general purpose. It is manipulated by the GRF_SOC_CON10 register.
If needed in the future support for the HDMI pins can also be added.
The GPIO node should be declared as the child of the GRF node.
The GPIO_MUTE pin is referred to in the format
<&grf_gpio 0 GPIO_ACTIVE_LOW>
The first cell is the pin number and
the second cell is used to specify the GPIO polarity
0 = Active high
1 = Active low
maintainers:
- Heiko Stuebner <heiko@sntech.de>
properties:
compatible:
const: rockchip,rk3328-grf-gpio
gpio-controller: true
"#gpio-cells":
const: 2
required:
- compatible
- gpio-controller
- "#gpio-cells"
additionalProperties: false
examples:
- |
grf_gpio: gpio {
compatible = "rockchip,rk3328-grf-gpio";
gpio-controller;
#gpio-cells = <2>;
};

View File

@ -0,0 +1,108 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/gpio/ti,omap-gpio.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: OMAP GPIO controller bindings
maintainers:
- Grygorii Strashko <grygorii.strashko@ti.com>
description: |
The general-purpose interface combines general-purpose input/output (GPIO) banks.
Each GPIO banks provides up to 32 dedicated general-purpose pins with input
and output capabilities; interrupt generation in active mode and wake-up
request generation in idle mode upon the detection of external events.
properties:
compatible:
oneOf:
- enum:
- ti,omap2-gpio
- ti,omap3-gpio
- ti,omap4-gpio
- items:
- const: ti,am4372-gpio
- const: ti,omap4-gpio
reg:
maxItems: 1
gpio-controller: true
'#gpio-cells':
const: 2
interrupt-controller: true
'#interrupt-cells':
const: 2
interrupts:
maxItems: 1
gpio-ranges: true
gpio-line-names:
minItems: 1
maxItems: 32
ti,gpio-always-on:
$ref: /schemas/types.yaml#/definitions/flag
description:
Indicates if a GPIO bank is always powered and will never lose its logic state.
ti,hwmods:
$ref: /schemas/types.yaml#/definitions/string
deprecated: true
description:
Name of the hwmod associated with the GPIO. Needed on some legacy OMAP
SoCs which have not been converted to the ti,sysc interconnect hierarachy.
ti,no-reset-on-init:
$ref: /schemas/types.yaml#/definitions/flag
deprecated: true
description:
Do not reset on init. Used with ti,hwmods on some legacy OMAP SoCs which
have not been converted to the ti,sysc interconnect hierarachy.
patternProperties:
"^(.+-hog(-[0-9]+)?)$":
type: object
required:
- gpio-hog
required:
- compatible
- reg
- gpio-controller
- "#gpio-cells"
- interrupt-controller
- "#interrupt-cells"
- interrupts
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
gpio0: gpio@0 {
compatible = "ti,omap4-gpio";
reg = <0x0 0x1000>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <96>;
ti,gpio-always-on;
ls-buf-en-hog {
gpio-hog;
gpios = <10 GPIO_ACTIVE_HIGH>;
output-high;
line-name = "LS_BUF_EN";
};
};

View File

@ -13471,7 +13471,7 @@ M: Santosh Shilimkar <ssantosh@kernel.org>
M: Kevin Hilman <khilman@kernel.org>
L: linux-omap@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/gpio/gpio-omap.txt
F: Documentation/devicetree/bindings/gpio/ti,omap-gpio.yaml
F: drivers/gpio/gpio-omap.c
OMAP HARDWARE SPINLOCK SUPPORT
@ -18448,7 +18448,7 @@ TI DAVINCI SERIES GPIO DRIVER
M: Keerthy <j-keerthy@ti.com>
L: linux-gpio@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/gpio/gpio-davinci.txt
F: Documentation/devicetree/bindings/gpio/gpio-davinci.yaml
F: drivers/gpio/gpio-davinci.c
TI DAVINCI SERIES MEDIA DRIVER

View File

@ -782,6 +782,18 @@ config GPIO_MSC313
Say Y here to support the main GPIO block on MStar/SigmaStar
ARMv7 based SoCs.
config GPIO_IDT3243X
tristate "IDT 79RC3243X GPIO support"
depends on MIKROTIK_RB532 || COMPILE_TEST
select GPIO_GENERIC
select GPIOLIB_IRQCHIP
help
Select this option to enable GPIO driver for
IDT 79RC3243X based devices like Mikrotik RB532.
To compile this driver as a module, choose M here: the module will
be called gpio-idt3243x.
endmenu
menu "Port-mapped I/O GPIO drivers"

View File

@ -68,6 +68,7 @@ obj-$(CONFIG_GPIO_HISI) += gpio-hisi.o
obj-$(CONFIG_GPIO_HLWD) += gpio-hlwd.o
obj-$(CONFIG_HTC_EGPIO) += gpio-htc-egpio.o
obj-$(CONFIG_GPIO_ICH) += gpio-ich.o
obj-$(CONFIG_GPIO_IDT3243X) += gpio-idt3243x.o
obj-$(CONFIG_GPIO_IOP) += gpio-iop.o
obj-$(CONFIG_GPIO_IT87) += gpio-it87.o
obj-$(CONFIG_GPIO_IXP4XX) += gpio-ixp4xx.o

View File

@ -44,11 +44,12 @@ struct idio_16_gpio {
struct gpio_chip chip;
raw_spinlock_t lock;
unsigned long irq_mask;
unsigned base;
unsigned out_state;
unsigned int base;
unsigned int out_state;
};
static int idio_16_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
static int idio_16_gpio_get_direction(struct gpio_chip *chip,
unsigned int offset)
{
if (offset > 15)
return GPIO_LINE_DIRECTION_IN;
@ -56,22 +57,23 @@ static int idio_16_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
return GPIO_LINE_DIRECTION_OUT;
}
static int idio_16_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
static int idio_16_gpio_direction_input(struct gpio_chip *chip,
unsigned int offset)
{
return 0;
}
static int idio_16_gpio_direction_output(struct gpio_chip *chip,
unsigned offset, int value)
unsigned int offset, int value)
{
chip->set(chip, offset, value);
return 0;
}
static int idio_16_gpio_get(struct gpio_chip *chip, unsigned offset)
static int idio_16_gpio_get(struct gpio_chip *chip, unsigned int offset)
{
struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
const unsigned mask = BIT(offset-16);
const unsigned int mask = BIT(offset-16);
if (offset < 16)
return -EINVAL;
@ -96,10 +98,11 @@ static int idio_16_gpio_get_multiple(struct gpio_chip *chip,
return 0;
}
static void idio_16_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
static void idio_16_gpio_set(struct gpio_chip *chip, unsigned int offset,
int value)
{
struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
const unsigned mask = BIT(offset);
const unsigned int mask = BIT(offset);
unsigned long flags;
if (offset > 15)
@ -180,7 +183,7 @@ static void idio_16_irq_unmask(struct irq_data *data)
}
}
static int idio_16_irq_set_type(struct irq_data *data, unsigned flow_type)
static int idio_16_irq_set_type(struct irq_data *data, unsigned int flow_type)
{
/* The only valid irq types are none and both-edges */
if (flow_type != IRQ_TYPE_NONE &&

View File

@ -113,10 +113,8 @@ static int adp5520_gpio_probe(struct platform_device *pdev)
if (pdata->gpio_en_mask & (1 << i))
dev->lut[gpios++] = 1 << i;
if (gpios < 1) {
ret = -EINVAL;
goto err;
}
if (gpios < 1)
return -EINVAL;
gc = &dev->gpio_chip;
gc->direction_input = adp5520_gpio_direction_input;
@ -148,18 +146,10 @@ static int adp5520_gpio_probe(struct platform_device *pdev)
if (ret) {
dev_err(&pdev->dev, "failed to write\n");
goto err;
return ret;
}
ret = devm_gpiochip_add_data(&pdev->dev, &dev->gpio_chip, dev);
if (ret)
goto err;
platform_set_drvdata(pdev, dev);
return 0;
err:
return ret;
return devm_gpiochip_add_data(&pdev->dev, &dev->gpio_chip, dev);
}
static struct platform_driver adp5520_gpio_driver = {

View File

@ -78,7 +78,6 @@ static const struct gpio_chip altr_a10sr_gc = {
static int altr_a10sr_gpio_probe(struct platform_device *pdev)
{
struct altr_a10sr_gpio *gpio;
int ret;
struct altr_a10sr *a10sr = dev_get_drvdata(pdev->dev.parent);
gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
@ -91,15 +90,7 @@ static int altr_a10sr_gpio_probe(struct platform_device *pdev)
gpio->gp.parent = pdev->dev.parent;
gpio->gp.of_node = pdev->dev.of_node;
ret = devm_gpiochip_add_data(&pdev->dev, &gpio->gp, gpio);
if (ret < 0) {
dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
return ret;
}
platform_set_drvdata(pdev, gpio);
return 0;
return devm_gpiochip_add_data(&pdev->dev, &gpio->gp, gpio);
}
static const struct of_device_id altr_a10sr_gpio_of_match[] = {

View File

@ -234,7 +234,6 @@ static int ath79_gpio_probe(struct platform_device *pdev)
ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
if (!ctrl)
return -ENOMEM;
platform_set_drvdata(pdev, ctrl);
if (np) {
err = of_property_read_u32(np, "ngpios", &ath79_gpio_count);
@ -290,13 +289,7 @@ static int ath79_gpio_probe(struct platform_device *pdev)
girq->handler = handle_simple_irq;
}
err = devm_gpiochip_add_data(dev, &ctrl->gc, ctrl);
if (err) {
dev_err(dev,
"cannot add AR71xx GPIO chip, error=%d", err);
return err;
}
return 0;
return devm_gpiochip_add_data(dev, &ctrl->gc, ctrl);
}
static struct platform_driver ath79_gpio_driver = {

View File

@ -97,25 +97,16 @@ static const struct gpio_chip template_chip = {
static int bd9571mwv_gpio_probe(struct platform_device *pdev)
{
struct bd9571mwv_gpio *gpio;
int ret;
gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
if (!gpio)
return -ENOMEM;
platform_set_drvdata(pdev, gpio);
gpio->regmap = dev_get_regmap(pdev->dev.parent, NULL);
gpio->chip = template_chip;
gpio->chip.parent = pdev->dev.parent;
ret = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
if (ret < 0) {
dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
return ret;
}
return 0;
return devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
}
static const struct platform_device_id bd9571mwv_gpio_id_table[] = {

View File

@ -196,7 +196,6 @@ static int da9052_gpio_probe(struct platform_device *pdev)
{
struct da9052_gpio *gpio;
struct da9052_pdata *pdata;
int ret;
gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
if (!gpio)
@ -209,15 +208,7 @@ static int da9052_gpio_probe(struct platform_device *pdev)
if (pdata && pdata->gpio_base)
gpio->gp.base = pdata->gpio_base;
ret = devm_gpiochip_add_data(&pdev->dev, &gpio->gp, gpio);
if (ret < 0) {
dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
return ret;
}
platform_set_drvdata(pdev, gpio);
return 0;
return devm_gpiochip_add_data(&pdev->dev, &gpio->gp, gpio);
}
static struct platform_driver da9052_gpio_driver = {

View File

@ -133,7 +133,6 @@ static int da9055_gpio_probe(struct platform_device *pdev)
{
struct da9055_gpio *gpio;
struct da9055_pdata *pdata;
int ret;
gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
if (!gpio)
@ -146,15 +145,7 @@ static int da9055_gpio_probe(struct platform_device *pdev)
if (pdata && pdata->gpio_base)
gpio->gp.base = pdata->gpio_base;
ret = devm_gpiochip_add_data(&pdev->dev, &gpio->gp, gpio);
if (ret < 0) {
dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
return ret;
}
platform_set_drvdata(pdev, gpio);
return 0;
return devm_gpiochip_add_data(&pdev->dev, &gpio->gp, gpio);
}
static struct platform_driver da9055_gpio_driver = {

View File

@ -13,17 +13,15 @@
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/irq.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/platform_data/gpio-dwapb.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/reset.h>
#include <linux/spinlock.h>
#include <linux/platform_data/gpio-dwapb.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include "gpiolib.h"
#include "gpiolib-acpi.h"
@ -297,9 +295,6 @@ static int dwapb_irq_set_type(struct irq_data *d, u32 type)
irq_hw_number_t bit = irqd_to_hwirq(d);
unsigned long level, polarity, flags;
if (type & ~IRQ_TYPE_SENSE_MASK)
return -EINVAL;
spin_lock_irqsave(&gc->bgpio_lock, flags);
level = dwapb_read(gpio, GPIO_INTTYPE_LEVEL);
polarity = dwapb_read(gpio, GPIO_INT_POLARITY);
@ -531,17 +526,13 @@ static int dwapb_gpio_add_port(struct dwapb_gpio *gpio,
static void dwapb_get_irq(struct device *dev, struct fwnode_handle *fwnode,
struct dwapb_port_property *pp)
{
struct device_node *np = NULL;
int irq = -ENXIO, j;
if (fwnode_property_read_bool(fwnode, "interrupt-controller"))
np = to_of_node(fwnode);
int irq, j;
for (j = 0; j < pp->ngpio; j++) {
if (np)
irq = of_irq_get(np, j);
else if (has_acpi_companion(dev))
if (has_acpi_companion(dev))
irq = platform_get_irq_optional(to_platform_device(dev), j);
else
irq = fwnode_irq_get(fwnode, j);
if (irq > 0)
pp->irq[j] = irq;
}

View File

@ -0,0 +1,206 @@
// SPDX-License-Identifier: GPL-2.0
/* Driver for IDT/Renesas 79RC3243x Interrupt Controller */
#include <linux/bitops.h>
#include <linux/gpio/driver.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/spinlock.h>
#define IDT_PIC_IRQ_PEND 0x00
#define IDT_PIC_IRQ_MASK 0x08
#define IDT_GPIO_DIR 0x00
#define IDT_GPIO_DATA 0x04
#define IDT_GPIO_ILEVEL 0x08
#define IDT_GPIO_ISTAT 0x0C
struct idt_gpio_ctrl {
struct gpio_chip gc;
void __iomem *pic;
void __iomem *gpio;
u32 mask_cache;
};
static void idt_gpio_dispatch(struct irq_desc *desc)
{
struct gpio_chip *gc = irq_desc_get_handler_data(desc);
struct idt_gpio_ctrl *ctrl = gpiochip_get_data(gc);
struct irq_chip *host_chip = irq_desc_get_chip(desc);
unsigned int bit, virq;
unsigned long pending;
chained_irq_enter(host_chip, desc);
pending = readl(ctrl->pic + IDT_PIC_IRQ_PEND);
pending &= ~ctrl->mask_cache;
for_each_set_bit(bit, &pending, gc->ngpio) {
virq = irq_linear_revmap(gc->irq.domain, bit);
if (virq)
generic_handle_irq(virq);
}
chained_irq_exit(host_chip, desc);
}
static int idt_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct idt_gpio_ctrl *ctrl = gpiochip_get_data(gc);
unsigned int sense = flow_type & IRQ_TYPE_SENSE_MASK;
unsigned long flags;
u32 ilevel;
/* hardware only supports level triggered */
if (sense == IRQ_TYPE_NONE || (sense & IRQ_TYPE_EDGE_BOTH))
return -EINVAL;
spin_lock_irqsave(&gc->bgpio_lock, flags);
ilevel = readl(ctrl->gpio + IDT_GPIO_ILEVEL);
if (sense & IRQ_TYPE_LEVEL_HIGH)
ilevel |= BIT(d->hwirq);
else if (sense & IRQ_TYPE_LEVEL_LOW)
ilevel &= ~BIT(d->hwirq);
writel(ilevel, ctrl->gpio + IDT_GPIO_ILEVEL);
irq_set_handler_locked(d, handle_level_irq);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
return 0;
}
static void idt_gpio_ack(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct idt_gpio_ctrl *ctrl = gpiochip_get_data(gc);
writel(~BIT(d->hwirq), ctrl->gpio + IDT_GPIO_ISTAT);
}
static void idt_gpio_mask(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct idt_gpio_ctrl *ctrl = gpiochip_get_data(gc);
unsigned long flags;
spin_lock_irqsave(&gc->bgpio_lock, flags);
ctrl->mask_cache |= BIT(d->hwirq);
writel(ctrl->mask_cache, ctrl->pic + IDT_PIC_IRQ_MASK);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
}
static void idt_gpio_unmask(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct idt_gpio_ctrl *ctrl = gpiochip_get_data(gc);
unsigned long flags;
spin_lock_irqsave(&gc->bgpio_lock, flags);
ctrl->mask_cache &= ~BIT(d->hwirq);
writel(ctrl->mask_cache, ctrl->pic + IDT_PIC_IRQ_MASK);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
}
static int idt_gpio_irq_init_hw(struct gpio_chip *gc)
{
struct idt_gpio_ctrl *ctrl = gpiochip_get_data(gc);
/* Mask interrupts. */
ctrl->mask_cache = 0xffffffff;
writel(ctrl->mask_cache, ctrl->pic + IDT_PIC_IRQ_MASK);
return 0;
}
static struct irq_chip idt_gpio_irqchip = {
.name = "IDTGPIO",
.irq_mask = idt_gpio_mask,
.irq_ack = idt_gpio_ack,
.irq_unmask = idt_gpio_unmask,
.irq_set_type = idt_gpio_irq_set_type
};
static int idt_gpio_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct gpio_irq_chip *girq;
struct idt_gpio_ctrl *ctrl;
unsigned int parent_irq;
int ngpios;
int ret;
ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
if (!ctrl)
return -ENOMEM;
ctrl->gpio = devm_platform_ioremap_resource_byname(pdev, "gpio");
if (IS_ERR(ctrl->gpio))
return PTR_ERR(ctrl->gpio);
ctrl->gc.parent = dev;
ret = bgpio_init(&ctrl->gc, &pdev->dev, 4, ctrl->gpio + IDT_GPIO_DATA,
NULL, NULL, ctrl->gpio + IDT_GPIO_DIR, NULL, 0);
if (ret) {
dev_err(dev, "bgpio_init failed\n");
return ret;
}
ret = device_property_read_u32(dev, "ngpios", &ngpios);
if (!ret)
ctrl->gc.ngpio = ngpios;
if (device_property_read_bool(dev, "interrupt-controller")) {
ctrl->pic = devm_platform_ioremap_resource_byname(pdev, "pic");
if (IS_ERR(ctrl->pic))
return PTR_ERR(ctrl->pic);
parent_irq = platform_get_irq(pdev, 0);
if (!parent_irq)
return -EINVAL;
girq = &ctrl->gc.irq;
girq->chip = &idt_gpio_irqchip;
girq->init_hw = idt_gpio_irq_init_hw;
girq->parent_handler = idt_gpio_dispatch;
girq->num_parents = 1;
girq->parents = devm_kcalloc(dev, girq->num_parents,
sizeof(*girq->parents),
GFP_KERNEL);
if (!girq->parents)
return -ENOMEM;
girq->parents[0] = parent_irq;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_bad_irq;
}
return devm_gpiochip_add_data(&pdev->dev, &ctrl->gc, ctrl);
}
static const struct of_device_id idt_gpio_of_match[] = {
{ .compatible = "idt,32434-gpio" },
{ }
};
MODULE_DEVICE_TABLE(of, idt_gpio_of_match);
static struct platform_driver idt_gpio_driver = {
.probe = idt_gpio_probe,
.driver = {
.name = "idt3243x-gpio",
.of_match_table = idt_gpio_of_match,
},
};
module_platform_driver(idt_gpio_driver);
MODULE_DESCRIPTION("IDT 79RC3243x GPIO/PIC Driver");
MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>");
MODULE_LICENSE("GPL");

View File

@ -114,10 +114,8 @@ static int logicvc_gpio_probe(struct platform_device *pdev)
}
base = devm_ioremap_resource(dev, &res);
if (IS_ERR(base)) {
dev_err(dev, "Failed to map I/O base\n");
if (IS_ERR(base))
return PTR_ERR(base);
}
logicvc_gpio_regmap_config.max_register = resource_size(&res) -
logicvc_gpio_regmap_config.reg_stride;

View File

@ -144,12 +144,9 @@ static void gpio_mockup_set_multiple(struct gpio_chip *gc,
static int gpio_mockup_apply_pull(struct gpio_mockup_chip *chip,
unsigned int offset, int value)
{
struct gpio_chip *gc = &chip->gc;
struct gpio_desc *desc = gpiochip_get_desc(gc, offset);
int curr, irq, irq_type, ret = 0;
struct gpio_desc *desc;
struct gpio_chip *gc;
gc = &chip->gc;
desc = &gc->gpiodev->descs[offset];
mutex_lock(&chip->lock);
@ -369,7 +366,7 @@ static void gpio_mockup_debugfs_setup(struct device *dev,
priv->chip = chip;
priv->offset = i;
priv->desc = &gc->gpiodev->descs[i];
priv->desc = gpiochip_get_desc(gc, i);
debugfs_create_file(name, 0200, chip->dbg_dir, priv,
&gpio_mockup_debugfs_ops);

View File

@ -229,14 +229,14 @@ static int mxs_gpio_init_gc(struct mxs_gpio_port *port, int irq_base)
return rv;
}
static int mxs_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
static int mxs_gpio_to_irq(struct gpio_chip *gc, unsigned int offset)
{
struct mxs_gpio_port *port = gpiochip_get_data(gc);
return irq_find_mapping(port->domain, offset);
}
static int mxs_gpio_get_direction(struct gpio_chip *gc, unsigned offset)
static int mxs_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
{
struct mxs_gpio_port *port = gpiochip_get_data(gc);
u32 mask = 1 << offset;

View File

@ -1241,6 +1241,7 @@ static const struct of_device_id pca953x_dt_ids[] = {
{ .compatible = "onnn,cat9554", .data = OF_953X( 8, PCA_INT), },
{ .compatible = "onnn,pca9654", .data = OF_953X( 8, PCA_INT), },
{ .compatible = "onnn,pca9655", .data = OF_953X(16, PCA_INT), },
{ .compatible = "exar,xra1202", .data = OF_953X( 8, 0), },
{ }

View File

@ -178,12 +178,6 @@ static int gpio_regmap_direction_output(struct gpio_chip *chip,
return gpio_regmap_set_direction(chip, offset, true);
}
void gpio_regmap_set_drvdata(struct gpio_regmap *gpio, void *data)
{
gpio->driver_data = data;
}
EXPORT_SYMBOL_GPL(gpio_regmap_set_drvdata);
void *gpio_regmap_get_drvdata(struct gpio_regmap *gpio)
{
return gpio->driver_data;
@ -226,6 +220,7 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config
return ERR_PTR(-ENOMEM);
gpio->parent = config->parent;
gpio->driver_data = config->drvdata;
gpio->regmap = config->regmap;
gpio->ngpio_per_reg = config->ngpio_per_reg;
gpio->reg_stride = config->reg_stride;
@ -311,9 +306,9 @@ void gpio_regmap_unregister(struct gpio_regmap *gpio)
}
EXPORT_SYMBOL_GPL(gpio_regmap_unregister);
static void devm_gpio_regmap_unregister(struct device *dev, void *res)
static void devm_gpio_regmap_unregister(void *res)
{
gpio_regmap_unregister(*(struct gpio_regmap **)res);
gpio_regmap_unregister(res);
}
/**
@ -330,20 +325,17 @@ static void devm_gpio_regmap_unregister(struct device *dev, void *res)
struct gpio_regmap *devm_gpio_regmap_register(struct device *dev,
const struct gpio_regmap_config *config)
{
struct gpio_regmap **ptr, *gpio;
ptr = devres_alloc(devm_gpio_regmap_unregister, sizeof(*ptr),
GFP_KERNEL);
if (!ptr)
return ERR_PTR(-ENOMEM);
struct gpio_regmap *gpio;
int ret;
gpio = gpio_regmap_register(config);
if (!IS_ERR(gpio)) {
*ptr = gpio;
devres_add(dev, ptr);
} else {
devres_free(ptr);
}
if (IS_ERR(gpio))
return gpio;
ret = devm_add_action_or_reset(dev, devm_gpio_regmap_unregister, gpio);
if (ret)
return ERR_PTR(ret);
return gpio;
}

View File

@ -122,7 +122,6 @@ static int spics_gpio_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct spear_spics *spics;
int ret;
spics = devm_kzalloc(&pdev->dev, sizeof(*spics), GFP_KERNEL);
if (!spics)
@ -148,8 +147,6 @@ static int spics_gpio_probe(struct platform_device *pdev)
&spics->cs_enable_shift))
goto err_dt_data;
platform_set_drvdata(pdev, spics);
spics->chip.ngpio = NUM_OF_GPIO;
spics->chip.base = -1;
spics->chip.request = spics_request;
@ -163,14 +160,7 @@ static int spics_gpio_probe(struct platform_device *pdev)
spics->chip.owner = THIS_MODULE;
spics->last_off = -1;
ret = devm_gpiochip_add_data(&pdev->dev, &spics->chip, spics);
if (ret) {
dev_err(&pdev->dev, "unable to add gpio chip\n");
return ret;
}
dev_info(&pdev->dev, "spear spics registered\n");
return 0;
return devm_gpiochip_add_data(&pdev->dev, &spics->chip, spics);
err_dt_data:
dev_err(&pdev->dev, "DT probe failed\n");

View File

@ -222,7 +222,6 @@ static int sprd_gpio_probe(struct platform_device *pdev)
{
struct gpio_irq_chip *irq;
struct sprd_gpio *sprd_gpio;
int ret;
sprd_gpio = devm_kzalloc(&pdev->dev, sizeof(*sprd_gpio), GFP_KERNEL);
if (!sprd_gpio)
@ -259,14 +258,7 @@ static int sprd_gpio_probe(struct platform_device *pdev)
irq->num_parents = 1;
irq->parents = &sprd_gpio->irq;
ret = devm_gpiochip_add_data(&pdev->dev, &sprd_gpio->chip, sprd_gpio);
if (ret < 0) {
dev_err(&pdev->dev, "Could not register gpiochip %d\n", ret);
return ret;
}
platform_set_drvdata(pdev, sprd_gpio);
return 0;
return devm_gpiochip_add_data(&pdev->dev, &sprd_gpio->chip, sprd_gpio);
}
static const struct of_device_id sprd_gpio_of_match[] = {

View File

@ -398,15 +398,7 @@ static int gsta_probe(struct platform_device *dev)
return err;
}
err = devm_gpiochip_add_data(&dev->dev, &chip->gpio, chip);
if (err < 0) {
dev_err(&dev->dev, "sta2x11 gpio: Can't register (%i)\n",
-err);
return err;
}
platform_set_drvdata(dev, chip);
return 0;
return devm_gpiochip_add_data(&dev->dev, &chip->gpio, chip);
}
static struct platform_driver sta2x11_gpio_platform_driver = {

View File

@ -449,6 +449,11 @@ static void stmpe_init_irq_valid_mask(struct gpio_chip *gc,
}
}
static void stmpe_gpio_disable(void *stmpe)
{
stmpe_disable(stmpe, STMPE_BLOCK_GPIO);
}
static int stmpe_gpio_probe(struct platform_device *pdev)
{
struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent);
@ -461,7 +466,7 @@ static int stmpe_gpio_probe(struct platform_device *pdev)
return -EINVAL;
}
stmpe_gpio = kzalloc(sizeof(*stmpe_gpio), GFP_KERNEL);
stmpe_gpio = devm_kzalloc(&pdev->dev, sizeof(*stmpe_gpio), GFP_KERNEL);
if (!stmpe_gpio)
return -ENOMEM;
@ -489,7 +494,11 @@ static int stmpe_gpio_probe(struct platform_device *pdev)
ret = stmpe_enable(stmpe, STMPE_BLOCK_GPIO);
if (ret)
goto out_free;
return ret;
ret = devm_add_action_or_reset(&pdev->dev, stmpe_gpio_disable, stmpe);
if (ret)
return ret;
if (irq > 0) {
struct gpio_irq_chip *girq;
@ -499,7 +508,7 @@ static int stmpe_gpio_probe(struct platform_device *pdev)
"stmpe-gpio", stmpe_gpio);
if (ret) {
dev_err(&pdev->dev, "unable to get irq: %d\n", ret);
goto out_disable;
return ret;
}
girq = &stmpe_gpio->chip.irq;
@ -514,22 +523,7 @@ static int stmpe_gpio_probe(struct platform_device *pdev)
girq->init_valid_mask = stmpe_init_irq_valid_mask;
}
ret = gpiochip_add_data(&stmpe_gpio->chip, stmpe_gpio);
if (ret) {
dev_err(&pdev->dev, "unable to add gpiochip: %d\n", ret);
goto out_disable;
}
platform_set_drvdata(pdev, stmpe_gpio);
return 0;
out_disable:
stmpe_disable(stmpe, STMPE_BLOCK_GPIO);
gpiochip_remove(&stmpe_gpio->chip);
out_free:
kfree(stmpe_gpio);
return ret;
return devm_gpiochip_add_data(&pdev->dev, &stmpe_gpio->chip, stmpe_gpio);
}
static struct platform_driver stmpe_gpio_driver = {

View File

@ -357,16 +357,7 @@ static int tc3589x_gpio_probe(struct platform_device *pdev)
return ret;
}
ret = devm_gpiochip_add_data(&pdev->dev, &tc3589x_gpio->chip,
tc3589x_gpio);
if (ret) {
dev_err(&pdev->dev, "unable to add gpiochip: %d\n", ret);
return ret;
}
platform_set_drvdata(pdev, tc3589x_gpio);
return 0;
return devm_gpiochip_add_data(&pdev->dev, &tc3589x_gpio->chip, tc3589x_gpio);
}
static struct platform_driver tc3589x_gpio_driver = {

View File

@ -730,18 +730,7 @@ static int tegra186_gpio_probe(struct platform_device *pdev)
offset += port->pins;
}
platform_set_drvdata(pdev, gpio);
err = devm_gpiochip_add_data(&pdev->dev, &gpio->gpio, gpio);
if (err < 0)
return err;
return 0;
}
static int tegra186_gpio_remove(struct platform_device *pdev)
{
return 0;
return devm_gpiochip_add_data(&pdev->dev, &gpio->gpio, gpio);
}
#define TEGRA186_MAIN_GPIO_PORT(_name, _bank, _port, _pins) \
@ -913,7 +902,6 @@ static struct platform_driver tegra186_gpio_driver = {
.of_match_table = tegra186_gpio_of_match,
},
.probe = tegra186_gpio_probe,
.remove = tegra186_gpio_remove,
};
module_platform_driver(tegra186_gpio_driver);

View File

@ -187,7 +187,6 @@ static int tps65218_gpio_probe(struct platform_device *pdev)
{
struct tps65218 *tps65218 = dev_get_drvdata(pdev->dev.parent);
struct tps65218_gpio *tps65218_gpio;
int ret;
tps65218_gpio = devm_kzalloc(&pdev->dev, sizeof(*tps65218_gpio),
GFP_KERNEL);
@ -201,16 +200,8 @@ static int tps65218_gpio_probe(struct platform_device *pdev)
tps65218_gpio->gpio_chip.of_node = pdev->dev.of_node;
#endif
ret = devm_gpiochip_add_data(&pdev->dev, &tps65218_gpio->gpio_chip,
tps65218_gpio);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to register gpiochip, %d\n", ret);
return ret;
}
platform_set_drvdata(pdev, tps65218_gpio);
return ret;
return devm_gpiochip_add_data(&pdev->dev, &tps65218_gpio->gpio_chip,
tps65218_gpio);
}
static const struct of_device_id tps65218_dt_match[] = {

View File

@ -76,7 +76,6 @@ static int tps6586x_gpio_probe(struct platform_device *pdev)
{
struct tps6586x_platform_data *pdata;
struct tps6586x_gpio *tps6586x_gpio;
int ret;
pdata = dev_get_platdata(pdev->dev.parent);
tps6586x_gpio = devm_kzalloc(&pdev->dev,
@ -106,16 +105,8 @@ static int tps6586x_gpio_probe(struct platform_device *pdev)
else
tps6586x_gpio->gpio_chip.base = -1;
ret = devm_gpiochip_add_data(&pdev->dev, &tps6586x_gpio->gpio_chip,
tps6586x_gpio);
if (ret < 0) {
dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
return ret;
}
platform_set_drvdata(pdev, tps6586x_gpio);
return ret;
return devm_gpiochip_add_data(&pdev->dev, &tps6586x_gpio->gpio_chip,
tps6586x_gpio);
}
static struct platform_driver tps6586x_gpio_driver = {

View File

@ -165,16 +165,8 @@ static int tps65910_gpio_probe(struct platform_device *pdev)
}
skip_init:
ret = devm_gpiochip_add_data(&pdev->dev, &tps65910_gpio->gpio_chip,
tps65910_gpio);
if (ret < 0) {
dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
return ret;
}
platform_set_drvdata(pdev, tps65910_gpio);
return ret;
return devm_gpiochip_add_data(&pdev->dev, &tps65910_gpio->gpio_chip,
tps65910_gpio);
}
static struct platform_driver tps65910_gpio_driver = {

View File

@ -99,7 +99,6 @@ static int tps65912_gpio_probe(struct platform_device *pdev)
{
struct tps65912 *tps = dev_get_drvdata(pdev->dev.parent);
struct tps65912_gpio *gpio;
int ret;
gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
if (!gpio)
@ -109,16 +108,7 @@ static int tps65912_gpio_probe(struct platform_device *pdev)
gpio->gpio_chip = template_chip;
gpio->gpio_chip.parent = tps->dev;
ret = devm_gpiochip_add_data(&pdev->dev, &gpio->gpio_chip,
gpio);
if (ret < 0) {
dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
return ret;
}
platform_set_drvdata(pdev, gpio);
return 0;
return devm_gpiochip_add_data(&pdev->dev, &gpio->gpio_chip, gpio);
}
static const struct platform_device_id tps65912_gpio_id_table[] = {

View File

@ -125,7 +125,6 @@ static const char *tps68470_names[TPS68470_N_GPIO] = {
static int tps68470_gpio_probe(struct platform_device *pdev)
{
struct tps68470_gpio_data *tps68470_gpio;
int ret;
tps68470_gpio = devm_kzalloc(&pdev->dev, sizeof(*tps68470_gpio),
GFP_KERNEL);
@ -146,16 +145,7 @@ static int tps68470_gpio_probe(struct platform_device *pdev)
tps68470_gpio->gc.base = -1;
tps68470_gpio->gc.parent = &pdev->dev;
ret = devm_gpiochip_add_data(&pdev->dev, &tps68470_gpio->gc,
tps68470_gpio);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to register gpio_chip: %d\n", ret);
return ret;
}
platform_set_drvdata(pdev, tps68470_gpio);
return ret;
return devm_gpiochip_add_data(&pdev->dev, &tps68470_gpio->gc, tps68470_gpio);
}
static struct platform_driver tps68470_gpio_driver = {

View File

@ -187,15 +187,7 @@ static int visconti_gpio_probe(struct platform_device *pdev)
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_level_irq;
ret = devm_gpiochip_add_data(dev, &priv->gpio_chip, priv);
if (ret) {
dev_err(dev, "failed to add GPIO chip\n");
return ret;
}
platform_set_drvdata(pdev, priv);
return ret;
return devm_gpiochip_add_data(dev, &priv->gpio_chip, priv);
}
static const struct of_device_id visconti_gpio_of_match[] = {

View File

@ -261,7 +261,6 @@ static int wm831x_gpio_probe(struct platform_device *pdev)
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
struct wm831x_pdata *pdata = &wm831x->pdata;
struct wm831x_gpio *wm831x_gpio;
int ret;
wm831x_gpio = devm_kzalloc(&pdev->dev, sizeof(*wm831x_gpio),
GFP_KERNEL);
@ -280,16 +279,7 @@ static int wm831x_gpio_probe(struct platform_device *pdev)
wm831x_gpio->gpio_chip.of_node = wm831x->dev->of_node;
#endif
ret = devm_gpiochip_add_data(&pdev->dev, &wm831x_gpio->gpio_chip,
wm831x_gpio);
if (ret < 0) {
dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
return ret;
}
platform_set_drvdata(pdev, wm831x_gpio);
return ret;
return devm_gpiochip_add_data(&pdev->dev, &wm831x_gpio->gpio_chip, wm831x_gpio);
}
static struct platform_driver wm831x_gpio_driver = {

View File

@ -105,7 +105,6 @@ static int wm8350_gpio_probe(struct platform_device *pdev)
struct wm8350 *wm8350 = dev_get_drvdata(pdev->dev.parent);
struct wm8350_platform_data *pdata = dev_get_platdata(wm8350->dev);
struct wm8350_gpio_data *wm8350_gpio;
int ret;
wm8350_gpio = devm_kzalloc(&pdev->dev, sizeof(*wm8350_gpio),
GFP_KERNEL);
@ -121,16 +120,7 @@ static int wm8350_gpio_probe(struct platform_device *pdev)
else
wm8350_gpio->gpio_chip.base = -1;
ret = devm_gpiochip_add_data(&pdev->dev, &wm8350_gpio->gpio_chip,
wm8350_gpio);
if (ret < 0) {
dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
return ret;
}
platform_set_drvdata(pdev, wm8350_gpio);
return ret;
return devm_gpiochip_add_data(&pdev->dev, &wm8350_gpio->gpio_chip, wm8350_gpio);
}
static struct platform_driver wm8350_gpio_driver = {

View File

@ -263,7 +263,6 @@ static int wm8994_gpio_probe(struct platform_device *pdev)
struct wm8994 *wm8994 = dev_get_drvdata(pdev->dev.parent);
struct wm8994_pdata *pdata = dev_get_platdata(wm8994->dev);
struct wm8994_gpio *wm8994_gpio;
int ret;
wm8994_gpio = devm_kzalloc(&pdev->dev, sizeof(*wm8994_gpio),
GFP_KERNEL);
@ -279,17 +278,7 @@ static int wm8994_gpio_probe(struct platform_device *pdev)
else
wm8994_gpio->gpio_chip.base = -1;
ret = devm_gpiochip_add_data(&pdev->dev, &wm8994_gpio->gpio_chip,
wm8994_gpio);
if (ret < 0) {
dev_err(&pdev->dev, "Could not register gpiochip, %d\n",
ret);
return ret;
}
platform_set_drvdata(pdev, wm8994_gpio);
return ret;
return devm_gpiochip_add_data(&pdev->dev, &wm8994_gpio->gpio_chip, wm8994_gpio);
}
static struct platform_driver wm8994_gpio_driver = {

View File

@ -159,7 +159,6 @@ static SIMPLE_DEV_PM_OPS(xgene_gpio_pm, xgene_gpio_suspend, xgene_gpio_resume);
static int xgene_gpio_probe(struct platform_device *pdev)
{
struct xgene_gpio *gpio;
int err = 0;
gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
if (!gpio)
@ -183,15 +182,7 @@ static int xgene_gpio_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, gpio);
err = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
if (err) {
dev_err(&pdev->dev,
"failed to register gpiochip.\n");
return err;
}
dev_info(&pdev->dev, "X-Gene GPIO driver registered.\n");
return 0;
return devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
}
static const struct of_device_id xgene_gpio_of_match[] = {

View File

@ -5,6 +5,7 @@
* Copyright 2008 - 2013 Xilinx, Inc.
*/
#include <linux/bitmap.h>
#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/errno.h>
@ -23,7 +24,8 @@
#define XGPIO_DATA_OFFSET (0x0) /* Data register */
#define XGPIO_TRI_OFFSET (0x4) /* I/O direction register */
#define XGPIO_CHANNEL_OFFSET 0x8
#define XGPIO_CHANNEL0_OFFSET 0x0
#define XGPIO_CHANNEL1_OFFSET 0x8
#define XGPIO_GIER_OFFSET 0x11c /* Global Interrupt Enable */
#define XGPIO_GIER_IE BIT(31)
@ -43,56 +45,101 @@
* struct xgpio_instance - Stores information about GPIO device
* @gc: GPIO chip
* @regs: register block
* @gpio_width: GPIO width for every channel
* @gpio_state: GPIO write state shadow register
* @gpio_last_irq_read: GPIO read state register from last interrupt
* @gpio_dir: GPIO direction shadow register
* @hw_map: GPIO pin mapping on hardware side
* @sw_map: GPIO pin mapping on software side
* @state: GPIO write state shadow register
* @last_irq_read: GPIO read state register from last interrupt
* @dir: GPIO direction shadow register
* @gpio_lock: Lock used for synchronization
* @irq: IRQ used by GPIO device
* @irqchip: IRQ chip
* @irq_enable: GPIO IRQ enable/disable bitfield
* @irq_rising_edge: GPIO IRQ rising edge enable/disable bitfield
* @irq_falling_edge: GPIO IRQ falling edge enable/disable bitfield
* @enable: GPIO IRQ enable/disable bitfield
* @rising_edge: GPIO IRQ rising edge enable/disable bitfield
* @falling_edge: GPIO IRQ falling edge enable/disable bitfield
* @clk: clock resource for this driver
*/
struct xgpio_instance {
struct gpio_chip gc;
void __iomem *regs;
unsigned int gpio_width[2];
u32 gpio_state[2];
u32 gpio_last_irq_read[2];
u32 gpio_dir[2];
DECLARE_BITMAP(hw_map, 64);
DECLARE_BITMAP(sw_map, 64);
DECLARE_BITMAP(state, 64);
DECLARE_BITMAP(last_irq_read, 64);
DECLARE_BITMAP(dir, 64);
spinlock_t gpio_lock; /* For serializing operations */
int irq;
struct irq_chip irqchip;
u32 irq_enable[2];
u32 irq_rising_edge[2];
u32 irq_falling_edge[2];
DECLARE_BITMAP(enable, 64);
DECLARE_BITMAP(rising_edge, 64);
DECLARE_BITMAP(falling_edge, 64);
struct clk *clk;
};
static inline int xgpio_index(struct xgpio_instance *chip, int gpio)
static inline int xgpio_from_bit(struct xgpio_instance *chip, int bit)
{
if (gpio >= chip->gpio_width[0])
return 1;
return 0;
return bitmap_bitremap(bit, chip->hw_map, chip->sw_map, 64);
}
static inline int xgpio_regoffset(struct xgpio_instance *chip, int gpio)
static inline int xgpio_to_bit(struct xgpio_instance *chip, int gpio)
{
if (xgpio_index(chip, gpio))
return XGPIO_CHANNEL_OFFSET;
return 0;
return bitmap_bitremap(gpio, chip->sw_map, chip->hw_map, 64);
}
static inline int xgpio_offset(struct xgpio_instance *chip, int gpio)
static inline u32 xgpio_get_value32(const unsigned long *map, int bit)
{
if (xgpio_index(chip, gpio))
return gpio - chip->gpio_width[0];
const size_t index = BIT_WORD(bit);
const unsigned long offset = (bit % BITS_PER_LONG) & BIT(5);
return gpio;
return (map[index] >> offset) & 0xFFFFFFFFul;
}
static inline void xgpio_set_value32(unsigned long *map, int bit, u32 v)
{
const size_t index = BIT_WORD(bit);
const unsigned long offset = (bit % BITS_PER_LONG) & BIT(5);
map[index] &= ~(0xFFFFFFFFul << offset);
map[index] |= v << offset;
}
static inline int xgpio_regoffset(struct xgpio_instance *chip, int ch)
{
switch (ch) {
case 0:
return XGPIO_CHANNEL0_OFFSET;
case 1:
return XGPIO_CHANNEL1_OFFSET;
default:
return -EINVAL;
}
}
static void xgpio_read_ch(struct xgpio_instance *chip, int reg, int bit, unsigned long *a)
{
void __iomem *addr = chip->regs + reg + xgpio_regoffset(chip, bit / 32);
xgpio_set_value32(a, bit, xgpio_readreg(addr));
}
static void xgpio_write_ch(struct xgpio_instance *chip, int reg, int bit, unsigned long *a)
{
void __iomem *addr = chip->regs + reg + xgpio_regoffset(chip, bit / 32);
xgpio_writereg(addr, xgpio_get_value32(a, bit));
}
static void xgpio_read_ch_all(struct xgpio_instance *chip, int reg, unsigned long *a)
{
int bit, lastbit = xgpio_to_bit(chip, chip->gc.ngpio - 1);
for (bit = 0; bit <= lastbit ; bit += 32)
xgpio_read_ch(chip, reg, bit, a);
}
static void xgpio_write_ch_all(struct xgpio_instance *chip, int reg, unsigned long *a)
{
int bit, lastbit = xgpio_to_bit(chip, chip->gc.ngpio - 1);
for (bit = 0; bit <= lastbit ; bit += 32)
xgpio_write_ch(chip, reg, bit, a);
}
/**
@ -109,12 +156,12 @@ static inline int xgpio_offset(struct xgpio_instance *chip, int gpio)
static int xgpio_get(struct gpio_chip *gc, unsigned int gpio)
{
struct xgpio_instance *chip = gpiochip_get_data(gc);
u32 val;
int bit = xgpio_to_bit(chip, gpio);
DECLARE_BITMAP(state, 64);
val = xgpio_readreg(chip->regs + XGPIO_DATA_OFFSET +
xgpio_regoffset(chip, gpio));
xgpio_read_ch(chip, XGPIO_DATA_OFFSET, bit, state);
return !!(val & BIT(xgpio_offset(chip, gpio)));
return test_bit(bit, state);
}
/**
@ -130,19 +177,14 @@ static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
{
unsigned long flags;
struct xgpio_instance *chip = gpiochip_get_data(gc);
int index = xgpio_index(chip, gpio);
int offset = xgpio_offset(chip, gpio);
int bit = xgpio_to_bit(chip, gpio);
spin_lock_irqsave(&chip->gpio_lock, flags);
/* Write to GPIO signal and set its direction to output */
if (val)
chip->gpio_state[index] |= BIT(offset);
else
chip->gpio_state[index] &= ~BIT(offset);
__assign_bit(bit, chip->state, val);
xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
xgpio_regoffset(chip, gpio), chip->gpio_state[index]);
xgpio_write_ch(chip, XGPIO_DATA_OFFSET, bit, chip->state);
spin_unlock_irqrestore(&chip->gpio_lock, flags);
}
@ -159,37 +201,22 @@ static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
unsigned long *bits)
{
DECLARE_BITMAP(hw_mask, 64);
DECLARE_BITMAP(hw_bits, 64);
DECLARE_BITMAP(state, 64);
unsigned long flags;
struct xgpio_instance *chip = gpiochip_get_data(gc);
int index = xgpio_index(chip, 0);
int offset, i;
bitmap_remap(hw_mask, mask, chip->sw_map, chip->hw_map, 64);
bitmap_remap(hw_bits, bits, chip->sw_map, chip->hw_map, 64);
spin_lock_irqsave(&chip->gpio_lock, flags);
/* Write to GPIO signals */
for (i = 0; i < gc->ngpio; i++) {
if (*mask == 0)
break;
/* Once finished with an index write it out to the register */
if (index != xgpio_index(chip, i)) {
xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
index * XGPIO_CHANNEL_OFFSET,
chip->gpio_state[index]);
spin_unlock_irqrestore(&chip->gpio_lock, flags);
index = xgpio_index(chip, i);
spin_lock_irqsave(&chip->gpio_lock, flags);
}
if (__test_and_clear_bit(i, mask)) {
offset = xgpio_offset(chip, i);
if (test_bit(i, bits))
chip->gpio_state[index] |= BIT(offset);
else
chip->gpio_state[index] &= ~BIT(offset);
}
}
bitmap_replace(state, chip->state, hw_bits, hw_mask, 64);
xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
index * XGPIO_CHANNEL_OFFSET, chip->gpio_state[index]);
xgpio_write_ch_all(chip, XGPIO_DATA_OFFSET, state);
bitmap_copy(chip->state, state, 64);
spin_unlock_irqrestore(&chip->gpio_lock, flags);
}
@ -207,15 +234,13 @@ static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
{
unsigned long flags;
struct xgpio_instance *chip = gpiochip_get_data(gc);
int index = xgpio_index(chip, gpio);
int offset = xgpio_offset(chip, gpio);
int bit = xgpio_to_bit(chip, gpio);
spin_lock_irqsave(&chip->gpio_lock, flags);
/* Set the GPIO bit in shadow register and set direction as input */
chip->gpio_dir[index] |= BIT(offset);
xgpio_writereg(chip->regs + XGPIO_TRI_OFFSET +
xgpio_regoffset(chip, gpio), chip->gpio_dir[index]);
__set_bit(bit, chip->dir);
xgpio_write_ch(chip, XGPIO_TRI_OFFSET, bit, chip->dir);
spin_unlock_irqrestore(&chip->gpio_lock, flags);
@ -238,23 +263,17 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
{
unsigned long flags;
struct xgpio_instance *chip = gpiochip_get_data(gc);
int index = xgpio_index(chip, gpio);
int offset = xgpio_offset(chip, gpio);
int bit = xgpio_to_bit(chip, gpio);
spin_lock_irqsave(&chip->gpio_lock, flags);
/* Write state of GPIO signal */
if (val)
chip->gpio_state[index] |= BIT(offset);
else
chip->gpio_state[index] &= ~BIT(offset);
xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
xgpio_regoffset(chip, gpio), chip->gpio_state[index]);
__assign_bit(bit, chip->state, val);
xgpio_write_ch(chip, XGPIO_DATA_OFFSET, bit, chip->state);
/* Clear the GPIO bit in shadow register and set direction as output */
chip->gpio_dir[index] &= ~BIT(offset);
xgpio_writereg(chip->regs + XGPIO_TRI_OFFSET +
xgpio_regoffset(chip, gpio), chip->gpio_dir[index]);
__clear_bit(bit, chip->dir);
xgpio_write_ch(chip, XGPIO_TRI_OFFSET, bit, chip->dir);
spin_unlock_irqrestore(&chip->gpio_lock, flags);
@ -267,16 +286,8 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
*/
static void xgpio_save_regs(struct xgpio_instance *chip)
{
xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET, chip->gpio_state[0]);
xgpio_writereg(chip->regs + XGPIO_TRI_OFFSET, chip->gpio_dir[0]);
if (!chip->gpio_width[1])
return;
xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET + XGPIO_CHANNEL_OFFSET,
chip->gpio_state[1]);
xgpio_writereg(chip->regs + XGPIO_TRI_OFFSET + XGPIO_CHANNEL_OFFSET,
chip->gpio_dir[1]);
xgpio_write_ch_all(chip, XGPIO_DATA_OFFSET, chip->state);
xgpio_write_ch_all(chip, XGPIO_TRI_OFFSET, chip->dir);
}
static int xgpio_request(struct gpio_chip *chip, unsigned int offset)
@ -302,8 +313,8 @@ static int __maybe_unused xgpio_suspend(struct device *dev)
struct irq_data *data = irq_get_irq_data(gpio->irq);
if (!data) {
dev_err(dev, "irq_get_irq_data() failed\n");
return -EINVAL;
dev_dbg(dev, "IRQ not connected\n");
return pm_runtime_force_suspend(dev);
}
if (!irqd_is_wakeup_set(data))
@ -348,8 +359,8 @@ static int __maybe_unused xgpio_resume(struct device *dev)
struct irq_data *data = irq_get_irq_data(gpio->irq);
if (!data) {
dev_err(dev, "irq_get_irq_data() failed\n");
return -EINVAL;
dev_dbg(dev, "IRQ not connected\n");
return pm_runtime_force_resume(dev);
}
if (!irqd_is_wakeup_set(data))
@ -391,18 +402,17 @@ static void xgpio_irq_mask(struct irq_data *irq_data)
unsigned long flags;
struct xgpio_instance *chip = irq_data_get_irq_chip_data(irq_data);
int irq_offset = irqd_to_hwirq(irq_data);
int index = xgpio_index(chip, irq_offset);
int offset = xgpio_offset(chip, irq_offset);
int bit = xgpio_to_bit(chip, irq_offset);
u32 mask = BIT(bit / 32), temp;
spin_lock_irqsave(&chip->gpio_lock, flags);
chip->irq_enable[index] &= ~BIT(offset);
__clear_bit(bit, chip->enable);
if (!chip->irq_enable[index]) {
if (xgpio_get_value32(chip->enable, bit) == 0) {
/* Disable per channel interrupt */
u32 temp = xgpio_readreg(chip->regs + XGPIO_IPIER_OFFSET);
temp &= ~BIT(index);
temp = xgpio_readreg(chip->regs + XGPIO_IPIER_OFFSET);
temp &= ~mask;
xgpio_writereg(chip->regs + XGPIO_IPIER_OFFSET, temp);
}
spin_unlock_irqrestore(&chip->gpio_lock, flags);
@ -417,30 +427,26 @@ static void xgpio_irq_unmask(struct irq_data *irq_data)
unsigned long flags;
struct xgpio_instance *chip = irq_data_get_irq_chip_data(irq_data);
int irq_offset = irqd_to_hwirq(irq_data);
int index = xgpio_index(chip, irq_offset);
int offset = xgpio_offset(chip, irq_offset);
u32 old_enable = chip->irq_enable[index];
int bit = xgpio_to_bit(chip, irq_offset);
u32 old_enable = xgpio_get_value32(chip->enable, bit);
u32 mask = BIT(bit / 32), val;
spin_lock_irqsave(&chip->gpio_lock, flags);
chip->irq_enable[index] |= BIT(offset);
__set_bit(bit, chip->enable);
if (!old_enable) {
if (old_enable == 0) {
/* Clear any existing per-channel interrupts */
u32 val = xgpio_readreg(chip->regs + XGPIO_IPISR_OFFSET) &
BIT(index);
if (val)
xgpio_writereg(chip->regs + XGPIO_IPISR_OFFSET, val);
val = xgpio_readreg(chip->regs + XGPIO_IPISR_OFFSET);
val &= mask;
xgpio_writereg(chip->regs + XGPIO_IPISR_OFFSET, val);
/* Update GPIO IRQ read data before enabling interrupt*/
val = xgpio_readreg(chip->regs + XGPIO_DATA_OFFSET +
index * XGPIO_CHANNEL_OFFSET);
chip->gpio_last_irq_read[index] = val;
xgpio_read_ch(chip, XGPIO_DATA_OFFSET, bit, chip->last_irq_read);
/* Enable per channel interrupt */
val = xgpio_readreg(chip->regs + XGPIO_IPIER_OFFSET);
val |= BIT(index);
val |= mask;
xgpio_writereg(chip->regs + XGPIO_IPIER_OFFSET, val);
}
@ -459,8 +465,7 @@ static int xgpio_set_irq_type(struct irq_data *irq_data, unsigned int type)
{
struct xgpio_instance *chip = irq_data_get_irq_chip_data(irq_data);
int irq_offset = irqd_to_hwirq(irq_data);
int index = xgpio_index(chip, irq_offset);
int offset = xgpio_offset(chip, irq_offset);
int bit = xgpio_to_bit(chip, irq_offset);
/*
* The Xilinx GPIO hardware provides a single interrupt status
@ -470,16 +475,16 @@ static int xgpio_set_irq_type(struct irq_data *irq_data, unsigned int type)
*/
switch (type & IRQ_TYPE_SENSE_MASK) {
case IRQ_TYPE_EDGE_BOTH:
chip->irq_rising_edge[index] |= BIT(offset);
chip->irq_falling_edge[index] |= BIT(offset);
__set_bit(bit, chip->rising_edge);
__set_bit(bit, chip->falling_edge);
break;
case IRQ_TYPE_EDGE_RISING:
chip->irq_rising_edge[index] |= BIT(offset);
chip->irq_falling_edge[index] &= ~BIT(offset);
__set_bit(bit, chip->rising_edge);
__clear_bit(bit, chip->falling_edge);
break;
case IRQ_TYPE_EDGE_FALLING:
chip->irq_rising_edge[index] &= ~BIT(offset);
chip->irq_falling_edge[index] |= BIT(offset);
__clear_bit(bit, chip->rising_edge);
__set_bit(bit, chip->falling_edge);
break;
default:
return -EINVAL;
@ -496,46 +501,44 @@ static int xgpio_set_irq_type(struct irq_data *irq_data, unsigned int type)
static void xgpio_irqhandler(struct irq_desc *desc)
{
struct xgpio_instance *chip = irq_desc_get_handler_data(desc);
struct gpio_chip *gc = &chip->gc;
struct irq_chip *irqchip = irq_desc_get_chip(desc);
u32 num_channels = chip->gpio_width[1] ? 2 : 1;
u32 offset = 0, index;
u32 status = xgpio_readreg(chip->regs + XGPIO_IPISR_OFFSET);
DECLARE_BITMAP(rising, 64);
DECLARE_BITMAP(falling, 64);
DECLARE_BITMAP(all, 64);
int irq_offset;
u32 status;
u32 bit;
status = xgpio_readreg(chip->regs + XGPIO_IPISR_OFFSET);
xgpio_writereg(chip->regs + XGPIO_IPISR_OFFSET, status);
chained_irq_enter(irqchip, desc);
for (index = 0; index < num_channels; index++) {
if ((status & BIT(index))) {
unsigned long rising_events, falling_events, all_events;
unsigned long flags;
u32 data, bit;
unsigned int irq;
spin_lock_irqsave(&chip->gpio_lock, flags);
data = xgpio_readreg(chip->regs + XGPIO_DATA_OFFSET +
index * XGPIO_CHANNEL_OFFSET);
rising_events = data &
~chip->gpio_last_irq_read[index] &
chip->irq_enable[index] &
chip->irq_rising_edge[index];
falling_events = ~data &
chip->gpio_last_irq_read[index] &
chip->irq_enable[index] &
chip->irq_falling_edge[index];
dev_dbg(chip->gc.parent,
"IRQ chan %u rising 0x%lx falling 0x%lx\n",
index, rising_events, falling_events);
all_events = rising_events | falling_events;
chip->gpio_last_irq_read[index] = data;
spin_unlock_irqrestore(&chip->gpio_lock, flags);
spin_lock(&chip->gpio_lock);
for_each_set_bit(bit, &all_events, 32) {
irq = irq_find_mapping(chip->gc.irq.domain,
offset + bit);
generic_handle_irq(irq);
}
}
offset += chip->gpio_width[index];
xgpio_read_ch_all(chip, XGPIO_DATA_OFFSET, all);
bitmap_complement(rising, chip->last_irq_read, 64);
bitmap_and(rising, rising, all, 64);
bitmap_and(rising, rising, chip->enable, 64);
bitmap_and(rising, rising, chip->rising_edge, 64);
bitmap_complement(falling, all, 64);
bitmap_and(falling, falling, chip->last_irq_read, 64);
bitmap_and(falling, falling, chip->enable, 64);
bitmap_and(falling, falling, chip->falling_edge, 64);
bitmap_copy(chip->last_irq_read, all, 64);
bitmap_or(all, rising, falling, 64);
spin_unlock(&chip->gpio_lock);
dev_dbg(gc->parent, "IRQ rising %*pb falling %*pb\n", 64, rising, 64, falling);
for_each_set_bit(bit, all, 64) {
irq_offset = xgpio_from_bit(chip, bit);
generic_handle_irq(irq_find_mapping(gc->irq.domain, irq_offset));
}
chained_irq_exit(irqchip, desc);
@ -556,6 +559,9 @@ static int xgpio_probe(struct platform_device *pdev)
struct device_node *np = pdev->dev.of_node;
u32 is_dual = 0;
u32 cells = 2;
u32 width[2];
u32 state[2];
u32 dir[2];
struct gpio_irq_chip *girq;
u32 temp;
@ -565,13 +571,25 @@ static int xgpio_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, chip);
/* First, check if the device is dual-channel */
of_property_read_u32(np, "xlnx,is-dual", &is_dual);
/* Setup defaults */
memset32(width, 0, ARRAY_SIZE(width));
memset32(state, 0, ARRAY_SIZE(state));
memset32(dir, 0xFFFFFFFF, ARRAY_SIZE(dir));
/* Update GPIO state shadow register with default value */
if (of_property_read_u32(np, "xlnx,dout-default", &chip->gpio_state[0]))
chip->gpio_state[0] = 0x0;
of_property_read_u32(np, "xlnx,dout-default", &state[0]);
of_property_read_u32(np, "xlnx,dout-default-2", &state[1]);
bitmap_from_arr32(chip->state, state, 64);
/* Update GPIO direction shadow register with default value */
if (of_property_read_u32(np, "xlnx,tri-default", &chip->gpio_dir[0]))
chip->gpio_dir[0] = 0xFFFFFFFF;
of_property_read_u32(np, "xlnx,tri-default", &dir[0]);
of_property_read_u32(np, "xlnx,tri-default-2", &dir[1]);
bitmap_from_arr32(chip->dir, dir, 64);
/* Update cells with gpio-cells value */
if (of_property_read_u32(np, "#gpio-cells", &cells))
@ -586,42 +604,29 @@ static int xgpio_probe(struct platform_device *pdev)
* Check device node and parent device node for device width
* and assume default width of 32
*/
if (of_property_read_u32(np, "xlnx,gpio-width", &chip->gpio_width[0]))
chip->gpio_width[0] = 32;
if (of_property_read_u32(np, "xlnx,gpio-width", &width[0]))
width[0] = 32;
if (chip->gpio_width[0] > 32)
if (width[0] > 32)
return -EINVAL;
if (is_dual && of_property_read_u32(np, "xlnx,gpio2-width", &width[1]))
width[1] = 32;
if (width[1] > 32)
return -EINVAL;
/* Setup software pin mapping */
bitmap_set(chip->sw_map, 0, width[0] + width[1]);
/* Setup hardware pin mapping */
bitmap_set(chip->hw_map, 0, width[0]);
bitmap_set(chip->hw_map, 32, width[1]);
spin_lock_init(&chip->gpio_lock);
if (of_property_read_u32(np, "xlnx,is-dual", &is_dual))
is_dual = 0;
if (is_dual) {
/* Update GPIO state shadow register with default value */
if (of_property_read_u32(np, "xlnx,dout-default-2",
&chip->gpio_state[1]))
chip->gpio_state[1] = 0x0;
/* Update GPIO direction shadow register with default value */
if (of_property_read_u32(np, "xlnx,tri-default-2",
&chip->gpio_dir[1]))
chip->gpio_dir[1] = 0xFFFFFFFF;
/*
* Check device node and parent device node for device width
* and assume default width of 32
*/
if (of_property_read_u32(np, "xlnx,gpio2-width",
&chip->gpio_width[1]))
chip->gpio_width[1] = 32;
if (chip->gpio_width[1] > 32)
return -EINVAL;
}
chip->gc.base = -1;
chip->gc.ngpio = chip->gpio_width[0] + chip->gpio_width[1];
chip->gc.ngpio = bitmap_weight(chip->hw_map, 64);
chip->gc.parent = &pdev->dev;
chip->gc.direction_input = xgpio_dir_in;
chip->gc.direction_output = xgpio_dir_out;

View File

@ -736,6 +736,11 @@ static int __maybe_unused zynq_gpio_suspend(struct device *dev)
struct zynq_gpio *gpio = dev_get_drvdata(dev);
struct irq_data *data = irq_get_irq_data(gpio->irq);
if (!data) {
dev_err(dev, "irq_get_irq_data() failed\n");
return -EINVAL;
}
if (!device_may_wakeup(dev))
disable_irq(gpio->irq);
@ -753,6 +758,11 @@ static int __maybe_unused zynq_gpio_resume(struct device *dev)
struct irq_data *data = irq_get_irq_data(gpio->irq);
int ret;
if (!data) {
dev_err(dev, "irq_get_irq_data() failed\n");
return -EINVAL;
}
if (!device_may_wakeup(dev))
enable_irq(gpio->irq);
@ -1001,8 +1011,11 @@ err_pm_dis:
static int zynq_gpio_remove(struct platform_device *pdev)
{
struct zynq_gpio *gpio = platform_get_drvdata(pdev);
int ret;
pm_runtime_get_sync(&pdev->dev);
ret = pm_runtime_get_sync(&pdev->dev);
if (ret < 0)
dev_warn(&pdev->dev, "pm_runtime_get_sync() Failed\n");
gpiochip_remove(&gpio->chip);
clk_disable_unprepare(gpio->clk);
device_set_wakeup_capable(&pdev->dev, 0);
@ -1020,22 +1033,7 @@ static struct platform_driver zynq_gpio_driver = {
.remove = zynq_gpio_remove,
};
/**
* zynq_gpio_init - Initial driver registration call
*
* Return: value from platform_driver_register
*/
static int __init zynq_gpio_init(void)
{
return platform_driver_register(&zynq_gpio_driver);
}
postcore_initcall(zynq_gpio_init);
static void __exit zynq_gpio_exit(void)
{
platform_driver_unregister(&zynq_gpio_driver);
}
module_exit(zynq_gpio_exit);
module_platform_driver(zynq_gpio_driver);
MODULE_AUTHOR("Xilinx Inc.");
MODULE_DESCRIPTION("Zynq GPIO driver");

View File

@ -66,9 +66,8 @@ static ssize_t direction_show(struct device *dev,
mutex_lock(&data->mutex);
gpiod_get_direction(desc);
status = sprintf(buf, "%s\n",
test_bit(FLAG_IS_OUT, &desc->flags)
? "out" : "in");
status = sysfs_emit(buf, "%s\n",
test_bit(FLAG_IS_OUT, &desc->flags) ? "out" : "in");
mutex_unlock(&data->mutex);
@ -109,13 +108,9 @@ static ssize_t value_show(struct device *dev,
mutex_lock(&data->mutex);
status = gpiod_get_value_cansleep(desc);
if (status < 0)
goto err;
if (status >= 0)
status = sysfs_emit(buf, "%zd\n", status);
buf[0] = '0' + status;
buf[1] = '\n';
status = 2;
err:
mutex_unlock(&data->mutex);
return status;
@ -249,11 +244,11 @@ static ssize_t edge_show(struct device *dev,
mutex_lock(&data->mutex);
for (i = 0; i < ARRAY_SIZE(trigger_types); i++) {
if (data->irq_flags == trigger_types[i].flags) {
status = sprintf(buf, "%s\n", trigger_types[i].name);
if (data->irq_flags == trigger_types[i].flags)
break;
}
}
if (i < ARRAY_SIZE(trigger_types))
status = sysfs_emit(buf, "%s\n", trigger_types[i].name);
mutex_unlock(&data->mutex);
@ -312,10 +307,7 @@ static int gpio_sysfs_set_active_low(struct device *dev, int value)
if (!!test_bit(FLAG_ACTIVE_LOW, &desc->flags) == !!value)
return 0;
if (value)
set_bit(FLAG_ACTIVE_LOW, &desc->flags);
else
clear_bit(FLAG_ACTIVE_LOW, &desc->flags);
assign_bit(FLAG_ACTIVE_LOW, &desc->flags, value);
/* reconfigure poll(2) support if enabled on one edge only */
if (flags == GPIO_IRQF_TRIGGER_FALLING ||
@ -336,8 +328,8 @@ static ssize_t active_low_show(struct device *dev,
mutex_lock(&data->mutex);
status = sprintf(buf, "%d\n",
!!test_bit(FLAG_ACTIVE_LOW, &desc->flags));
status = sysfs_emit(buf, "%d\n",
!!test_bit(FLAG_ACTIVE_LOW, &desc->flags));
mutex_unlock(&data->mutex);
@ -415,7 +407,7 @@ static ssize_t base_show(struct device *dev,
{
const struct gpio_chip *chip = dev_get_drvdata(dev);
return sprintf(buf, "%d\n", chip->base);
return sysfs_emit(buf, "%d\n", chip->base);
}
static DEVICE_ATTR_RO(base);
@ -424,7 +416,7 @@ static ssize_t label_show(struct device *dev,
{
const struct gpio_chip *chip = dev_get_drvdata(dev);
return sprintf(buf, "%s\n", chip->label ? : "");
return sysfs_emit(buf, "%s\n", chip->label ?: "");
}
static DEVICE_ATTR_RO(label);
@ -433,7 +425,7 @@ static ssize_t ngpio_show(struct device *dev,
{
const struct gpio_chip *chip = dev_get_drvdata(dev);
return sprintf(buf, "%u\n", chip->ngpio);
return sysfs_emit(buf, "%u\n", chip->ngpio);
}
static DEVICE_ATTR_RO(ngpio);

View File

@ -2004,9 +2004,6 @@ const char *gpiochip_is_requested(struct gpio_chip *gc, unsigned int offset)
{
struct gpio_desc *desc;
if (offset >= gc->ngpio)
return NULL;
desc = gpiochip_get_desc(gc, offset);
if (IS_ERR(desc))
return NULL;
@ -2543,21 +2540,28 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
while (i < array_size) {
struct gpio_chip *gc = desc_array[i]->gdev->chip;
unsigned long fastpath[2 * BITS_TO_LONGS(FASTPATH_NGPIO)];
DECLARE_BITMAP(fastpath_mask, FASTPATH_NGPIO);
DECLARE_BITMAP(fastpath_bits, FASTPATH_NGPIO);
unsigned long *mask, *bits;
int first, j;
if (likely(gc->ngpio <= FASTPATH_NGPIO)) {
mask = fastpath;
mask = fastpath_mask;
bits = fastpath_bits;
} else {
mask = kmalloc_array(2 * BITS_TO_LONGS(gc->ngpio),
sizeof(*mask),
can_sleep ? GFP_KERNEL : GFP_ATOMIC);
gfp_t flags = can_sleep ? GFP_KERNEL : GFP_ATOMIC;
mask = bitmap_alloc(gc->ngpio, flags);
if (!mask)
return -ENOMEM;
bits = bitmap_alloc(gc->ngpio, flags);
if (!bits) {
bitmap_free(mask);
return -ENOMEM;
}
}
bits = mask + BITS_TO_LONGS(gc->ngpio);
bitmap_zero(mask, gc->ngpio);
if (!can_sleep)
@ -2580,8 +2584,10 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
ret = gpio_chip_get_multiple(gc, mask, bits);
if (ret) {
if (mask != fastpath)
kfree(mask);
if (mask != fastpath_mask)
bitmap_free(mask);
if (bits != fastpath_bits)
bitmap_free(bits);
return ret;
}
@ -2601,8 +2607,10 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
j);
}
if (mask != fastpath)
kfree(mask);
if (mask != fastpath_mask)
bitmap_free(mask);
if (bits != fastpath_bits)
bitmap_free(bits);
}
return 0;
}
@ -2826,21 +2834,28 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
while (i < array_size) {
struct gpio_chip *gc = desc_array[i]->gdev->chip;
unsigned long fastpath[2 * BITS_TO_LONGS(FASTPATH_NGPIO)];
DECLARE_BITMAP(fastpath_mask, FASTPATH_NGPIO);
DECLARE_BITMAP(fastpath_bits, FASTPATH_NGPIO);
unsigned long *mask, *bits;
int count = 0;
if (likely(gc->ngpio <= FASTPATH_NGPIO)) {
mask = fastpath;
mask = fastpath_mask;
bits = fastpath_bits;
} else {
mask = kmalloc_array(2 * BITS_TO_LONGS(gc->ngpio),
sizeof(*mask),
can_sleep ? GFP_KERNEL : GFP_ATOMIC);
gfp_t flags = can_sleep ? GFP_KERNEL : GFP_ATOMIC;
mask = bitmap_alloc(gc->ngpio, flags);
if (!mask)
return -ENOMEM;
bits = bitmap_alloc(gc->ngpio, flags);
if (!bits) {
bitmap_free(mask);
return -ENOMEM;
}
}
bits = mask + BITS_TO_LONGS(gc->ngpio);
bitmap_zero(mask, gc->ngpio);
if (!can_sleep)
@ -2885,8 +2900,10 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
if (count != 0)
gpio_chip_set_multiple(gc, mask, bits);
if (mask != fastpath)
kfree(mask);
if (mask != fastpath_mask)
bitmap_free(mask);
if (bits != fastpath_bits)
bitmap_free(bits);
}
return 0;
}

View File

@ -37,6 +37,9 @@ struct regmap;
* offset to a register/bitmask pair. If not
* given the default gpio_regmap_simple_xlate()
* is used.
* @drvdata: (Optional) Pointer to driver specific data which is
* not used by gpio-remap but is provided "as is" to the
* driver callback(s).
*
* The ->reg_mask_xlate translates a given base address and GPIO offset to
* register and mask pair. The base address is one of the given register
@ -78,13 +81,14 @@ struct gpio_regmap_config {
int (*reg_mask_xlate)(struct gpio_regmap *gpio, unsigned int base,
unsigned int offset, unsigned int *reg,
unsigned int *mask);
void *drvdata;
};
struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config);
void gpio_regmap_unregister(struct gpio_regmap *gpio);
struct gpio_regmap *devm_gpio_regmap_register(struct device *dev,
const struct gpio_regmap_config *config);
void gpio_regmap_set_drvdata(struct gpio_regmap *gpio, void *data);
void *gpio_regmap_get_drvdata(struct gpio_regmap *gpio);
#endif /* _LINUX_GPIO_REGMAP_H */

View File

@ -793,8 +793,6 @@ int bitmap_parse(const char *start, unsigned int buflen,
}
EXPORT_SYMBOL(bitmap_parse);
#ifdef CONFIG_NUMA
/**
* bitmap_pos_to_ord - find ordinal of set bit at given position in bitmap
* @buf: pointer to a bitmap
@ -903,6 +901,7 @@ void bitmap_remap(unsigned long *dst, const unsigned long *src,
set_bit(bitmap_ord_to_pos(new, n % w, nbits), dst);
}
}
EXPORT_SYMBOL(bitmap_remap);
/**
* bitmap_bitremap - Apply map defined by a pair of bitmaps to a single bit
@ -940,7 +939,9 @@ int bitmap_bitremap(int oldbit, const unsigned long *old,
else
return bitmap_ord_to_pos(new, n % w, bits);
}
EXPORT_SYMBOL(bitmap_bitremap);
#ifdef CONFIG_NUMA
/**
* bitmap_onto - translate one bitmap relative to another
* @dst: resulting translated bitmap