diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-01-29 09:43:39 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-01-29 09:43:39 -0800 |
commit | fa889d85551e0bd962fdefe1cc113f9ba1d04a36 (patch) | |
tree | 4f74147dc17e9fa39d06053a949c5491ccf2bace | |
parent | b3a6082223369203d7e7db7e81253ac761377644 (diff) | |
parent | 0282c72d30d32913d641dc81f3f38607ace98802 (diff) |
Merge tag 'gpio-v5.6-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 GPIO changes for the v5.6 kernel cycle.
This is a pretty calm cycle so far, nothing special going on really.
Some more changes will come in from the irqchip and pin control trees.
I also deleted an orphan include file for FMC that was dangling since
subsystem was removed.
Core changes:
- Document the usecases for the kernelspace vs userspace handling of
GPIOs.
- Handle MSI (message signalled interrupts) properly in the core
hierarchical irqdomain code.
- Fix a rare race condition while initializing the descriptor array.
New drivers:
- Xylon LogiCVC GPIO driver.
- WDC934x GPIO controller driver.
Driver improvements:
- Implemented suspend/resume in the Tegra driver.
- MPC8xx edge detection fixup.
- Properly convert ThunderX to use hierarchical irqdomain with
GPIOLIB_IRQCHIP on top of the revert of the previous buggy
switchover. This time it works (hopefully).
Misc:
- Drop a FMC remnant file <linux/ipmi-fru.h>
- A slew of fixes"
* tag 'gpio-v5.6-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio: (48 commits)
MAINTAINERS: Replace Tien Hock Loh as Altera PIO maintainer
gpiolib: hold gpio devices lock until ->descs array is initialised
gpio: aspeed-sgpio: fixed typos
gpio: mvebu: clear irq in edge cause register before unmask edge irq
gpiolib: Lower verbosity when allocating hierarchy irq
gpiolib: Remove duplicated function gpio_do_set_config()
gpio: Fix the no return statement warning
gpio: wcd934x: Add support to wcd934x gpio controller
gpiolib: remove set but not used variable 'config'
gpio: vx855: fixed a typo
gpio: mockup: sort headers alphabetically
gpio: mockup: update the license tag
gpio: Remove the unused flags
gpiolib: Set lockdep class for hierarchical irq domains
gpio: thunderx: Switch to GPIOLIB_IRQCHIP
gpiolib: Add the support for the msi parent domain
gpiolib: Add support for the irqdomain which doesn't use irq_fwspec as arg
gpio: Add use guidance documentation
dt-bindings: gpio: wcd934x: Add bindings for gpio
gpio: altera: change to platform_get_irq_optional to avoid false-positive error
...
38 files changed, 814 insertions, 413 deletions
diff --git a/Documentation/devicetree/bindings/gpio/qcom,wcd934x-gpio.yaml b/Documentation/devicetree/bindings/gpio/qcom,wcd934x-gpio.yaml new file mode 100644 index 000000000000..32a566ec3558 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/qcom,wcd934x-gpio.yaml @@ -0,0 +1,47 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/gpio/qcom,wcd934x-gpio.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: WCD9340/WCD9341 GPIO controller + +maintainers: + - Srinivas Kandagatla <srinivas.kandagatla@linaro.org> + +description: | + Qualcomm Technologies Inc WCD9340/WCD9341 Audio Codec has integrated + gpio controller to control 5 gpios on the chip. + +properties: + compatible: + enum: + - qcom,wcd9340-gpio + - qcom,wcd9341-gpio + + reg: + maxItems: 1 + + gpio-controller: true + + '#gpio-cells': + const: 2 + +required: + - compatible + - reg + - gpio-controller + - "#gpio-cells" + +additionalProperties: false + +examples: + - | + wcdgpio: gpio@42 { + compatible = "qcom,wcd9340-gpio"; + reg = <0x042 0x2>; + gpio-controller; + #gpio-cells = <2>; + }; + +... diff --git a/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt b/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt index 41e5fed0f842..10dce84b1545 100644 --- a/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt +++ b/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt @@ -18,7 +18,8 @@ Required Properties: - "renesas,gpio-r8a7793": for R8A7793 (R-Car M2-N) 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-r8a7796": for R8A7796 (R-Car M3-W) compatible GPIO controller. + - "renesas,gpio-r8a7796": for R8A77960 (R-Car M3-W) compatible GPIO controller. + - "renesas,gpio-r8a77961": for R8A77961 (R-Car M3-W+) compatible GPIO controller. - "renesas,gpio-r8a77965": for R8A77965 (R-Car M3-N) compatible GPIO controller. - "renesas,gpio-r8a77970": for R8A77970 (R-Car V3M) compatible GPIO controller. - "renesas,gpio-r8a77980": for R8A77980 (R-Car V3H) compatible GPIO controller. diff --git a/Documentation/devicetree/bindings/gpio/xylon,logicvc-gpio.yaml b/Documentation/devicetree/bindings/gpio/xylon,logicvc-gpio.yaml new file mode 100644 index 000000000000..d102888c1be7 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/xylon,logicvc-gpio.yaml @@ -0,0 +1,69 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +# Copyright 2019 Bootlin +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/gpio/xylon,logicvc-gpio.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Xylon LogiCVC GPIO controller + +maintainers: + - Paul Kocialkowski <paul.kocialkowski@bootlin.com> + +description: | + The LogiCVC GPIO describes the GPIO block included in the LogiCVC display + controller. These are meant to be used for controlling display-related + signals. + + The controller exposes GPIOs from the display and power control registers, + which are mapped by the driver as follows: + - GPIO[4:0] (display control) mapped to index 0-4 + - EN_BLIGHT (power control) mapped to index 5 + - EN_VDD (power control) mapped to index 6 + - EN_VEE (power control) mapped to index 7 + - V_EN (power control) mapped to index 8 + +properties: + $nodename: + pattern: "^gpio@[0-9a-f]+$" + + compatible: + enum: + - xylon,logicvc-3.02.a-gpio + + reg: + maxItems: 1 + + "#gpio-cells": + const: 2 + + gpio-controller: true + + gpio-line-names: + minItems: 1 + maxItems: 9 + +required: + - compatible + - reg + - "#gpio-cells" + - gpio-controller + +examples: + - | + logicvc: logicvc@43c00000 { + compatible = "xylon,logicvc-3.02.a", "syscon", "simple-mfd"; + reg = <0x43c00000 0x6000>; + + #address-cells = <1>; + #size-cells = <1>; + + logicvc_gpio: gpio@40 { + compatible = "xylon,logicvc-3.02.a-gpio"; + reg = <0x40 0x40>; + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = "GPIO0", "GPIO1", "GPIO2", "GPIO3", "GPIO4", + "EN_BLIGHT", "EN_VDD", "EN_VEE", "V_EN"; + }; + }; diff --git a/Documentation/devicetree/bindings/mfd/xylon,logicvc.yaml b/Documentation/devicetree/bindings/mfd/xylon,logicvc.yaml new file mode 100644 index 000000000000..abc9937506e0 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/xylon,logicvc.yaml @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +# Copyright 2019 Bootlin +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/mfd/xylon,logicvc.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Xylon LogiCVC multi-function device + +maintainers: + - Paul Kocialkowski <paul.kocialkowski@bootlin.com> + +description: | + The LogiCVC is a display controller that also contains a GPIO controller. + As a result, a multi-function device is exposed as parent of the display + and GPIO blocks. + +properties: + compatible: + items: + - enum: + - xylon,logicvc-3.02.a + - const: syscon + - const: simple-mfd + + reg: + maxItems: 1 + +select: + properties: + compatible: + contains: + enum: + - xylon,logicvc-3.02.a + + required: + - compatible + +required: + - compatible + - reg + +examples: + - | + logicvc: logicvc@43c00000 { + compatible = "xylon,logicvc-3.02.a", "syscon", "simple-mfd"; + reg = <0x43c00000 0x6000>; + #address-cells = <1>; + #size-cells = <1>; + }; diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 6046f4555852..9cb3bc683db7 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -1060,6 +1060,8 @@ patternProperties: description: Xilinx "^xunlong,.*": description: Shenzhen Xunlong Software CO.,Limited + "^xylon,.*": + description: Xylon "^yones-toptech,.*": description: Yones Toptech Co., Ltd. "^ysoft,.*": diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst index 20e07e40be02..46c13780994c 100644 --- a/Documentation/driver-api/driver-model/devres.rst +++ b/Documentation/driver-api/driver-model/devres.rst @@ -267,6 +267,8 @@ DRM GPIO devm_gpiod_get() + devm_gpiod_get_array() + devm_gpiod_get_array_optional() devm_gpiod_get_index() devm_gpiod_get_index_optional() devm_gpiod_get_optional() diff --git a/Documentation/driver-api/gpio/drivers-on-gpio.rst b/Documentation/driver-api/gpio/drivers-on-gpio.rst index f3a189320e11..820b403d50f6 100644 --- a/Documentation/driver-api/gpio/drivers-on-gpio.rst +++ b/Documentation/driver-api/gpio/drivers-on-gpio.rst @@ -95,7 +95,7 @@ to emulate MCTRL (modem control) signals CTS/RTS by using two GPIO lines. The MTD NOR flash has add-ons for extra GPIO lines too, though the address bus is usually connected directly to the flash. -Use those instead of talking directly to the GPIOs using sysfs; they integrate -with kernel frameworks better than your userspace code could. Needless to say, -just using the appropriate kernel drivers will simplify and speed up your -embedded hacking in particular by providing ready-made components. +Use those instead of talking directly to the GPIOs from userspace; they +integrate with kernel frameworks better than your userspace code could. +Needless to say, just using the appropriate kernel drivers will simplify and +speed up your embedded hacking in particular by providing ready-made components. diff --git a/Documentation/driver-api/gpio/index.rst b/Documentation/driver-api/gpio/index.rst index 5b61032aa4ea..1d48fe248f05 100644 --- a/Documentation/driver-api/gpio/index.rst +++ b/Documentation/driver-api/gpio/index.rst @@ -8,6 +8,7 @@ Contents: :maxdepth: 2 intro + using-gpio driver consumer board diff --git a/Documentation/driver-api/gpio/using-gpio.rst b/Documentation/driver-api/gpio/using-gpio.rst new file mode 100644 index 000000000000..dda069444032 --- /dev/null +++ b/Documentation/driver-api/gpio/using-gpio.rst @@ -0,0 +1,50 @@ +========================= +Using GPIO Lines in Linux +========================= + +The Linux kernel exists to abstract and present hardware to users. GPIO lines +as such are normally not user facing abstractions. The most obvious, natural +and preferred way to use GPIO lines is to let kernel hardware drivers deal +with them. + +For examples of already existing generic drivers that will also be good +examples for any other kernel drivers you want to author, refer to +:doc:`drivers-on-gpio` + +For any kind of mass produced system you want to support, such as servers, +laptops, phones, tablets, routers, and any consumer or office or business goods +using appropriate kernel drivers is paramount. Submit your code for inclusion +in the upstream Linux kernel when you feel it is mature enough and you will get +help to refine it, see :doc:`../../process/submitting-patches`. + +In Linux GPIO lines also have a userspace ABI. + +The userspace ABI is intended for one-off deployments. Examples are prototypes, +factory lines, maker community projects, workshop specimen, production tools, +industrial automation, PLC-type use cases, door controllers, in short a piece +of specialized equipment that is not produced by the numbers, requiring +operators to have a deep knowledge of the equipment and knows about the +software-hardware interface to be set up. They should not have a natural fit +to any existing kernel subsystem and not be a good fit for an operating system, +because of not being reusable or abstract enough, or involving a lot of non +computer hardware related policy. + +Applications that have a good reason to use the industrial I/O (IIO) subsystem +from userspace will likely be a good fit for using GPIO lines from userspace as +well. + +Do not under any circumstances abuse the GPIO userspace ABI to cut corners in +any product development projects. If you use it for prototyping, then do not +productify the prototype: rewrite it using proper kernel drivers. Do not under +any circumstances deploy any uniform products using GPIO from userspace. + +The userspace ABI is a character device for each GPIO hardware unit (GPIO chip). +These devices will appear on the system as ``/dev/gpiochip0`` thru +``/dev/gpiochipN``. Examples of how to directly use the userspace ABI can be +found in the kernel tree ``tools/gpio`` subdirectory. + +For structured and managed applications, we recommend that you make use of the +libgpiod_ library. This provides helper abstractions, command line utlities +and arbitration for multiple simultaneous consumers on the same GPIO chip. + +.. _libgpiod: https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/ diff --git a/MAINTAINERS b/MAINTAINERS index d51ce1a0a817..e12989b9dfd3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -734,7 +734,7 @@ S: Maintained F: drivers/mailbox/mailbox-altera.c ALTERA PIO DRIVER -M: Tien Hock Loh <thloh@altera.com> +M: Joyce Ooi <joyce.ooi@intel.com> L: linux-gpio@vger.kernel.org S: Maintained F: drivers/gpio/gpio-altera.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index f57d95a3db02..081776b91e5a 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -312,6 +312,12 @@ config GPIO_IXP4XX IXP4xx series of chips. If unsure, say N. +config GPIO_LOGICVC + tristate "Xylon LogiCVC GPIO support" + depends on MFD_SYSCON && OF + help + Say yes here to support GPIO functionality of the Xylon LogiCVC + programmable logic block. config GPIO_LOONGSON bool "Loongson-2/3 GPIO support" @@ -582,6 +588,7 @@ config GPIO_THUNDERX tristate "Cavium ThunderX/OCTEON-TX GPIO" depends on ARCH_THUNDER || (64BIT && COMPILE_TEST) depends on PCI_MSI + select GPIOLIB_IRQCHIP select IRQ_DOMAIN_HIERARCHY select IRQ_FASTEOI_HIERARCHY_HANDLERS help @@ -621,6 +628,13 @@ config GPIO_VX855 additional drivers must be enabled in order to use the functionality of the device. +config GPIO_WCD934X + tristate "Qualcomm Technologies Inc WCD9340/WCD9341 gpio controller driver" + depends on MFD_WCD934X && OF_GPIO + help + This driver is to supprot GPIO block found on the Qualcomm Technologies + Inc WCD9340/WCD9341 Audio Codec. + config GPIO_XGENE bool "APM X-Gene GPIO controller support" depends on ARM64 && OF_GPIO diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 11eeeebbde0d..af158b7e1a43 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -69,6 +69,7 @@ obj-$(CONFIG_GPIO_IT87) += gpio-it87.o obj-$(CONFIG_GPIO_IXP4XX) += gpio-ixp4xx.o obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o obj-$(CONFIG_GPIO_KEMPLD) += gpio-kempld.o +obj-$(CONFIG_GPIO_LOGICVC) += gpio-logicvc.o obj-$(CONFIG_GPIO_LOONGSON1) += gpio-loongson1.o obj-$(CONFIG_GPIO_LOONGSON) += gpio-loongson.o obj-$(CONFIG_GPIO_LP3943) += gpio-lp3943.o @@ -158,6 +159,7 @@ obj-$(CONFIG_GPIO_VF610) += gpio-vf610.o obj-$(CONFIG_GPIO_VIPERBOARD) += gpio-viperboard.o obj-$(CONFIG_GPIO_VR41XX) += gpio-vr41xx.o obj-$(CONFIG_GPIO_VX855) += gpio-vx855.o +obj-$(CONFIG_GPIO_WCD934X) += gpio-wcd934x.o obj-$(CONFIG_GPIO_WHISKEY_COVE) += gpio-wcove.o obj-$(CONFIG_GPIO_WINBOND) += gpio-winbond.o obj-$(CONFIG_GPIO_WM831X) += gpio-wm831x.o diff --git a/drivers/gpio/TODO b/drivers/gpio/TODO index 76f8c7ff18ff..3a44e6ae52bd 100644 --- a/drivers/gpio/TODO +++ b/drivers/gpio/TODO @@ -10,6 +10,28 @@ approach. This means that GPIO consumers, drivers and machine descriptions ideally have no use or idea of the global GPIO numberspace that has/was used in the inception of the GPIO subsystem. +The numberspace issue is the same as to why irq is moving away from irq +numbers to IRQ descriptors. + +The underlying motivation for this is that the GPIO numberspace has become +unmanageable: machine board files tend to become full of macros trying to +establish the numberspace at compile-time, making it hard to add any numbers +in the middle (such as if you missed a pin on a chip) without the numberspace +breaking. + +Machine descriptions such as device tree or ACPI does not have a concept of the +Linux GPIO number as those descriptions are external to the Linux kernel +and treat GPIO lines as abstract entities. + +The runtime-assigned GPIO numberspace (what you get if you assign the GPIO +base as -1 in struct gpio_chip) has also became unpredictable due to factors +such as probe ordering and the introduction of -EPROBE_DEFER making probe +ordering of independent GPIO chips essentially unpredictable, as their base +number will be assigned on a first come first serve basis. + +The best way to get out of the problem is to make the global GPIO numbers +unimportant by simply not using them. GPIO descriptors deal with this. + Work items: - Convert all GPIO device drivers to only #include <linux/gpio/driver.h> @@ -33,7 +55,7 @@ This header and helpers appeared at one point when there was no proper driver infrastructure for doing simpler MMIO GPIO devices and there was no core support for parsing device tree GPIOs from the core library with the [devm_]gpiod_get() calls we have today that will implicitly go into -the device tree back-end. +the device tree back-end. It is legacy and should not be used in new code. Work items: @@ -59,6 +81,15 @@ Work items: uses <linux/gpio/consumer.h> or <linux/gpio/driver.h> instead. +Get rid of <linux/gpio.h> + +This legacy header is a one stop shop for anything GPIO is closely tied +to the global GPIO numberspace. The endgame of the above refactorings will +be the removal of <linux/gpio.h> and from that point only the specialized +headers under <linux/gpio/*.h> will be used. This requires all the above to +be completed and is expected to take a long time. + + Collect drivers Collect GPIO drivers from arch/* and other places that should be placed @@ -109,7 +140,7 @@ try to cover any generic kind of irqchip cascaded from a GPIO. int irq; /* from platform etc */ struct my_gpio *g; - struct gpio_irq_chip *girq + struct gpio_irq_chip *girq; /* Set up the irqchip dynamically */ g->irq.name = "my_gpio_irq"; @@ -137,9 +168,14 @@ try to cover any generic kind of irqchip cascaded from a GPIO. - Look over and identify any remaining easily converted drivers and dry-code conversions to gpiolib irqchip for maintainers to test -- Support generic hierarchical GPIO interrupts: these are for the - non-cascading case where there is one IRQ per GPIO line, there is - currently no common infrastructure for this. +- Drop gpiochip_set_chained_irqchip() when all the chained irqchips + have been converted to the above infrastructure. + +- Add more infrastructure to make it possible to also pass a threaded + irqchip in struct gpio_irq_chip. + +- Drop gpiochip_irqchip_add_nested() when all the chained irqchips + have been converted to the above infrastructure. Increase integration with pin control diff --git a/drivers/gpio/gpio-altera.c b/drivers/gpio/gpio-altera.c index 9f2e6b04c361..cc4ba71e4fe3 100644 --- a/drivers/gpio/gpio-altera.c +++ b/drivers/gpio/gpio-altera.c @@ -266,7 +266,7 @@ static int altera_gpio_probe(struct platform_device *pdev) altera_gc->mmchip.gc.owner = THIS_MODULE; altera_gc->mmchip.gc.parent = &pdev->dev; - altera_gc->mapped_irq = platform_get_irq(pdev, 0); + altera_gc->mapped_irq = platform_get_irq_optional(pdev, 0); if (altera_gc->mapped_irq < 0) goto skip_irq; diff --git a/drivers/gpio/gpio-aspeed-sgpio.c b/drivers/gpio/gpio-aspeed-sgpio.c index 8319812593e3..d16645c1d8d9 100644 --- a/drivers/gpio/gpio-aspeed-sgpio.c +++ b/drivers/gpio/gpio-aspeed-sgpio.c @@ -391,7 +391,7 @@ static int aspeed_sgpio_setup_irqs(struct aspeed_sgpio *gpio, gpio->irq = rc; - /* Disable IRQ and clear Interrupt status registers for all SPGIO Pins. */ + /* Disable IRQ and clear Interrupt status registers for all SGPIO Pins. */ for (i = 0; i < ARRAY_SIZE(aspeed_sgpio_banks); i++) { bank = &aspeed_sgpio_banks[i]; /* disable irq enable bits */ diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c index f1037b61f763..879db23d8454 100644 --- a/drivers/gpio/gpio-aspeed.c +++ b/drivers/gpio/gpio-aspeed.c @@ -978,7 +978,7 @@ static int aspeed_gpio_set_config(struct gpio_chip *chip, unsigned int offset, } /** - * aspeed_gpio_copro_set_ops - Sets the callbacks used for handhsaking with + * aspeed_gpio_copro_set_ops - Sets the callbacks used for handshaking with * the coprocessor for shared GPIO banks * @ops: The callbacks * @data: Pointer passed back to the callbacks diff --git a/drivers/gpio/gpio-bcm-kona.c b/drivers/gpio/gpio-bcm-kona.c index 4122683eb1f9..baee8c3f06ad 100644 --- a/drivers/gpio/gpio-bcm-kona.c +++ b/drivers/gpio/gpio-bcm-kona.c @@ -19,7 +19,6 @@ #include <linux/io.h> #include <linux/gpio/driver.h> #include <linux/of_device.h> -#include <linux/of_irq.h> #include <linux/init.h> #include <linux/irqdomain.h> #include <linux/irqchip/chained_irq.h> @@ -586,11 +585,18 @@ static int bcm_kona_gpio_probe(struct platform_device *pdev) kona_gpio->gpio_chip = template_chip; chip = &kona_gpio->gpio_chip; - kona_gpio->num_bank = of_irq_count(dev->of_node); - if (kona_gpio->num_bank == 0) { + ret = platform_irq_count(pdev); + if (!ret) { dev_err(dev, "Couldn't determine # GPIO banks\n"); return -ENOENT; + } else if (ret < 0) { + if (ret != -EPROBE_DEFER) + dev_err(dev, "Couldn't determine GPIO banks: (%pe)\n", + ERR_PTR(ret)); + return ret; } + kona_gpio->num_bank = ret; + if (kona_gpio->num_bank > GPIO_MAX_BANK_NUM) { dev_err(dev, "Too many GPIO banks configured (max=%d)\n", GPIO_MAX_BANK_NUM); diff --git a/drivers/gpio/gpio-creg-snps.c b/drivers/gpio/gpio-creg-snps.c index ff19a8ad5663..1d0827e79703 100644 --- a/drivers/gpio/gpio-creg-snps.c +++ b/drivers/gpio/gpio-creg-snps.c @@ -64,11 +64,11 @@ static int creg_gpio_validate_pg(struct device *dev, struct creg_gpio *hcg, if (layout->bit_per_gpio[i] < 1 || layout->bit_per_gpio[i] > 8) return -EINVAL; - /* Check that on valiue fits it's placeholder */ + /* Check that on value fits its placeholder */ if (GENMASK(31, layout->bit_per_gpio[i]) & layout->on[i]) return -EINVAL; - /* Check that off valiue fits it's placeholder */ + /* Check that off value fits its placeholder */ if (GENMASK(31, layout->bit_per_gpio[i]) & layout->off[i]) return -EINVAL; diff --git a/drivers/gpio/gpio-grgpio.c b/drivers/gpio/gpio-grgpio.c index 08234e64993a..f954359c9544 100644 --- a/drivers/gpio/gpio-grgpio.c +++ b/drivers/gpio/gpio-grgpio.c @@ -253,17 +253,16 @@ static int grgpio_irq_map(struct irq_domain *d, unsigned int irq, lirq->irq = irq; uirq = &priv->uirqs[lirq->index]; if (uirq->refcnt == 0) { + spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); ret = request_irq(uirq->uirq, grgpio_irq_handler, 0, dev_name(priv->dev), priv); if (ret) { dev_err(priv->dev, "Could not request underlying irq %d\n", uirq->uirq); - - spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); - return ret; } + spin_lock_irqsave(&priv->gc.bgpio_lock, flags); } uirq->refcnt++; @@ -309,8 +308,11 @@ static void grgpio_irq_unmap(struct irq_domain *d, unsigned int irq) if (index >= 0) { uirq = &priv->uirqs[lirq->index]; uirq->refcnt--; - if (uirq->refcnt == 0) + if (uirq->refcnt == 0) { + spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); free_irq(uirq->uirq, priv); + return; + } } spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); @@ -433,12 +435,9 @@ static int grgpio_probe(struct platform_device *ofdev) static int grgpio_remove(struct platform_device *ofdev) { struct grgpio_priv *priv = platform_get_drvdata(ofdev); - unsigned long flags; int i; int ret = 0; - spin_lock_irqsave(&priv->gc.bgpio_lock, flags); - if (priv->domain) { for (i = 0; i < GRGPIO_MAX_NGPIO; i++) { if (priv->uirqs[i].refcnt != 0) { @@ -454,8 +453,6 @@ static int grgpio_remove(struct platform_device *ofdev) irq_domain_remove(priv->domain); out: - spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); - return ret; } diff --git a/drivers/gpio/gpio-logicvc.c b/drivers/gpio/gpio-logicvc.c new file mode 100644 index 000000000000..015632cf159f --- /dev/null +++ b/drivers/gpio/gpio-logicvc.c @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 Bootlin + * Author: Paul Kocialkowski <paul.kocialkowski@bootlin.com> + */ + +#include <linux/err.h> +#include <linux/gpio/driver.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/of_address.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/mfd/syscon.h> + +#define LOGICVC_CTRL_REG 0x40 +#define LOGICVC_CTRL_GPIO_SHIFT 11 +#define LOGICVC_CTRL_GPIO_BITS 5 + +#define LOGICVC_POWER_CTRL_REG 0x78 +#define LOGICVC_POWER_CTRL_GPIO_SHIFT 0 +#define LOGICVC_POWER_CTRL_GPIO_BITS 4 + +struct logicvc_gpio { + struct gpio_chip chip; + struct regmap *regmap; +}; + +static void logicvc_gpio_offset(struct logicvc_gpio *logicvc, unsigned offset, + unsigned int *reg, unsigned int *bit) +{ + if (offset >= LOGICVC_CTRL_GPIO_BITS) { + *reg = LOGICVC_POWER_CTRL_REG; + + /* To the (virtual) power ctrl offset. */ + offset -= LOGICVC_CTRL_GPIO_BITS; + /* To the actual bit offset in reg. */ + offset += LOGICVC_POWER_CTRL_GPIO_SHIFT; + } else { + *reg = LOGICVC_CTRL_REG; + |