Commit 70b8e9eb authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'gpio-v4.14-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio

Pull GPIO updates from Linus Walleij:
 "This is the bulk of the GPIO changes for the v4.14 cycle.

  Not so much changes this time, phew. David Daney and Bartosz
  Golaszewski did all the really interesting work in infrastructure
  improvement across GPIO and IRQ core, hats off for them and to tglx
  and Marc Z for general help with these patch sets.

  Core changes:

   - Allow the GPIO irqchip to allocate IRQs dynamically. This is an
     important change on systems where only a restricted number of IRQs,
     lesser than the number of GPIO lines, can be utilized. Now we can
     allocate these on a first-come-first-served basis instead of
     hogging up valuable IRQ lines.

   - Serious fix-up of the kerneldoc documentation and inclusion into
     the kerneldoc builds.

   - Pulled in the IRQ simulator from the IRQ core tree and use this in
     the GPIO mockup driver for exhaustive testing of interrupt
     abilities.

  New drivers:

   - New driver for ThunderX and OCTEON-TX. This is especially
     interesting as it picks up improvements from the IRQ core that
     allow us to handle fasteoi ACKs upwards in a hierarchy when there
     are IRQ flag latches on several levels in a hierarchy. Very
     interesting work here.

   - New subdriver for Renesas R-Car r8a7745 (RZ/G1E).

  Misc:

   - Several fixes and improvements for Xilinx Zynq GPIO.

   - Support an enablement GPIO for the 74x164 GPIO.

   - Switch a bunch of chips to use devres to allocate irq descriptors.

   - A bunch of constification fixes"

* tag 'gpio-v4.14-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio: (63 commits)
  gpio: mockup: remove unused variable gc
  gpio: pl061: constify amba_id
  Revert "gpiolib: request the gpio before querying its direction"
  gpio: twl6040: remove unneeded forward declaration
  gpio: zevio: make gpio_chip const
  gpio: add gpio_add_lookup_tables() to add several tables at once
  gpio: rcar: Add r8a7745 (RZ/G1E) support
  gpio: brcmstb: check return value of gpiochip_irqchip_add()
  MAINTAINERS: Add entry for THUNDERX GPIO Driver.
  gpio: Add gpio driver support for ThunderX and OCTEON-TX
  gpio: mockup: use irq_sim
  gpio: mxs: use devres for irq generic chip
  gpio: mxc: use devres for irq generic chip
  gpio: pch: use devres for irq generic chip
  gpio: ml-ioh: use devres for irq generic chip
  gpio: sta2x11: use devres for irq generic chip
  gpio: sta2x11: disallow unbinding the driver
  gpio: mxs: disallow unbinding the driver
  gpio: mxc: disallow unbinding the driver
  gpio: aspeed: Remove reference to clock name in debounce warning message
  ...
parents d16605c9 02b6bddb
...@@ -12,6 +12,9 @@ Required properties: ...@@ -12,6 +12,9 @@ Required properties:
1 = active low 1 = active low
- registers-number: Number of daisy-chained shift registers - registers-number: Number of daisy-chained shift registers
Optional properties:
- enable-gpios: GPIO connected to the OE (Output Enable) pin.
Example: Example:
gpio5: gpio5@0 { gpio5: gpio5@0 {
......
...@@ -18,7 +18,7 @@ Required properties: ...@@ -18,7 +18,7 @@ Required properties:
Optional properties: Optional properties:
- interrupt-parent : The parent interrupt controller, optional if inherited - interrupt-parent : The parent interrupt controller, optional if inherited
- clocks : A phandle to the HPLL clock node for debounce timings - clocks : A phandle to the clock to use for debounce timings
The gpio and interrupt properties are further described in their respective The gpio and interrupt properties are further described in their respective
bindings documentation: bindings documentation:
......
Davinci/Keystone GPIO controller bindings Davinci/Keystone GPIO controller bindings
Required Properties: Required Properties:
- compatible: should be "ti,dm6441-gpio", "ti,keystone-gpio" - 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
- reg: Physical base address of the controller and the size of memory mapped - reg: Physical base address of the controller and the size of memory mapped
registers. registers.
...@@ -20,7 +23,21 @@ Required Properties: ...@@ -20,7 +23,21 @@ Required Properties:
- ti,ngpio: The number of GPIO pins supported. - ti,ngpio: The number of GPIO pins supported.
- ti,davinci-gpio-unbanked: The number of GPIOs that have an individual interrupt - ti,davinci-gpio-unbanked: The number of GPIOs that have an individual interrupt
line to processor. 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.txt
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 The GPIO controller also acts as an interrupt controller. It uses the default
two cells specifier as described in Documentation/devicetree/bindings/ two cells specifier as described in Documentation/devicetree/bindings/
...@@ -60,3 +77,73 @@ leds { ...@@ -60,3 +77,73 @@ leds {
... ...
}; };
}; };
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>;
};
...@@ -5,7 +5,9 @@ functionality. Each pair serves 32 GPIOs. The VF610 has 5 instances of ...@@ -5,7 +5,9 @@ functionality. Each pair serves 32 GPIOs. The VF610 has 5 instances of
each, and each PORT module has its own interrupt. each, and each PORT module has its own interrupt.
Required properties for GPIO node: Required properties for GPIO node:
- compatible : Should be "fsl,<soc>-gpio", currently "fsl,vf610-gpio" - compatible : Should be "fsl,<soc>-gpio", below is supported list:
"fsl,vf610-gpio"
"fsl,imx7ulp-gpio"
- reg : The first reg tuple represents the PORT module, the second tuple - reg : The first reg tuple represents the PORT module, the second tuple
the GPIO module. the GPIO module.
- interrupts : Should be the port interrupt shared by all 32 pins. - interrupts : Should be the port interrupt shared by all 32 pins.
......
...@@ -2,8 +2,9 @@ ...@@ -2,8 +2,9 @@
Required Properties: Required Properties:
- compatible: should contain one of the following. - compatible: should contain one or more of the following:
- "renesas,gpio-r8a7743": for R8A7743 (RZ/G1M) compatible GPIO controller. - "renesas,gpio-r8a7743": for R8A7743 (RZ/G1M) compatible GPIO controller.
- "renesas,gpio-r8a7745": for R8A7745 (RZ/G1E) compatible GPIO controller.
- "renesas,gpio-r8a7778": for R8A7778 (R-Mobile M1) compatible GPIO controller. - "renesas,gpio-r8a7778": for R8A7778 (R-Mobile M1) compatible GPIO controller.
- "renesas,gpio-r8a7779": for R8A7779 (R-Car H1) compatible GPIO controller. - "renesas,gpio-r8a7779": for R8A7779 (R-Car H1) compatible GPIO controller.
- "renesas,gpio-r8a7790": for R8A7790 (R-Car H2) compatible GPIO controller. - "renesas,gpio-r8a7790": for R8A7790 (R-Car H2) compatible GPIO controller.
...@@ -13,7 +14,14 @@ Required Properties: ...@@ -13,7 +14,14 @@ Required Properties:
- "renesas,gpio-r8a7794": for R8A7794 (R-Car E2) compatible GPIO controller. - "renesas,gpio-r8a7794": for R8A7794 (R-Car E2) compatible GPIO controller.
- "renesas,gpio-r8a7795": for R8A7795 (R-Car H3) compatible GPIO controller. - "renesas,gpio-r8a7795": for R8A7795 (R-Car H3) compatible GPIO controller.
- "renesas,gpio-r8a7796": for R8A7796 (R-Car M3-W) compatible GPIO controller. - "renesas,gpio-r8a7796": for R8A7796 (R-Car M3-W) compatible GPIO controller.
- "renesas,gpio-rcar": for generic R-Car GPIO controller. - "renesas,rcar-gen1-gpio": for a generic R-Car Gen1 GPIO controller.
- "renesas,rcar-gen2-gpio": for a generic R-Car Gen2 or RZ/G1 GPIO controller.
- "renesas,rcar-gen3-gpio": for a generic R-Car Gen3 GPIO controller.
- "renesas,gpio-rcar": deprecated.
When compatible with the generic version nodes must list the
SoC-specific version corresponding to the platform first followed by
the generic version.
- reg: Base address and length of each memory resource used by the GPIO - reg: Base address and length of each memory resource used by the GPIO
controller hardware module. controller hardware module.
...@@ -43,7 +51,7 @@ interrupt-controller/interrupts.txt. ...@@ -43,7 +51,7 @@ interrupt-controller/interrupts.txt.
Example: R8A7779 (R-Car H1) GPIO controller nodes Example: R8A7779 (R-Car H1) GPIO controller nodes
gpio0: gpio@ffc40000 { gpio0: gpio@ffc40000 {
compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; compatible = "renesas,gpio-r8a7779", "renesas,rcar-gen1-gpio";
reg = <0xffc40000 0x2c>; reg = <0xffc40000 0x2c>;
interrupt-parent = <&gic>; interrupt-parent = <&gic>;
interrupts = <0 141 0x4>; interrupts = <0 141 0x4>;
...@@ -55,7 +63,7 @@ Example: R8A7779 (R-Car H1) GPIO controller nodes ...@@ -55,7 +63,7 @@ Example: R8A7779 (R-Car H1) GPIO controller nodes
}; };
... ...
gpio6: gpio@ffc46000 { gpio6: gpio@ffc46000 {
compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; compatible = "renesas,gpio-r8a7779", "renesas,rcar-gen1-gpio";
reg = <0xffc46000 0x2c>; reg = <0xffc46000 0x2c>;
interrupt-parent = <&gic>; interrupt-parent = <&gic>;
interrupts = <0 147 0x4>; interrupts = <0 147 0x4>;
......
===================================
General Purpose Input/Output (GPIO)
===================================
Core
====
.. kernel-doc:: include/linux/gpio/driver.h
:internal:
.. kernel-doc:: drivers/gpio/gpiolib.c
:export:
Legacy API
==========
The functions listed in this section are deprecated. The GPIO descriptor based
API described above should be used in new code.
.. kernel-doc:: drivers/gpio/gpiolib-legacy.c
:export:
ACPI support
============
.. kernel-doc:: drivers/gpio/gpiolib-acpi.c
:export:
Device tree support
===================
.. kernel-doc:: drivers/gpio/gpiolib-of.c
:export:
Device-managed API
==================
.. kernel-doc:: drivers/gpio/devres.c
:export:
sysfs helpers
=============
.. kernel-doc:: drivers/gpio/gpiolib-sysfs.c
:export:
...@@ -44,6 +44,7 @@ available subsections can be seen below. ...@@ -44,6 +44,7 @@ available subsections can be seen below.
uio-howto uio-howto
firmware/index firmware/index
pinctl pinctl
gpio
misc_devices misc_devices
.. only:: subproject and html .. only:: subproject and html
......
...@@ -13018,6 +13018,11 @@ M: Yehezkel Bernat <yehezkel.bernat@intel.com> ...@@ -13018,6 +13018,11 @@ M: Yehezkel Bernat <yehezkel.bernat@intel.com>
S: Maintained S: Maintained
F: drivers/thunderbolt/ F: drivers/thunderbolt/
THUNDERX GPIO DRIVER
M: David Daney <david.daney@cavium.com>
S: Maintained
F: drivers/gpio/gpio-thunderx.c
TI AM437X VPFE DRIVER TI AM437X VPFE DRIVER
M: "Lad, Prabhakar" <prabhakar.csengg@gmail.com> M: "Lad, Prabhakar" <prabhakar.csengg@gmail.com>
L: linux-media@vger.kernel.org L: linux-media@vger.kernel.org
......
...@@ -311,7 +311,7 @@ config GPIO_MOCKUP ...@@ -311,7 +311,7 @@ config GPIO_MOCKUP
depends on GPIOLIB && SYSFS depends on GPIOLIB && SYSFS
select GPIO_SYSFS select GPIO_SYSFS
select GPIOLIB_IRQCHIP select GPIOLIB_IRQCHIP
select IRQ_WORK select IRQ_SIM
help help
This enables GPIO Testing driver, which provides a way to test GPIO This enables GPIO Testing driver, which provides a way to test GPIO
subsystem through sysfs(or char device) and debugfs. GPIO_SYSFS subsystem through sysfs(or char device) and debugfs. GPIO_SYSFS
...@@ -450,6 +450,15 @@ config GPIO_TS4800 ...@@ -450,6 +450,15 @@ config GPIO_TS4800
help help
This driver support TS-4800 FPGA GPIO controllers. This driver support TS-4800 FPGA GPIO controllers.
config GPIO_THUNDERX
tristate "Cavium ThunderX/OCTEON-TX GPIO"
depends on ARCH_THUNDER || (64BIT && COMPILE_TEST)
depends on PCI_MSI && IRQ_DOMAIN_HIERARCHY
select IRQ_FASTEOI_HIERARCHY_HANDLERS
help
Say yes here to support the on-chip GPIO lines on the ThunderX
and OCTEON-TX families of SoCs.
config GPIO_TZ1090 config GPIO_TZ1090
bool "Toumaz Xenif TZ1090 GPIO support" bool "Toumaz Xenif TZ1090 GPIO support"
depends on SOC_TZ1090 depends on SOC_TZ1090
...@@ -1065,6 +1074,21 @@ config GPIO_TPS65912 ...@@ -1065,6 +1074,21 @@ config GPIO_TPS65912
help help
This driver supports TPS65912 gpio chip This driver supports TPS65912 gpio chip
config GPIO_TPS68470
bool "TPS68470 GPIO"
depends on MFD_TPS68470
help
Select this option to enable GPIO driver for the TPS68470
chip family.
There are 7 GPIOs and few sensor related GPIOs supported
by the TPS68470. While the 7 GPIOs can be configured as
input or output as appropriate, the sensor related GPIOs
are "output only" GPIOs.
This driver config is bool, as the GPIO functionality
of the TPS68470 must be available before dependent
drivers are loaded.
config GPIO_TWL4030 config GPIO_TWL4030
tristate "TWL4030, TWL5030, and TPS659x0 GPIOs" tristate "TWL4030, TWL5030, and TPS659x0 GPIOs"
depends on TWL4030_CORE depends on TWL4030_CORE
......
...@@ -113,6 +113,7 @@ obj-$(CONFIG_GPIO_SYSCON) += gpio-syscon.o ...@@ -113,6 +113,7 @@ obj-$(CONFIG_GPIO_SYSCON) += gpio-syscon.o
obj-$(CONFIG_GPIO_TB10X) += gpio-tb10x.o obj-$(CONFIG_GPIO_TB10X) += gpio-tb10x.o
obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o
obj-$(CONFIG_GPIO_TEGRA) += gpio-tegra.o obj-$(CONFIG_GPIO_TEGRA) += gpio-tegra.o
obj-$(CONFIG_GPIO_THUNDERX) += gpio-thunderx.o
obj-$(CONFIG_GPIO_TIMBERDALE) += gpio-timberdale.o obj-$(CONFIG_GPIO_TIMBERDALE) += gpio-timberdale.o
obj-$(CONFIG_GPIO_PALMAS) += gpio-palmas.o obj-$(CONFIG_GPIO_PALMAS) += gpio-palmas.o
obj-$(CONFIG_GPIO_TPIC2810) += gpio-tpic2810.o obj-$(CONFIG_GPIO_TPIC2810) += gpio-tpic2810.o
...@@ -121,6 +122,7 @@ obj-$(CONFIG_GPIO_TPS65218) += gpio-tps65218.o ...@@ -121,6 +122,7 @@ obj-$(CONFIG_GPIO_TPS65218) += gpio-tps65218.o
obj-$(CONFIG_GPIO_TPS6586X) += gpio-tps6586x.o obj-$(CONFIG_GPIO_TPS6586X) += gpio-tps6586x.o
obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o
obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o
obj-$(CONFIG_GPIO_TPS68470) += gpio-tps68470.o
obj-$(CONFIG_GPIO_TS4800) += gpio-ts4800.o obj-$(CONFIG_GPIO_TS4800) += gpio-ts4800.o
obj-$(CONFIG_GPIO_TS4900) += gpio-ts4900.o obj-$(CONFIG_GPIO_TS4900) += gpio-ts4900.o
obj-$(CONFIG_GPIO_TS5500) += gpio-ts5500.o obj-$(CONFIG_GPIO_TS5500) += gpio-ts5500.o
......
...@@ -132,6 +132,7 @@ EXPORT_SYMBOL(devm_gpiod_get_index); ...@@ -132,6 +132,7 @@ EXPORT_SYMBOL(devm_gpiod_get_index);
* @index: index of the GPIO to obtain in the consumer * @index: index of the GPIO to obtain in the consumer
* @child: firmware node (child of @dev) * @child: firmware node (child of @dev)
* @flags: GPIO initialization flags * @flags: GPIO initialization flags
* @label: label to attach to the requested GPIO
* *
* GPIO descriptors returned from this function are automatically disposed on * GPIO descriptors returned from this function are automatically disposed on
* driver detach. * driver detach.
...@@ -271,6 +272,7 @@ EXPORT_SYMBOL(devm_gpiod_get_array_optional); ...@@ -271,6 +272,7 @@ EXPORT_SYMBOL(devm_gpiod_get_array_optional);
/** /**
* devm_gpiod_put - Resource-managed gpiod_put() * devm_gpiod_put - Resource-managed gpiod_put()
* @dev: GPIO consumer
* @desc: GPIO descriptor to dispose of * @desc: GPIO descriptor to dispose of
* *
* Dispose of a GPIO descriptor obtained with devm_gpiod_get() or * Dispose of a GPIO descriptor obtained with devm_gpiod_get() or
...@@ -286,6 +288,7 @@ EXPORT_SYMBOL(devm_gpiod_put); ...@@ -286,6 +288,7 @@ EXPORT_SYMBOL(devm_gpiod_put);
/** /**
* devm_gpiod_put_array - Resource-managed gpiod_put_array() * devm_gpiod_put_array - Resource-managed gpiod_put_array()
* @dev: GPIO consumer
* @descs: GPIO descriptor array to dispose of * @descs: GPIO descriptor array to dispose of
* *
* Dispose of an array of GPIO descriptors obtained with devm_gpiod_get_array(). * Dispose of an array of GPIO descriptors obtained with devm_gpiod_get_array().
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#include <linux/gpio/consumer.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
...@@ -31,6 +32,7 @@ struct gen_74x164_chip { ...@@ -31,6 +32,7 @@ struct gen_74x164_chip {
* numbering, store the bytes in reverse order. * numbering, store the bytes in reverse order.
*/ */
u8 buffer[0]; u8 buffer[0];
struct gpio_desc *gpiod_oe;
}; };
static int __gen_74x164_write_config(struct gen_74x164_chip *chip) static int __gen_74x164_write_config(struct gen_74x164_chip *chip)
...@@ -126,6 +128,13 @@ static int gen_74x164_probe(struct spi_device *spi) ...@@ -126,6 +128,13 @@ static int gen_74x164_probe(struct spi_device *spi)
if (!chip) if (!chip)
return -ENOMEM; return -ENOMEM;
chip->gpiod_oe = devm_gpiod_get_optional(&spi->dev, "enable",
GPIOD_OUT_LOW);
if (IS_ERR(chip->gpiod_oe))
return PTR_ERR(chip->gpiod_oe);
gpiod_set_value_cansleep(chip->gpiod_oe, 1);
spi_set_drvdata(spi, chip); spi_set_drvdata(spi, chip);
chip->gpio_chip.label = spi->modalias; chip->gpio_chip.label = spi->modalias;
...@@ -164,6 +173,7 @@ static int gen_74x164_remove(struct spi_device *spi) ...@@ -164,6 +173,7 @@ static int gen_74x164_remove(struct spi_device *spi)
{ {
struct gen_74x164_chip *chip = spi_get_drvdata(spi); struct gen_74x164_chip *chip = spi_get_drvdata(spi);
gpiod_set_value_cansleep(chip->gpiod_oe, 0);
gpiochip_remove(&chip->gpio_chip); gpiochip_remove(&chip->gpio_chip);
mutex_destroy(&chip->lock); mutex_destroy(&chip->lock);
......
...@@ -71,7 +71,7 @@ static int altr_a10sr_gpio_direction_output(struct gpio_chip *gc, ...@@ -71,7 +71,7 @@ static int altr_a10sr_gpio_direction_output(struct gpio_chip *gc,
return -EINVAL; return -EINVAL;
} }
static struct gpio_chip altr_a10sr_gc = { static const struct gpio_chip altr_a10sr_gc = {
.label = "altr_a10sr_gpio", .label = "altr_a10sr_gpio",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.get = altr_a10sr_gpio_get, .get = altr_a10sr_gpio_get,
......
...@@ -324,8 +324,8 @@ static int altera_gpio_probe(struct platform_device *pdev) ...@@ -324,8 +324,8 @@ static int altera_gpio_probe(struct platform_device *pdev)
return 0; return 0;
teardown: teardown:
of_mm_gpiochip_remove(&altera_gc->mmchip); of_mm_gpiochip_remove(&altera_gc->mmchip);
pr_err("%s: registration failed with status %d\n", pr_err("%pOF: registration failed with status %d\n",
node->full_name, ret); node, ret);
return ret; return ret;
} }
......
...@@ -834,7 +834,7 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev) ...@@ -834,7 +834,7 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)
gpio->clk = of_clk_get(pdev->dev.of_node, 0); gpio->clk = of_clk_get(pdev->dev.of_node, 0);
if (IS_ERR(gpio->clk)) { if (IS_ERR(gpio->clk)) {
dev_warn(&pdev->dev, dev_warn(&pdev->dev,
"No HPLL clock phandle provided, debouncing disabled\n"); "Failed to get clock from devicetree, debouncing disabled\n");
gpio->clk = NULL; gpio->clk = NULL;
} }
......
...@@ -339,6 +339,7 @@ static int brcmstb_gpio_irq_setup(struct platform_device *pdev, ...@@ -339,6 +339,7 @@ static int brcmstb_gpio_irq_setup(struct platform_device *pdev,
struct brcmstb_gpio_priv *priv = bank->parent_priv; struct brcmstb_gpio_priv *priv = bank->parent_priv;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node; struct device_node *np = dev->of_node;
int err;
bank->irq_chip.name = dev_name(dev); bank->irq_chip.name = dev_name(dev);
bank->irq_chip.irq_mask = brcmstb_gpio_irq_mask; bank->irq_chip.irq_mask = brcmstb_gpio_irq_mask;
...@@ -355,8 +356,6 @@ static int brcmstb_gpio_irq_setup(struct platform_device *pdev, ...@@ -355,8 +356,6 @@ static int brcmstb_gpio_irq_setup(struct platform_device *pdev,
dev_warn(dev, dev_warn(dev,
"Couldn't get wake IRQ - GPIOs will not be able to wake from sleep"); "Couldn't get wake IRQ - GPIOs will not be able to wake from sleep");
} else { } else {
int err;
/* /*
* Set wakeup capability before requesting wakeup * Set wakeup capability before requesting wakeup
* interrupt, so we can process boot-time "wakeups" * interrupt, so we can process boot-time "wakeups"
...@@ -383,8 +382,10 @@ static int brcmstb_gpio_irq_setup(struct platform_device *pdev, ...@@ -383,8 +382,10 @@ static int brcmstb_gpio_irq_setup(struct platform_device *pdev,
if (priv->can_wake) if (priv->can_wake)
bank->irq_chip.irq_set_wake = brcmstb_gpio_irq_set_wake; bank->irq_chip.irq_set_wake = brcmstb_gpio_irq_set_wake;
gpiochip_irqchip_add(&bank->gc, &bank->irq_chip, 0, err = gpiochip_irqchip_add(&bank->gc, &bank->irq_chip, 0,
handle_simple_irq, IRQ_TYPE_NONE); handle_simple_irq, IRQ_TYPE_NONE);
if (err)
return err;
gpiochip_set_chained_irqchip(&bank->gc, &bank->irq_chip, gpiochip_set_chained_irqchip(&bank->gc, &bank->irq_chip,
priv->parent_irq, brcmstb_gpio_irq_handler); priv->parent_irq, brcmstb_gpio_irq_handler);
...@@ -483,7 +484,7 @@ static int brcmstb_gpio_probe(struct platform_device *pdev) ...@@ -483,7 +484,7 @@ static int brcmstb_gpio_probe(struct platform_device *pdev)
gc->of_node = np; gc->of_node = np;
gc->owner = THIS_MODULE; gc->owner = THIS_MODULE;
gc->label = np->full_name; gc->label = devm_kasprintf(dev, GFP_KERNEL, "%pOF", dev->of_node);
gc->base = gpio_base; gc->base = gpio_base;
gc->of_gpio_n_cells = 2; gc->of_gpio_n_cells = 2;
gc->of_xlate = brcmstb_gpio_of_xlate; gc->of_xlate = brcmstb_gpio_of_xlate;
......
...@@ -166,7 +166,7 @@ davinci_gpio_get_pdata(struct platform_device *pdev) ...@@ -166,7 +166,7 @@ davinci_gpio_get_pdata(struct platform_device *pdev)
static int davinci_gpio_probe(struct platform_device *pdev) static int davinci_gpio_probe(struct platform_device *pdev)
{ {
static int ctrl_num, bank_base; static int ctrl_num, bank_base;
int gpio, bank; int gpio, bank, ret = 0;
unsigned ngpio, nbank; unsigned ngpio, nbank;
struct davinci_gpio_controller *chips; struct davinci_gpio_controller *chips;
struct davinci_gpio_platform_data *pdata; struct davinci_gpio_platform_data *pdata;
...@@ -232,10 +232,23 @@ static int davinci_gpio_probe(struct platform_device *pdev) ...@@ -232,10 +232,23 @@ static int davinci_gpio_probe(struct platform_device *pdev)
for (gpio = 0, bank = 0; gpio < ngpio; gpio += 32, bank++) for (gpio = 0, bank = 0; gpio < ngpio; gpio += 32, bank++)
chips->regs[bank] = gpio_base + offset_array[bank]; chips->regs[bank] = gpio_base + offset_array[bank];
gpiochip_add_data(&chips->chip, chips); ret = devm_gpiochip_add_data(dev, &chips->chip, chips);
if (ret)
goto err;
platform_set_drvdata(pdev, chips); platform_set_drvdata(pdev, chips);
davinci_gpio_irq_setup(pdev); ret = davinci_gpio_irq_setup(pdev);
if (ret)
goto err;
return 0; return 0;
err:
/* Revert the static variable increments */
ctrl_num--;
bank_base -= ngpio;
return ret;
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
...@@ -477,8 +490,7 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev) ...@@ -477,8 +490,7 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
clk = devm_clk_get(dev, "gpio"); clk = devm_clk_get(dev, "gpio");
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
printk(KERN_ERR "Error %ld getting gpio clock?\n", dev_err(dev, "Error %ld getting gpio clock\n", PTR_ERR(clk));
PTR_ERR(clk));
return PTR_ERR(clk); return PTR_ERR(clk);
} }
ret = clk_prepare_enable(clk); ret = clk_prepare_enable(clk);
......
...@@ -76,8 +76,7 @@ static int __init gef_gpio_probe(struct platform_device *pdev) ...@@ -76,8 +76,7 @@ static int __init gef_gpio_probe(struct platform_device *pdev)
} }
/* Setup pointers to chip functions */ /* Setup pointers to chip functions */
gc->label = devm_kstrdup(&pdev->dev, pdev->dev.of_node->full_name, gc->label = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%pOF", pdev->dev.of_node);
GFP_KERNEL);
if (!gc->label) { if (!gc->label) {
ret = -ENOMEM; ret = -ENOMEM;
goto err0; goto err0;
...@@ -96,8 +95,7 @@ static int __init gef_gpio_probe(struct platform_device *pdev) ...@@ -96,8 +95,7 @@ static int __init gef_gpio_probe(struct platform_device *pdev)
return 0; return 0;
err0: err0:
iounmap(regs); iounmap(regs);
pr_err("%s: GPIO chip registration failed\n", pr_err("%pOF: GPIO chip registration failed\n", pdev->dev.of_node);
pdev->dev.of_node->full_name);
return ret; return ret;
}; };
......
...@@ -367,7 +367,7 @@ static int grgpio_probe(struct platform_device *ofdev) ...@@ -367,7 +367,7 @@ static int grgpio_probe(struct platform_device *ofdev)
gc->of_node = np; gc->of_node = np;
gc->owner = THIS_MODULE; gc->owner = THIS_MODULE;
gc->to_irq = grgpio_to_irq; gc->to_irq = grgpio_to_irq;
gc->label = np->full_name; gc->label = devm_kasprintf(&ofdev->dev, GFP_KERNEL, "%pOF", np);
gc->base = -1; gc->base = -1;
err = of_property_read_u32(np, "nbits", &prop); err = of_property_read_u32(np, "nbits", &prop);
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* GPIO interface for IT87xx Super I/O chips * GPIO interface for IT87xx Super I/O chips
* *
* Author: Diego Elio Pettenò <flameeyes@flameeyes.eu> * Author: Diego Elio Pettenò <flameeyes@flameeyes.eu>
* Copyright (c) 2017 Google, Inc.
* *
* Based on it87_wdt.c by Oliver Schuster * Based on it87_wdt.c by Oliver Schuster
* gpio-it8761e.c by Denis Turischev * gpio-it8761e.c by Denis Turischev
...@@ -39,6 +40,7 @@ ...@@ -39,6 +40,7 @@
#define IT8728_ID 0x8728 #define IT8728_ID 0x8728
#define IT8732_ID 0x8732 #define IT8732_ID 0x8732
#define IT8761_ID 0x8761 #define IT8761_ID 0x8761
#define IT8772_ID 0x8772
/* IO Ports */ /* IO Ports */
#define REG 0x2e #define REG 0x2e
...@@ -314,6 +316,7 @@ static int __init it87_gpio_init(void) ...@@ -314,6 +316,7 @@ static int __init it87_gpio_init(void)
break; break;
case IT8728_ID: case IT8728_ID:
case IT8732_ID: case IT8732_ID:
case IT8772_ID:
gpio_ba_reg = 0x62; gpio_ba_reg = 0x62;
it87_gpio->io_size = 8; it87_gpio->io_size = 8;
it87_gpio->output_base = 0xc8; it87_gpio->output_base = 0xc8;
......
...@@ -82,7 +82,7 @@ static const struct regmap_irq max77620_gpio_irqs[] = { ...@@ -82,7 +82,7 @@ static const struct regmap_irq max77620_gpio_irqs[] = {
}, },
}; };
static struct regmap_irq_chip max77620_gpio_irq_chip = { static const struct regmap_irq_chip max77620_gpio_irq_chip = {
.name = "max77620-gpio", .name = "max77620-gpio",
.irqs = max77620_gpio_irqs, .irqs = max77620_gpio_irqs,
.num_irqs = ARRAY_SIZE(max77620_gpio_irqs), .num_irqs = ARRAY_SIZE(max77620_gpio_irqs),
......
...@@ -168,7 +168,9 @@ static int mb86s70_gpio_probe(struct platform_device *pdev) ...@@ -168,7 +168,9 @@ static int mb86s70_gpio_probe(struct platform_device *pdev)
if (IS_ERR(gchip->clk)) if (IS_ERR(gchip->clk))
return PTR_ERR(gchip->clk); return PTR_ERR(gchip->clk);
clk_prepare_enable(gchip->clk); ret = clk_prepare_enable(gchip->clk);
if (ret)
return ret;
spin_lock_init(&gchip->lock); spin_lock_init(&gchip->lock);
......
...@@ -391,9 +391,10 @@ static int ioh_gpio_alloc_generic_chip(struct ioh_gpio *chip, ...@@ -391,9 +391,10 @@ static int ioh_gpio_alloc_generic_chip(struct ioh_gpio *chip,
{ {
struct irq_chip_generic *gc; struct irq_chip_generic *gc;
struct irq_chip_type *ct; struct irq_chip_type *ct;
int rv;
gc = irq_alloc_generic_chip("ioh_gpio", 1, irq_start, chip->base, gc = devm_irq_alloc_generic_chip(chip->dev, "ioh_gpio", 1, irq_start,
handle_simple_irq); chip->base, handle_simple_irq);
if (!gc) if (!gc)
return -ENOMEM; return -ENOMEM;
...@@ -406,10 +407,11 @@ static int ioh_gpio_alloc_generic_chip(struct ioh_gpio *chip, ...@@ -406,10 +407,11 @@ static int ioh_gpio_alloc_generic_chip(struct ioh_gpio *chip,
ct->chip.irq_disable = ioh_irq_disable; ct->chip.irq_disable = ioh_irq_disable;
ct->chip.irq_enable = ioh_irq_enable; ct->chip.irq_enable = ioh_irq_enable;
irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE, rv = devm_irq_setup_generic_chip(chip->dev, gc, IRQ_MSK(num),
IRQ_NOREQUEST | IRQ_NOPROBE, 0); IRQ_GC_INIT_MASK_CACHE,
IRQ_NOREQUEST | IRQ_NOPROBE, 0);
return 0; return rv;
} }
static int ioh_gpio_probe(struct pci_dev *pdev, static int ioh_gpio_probe(struct pci_dev *pdev,
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/irq_work.h> #include <linux/irq_sim.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
...@@ -47,18 +47,12 @@ enum { ...@@ -47,18 +47,12 @@ enum {
struct gpio_mockup_line_status { struct gpio_mockup_line_status {
int dir; int dir;
bool value; bool value;
bool irq_enabled;
};
struct gpio_mockup_irq_context {
struct irq_work work;
int irq;
}; };
struct gpio_mockup_chip { struct gpio_mockup_chip {
struct gpio_chip gc; struct gpio_chip gc;
struct gpio_mockup_line_status *lines; struct gpio_mockup_line_status *lines;
struct gpio_mockup_irq_context irq_ctx; struct irq_sim irqsim;
struct dentry *dbg_dir; struct dentry *dbg_dir;
}; };
...@@ -144,65 +138,11 @@ static int gpio_mockup_name_lines(struct device *dev, ...@@ -144,65 +138,11 @@ static int gpio_mockup_name_lines(struct device *dev,
return 0; return 0;
} }
static int gpio_mockup_to_irq(struct gpio_chip *chip, unsigned int offset) static int gpio_mockup_to_irq(struct gpio_chip *gc, unsigned int offset)
{
return chip->irq_base + offset;
}
static void gpio_mockup_irqmask(struct irq_data *data)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
chip->lines[data->irq - gc->irq_base].irq_enabled = false;
}
static void gpio_mockup_irqunmask(struct irq_data *data)
{ {
struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
struct gpio_mockup_chip *chip = gpiochip_get_data(gc); struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
chip->lines[data->irq - gc->irq_base].irq_enabled = true; return irq_sim_irqnum(&chip->irqsim, offset);
}
static struct irq_chip gpio_mockup_irqchip = {
.name = GPIO_MOCKUP_NAME,
.irq_mask = gpio_mockup_irqmask,
.irq_unmask = gpio_mockup_irqunmask,
};
static void gpio_mockup_handle_irq(struct irq_work *work)
{
struct gpio_mockup_irq_context *irq_ctx;
irq_ctx = container_of(work, struct gpio_mockup_irq_context, work);
handle_simple_irq(irq_to_desc(irq_ctx->irq));
}
static int gpio_mockup_irqchip_setup(struct device *dev,
struct gpio_mockup_chip *chip)
{
struct gpio_chip *gc = &chip->gc;
int irq_base, i;
irq_base = devm_irq_alloc_descs(dev, -1, 0, gc->ngpio, 0);
if (irq_base < 0)
return irq_base;
gc->irq_base = irq_base;
gc->irqchip = &gpio_mockup_irqchip;
for (i = 0; i < gc->ngpio; i++) {
irq_set_chip(irq_base + i, gc->irqchip);
irq_set_chip_data(irq_base + i, gc);
irq_set_handler(irq_base + i, &handle_simple_irq);
irq_modify_status(irq_base + i,
IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
}
init_irq_work(&chip->irq_ctx.work, gpio_mockup_handle_irq);
return 0;
} }
static ssize_t gpio_mockup_event_write(struct file *file, static ssize_t gpio_mockup_event_write(struct file *file,
...@@ -213,7 +153,6 @@ static ssize_t gpio_mockup_event_write(struct file *file, ...@@ -213,7 +153,6 @@ static ssize_t gpio_mockup_event_write(struct file *file,
struct gpio_mockup_chip *chip; struct gpio_mockup_chip *chip;
struct seq_file *sfile; struct seq_file *sfile;
struct gpio_desc *desc; struct gpio_desc *desc;
struct gpio_chip *gc;
int rv, val; int rv, val;
rv = kstrtoint_from_user(usr_buf, size, 0, &val); rv = kstrtoint_from_user(usr_buf, size, 0, &val);
...@@ -226,13 +165,9 @@ static ssize_t gpio_mockup_event_write(struct file *file, ...@@ -226,13 +165,9 @@ static ssize_t gpio_mockup_event_write(struct file *file,
priv = sfile->private; priv = sfile->private;
desc = priv->desc; desc = priv->desc;
chip = priv->chip; chip = priv->chip;
gc = &chip->gc;
if (chip->lines[priv->offset].irq_enabled) { gpiod_set_value_cansleep(desc, val);
gpiod_set_value_cansleep(desc, val); irq_sim_fire(&chip->irqsim, priv->offset);
priv->chip->irq_ctx.irq = gc->irq_base + priv->offset;
irq_work_queue(&priv->chip->irq_ctx.work);
}
return size; return size;
} }
...@@ -319,7 +254,7 @@ static int gpio_mockup_add(struct device *dev, ...@@ -319,7 +254,7 @@ static int gpio_mockup_add(struct device *dev,
return ret; return ret;
} }
ret = gpio_mockup_irqchip_setup(dev, chip); ret = devm_irq_sim_init(dev, &chip->irqsim, gc->ngpio);
if (ret) if (ret)
return ret; return ret;
......
...@@ -348,8 +348,8 @@ static int mpc8xxx_probe(struct platform_device *pdev) ...@@ -348,8 +348,8 @@ static int mpc8xxx_probe(struct platform_device *pdev)
ret = gpiochip_add_data(gc, mpc8xxx_gc); ret = gpiochip_add_data(gc, mpc8xxx_gc);
if (ret) { if (ret) {
pr_err("%s: GPIO chip registration failed with status %d\n", pr_err("%pOF: GPIO chip registration failed with status %d\n",
np->full_name, ret); np, ret);
goto err; goto err;
} }
......
...@@ -265,8 +265,8 @@ static int platform_msic_gpio_probe(struct platform_device *pdev) ...@@ -265,8 +265,8 @@ static int platform_msic_gpio_probe(struct platform_device *pdev)
int i; int i;
if (irq < 0) { if (irq < 0) {
dev_err(dev, "no IRQ line\n"); dev_err(dev, "no IRQ line: %d\n", irq);
return -EINVAL; return irq;
} }
if (!pdata || !pdata->gpio_base) { if (!pdata || !pdata->gpio_base) {
......
...@@ -66,6 +66,7 @@ struct mxc_gpio_port { ...@@ -66,6 +66,7 @@ struct mxc_gpio_port {
int irq_high; int irq_high;
struct irq_domain *domain; struct irq_domain *domain;
struct gpio_chip gc; struct gpio_chip gc;
struct device *dev;
u32 both_edges; u32 both_edges;
}; };
...@@ -324,29 +325,31 @@ static int gpio_set_wake_irq(struct irq_data *d, u32 enable) ...@@ -324,29 +325,31 @@ static int gpio_set_wake_irq(struct irq_data *d, u32 enable)
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
struct mxc_gpio_port *port = gc->private; struct mxc_gpio_port *port = gc->private;
u32 gpio_idx = d->hwirq; u32 gpio_idx = d->hwirq;
int ret;
if (enable) { if (enable) {
if (port->irq_high && (gpio_idx >= 16)) if (port->irq_high && (gpio_idx >= 16))
enable_irq_wake(port->irq_high); ret = enable_irq_wake(port->irq_high);
else else
enable_irq_wake(port->irq); ret = enable_irq_wake(port->irq);
} else { } else {
if (port->irq_high && (gpio_idx >= 16)) if (port->irq_high && (gpio_idx >= 16))
disable_irq_wake(port->irq_high); ret = disable_irq_wake(port->irq_high);
else else
disable_irq_wake(port->irq); ret = disable_irq_wake(port->irq);
} }
return 0; return ret;
} }
static int mxc_gpio_init_gc(struct mxc_gpio_port *port, int irq_base) static int mxc_gpio_init_gc(struct mxc_gpio_port *port, int irq_base)
{ {
struct irq_chip_generic *gc; struct irq_chip_generic *gc;
struct irq_chip_type *ct; struct irq_chip_type *ct;
int rv;
gc = irq_alloc_generic_chip("gpio-mxc", 1, irq_base, gc = devm_irq_alloc_generic_chip(port->dev, "gpio-mxc", 1, irq_base,
port->base, handle_level_irq); port->base, handle_level_irq);
if (!gc) if (!gc)
return -ENOMEM; return -ENOMEM;
gc->private = port; gc->private = port;
...@@ -361,10 +364,11 @@ static int mxc_gpio_init_gc(struct mxc_gpio_port *port, int irq_base) ...@@ -361,10 +364,11 @@ static int mxc_gpio_init_gc(struct mxc_gpio_port *port, int irq_base)
ct->regs.ack = GPIO_ISR; ct->regs.ack = GPIO_ISR;
ct->regs.mask = GPIO_IMR; ct->regs.mask = GPIO_IMR;
irq_setup_generic_chip(gc, IRQ_MSK(32), IRQ_GC_INIT_NESTED_LOCK, rv = devm_irq_setup_generic_chip(port->dev, gc, IRQ_MSK(32),
IRQ_NOREQUEST, 0); IRQ_GC_INIT_NESTED_LOCK,
IRQ_NOREQUEST, 0);
return 0; return rv;
} }
static void mxc_gpio_get_hw(struct platform_device *pdev) static void mxc_gpio_get_hw(struct platform_device *pdev)
...@@ -418,6 +422,8 @@ static int mxc_gpio_probe(struct platform_device *pdev) ...@@ -418,6 +422,8 @@ static int mxc_gpio_probe(struct platform_device *pdev)
if (!port) if (!port)
return -ENOMEM; return -ENOMEM;
port->dev = &pdev->dev;
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
port->base = devm_ioremap_resource(&pdev->dev, iores); port->base = devm_ioremap_resource(&pdev->dev, iores);
if (IS_ERR(port->base)) if (IS_ERR(port->base))
...@@ -507,6 +513,7 @@ static struct platform_driver mxc_gpio_driver = { ...@@ -507,6 +513,7 @@ static struct platform_driver mxc_gpio_driver = {
.driver = { .driver = {
.name = "gpio-mxc", .name = "gpio-mxc",
.of_match_table = mxc_gpio_dt_ids, .of_match_table = mxc_gpio_dt_ids,
.suppress_bind_attrs = true,
}, },
.probe = mxc_gpio_probe, .probe = mxc_gpio_probe,
.id_table = mxc_gpio_devtype, .id_table = mxc_gpio_devtype,
......
...@@ -66,6 +66,7 @@ struct mxs_gpio_port { ...@@ -66,6 +66,7 @@ struct mxs_gpio_port {
int irq; int irq;
struct irq_domain *domain; struct irq_domain *domain;
struct gpio_chip gc; struct gpio_chip gc;
struct device *dev;
enum mxs_gpio_id devid; enum mxs_gpio_id devid;
u32 both_edges; u32 both_edges;
}; };
...@@ -209,9 +210,10 @@ static int mxs_gpio_init_gc(struct mxs_gpio_port *port, int irq_base) ...@@ -209,9 +210,10 @@ static int mxs_gpio_init_gc(struct mxs_gpio_port *port, int irq_base)
{ {
struct irq_chip_generic *gc; struct irq_chip_generic *gc;
struct irq_chip_type *ct; struct irq_chip_type *ct;
int rv;
gc = irq_alloc_generic_chip("gpio-mxs", 2, irq_base, gc = devm_irq_alloc_generic_chip(port->dev, "gpio-mxs", 2, irq_base,
port->base, handle_level_irq); port->base, handle_level_irq);
if (!gc) if (!gc)
return -ENOMEM; return -ENOMEM;
...@@ -242,10 +244,11 @@ static int mxs_gpio_init_gc(struct mxs_gpio_port *port, int irq_base) ...@@ -242,10 +244,11 @@ static int mxs_gpio_init_gc(struct mxs_gpio_port *port, int irq_base)
ct->regs.disable = PINCTRL_IRQEN(port) + MXS_CLR; ct->regs.disable = PINCTRL_IRQEN(port) + MXS_CLR;
ct->handler = handle_level_irq; ct->handler = handle_level_irq;
irq_setup_generic_chip(gc, IRQ_MSK(32), IRQ_GC_INIT_NESTED_LOCK, rv = devm_irq_setup_generic_chip(port->dev, gc, IRQ_MSK(32),
IRQ_NOREQUEST, 0); IRQ_GC_INIT_NESTED_LOCK,
IRQ_NOREQUEST, 0);
return 0; 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 offset)
...@@ -304,6 +307,7 @@ static int mxs_gpio_probe(struct platform_device *pdev) ...@@ -304,6 +307,7 @@ static int mxs_gpio_probe(struct platform_device *pdev)
if (port->id < 0) if (port->id < 0)
return port->id; return port->id;
port->devid = (enum mxs_gpio_id) of_id->data; port->devid = (enum mxs_gpio_id) of_id->data;
port->dev = &pdev->dev;
port->irq = platform_get_irq(pdev, 0); port->irq = platform_get_irq(pdev, 0);
if (port->irq < 0) if (port->irq < 0)
return port->irq; return port->irq;
...@@ -379,6 +383,7 @@ static struct platform_driver mxs_gpio_driver = { ...@@ -379,6 +383,7 @@ static struct platform_driver mxs_gpio_driver = {
.driver = { .driver = {
.name = "gpio-mxs", .name = "gpio-mxs",
.of_match_table = mxs_gpio_dt_ids, .of_match_table = mxs_gpio_dt_ids,
.suppress_bind_attrs = true,
}, },
.probe = mxs_gpio_probe, .probe = mxs_gpio_probe,
.id_table = mxs_gpio_ids, .id_table = mxs_gpio_ids,
......
...@@ -1247,6 +1247,8 @@ static int omap_gpio_probe(struct platform_device *pdev) ...@@ -1247,6 +1247,8 @@ static int omap_gpio_probe(struct platform_device *pdev)
if (ret) { if (ret) {
pm_runtime_put_sync(dev); pm_runtime_put_sync(dev);
pm_runtime_disable(dev); pm_runtime_disable(dev);
if (bank->dbck_flag)
clk_unprepare(bank->dbck);
return ret; return ret;
} }
......
...@@ -187,10 +187,9 @@ static int pca953x_write_regs_8(struct pca953x_chip *chip, int reg, u8 *val) ...@@ -187,10 +187,9 @@ static int pca953x_write_regs_8(struct pca953x_chip *chip, int reg, u8 *val)
static int pca953x_write_regs_16(struct pca953x_chip *chip, int reg, u8 *val) static int pca953x_write_regs_16(struct pca953x_chip *chip, int reg, u8 *val)
{ {
__le16 word = cpu_to_le16(get_unaligned((u16 *)val)); u16 word = get_unaligned((u16 *)val);
return i2c_smbus_write_word_data(chip->client, return i2c_smbus_write_word_data(chip->client, reg << 1, word);
reg << 1, (__force u16)word);
} }
static int pca957x_write_regs_16(struct pca953x_chip *chip, int reg, u8 *val) static int pca957x_write_regs_16(struct pca953x_chip *chip, int reg, u8 *val)
...@@ -241,8 +240,7 @@ static int pca953x_read_regs_16(struct pca953x_chip *chip, int reg, u8 *val) ...@@ -241,8 +240,7 @@ static int pca953x_read_regs_16(struct pca953x_chip *chip, int reg, u8 *val)
int ret; int ret;
ret = i2c_smbus_read_word_data(chip->client, reg << 1); ret = i2c_smbus_read_word_data(chip->client, reg << 1);
val[0] = (u16)ret & 0xFF; put_unaligned(ret, (u16 *)val);
val[1] = (u16)ret >> 8;
return ret; return ret;
} }
......
...@@ -337,9 +337,10 @@ static int pch_gpio_alloc_generic_chip(struct pch_gpio *chip, ...@@ -337,9 +337,10 @@ static int pch_gpio_alloc_generic_chip(struct pch_gpio *chip,
{ {
struct irq_chip_generic *gc; struct irq_chip_generic *gc;
struct irq_chip_type *ct; struct irq_chip_type *ct;
int rv;
gc = irq_alloc_generic_chip("pch_gpio", 1, irq_start, chip->base, gc = devm_irq_alloc_generic_chip(chip->dev, "pch_gpio", 1, irq_start,
handle_simple_irq); chip->base, handle_simple_irq);
if (!gc) if (!gc)
return -ENOMEM; return -ENOMEM;
...@@ -351,10 +352,11 @@ static int pch_gpio_alloc_generic_chip(struct pch_gpio *chip, ...@@ -351,10 +352,11 @@ static int pch_gpio_alloc_generic_chip(struct pch_gpio *chip,
ct->chip.irq_unmask = pch_irq_unmask; ct->chip.irq_unmask = pch_irq_unmask;
ct->chip.irq_set_type = pch_irq_type; ct->chip.irq_set_type = pch_irq_type;
irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE, rv = devm_irq_setup_generic_chip(chip->dev, gc, IRQ_MSK(num),
IRQ_NOREQUEST | IRQ_NOPROBE, 0); IRQ_GC_INIT_MASK_CACHE,
IRQ_NOREQUEST | IRQ_NOPROBE, 0);
return 0; return rv;
} }
static int pch_gpio_probe(struct pci_dev *pdev, static int pch_gpio_probe(struct pci_dev *pdev,
......
...@@ -405,7 +405,7 @@ static const struct dev_pm_ops pl061_dev_pm_ops = { ...@@ -405,7 +405,7 @@ static const struct dev_pm_ops pl061_dev_pm_ops = {
}; };
#endif #endif
static struct amba_id pl061_ids[] = { static const struct amba_id pl061_ids[] = {
{ {
.id = 0x00041061, .id = 0x00041061,
.mask = 0x000fffff, .mask = 0x000fffff,
......
...@@ -451,7 +451,9 @@ static irqreturn_t pxa_gpio_demux_handler(int in_irq, void *d) ...@@ -451,7 +451,9 @@ static irqreturn_t pxa_gpio_demux_handler(int in_irq, void *d)
for_each_set_bit(n, &gedr, BITS_PER_LONG) { for_each_set_bit(n, &gedr, BITS_PER_LONG) {
loop = 1; loop = 1;
generic_handle_irq(gpio_to_irq(gpio + n)); generic_handle_irq(
irq_find_mapping(pchip->irqdomain,
gpio + n));
} }
} }
handled += loop; handled += loop;
...@@ -465,9 +467,9 @@ static irqreturn_t pxa_gpio_direct_handler(int in_irq, void *d) ...@@ -465,9 +467,9 @@ static irqreturn_t pxa_gpio_direct_handler(int in_irq, void *d)
struct pxa_gpio_chip *pchip = d; struct pxa_gpio_chip *pchip = d;
if (in_irq == pchip->irq0) { if (in_irq == pchip->irq0) {
generic_handle_irq(gpio_to_irq(0)); generic_handle_irq(irq_find_mapping(pchip->irqdomain, 0));
} else if (in_irq == pchip->irq1) { } else if (in_irq == pchip->irq1) {
generic_handle_irq(gpio_to_irq(1)); generic_handle_irq(irq_find_mapping(pchip->irqdomain, 1));
} else { } else {
pr_err("%s() unknown irq %d\n", __func__, in_irq); pr_err("%s() unknown irq %d\n", __func__, in_irq);
return IRQ_NONE; return IRQ_NONE;
......
...@@ -370,6 +370,16 @@ static const struct of_device_id gpio_rcar_of_table[] = { ...@@ -370,6 +370,16 @@ static const struct of_device_id gpio_rcar_of_table[] = {
.compatible = "renesas,gpio-r8a7796", .compatible = "renesas,gpio-r8a7796",
/* Gen3 GPIO is identical to Gen2. */ /* Gen3 GPIO is identical to Gen2. */
.data = &gpio_rcar_info_gen2, .data = &gpio_rcar_info_gen2,
}, {
.compatible = "renesas,rcar-gen1-gpio",
.data = &gpio_rcar_info_gen1,
}, {
.compatible = "renesas,rcar-gen2-gpio",
.data = &gpio_rcar_info_gen2,
}, {
.compatible = "renesas,rcar-gen3-gpio",
/* Gen3 GPIO is identical to Gen2. */
.data = &gpio_rcar_info_gen2,
}, { }, {
.compatible = "renesas,gpio-rcar", .compatible = "renesas,gpio-rcar",
.data = &gpio_rcar_info_gen1, .data = &gpio_rcar_info_gen1,
......
...@@ -324,9 +324,11 @@ static int gsta_alloc_irq_chip(struct gsta_gpio *chip) ...@@ -324,9 +324,11 @@ static int gsta_alloc_irq_chip(struct gsta_gpio *chip)
{ {
struct irq_chip_generic *gc; struct irq_chip_generic *gc;
struct irq_chip_type *ct; struct irq_chip_type *ct;
int rv;
gc = irq_alloc_generic_chip(KBUILD_MODNAME, 1, chip->irq_base, gc = devm_irq_alloc_generic_chip(chip->dev, KBUILD_MODNAME, 1,
chip->reg_base, handle_simple_irq); chip->irq_base,
chip->reg_base, handle_simple_irq);
if (!gc) if (!gc)
return -ENOMEM; return -ENOMEM;
...@@ -338,8 +340,11 @@ static int gsta_alloc_irq_chip(struct gsta_gpio *chip) ...@@ -338,8 +340,11 @@ static int gsta_alloc_irq_chip(struct gsta_gpio *chip)
ct->chip.irq_enable = gsta_irq_enable; ct->chip.irq_enable = gsta_irq_enable;
/* FIXME: this makes at most 32 interrupts. Request 0 by now */ /* FIXME: this makes at most 32 interrupts. Request 0 by now */
irq_setup_generic_chip(gc, 0 /* IRQ_MSK(GSTA_GPIO_PER_BLOCK) */, 0, rv = devm_irq_setup_generic_chip(chip->dev, gc,
IRQ_NOREQUEST | IRQ_NOPROBE, 0); 0 /* IRQ_MSK(GSTA_GPIO_PER_BLOCK) */,
0, IRQ_NOREQUEST | IRQ_NOPROBE, 0);
if (rv)
return rv;
/* Set up all all 128 interrupts: code from setup_generic_chip */ /* Set up all all 128 interrupts: code from setup_generic_chip */
{ {
...@@ -432,6 +437,7 @@ static int gsta_probe(struct platform_device *dev) ...@@ -432,6 +437,7 @@ static int gsta_probe(struct platform_device *dev)
static struct platform_driver sta2x11_gpio_platform_driver = { static struct platform_driver sta2x11_gpio_platform_driver = {
.driver = { .driver = {
.name = "sta2x11-gpio", .name = "sta2x11-gpio",
.suppress_bind_attrs = true,
}, },
.probe = gsta_probe, .probe = gsta_probe,
}; };
......
...@@ -191,7 +191,8 @@ static int tb10x_gpio_probe(struct platform_device *pdev) ...@@ -191,7 +191,8 @@ static int tb10x_gpio_probe(struct platform_device *pdev)
if (IS_ERR(tb10x_gpio->base)) if (IS_ERR(tb10x_gpio->base))
return PTR_ERR(tb10x_gpio->base); return PTR_ERR(tb10x_gpio->base);
tb10x_gpio->gc.label = of_node_full_name(dn); tb10x_gpio->gc.label =
devm_kasprintf(&pdev->dev, GFP_KERNEL, "%pOF", pdev->dev.of_node);
tb10x_gpio->gc.parent = &pdev->dev; tb10x_gpio->gc.parent = &pdev->dev;
tb10x_gpio->gc.owner = THIS_MODULE; tb10x_gpio->gc.owner = THIS_MODULE;
tb10x_gpio->gc.direction_input = tb10x_gpio_direction_in; tb10x_gpio->gc.direction_input = tb10x_gpio_direction_in;
......
This diff is collapsed.
This diff is collapsed.
/*
* GPIO driver for TPS68470 PMIC
*
* Copyright (C) 2017 Intel Corporation
*
* Authors:
* Antti Laakso <antti.laakso@intel.com>
* Tianshu Qiu <tian.shu.qiu@intel.com>
* Jian Xu Zheng <jian.xu.zheng@intel.com>
* Yuning Pu <yuning.pu@intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/gpio/driver.h>
#include <linux/mfd/tps68470.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#define TPS68470_N_LOGIC_OUTPUT 3
#define TPS68470_N_REGULAR_GPIO 7
#define TPS68470_N_GPIO (TPS68470_N_LOGIC_OUTPUT + TPS68470_N_REGULAR_GPIO)
struct tps68470_gpio_data {
struct regmap *tps68470_regmap;
struct gpio_chip gc;
};
static int tps68470_gpio_get(struct gpio_chip *gc, unsigned int offset)
{
struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc);
struct regmap *regmap = tps68470_gpio->tps68470_regmap;
unsigned int reg = TPS68470_REG_GPDO;
int val, ret;
if (offset >= TPS68470_N_REGULAR_GPIO) {
offset -= TPS68470_N_REGULAR_GPIO;
reg = TPS68470_REG_SGPO;
}
ret = regmap_read(regmap, reg, &val);
if (ret) {
dev_err(tps68470_gpio->gc.parent, "reg 0x%x read failed\n",
TPS68470_REG_SGPO);
return ret;
}
return !!(val & BIT(offset));
}
/* Return 0 if output, 1 if input */
static int tps68470_gpio_get_direction(struct gpio_chip *gc,
unsigned int offset)
{
struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc);
struct regmap *regmap = tps68470_gpio->tps68470_regmap;
int val, ret;
/* rest are always outputs */
if (offset >= TPS68470_N_REGULAR_GPIO)
return 0;
ret = regmap_read(regmap, TPS68470_GPIO_CTL_REG_A(offset), &val);
if (ret) {
dev_err(tps68470_gpio->gc.parent, "reg 0x%x read failed\n",
TPS68470_GPIO_CTL_REG_A(offset));
return ret;
}
val &= TPS68470_GPIO_MODE_MASK;
return val >= TPS68470_GPIO_MODE_OUT_CMOS ? 0 : 1;
}
static void tps68470_gpio_set(struct gpio_chip *gc, unsigned int offset,
int value)
{
struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc);
struct regmap *regmap = tps68470_gpio->tps68470_regmap;
unsigned int reg = TPS68470_REG_GPDO;
if (offset >= TPS68470_N_REGULAR_GPIO) {
reg = TPS68470_REG_SGPO;
offset -= TPS68470_N_REGULAR_GPIO;
}
regmap_update_bits(regmap, reg, BIT(offset), value ? BIT(offset) : 0);
}
static int tps68470_gpio_output(struct gpio_chip *gc, unsigned int offset,
int value)
{
struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc);
struct regmap *regmap = tps68470_gpio->tps68470_regmap;
/* rest are always outputs */
if (offset >= TPS68470_N_REGULAR_GPIO)
return 0;
/* Set the initial value */
tps68470_gpio_set(gc, offset, value);
return regmap_update_bits(regmap, TPS68470_GPIO_CTL_REG_A(offset),
TPS68470_GPIO_MODE_MASK,
TPS68470_GPIO_MODE_OUT_CMOS);
}
static int tps68470_gpio_input(struct gpio_chip *gc, unsigned int offset)
{
struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc);
struct regmap *regmap = tps68470_gpio->tps68470_regmap;
/* rest are always outputs */
if (offset >= TPS68470_N_REGULAR_GPIO)
return -EINVAL;
return regmap_update_bits(regmap, TPS68470_GPIO_CTL_REG_A(offset),
TPS68470_GPIO_MODE_MASK, 0x00);
}
static const char *tps68470_names[TPS68470_N_GPIO] = {
"gpio.0", "gpio.1", "gpio.2", "gpio.3",
"gpio.4", "gpio.5", "gpio.6",
"s_enable", "s_idle", "s_resetn",
};
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);
if (!tps68470_gpio)
return -ENOMEM;
tps68470_gpio->tps68470_regmap = dev_get_drvdata(pdev->dev.parent);
tps68470_gpio->gc.label = "tps68470-gpio";
tps68470_gpio->gc.owner = THIS_MODULE;
tps68470_gpio->gc.direction_input = tps68470_gpio_input;
tps68470_gpio->gc.direction_output = tps68470_gpio_output;
tps68470_gpio->gc.get = tps68470_gpio_get;
tps68470_gpio->gc.get_direction = tps68470_gpio_get_direction;
tps68470_gpio->gc.set = tps68470_gpio_set;
tps68470_gpio->gc.can_sleep = true;
tps68470_gpio->gc.names = tps68470_names;
tps68470_gpio->gc.ngpio = TPS68470_N_GPIO;
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;
}
static struct platform_driver tps68470_gpio_driver = {
.driver = {
.name = "tps68470-gpio",
},
.probe = tps68470_gpio_probe,
};
builtin_platform_driver(tps68470_gpio_driver)
...@@ -32,8 +32,6 @@ ...@@ -32,8 +32,6 @@
#include <linux/mfd/twl6040.h> #include <linux/mfd/twl6040.h>
static struct gpio_chip twl6040gpo_chip;
static int twl6040gpo_get(struct gpio_chip *chip, unsigned offset) static int twl6040gpo_get(struct gpio_chip *chip, unsigned offset)
{ {
struct twl6040 *twl6040 = dev_get_drvdata(chip->parent->parent); struct twl6040 *twl6040 = dev_get_drvdata(chip->parent->parent);
......
...@@ -527,13 +527,12 @@ static void tz1090_gpio_register_banks(struct tz1090_gpio *priv) ...@@ -527,13 +527,12 @@ static void tz1090_gpio_register_banks(struct tz1090_gpio *priv)
ret = of_property_read_u32(node, "reg", &addr); ret = of_property_read_u32(node, "reg", &addr);
if (ret) { if (ret) {
dev_err(priv->dev, "invalid reg on %s\n", dev_err(priv->dev, "invalid reg on %pOF\n", node);
node->full_name);
continue; continue;
} }
if (addr >= 3) { if (addr >= 3) {
dev_err(priv->dev, "index %u in %s out of range\n", dev_err(priv->dev, "index %u in %pOF out of range\n",
addr, node->full_name); addr, node);
continue; continue;
} }
...@@ -543,8 +542,7 @@ static void tz1090_gpio_register_banks(struct tz1090_gpio *priv) ...@@ -543,8 +542,7 @@ static void tz1090_gpio_register_banks(struct tz1090_gpio *priv)
ret = tz1090_gpio_bank_probe(&info); ret = tz1090_gpio_bank_probe(&info);
if (ret) { if (ret) {
dev_err(priv->dev, "failure registering %s\n", dev_err(priv->dev, "failure registering %pOF\n", node);
node->full_name);
of_node_put(node); of_node_put(node);
continue; continue;
} }
......
...@@ -30,10 +30,16 @@ ...@@ -30,10 +30,16 @@
#define VF610_GPIO_PER_PORT 32 #define VF610_GPIO_PER_PORT 32
struct fsl_gpio_soc_data {
/* SoCs has a Port Data Direction Register (PDDR) */
bool have_paddr;
};
struct vf610_gpio_port { struct vf610_gpio_port {
struct gpio_chip gc; struct gpio_chip gc;
void __iomem *base; void __iomem *base;
void __iomem *gpio_base; void __iomem *gpio_base;
const struct fsl_gpio_soc_data *sdata;
u8 irqc[VF610_GPIO_PER_PORT]; u8 irqc[VF610_GPIO_PER_PORT];
int irq; int irq;
}; };
...@@ -43,6 +49,7 @@ struct vf610_gpio_port { ...@@ -43,6 +49,7 @@ struct vf610_gpio_port {
#define GPIO_PCOR 0x08 #define GPIO_PCOR 0x08
#define GPIO_PTOR 0x0c #define GPIO_PTOR 0x0c
#define GPIO_PDIR 0x10 #define GPIO_PDIR 0x10
#define GPIO_PDDR 0x14
#define PORT_PCR(n) ((n) * 0x4) #define PORT_PCR(n) ((n) * 0x4)
#define PORT_PCR_IRQC_OFFSET 16 #define PORT_PCR_IRQC_OFFSET 16
...@@ -61,8 +68,13 @@ struct vf610_gpio_port { ...@@ -61,8 +68,13 @@ struct vf610_gpio_port {
static struct irq_chip vf610_gpio_irq_chip; static struct irq_chip vf610_gpio_irq_chip;
static const struct fsl_gpio_soc_data imx_data = {
.have_paddr = true,
};
static const struct of_device_id vf610_gpio_dt_ids[] = { static const struct of_device_id vf610_gpio_dt_ids[] = {
{ .compatible = "fsl,vf610-gpio" }, { .compatible = "fsl,vf610-gpio", .data = NULL, },
{ .compatible = "fsl,imx7ulp-gpio", .data = &imx_data, },
{ /* sentinel */ } { /* sentinel */ }
}; };
...@@ -79,8 +91,18 @@ static inline u32 vf610_gpio_readl(void __iomem *reg) ...@@ -79,8 +91,18 @@ static inline u32 vf610_gpio_readl(void __iomem *reg)
static int vf610_gpio_get(struct gpio_chip *gc, unsigned int gpio) static int vf610_gpio_get(struct gpio_chip *gc, unsigned int gpio)
{ {
struct vf610_gpio_port *port = gpiochip_get_data(gc); struct vf610_gpio_port *port = gpiochip_get_data(gc);
unsigned long mask = BIT(gpio);
return !!(vf610_gpio_readl(port->gpio_base + GPIO_PDIR) & BIT(gpio)); void __iomem *addr;
if (port->sdata && port->sdata->have_paddr) {
mask &= vf610_gpio_readl(port->gpio_base + GPIO_PDDR);
addr = mask ? port->gpio_base + GPIO_PDOR :
port->gpio_base + GPIO_PDIR;
return !!(vf610_gpio_readl(addr) & BIT(gpio));
} else {
return !!(vf610_gpio_readl(port->gpio_base + GPIO_PDIR)
& BIT(gpio));
}
} }
static void vf610_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) static void vf610_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
...@@ -96,12 +118,28 @@ static void vf610_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) ...@@ -96,12 +118,28 @@ static void vf610_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
static int vf610_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) static int vf610_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
{ {
struct vf610_gpio_port *port = gpiochip_get_data(chip);
unsigned long mask = BIT(gpio);
u32 val;
if (port->sdata && port->sdata->have_paddr) {
val = vf610_gpio_readl(port->gpio_base + GPIO_PDDR);
val &= ~mask;
vf610_gpio_writel(val, port->gpio_base + GPIO_PDDR);
}
return pinctrl_gpio_direction_input(chip->base + gpio); return pinctrl_gpio_direction_input(chip->base + gpio);
} }
static int vf610_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, static int vf610_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
int value) int value)
{ {
struct vf610_gpio_port *port = gpiochip_get_data(chip);
unsigned long mask = BIT(gpio);
if (port->sdata && port->sdata->have_paddr)
vf610_gpio_writel(mask, port->gpio_base + GPIO_PDDR);
vf610_gpio_set(chip, gpio, value); vf610_gpio_set(chip, gpio, value);
return pinctrl_gpio_direction_output(chip->base + gpio); return pinctrl_gpio_direction_output(chip->base + gpio);
...@@ -216,6 +254,8 @@ static struct irq_chip vf610_gpio_irq_chip = { ...@@ -216,6 +254,8 @@ static struct irq_chip vf610_gpio_irq_chip = {
static int vf610_gpio_probe(struct platform_device *pdev) static int vf610_gpio_probe(struct platform_device *pdev)
{ {
const struct of_device_id *of_id = of_match_device(vf610_gpio_dt_ids,
&pdev->dev);
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node; struct device_node *np = dev->of_node;
struct vf610_gpio_port *port; struct vf610_gpio_port *port;
...@@ -227,6 +267,7 @@ static int vf610_gpio_probe(struct platform_device *pdev) ...@@ -227,6 +267,7 @@ static int vf610_gpio_probe(struct platform_device *pdev)
if (!port) if (!port)
return -ENOMEM; return -ENOMEM;
port->sdata = of_id->data;
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
port->base = devm_ioremap_resource(dev, iores); port->base = devm_ioremap_resource(dev, iores);
if (IS_ERR(port->base)) if (IS_ERR(port->base))
......
...@@ -360,8 +360,8 @@ static int xgpio_probe(struct platform_device *pdev) ...@@ -360,8 +360,8 @@ static int xgpio_probe(struct platform_device *pdev)
/* Call the OF gpio helper to setup and register the GPIO device */ /* Call the OF gpio helper to setup and register the GPIO device */
status = of_mm_gpiochip_add_data(np, &chip->mmchip, chip); status = of_mm_gpiochip_add_data(np, &chip->mmchip, chip);
if (status) { if (status) {
pr_err("%s: error in probe function with status %d\n", pr_err("%pOF: error in probe function with status %d\n",
np->full_name, status); np, status);
return status; return status;
} }
......
...@@ -156,7 +156,7 @@ static int zevio_gpio_to_irq(struct gpio_chip *chip, unsigned pin) ...@@ -156,7 +156,7 @@ static int zevio_gpio_to_irq(struct gpio_chip *chip, unsigned pin)
return -ENXIO; return -ENXIO;
} }
static struct gpio_chip zevio_gpio_chip = { static const struct gpio_chip zevio_gpio_chip = {
.direction_input = zevio_gpio_direction_input, .direction_input = zevio_gpio_direction_input,
.direction_output = zevio_gpio_direction_output, .direction_output = zevio_gpio_direction_output,
.set = zevio_gpio_set, .set = zevio_gpio_set,
......
This diff is collapsed.
...@@ -61,7 +61,7 @@ static int acpi_gpiochip_find(struct gpio_chip *gc, void *data) ...@@ -61,7 +61,7 @@ static int acpi_gpiochip_find(struct gpio_chip *gc, void *data)
#ifdef CONFIG_PINCTRL #ifdef CONFIG_PINCTRL
/** /**
* acpi_gpiochip_pin_to_gpio_offset() - translates ACPI GPIO to Linux GPIO * acpi_gpiochip_pin_to_gpio_offset() - translates ACPI GPIO to Linux GPIO
* @chip: GPIO chip * @gdev: GPIO device
* @pin: ACPI GPIO pin number from GpioIo/GpioInt resource * @pin: ACPI GPIO pin number from GpioIo/GpioInt resource
* *
* Function takes ACPI GpioIo/GpioInt pin number as a parameter and * Function takes ACPI GpioIo/GpioInt pin number as a parameter and
...@@ -763,7 +763,7 @@ struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode, ...@@ -763,7 +763,7 @@ struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
* The function is idempotent, though each time it runs it will configure GPIO * The function is idempotent, though each time it runs it will configure GPIO
* pin direction according to the flags in GpioInt resource. * pin direction according to the flags in GpioInt resource.
* *
* Return: Linux IRQ number (>%0) on success, negative errno on failure. * Return: Linux IRQ number (> %0) on success, negative errno on failure.
*/ */
int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index) int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
{ {
......
...@@ -78,8 +78,8 @@ struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np, ...@@ -78,8 +78,8 @@ struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np,
ret = of_parse_phandle_with_args(np, propname, "#gpio-cells", index, ret = of_parse_phandle_with_args(np, propname, "#gpio-cells", index,
&gpiospec); &gpiospec);
if (ret) { if (ret) {
pr_debug("%s: can't parse '%s' property of node '%s[%d]'\n", pr_debug("%s: can't parse '%s' property of node '%pOF[%d]'\n",
__func__, propname, np->full_name, index); __func__, propname, np, index);
return ERR_PTR(ret); return ERR_PTR(ret);
} }
...@@ -93,8 +93,8 @@ struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np, ...@@ -93,8 +93,8 @@ struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np,
if (IS_ERR(desc)) if (IS_ERR(desc))
goto out; goto out;
pr_debug("%s: parsed '%s' property of node '%s[%d]' - status (%d)\n", pr_debug("%s: parsed '%s' property of node '%pOF[%d]' - status (%d)\n",
__func__, propname, np->full_name, index, __func__, propname, np, index,
PTR_ERR_OR_ZERO(desc)); PTR_ERR_OR_ZERO(desc));
out: out:
...@@ -273,14 +273,13 @@ static int of_gpiochip_scan_gpios(struct gpio_chip *chip) ...@@ -273,14 +273,13 @@ static int of_gpiochip_scan_gpios(struct gpio_chip *chip)
} }
/** /**
* of_gpio_simple_xlate - translate gpio_spec to the GPIO number and flags * of_gpio_simple_xlate - translate gpiospec to the GPIO number and flags
* @gc: pointer to the gpio_chip structure * @gc: pointer to the gpio_chip structure
* @np: device node of the GPIO chip * @gpiospec: GPIO specifier as found in the device tree
* @gpio_spec: gpio specifier as found in the device tree
* @flags: a flags pointer to fill in * @flags: a flags pointer to fill in
* *
* This is simple translation function, suitable for the most 1:1 mapped * This is simple translation function, suitable for the most 1:1 mapped
* gpio chips. This function performs only one sanity check: whether gpio * GPIO chips. This function performs only one sanity check: whether GPIO
* is less than ngpios (that is specified in the gpio_chip). * is less than ngpios (that is specified in the gpio_chip).
*/ */
int of_gpio_simple_xlate(struct gpio_chip *gc, int of_gpio_simple_xlate(struct gpio_chip *gc,
...@@ -337,7 +336,7 @@ int of_mm_gpiochip_add_data(struct device_node *np, ...@@ -337,7 +336,7 @@ int of_mm_gpiochip_add_data(struct device_node *np,
int ret = -ENOMEM; int ret = -ENOMEM;
struct gpio_chip *gc = &mm_gc->gc; struct gpio_chip *gc = &mm_gc->gc;
gc->label = kstrdup(np->full_name, GFP_KERNEL); gc->label = kasprintf(GFP_KERNEL, "%pOF", np);
if (!gc->label) if (!gc->label)
goto err0; goto err0;
...@@ -362,8 +361,7 @@ int of_mm_gpiochip_add_data(struct device_node *np, ...@@ -362,8 +361,7 @@ int of_mm_gpiochip_add_data(struct device_node *np,
err1: err1:
kfree(gc->label); kfree(gc->label);
err0: err0:
pr_err("%s: GPIO chip registration failed with status %d\n", pr_err("%pOF: GPIO chip registration failed with status %d\n", np, ret);
np->full_name, ret);
return ret; return ret;
} }
EXPORT_SYMBOL(of_mm_gpiochip_add_data); EXPORT_SYMBOL(of_mm_gpiochip_add_data);
...@@ -418,8 +416,8 @@ static int of_gpiochip_add_pin_range(struct gpio_chip *chip) ...@@ -418,8 +416,8 @@ static int of_gpiochip_add_pin_range(struct gpio_chip *chip)
group_names_propname, group_names_propname,
index, &name); index, &name);
if (strlen(name)) { if (strlen(name)) {
pr_err("%s: Group name of numeric GPIO ranges must be the empty string.\n", pr_err("%pOF: Group name of numeric GPIO ranges must be the empty string.\n",
np->full_name); np);
break; break;
} }
} }
...@@ -434,14 +432,14 @@ static int of_gpiochip_add_pin_range(struct gpio_chip *chip) ...@@ -434,14 +432,14 @@ static int of_gpiochip_add_pin_range(struct gpio_chip *chip)
} else { } else {
/* npins == 0: special range */ /* npins == 0: special range */
if (pinspec.args[1]) { if (pinspec.args[1]) {
pr_err("%s: Illegal gpio-range format.\n", pr_err("%pOF: Illegal gpio-range format.\n",
np->full_name); np);
break; break;
} }
if (!group_names) { if (!group_names) {
pr_err("%s: GPIO group range requested but no %s property.\n", pr_err("%pOF: GPIO group range requested but no %s property.\n",
np->full_name, group_names_propname); np, group_names_propname);
break; break;
} }
...@@ -452,8 +450,8 @@ static int of_gpiochip_add_pin_range(struct gpio_chip *chip) ...@@ -452,8 +450,8 @@ static int of_gpiochip_add_pin_range(struct gpio_chip *chip)
break; break;
if (!strlen(name)) { if (!strlen(name)) {
pr_err("%s: Group name of GPIO group range cannot be the empty string.\n", pr_err("%pOF: Group name of GPIO group range cannot be the empty string.\n",
np->full_name); np);
break; break;
} }
......
...@@ -540,8 +540,8 @@ static struct class gpio_class = { ...@@ -540,8 +540,8 @@ static struct class gpio_class = {
/** /**
* gpiod_export - export a GPIO through sysfs * gpiod_export - export a GPIO through sysfs
* @gpio: gpio to make available, already requested * @desc: GPIO to make available, already requested
* @direction_may_change: true if userspace may change gpio direction * @direction_may_change: true if userspace may change GPIO direction
* Context: arch_initcall or later * Context: arch_initcall or later
* *
* When drivers want to make a GPIO accessible to userspace after they * When drivers want to make a GPIO accessible to userspace after they
...@@ -649,7 +649,7 @@ static int match_export(struct device *dev, const void *desc) ...@@ -649,7 +649,7 @@ static int match_export(struct device *dev, const void *desc)
* gpiod_export_link - create a sysfs link to an exported GPIO node * gpiod_export_link - create a sysfs link to an exported GPIO node
* @dev: device under which to create symlink * @dev: device under which to create symlink
* @name: name of the symlink * @name: name of the symlink
* @gpio: gpio to create symlink to, already exported * @desc: GPIO to create symlink to, already exported
* *
* Set up a symlink from /sys/.../dev/name to /sys/class/gpio/gpioN * Set up a symlink from /sys/.../dev/name to /sys/class/gpio/gpioN
* node. Caller is responsible for unlinking. * node. Caller is responsible for unlinking.
...@@ -680,7 +680,7 @@ EXPORT_SYMBOL_GPL(gpiod_export_link); ...@@ -680,7 +680,7 @@ EXPORT_SYMBOL_GPL(gpiod_export_link);
/** /**
* gpiod_unexport - reverse effect of gpiod_export() * gpiod_unexport - reverse effect of gpiod_export()
* @gpio: gpio to make unavailable * @desc: GPIO to make unavailable
* *
* This is implicit on gpiod_free(). * This is implicit on gpiod_free().
*/ */
......
This diff is collapsed.
...@@ -219,7 +219,7 @@ int gpiod_hog(struct gpio_desc *desc, const char *name, ...@@ -219,7 +219,7 @@ int gpiod_hog(struct gpio_desc *desc, const char *name,
/* /*
* Return the GPIO number of the passed descriptor relative to its chip * Return the GPIO number of the passed descriptor relative to its chip
*/ */
static int __maybe_unused gpio_chip_hwgpio(const struct gpio_desc *desc) static inline int gpio_chip_hwgpio(const struct gpio_desc *desc)
{ {
return desc - &desc->gdev->descs[0]; return desc - &desc->gdev->descs[0];
} }
......
...@@ -180,8 +180,27 @@ struct gpio_chip { ...@@ -180,8 +180,27 @@ struct gpio_chip {
* If CONFIG_OF is enabled, then all GPIO controllers described in the * If CONFIG_OF is enabled, then all GPIO controllers described in the
* device tree automatically may have an OF translation * device tree automatically may have an OF translation
*/ */
/**
* @of_node:
*
* Pointer to a device tree node representing this GPIO controller.
*/
struct device_node *of_node; struct device_node *of_node;
int of_gpio_n_cells;
/**
* @of_gpio_n_cells:
*
* Number of cells used to form the GPIO specifier.
*/
unsigned int of_gpio_n_cells;
/**
* @of_xlate:
*
* Callback to translate a device tree GPIO specifier into a chip-
* relative GPIO number and flags.
*/
int (*of_xlate)(struct gpio_chip *gc, int (*of_xlate)(struct gpio_chip *gc,
const struct of_phandle_args *gpiospec, u32 *flags); const struct of_phandle_args *gpiospec, u32 *flags);
#endif #endif
...@@ -327,11 +346,10 @@ int gpiochip_generic_config(struct gpio_chip *chip, unsigned offset, ...@@ -327,11 +346,10 @@ int gpiochip_generic_config(struct gpio_chip *chip, unsigned offset,
/** /**
* struct gpio_pin_range - pin range controlled by a gpio chip * struct gpio_pin_range - pin range controlled by a gpio chip
* @head: list for maintaining set of pin ranges, used internally * @node: list for maintaining set of pin ranges, used internally
* @pctldev: pinctrl device which handles corresponding pins * @pctldev: pinctrl device which handles corresponding pins
* @range: actual range of pins controlled by a gpio controller * @range: actual range of pins controlled by a gpio controller
*/ */
struct gpio_pin_range { struct gpio_pin_range {
struct list_head node; struct list_head node;
struct pinctrl_dev *pctldev; struct pinctrl_dev *pctldev;
......
...@@ -60,11 +60,14 @@ struct gpiod_lookup_table { ...@@ -60,11 +60,14 @@ struct gpiod_lookup_table {
#ifdef CONFIG_GPIOLIB #ifdef CONFIG_GPIOLIB
void gpiod_add_lookup_table(struct gpiod_lookup_table *table); void gpiod_add_lookup_table(struct gpiod_lookup_table *table);
void gpiod_add_lookup_tables(struct gpiod_lookup_table **tables, size_t n);
void gpiod_remove_lookup_table(struct gpiod_lookup_table *table); void gpiod_remove_lookup_table(struct gpiod_lookup_table *table);
#else #else
static inline static inline
void gpiod_add_lookup_table(struct gpiod_lookup_table *table) {} void gpiod_add_lookup_table(struct gpiod_lookup_table *table) {}
static inline static inline
void gpiod_add_lookup_tables(struct gpiod_lookup_table **tables, size_t n) {}
static inline
void gpiod_remove_lookup_table(struct gpiod_lookup_table *table) {} void gpiod_remove_lookup_table(struct gpiod_lookup_table *table) {}
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment