From c8f3d144004dd3f471ffd414690d15a005e4acd6 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Thu, 19 Sep 2019 17:39:17 +0800 Subject: [PATCH 01/12] gpio: mxc: Only get the second IRQ when there is more than one IRQ On some of i.MX SoCs like i.MX8QXP, there is ONLY one IRQ for each GPIO bank, so it is better to check the IRQ count before getting second IRQ to avoid below error message during probe: [ 1.070908] gpio-mxc 5d080000.gpio: IRQ index 1 not found [ 1.077420] gpio-mxc 5d090000.gpio: IRQ index 1 not found [ 1.083766] gpio-mxc 5d0a0000.gpio: IRQ index 1 not found [ 1.090122] gpio-mxc 5d0b0000.gpio: IRQ index 1 not found [ 1.096470] gpio-mxc 5d0c0000.gpio: IRQ index 1 not found [ 1.102804] gpio-mxc 5d0d0000.gpio: IRQ index 1 not found [ 1.109144] gpio-mxc 5d0e0000.gpio: IRQ index 1 not found [ 1.115475] gpio-mxc 5d0f0000.gpio: IRQ index 1 not found Signed-off-by: Anson Huang Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-mxc.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c index 7907a8755866..c77d474185f3 100644 --- a/drivers/gpio/gpio-mxc.c +++ b/drivers/gpio/gpio-mxc.c @@ -411,6 +411,7 @@ static int mxc_gpio_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct mxc_gpio_port *port; + int irq_count; int irq_base; int err; @@ -426,9 +427,15 @@ static int mxc_gpio_probe(struct platform_device *pdev) if (IS_ERR(port->base)) return PTR_ERR(port->base); - port->irq_high = platform_get_irq(pdev, 1); - if (port->irq_high < 0) - port->irq_high = 0; + irq_count = platform_irq_count(pdev); + if (irq_count < 0) + return irq_count; + + if (irq_count > 1) { + port->irq_high = platform_get_irq(pdev, 1); + if (port->irq_high < 0) + port->irq_high = 0; + } port->irq = platform_get_irq(pdev, 0); if (port->irq < 0) From bcc6d99ac913e3115cfa564534c432b950408e21 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Mon, 16 Sep 2019 11:46:23 +0200 Subject: [PATCH 02/12] gpiolib: sanitize flags before allocating memory in lineevent_create() Move all the flags sanitization before any memory allocation in lineevent_create() in order to remove a couple unneeded gotos. Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpiolib.c | 42 ++++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index bdbc1649eafa..e8964493c571 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -894,6 +894,24 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip) if (copy_from_user(&eventreq, ip, sizeof(eventreq))) return -EFAULT; + offset = eventreq.lineoffset; + lflags = eventreq.handleflags; + eflags = eventreq.eventflags; + + if (offset >= gdev->ngpio) + return -EINVAL; + + /* Return an error if a unknown flag is set */ + if ((lflags & ~GPIOHANDLE_REQUEST_VALID_FLAGS) || + (eflags & ~GPIOEVENT_REQUEST_VALID_FLAGS)) + return -EINVAL; + + /* This is just wrong: we don't look for events on output lines */ + if ((lflags & GPIOHANDLE_REQUEST_OUTPUT) || + (lflags & GPIOHANDLE_REQUEST_OPEN_DRAIN) || + (lflags & GPIOHANDLE_REQUEST_OPEN_SOURCE)) + return -EINVAL; + le = kzalloc(sizeof(*le), GFP_KERNEL); if (!le) return -ENOMEM; @@ -911,30 +929,6 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip) } } - offset = eventreq.lineoffset; - lflags = eventreq.handleflags; - eflags = eventreq.eventflags; - - if (offset >= gdev->ngpio) { - ret = -EINVAL; - goto out_free_label; - } - - /* Return an error if a unknown flag is set */ - if ((lflags & ~GPIOHANDLE_REQUEST_VALID_FLAGS) || - (eflags & ~GPIOEVENT_REQUEST_VALID_FLAGS)) { - ret = -EINVAL; - goto out_free_label; - } - - /* This is just wrong: we don't look for events on output lines */ - if ((lflags & GPIOHANDLE_REQUEST_OUTPUT) || - (lflags & GPIOHANDLE_REQUEST_OPEN_DRAIN) || - (lflags & GPIOHANDLE_REQUEST_OPEN_SOURCE)) { - ret = -EINVAL; - goto out_free_label; - } - desc = &gdev->descs[offset]; ret = gpiod_request(desc, le->label); if (ret) From 35c3ba911ae19538b3855165f8e2c71ce853c0ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Neusch=C3=A4fer?= Date: Wed, 2 Oct 2019 16:41:41 +0200 Subject: [PATCH 03/12] Documentation: gpio: driver: Format code blocks properly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a lot of Sphinx warnings, and makes the code blocks look nice in HTML. Signed-off-by: Jonathan Neuschäfer Signed-off-by: Bartosz Golaszewski --- Documentation/driver-api/gpio/driver.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/driver-api/gpio/driver.rst b/Documentation/driver-api/gpio/driver.rst index 3fdb32422f8a..18dca55eddfd 100644 --- a/Documentation/driver-api/gpio/driver.rst +++ b/Documentation/driver-api/gpio/driver.rst @@ -415,6 +415,8 @@ If you do this, the additional irq_chip will be set up by gpiolib at the same time as setting up the rest of the GPIO functionality. The following is a typical example of a cascaded interrupt handler using gpio_irq_chip: +.. code-block:: c + /* Typical state container with dynamic irqchip */ struct my_gpio { struct gpio_chip gc; @@ -450,6 +452,8 @@ is a typical example of a cascaded interrupt handler using gpio_irq_chip: The helper support using hierarchical interrupt controllers as well. In this case the typical set-up will look like this: +.. code-block:: c + /* Typical state container with dynamic irqchip */ struct my_gpio { struct gpio_chip gc; From 5ede17d61592844c6d09eaba513f9de14920965c Mon Sep 17 00:00:00 2001 From: Biju Das Date: Mon, 23 Sep 2019 14:27:48 +0100 Subject: [PATCH 04/12] dt-bindings: gpio: rcar: Add DT binding for r8a774b1 Document Renesas' RZ/G2N (R8A774B1) GPIO blocks compatibility within the relevant dt-bindings. Signed-off-by: Biju Das Reviewed-by: Geert Uytterhoeven Acked-by: Rob Herring Signed-off-by: Bartosz Golaszewski --- Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt b/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt index f3f2c468c1b6..41e5fed0f842 100644 --- a/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt +++ b/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt @@ -8,6 +8,7 @@ Required Properties: - "renesas,gpio-r8a7745": for R8A7745 (RZ/G1E) compatible GPIO controller. - "renesas,gpio-r8a77470": for R8A77470 (RZ/G1C) compatible GPIO controller. - "renesas,gpio-r8a774a1": for R8A774A1 (RZ/G2M) compatible GPIO controller. + - "renesas,gpio-r8a774b1": for R8A774B1 (RZ/G2N) compatible GPIO controller. - "renesas,gpio-r8a774c0": for R8A774C0 (RZ/G2E) compatible GPIO controller. - "renesas,gpio-r8a7778": for R8A7778 (R-Car M1) compatible GPIO controller. - "renesas,gpio-r8a7779": for R8A7779 (R-Car H1) compatible GPIO controller. From cf62b4e44c49a0bdf363464168e3c9c6e1d8efe5 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Wed, 2 Oct 2019 18:28:52 +0200 Subject: [PATCH 05/12] gpio: xgene: remove redundant error message There's no need to emit an error message on probe failure unless we're printing some meaningful info. Otherwise the core driver code will inform us about a probe error. Signed-off-by: Bartosz Golaszewski Reviewed-by: Linus Walleij --- drivers/gpio/gpio-xgene.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/drivers/gpio/gpio-xgene.c b/drivers/gpio/gpio-xgene.c index 2918363884de..900b38a7dba8 100644 --- a/drivers/gpio/gpio-xgene.c +++ b/drivers/gpio/gpio-xgene.c @@ -160,23 +160,17 @@ static int xgene_gpio_probe(struct platform_device *pdev) int err = 0; gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); - if (!gpio) { - err = -ENOMEM; - goto err; - } + if (!gpio) + return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - err = -EINVAL; - goto err; - } + if (!res) + return -EINVAL; gpio->base = devm_ioremap_nocache(&pdev->dev, res->start, resource_size(res)); - if (!gpio->base) { - err = -ENOMEM; - goto err; - } + if (!gpio->base) + return -ENOMEM; gpio->chip.ngpio = XGENE_MAX_GPIOS; @@ -196,14 +190,11 @@ static int xgene_gpio_probe(struct platform_device *pdev) if (err) { dev_err(&pdev->dev, "failed to register gpiochip.\n"); - goto err; + return err; } dev_info(&pdev->dev, "X-Gene GPIO driver registered.\n"); return 0; -err: - dev_err(&pdev->dev, "X-Gene GPIO driver registration failed.\n"); - return err; } static const struct of_device_id xgene_gpio_of_match[] = { From f63516f4d6445ec23d0b7c286c5ff0064bdbe46b Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Wed, 2 Oct 2019 18:31:10 +0200 Subject: [PATCH 06/12] gpio: xgene: use devm_platform_ioremap_resource() There's no need to use the nocache variant of ioremap(). Switch to using devm_platform_ioremap_resource(). Signed-off-by: Bartosz Golaszewski Reviewed-by: Linus Walleij --- drivers/gpio/gpio-xgene.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/gpio/gpio-xgene.c b/drivers/gpio/gpio-xgene.c index 900b38a7dba8..a6e66ac18e1f 100644 --- a/drivers/gpio/gpio-xgene.c +++ b/drivers/gpio/gpio-xgene.c @@ -155,7 +155,6 @@ static SIMPLE_DEV_PM_OPS(xgene_gpio_pm, xgene_gpio_suspend, xgene_gpio_resume); static int xgene_gpio_probe(struct platform_device *pdev) { - struct resource *res; struct xgene_gpio *gpio; int err = 0; @@ -163,14 +162,9 @@ static int xgene_gpio_probe(struct platform_device *pdev) if (!gpio) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -EINVAL; - - gpio->base = devm_ioremap_nocache(&pdev->dev, res->start, - resource_size(res)); - if (!gpio->base) - return -ENOMEM; + gpio->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(gpio->base)) + return PTR_ERR(gpio->base); gpio->chip.ngpio = XGENE_MAX_GPIOS; From 94bfcbf0368b61403c33477e404eb16299b7423d Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Wed, 2 Oct 2019 18:33:48 +0200 Subject: [PATCH 07/12] gpio: em: use devm_platform_ioremap_resource() There's no need to use the nocache variant of ioremap(). Switch to using devm_platform_ioremap_resource(). Signed-off-by: Bartosz Golaszewski Reviewed-by: Linus Walleij Reviewed-by: Geert Uytterhoeven --- drivers/gpio/gpio-em.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c index 620f25b7efb4..674ebebaf90b 100644 --- a/drivers/gpio/gpio-em.c +++ b/drivers/gpio/gpio-em.c @@ -269,7 +269,7 @@ static void em_gio_irq_domain_remove(void *data) static int em_gio_probe(struct platform_device *pdev) { struct em_gio_priv *p; - struct resource *io[2], *irq[2]; + struct resource *irq[2]; struct gpio_chip *gpio_chip; struct irq_chip *irq_chip; struct device *dev = &pdev->dev; @@ -285,25 +285,21 @@ static int em_gio_probe(struct platform_device *pdev) platform_set_drvdata(pdev, p); spin_lock_init(&p->sense_lock); - io[0] = platform_get_resource(pdev, IORESOURCE_MEM, 0); - io[1] = platform_get_resource(pdev, IORESOURCE_MEM, 1); irq[0] = platform_get_resource(pdev, IORESOURCE_IRQ, 0); irq[1] = platform_get_resource(pdev, IORESOURCE_IRQ, 1); - if (!io[0] || !io[1] || !irq[0] || !irq[1]) { + if (!irq[0] || !irq[1]) { dev_err(dev, "missing IRQ or IOMEM\n"); return -EINVAL; } - p->base0 = devm_ioremap_nocache(dev, io[0]->start, - resource_size(io[0])); - if (!p->base0) - return -ENOMEM; + p->base0 = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(p->base0)) + return PTR_ERR(p->base0); - p->base1 = devm_ioremap_nocache(dev, io[1]->start, - resource_size(io[1])); - if (!p->base1) - return -ENOMEM; + p->base1 = devm_platform_ioremap_resource(pdev, 1); + if (IS_ERR(p->base1)) + return PTR_ERR(p->base1); if (of_property_read_u32(dev->of_node, "ngpios", &ngpios)) { dev_err(dev, "Missing ngpios OF property\n"); From 71b4da2b370bb2b0f3391d24049417e9be0281a0 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Wed, 2 Oct 2019 18:41:10 +0200 Subject: [PATCH 08/12] gpio: ath79: use devm_platform_ioremap_resource() There's no need to use the nocache variant of ioremap(). Switch to using devm_platform_ioremap_resource(). Signed-off-by: Bartosz Golaszewski Reviewed-by: Linus Walleij --- drivers/gpio/gpio-ath79.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/gpio/gpio-ath79.c b/drivers/gpio/gpio-ath79.c index f1a5ea9b3de2..53fae02c40ad 100644 --- a/drivers/gpio/gpio-ath79.c +++ b/drivers/gpio/gpio-ath79.c @@ -226,7 +226,6 @@ static int ath79_gpio_probe(struct platform_device *pdev) struct device_node *np = dev->of_node; struct ath79_gpio_ctrl *ctrl; struct gpio_irq_chip *girq; - struct resource *res; u32 ath79_gpio_count; bool oe_inverted; int err; @@ -256,12 +255,9 @@ static int ath79_gpio_probe(struct platform_device *pdev) return -EINVAL; } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -EINVAL; - ctrl->base = devm_ioremap_nocache(dev, res->start, resource_size(res)); - if (!ctrl->base) - return -ENOMEM; + ctrl->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(ctrl->base)) + return PTR_ERR(ctrl->base); raw_spin_lock_init(&ctrl->lock); err = bgpio_init(&ctrl->gc, dev, 4, From 1135ee4af74078a92b343e0fea08814c077d512c Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Wed, 2 Oct 2019 18:53:57 +0200 Subject: [PATCH 09/12] gpio: htc-egpio: use devm_platform_ioremap_resource() There's no need to use the nocache variant of ioremap(). Switch to using devm_platform_ioremap_resource(). Signed-off-by: Bartosz Golaszewski Reviewed-by: Linus Walleij --- drivers/gpio/gpio-htc-egpio.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/gpio/gpio-htc-egpio.c b/drivers/gpio/gpio-htc-egpio.c index 6eb56f7ab9c9..2d4b0b888f66 100644 --- a/drivers/gpio/gpio-htc-egpio.c +++ b/drivers/gpio/gpio-htc-egpio.c @@ -281,14 +281,9 @@ static int __init egpio_probe(struct platform_device *pdev) ei->chained_irq = res->start; /* Map egpio chip into virtual address space. */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) + ei->base_addr = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(ei->base_addr)) goto fail; - ei->base_addr = devm_ioremap_nocache(&pdev->dev, res->start, - resource_size(res)); - if (!ei->base_addr) - goto fail; - pr_debug("EGPIO phys=%08x virt=%p\n", (u32)res->start, ei->base_addr); if ((pdata->bus_width != 16) && (pdata->bus_width != 32)) goto fail; From a02712e1ebcdcbc71ec30f5ed241eae5696dda50 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Wed, 2 Oct 2019 18:56:14 +0200 Subject: [PATCH 10/12] gpio: htc-egpio: remove redundant error message There's no need to emit an error message on probe failure unless we're printing some meaningful info. Otherwise the core driver code will inform us about a probe error. Also: the driver currently drops info about errors propagated from called functions by default to returning -EINVAL. This fixes it as well. Signed-off-by: Bartosz Golaszewski Reviewed-by: Linus Walleij --- drivers/gpio/gpio-htc-egpio.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/drivers/gpio/gpio-htc-egpio.c b/drivers/gpio/gpio-htc-egpio.c index 2d4b0b888f66..8aa23d70b1e6 100644 --- a/drivers/gpio/gpio-htc-egpio.c +++ b/drivers/gpio/gpio-htc-egpio.c @@ -265,7 +265,6 @@ static int __init egpio_probe(struct platform_device *pdev) struct gpio_chip *chip; unsigned int irq, irq_end; int i; - int ret; /* Initialize ei data structure. */ ei = devm_kzalloc(&pdev->dev, sizeof(*ei), GFP_KERNEL); @@ -275,7 +274,6 @@ static int __init egpio_probe(struct platform_device *pdev) spin_lock_init(&ei->lock); /* Find chained irq */ - ret = -EINVAL; res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res) ei->chained_irq = res->start; @@ -283,15 +281,17 @@ static int __init egpio_probe(struct platform_device *pdev) /* Map egpio chip into virtual address space. */ ei->base_addr = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(ei->base_addr)) - goto fail; + return PTR_ERR(ei->base_addr); if ((pdata->bus_width != 16) && (pdata->bus_width != 32)) - goto fail; + return -EINVAL; + ei->bus_shift = fls(pdata->bus_width - 1) - 3; pr_debug("bus_shift = %d\n", ei->bus_shift); if ((pdata->reg_width != 8) && (pdata->reg_width != 16)) - goto fail; + return -EINVAL; + ei->reg_shift = fls(pdata->reg_width - 1); pr_debug("reg_shift = %d\n", ei->reg_shift); @@ -303,10 +303,9 @@ static int __init egpio_probe(struct platform_device *pdev) ei->chip = devm_kcalloc(&pdev->dev, ei->nchips, sizeof(struct egpio_chip), GFP_KERNEL); - if (!ei->chip) { - ret = -ENOMEM; - goto fail; - } + if (!ei->chip) + return -ENOMEM; + for (i = 0; i < ei->nchips; i++) { ei->chip[i].reg_start = pdata->chip[i].reg_start; ei->chip[i].cached_values = pdata->chip[i].initial_values; @@ -316,10 +315,9 @@ static int __init egpio_probe(struct platform_device *pdev) chip->label = devm_kasprintf(&pdev->dev, GFP_KERNEL, "htc-egpio-%d", i); - if (!chip->label) { - ret = -ENOMEM; - goto fail; - } + if (!chip->label) + return -ENOMEM; + chip->parent = &pdev->dev; chip->owner = THIS_MODULE; chip->get = egpio_get; @@ -361,10 +359,6 @@ static int __init egpio_probe(struct platform_device *pdev) } return 0; - -fail: - printk(KERN_ERR "EGPIO failed to setup\n"); - return ret; } #ifdef CONFIG_PM From ac4062aa6c811db89ee3bbfd3101af931a50c1ba Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Sun, 6 Oct 2019 15:42:56 +0100 Subject: [PATCH 11/12] gpio: 104-idi-48e: make array register_offset static, makes object smaller Don't populate the array register_offset on the stack but instead make it static. Makes the object code smaller by 63 bytes. Also add the int type specifier to clean up a checkpatch warning. Before: text data bss dec hex filename 9212 5712 1408 16332 3fcc drivers/gpio/gpio-104-idi-48.o After: text data bss dec hex filename 9085 5776 1408 16269 3f8d drivers/gpio/gpio-104-idi-48.o (gcc version 9.2.1, amd64) Signed-off-by: Colin Ian King Acked-by: William Breathitt Gray Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-104-idi-48.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-104-idi-48.c b/drivers/gpio/gpio-104-idi-48.c index ff53887bdaa8..79dead61e776 100644 --- a/drivers/gpio/gpio-104-idi-48.c +++ b/drivers/gpio/gpio-104-idi-48.c @@ -65,7 +65,7 @@ static int idi_48_gpio_get(struct gpio_chip *chip, unsigned offset) { struct idi_48_gpio *const idi48gpio = gpiochip_get_data(chip); unsigned i; - const unsigned register_offset[6] = { 0, 1, 2, 4, 5, 6 }; + static const unsigned int register_offset[6] = { 0, 1, 2, 4, 5, 6 }; unsigned base_offset; unsigned mask; From 228fc01040704f55fd884ab41daf3eafd2644b54 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 18 Oct 2019 12:05:38 +0200 Subject: [PATCH 12/12] gpio: of: don't warn if ignored GPIO flag matches the behavior Some devicetrees specify the ACTIVE_LOW flag in the fixed regulator GPIO handle. While this has always been ignored, it's consistent with the behavior of the regulator binding in the absence of the "enable-active-high" DT property. It doesn't make much sense to print a user visible warning for a configuration which is consistent, so only print the warning if the GPIO flag contradicts the behavior dictated by by the enable-active-high property. Signed-off-by: Lucas Stach [Bartosz: coding style tweak] Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpiolib-of.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 1eea2c6c2e1d..576c7419bbc1 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -134,18 +134,20 @@ static void of_gpio_flags_quirks(struct device_node *np, (!(strcmp(propname, "enable-gpio") && strcmp(propname, "enable-gpios")) && of_device_is_compatible(np, "regulator-gpio")))) { + bool active_low = !of_property_read_bool(np, + "enable-active-high"); /* * The regulator GPIO handles are specified such that the * presence or absence of "enable-active-high" solely controls * the polarity of the GPIO line. Any phandle flags must * be actively ignored. */ - if (*flags & OF_GPIO_ACTIVE_LOW) { + if ((*flags & OF_GPIO_ACTIVE_LOW) && !active_low) { pr_warn("%s GPIO handle specifies active low - ignored\n", of_node_full_name(np)); *flags &= ~OF_GPIO_ACTIVE_LOW; } - if (!of_property_read_bool(np, "enable-active-high")) + if (active_low) *flags |= OF_GPIO_ACTIVE_LOW; } /*