History log of /linux-master/drivers/gpio/gpio-grgpio.c
Revision Date Author Comments
# b6c43915 28-Sep-2023 Uwe Kleine-König <u.kleine-koenig@pengutronix.de>

gpio: grgpio: Convert to platform remove callback returning void

The .remove() callback for a platform driver returns an int which makes
many driver authors wrongly assume it's possible to do error handling by
returning an error code. However the value returned is ignored (apart
from emitting a warning) and this typically results in resource leaks.

To improve here there is a quest to make the remove callback return
void. In the first step of this quest all drivers are converted to
.remove_new(), which already returns void. Eventually after all drivers
are converted, .remove_new() will be renamed to .remove().

Trivially convert this driver from always returning zero in the remove
callback to the void returning variant.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>


# e91d0f05 14-Jul-2023 Rob Herring <robh@kernel.org>

gpio: Explicitly include correct DT includes

The DT of_device.h and of_platform.h date back to the separate
of_platform_bus_type before it as merged into the regular platform bus.
As part of that merge prepping Arm DT support 13 years ago, they
"temporarily" include each other. They also include platform_device.h
and of.h. As a result, there's a pretty much random mix of those include
files used throughout the tree. In order to detangle these headers and
replace the implicit includes with struct declarations, users need to
explicitly include the correct includes.

Signed-off-by: Rob Herring <robh@kernel.org>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Acked-by: Romain Perier <romain.perier@gmail.com>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>


# c1c2a15c 21-Jun-2022 Uwe Kleine-König <u.kleine-koenig@pengutronix.de>

gpio: grgpio: Fix device removing

If a platform device's remove callback returns non-zero, the device core
emits a warning and still removes the device and calls the devm cleanup
callbacks.

So it's not save to not unregister the gpiochip because on the next request
to a GPIO the driver accesses kfree()'d memory. Also if an IRQ triggers,
the freed memory is accessed.

Instead rely on the GPIO framework to ensure that after gpiochip_remove()
all GPIOs are freed and so the corresponding IRQs are unmapped.

This is a preparation for making platform remove callbacks return void.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>


# 3c938cc5 18-Apr-2022 Schspa Shi <schspa@gmail.com>

gpio: use raw spinlock for gpio chip shadowed data

In case of PREEMPT_RT, there is a raw_spinlock -> spinlock dependency
as the lockdep report shows.

__irq_set_handler
irq_get_desc_buslock
__irq_get_desc_lock
raw_spin_lock_irqsave(&desc->lock, *flags); // raw spinlock get here
__irq_do_set_handler
mask_ack_irq
dwapb_irq_ack
spin_lock_irqsave(&gc->bgpio_lock, flags); // sleep able spinlock
irq_put_desc_busunlock

Replace with a raw lock to avoid BUGs. This lock is only used to access
registers, and It's safe to replace with the raw lock without bad
influence.

[ 15.090359][ T1] =============================
[ 15.090365][ T1] [ BUG: Invalid wait context ]
[ 15.090373][ T1] 5.10.59-rt52-00983-g186a6841c682-dirty #3 Not tainted
[ 15.090386][ T1] -----------------------------
[ 15.090392][ T1] swapper/0/1 is trying to lock:
[ 15.090402][ T1] 70ff00018507c188 (&gc->bgpio_lock){....}-{3:3}, at: _raw_spin_lock_irqsave+0x1c/0x28
[ 15.090470][ T1] other info that might help us debug this:
[ 15.090477][ T1] context-{5:5}
[ 15.090485][ T1] 3 locks held by swapper/0/1:
[ 15.090497][ T1] #0: c2ff0001816de1a0 (&dev->mutex){....}-{4:4}, at: __device_driver_lock+0x98/0x104
[ 15.090553][ T1] #1: ffff90001485b4b8 (irq_domain_mutex){+.+.}-{4:4}, at: irq_domain_associate+0xbc/0x6d4
[ 15.090606][ T1] #2: 4bff000185d7a8e0 (lock_class){....}-{2:2}, at: _raw_spin_lock_irqsave+0x1c/0x28
[ 15.090654][ T1] stack backtrace:
[ 15.090661][ T1] CPU: 4 PID: 1 Comm: swapper/0 Not tainted 5.10.59-rt52-00983-g186a6841c682-dirty #3
[ 15.090682][ T1] Hardware name: Horizon Robotics Journey 5 DVB (DT)
[ 15.090692][ T1] Call trace:
......
[ 15.090811][ T1] _raw_spin_lock_irqsave+0x1c/0x28
[ 15.090828][ T1] dwapb_irq_ack+0xb4/0x300
[ 15.090846][ T1] __irq_do_set_handler+0x494/0xb2c
[ 15.090864][ T1] __irq_set_handler+0x74/0x114
[ 15.090881][ T1] irq_set_chip_and_handler_name+0x44/0x58
[ 15.090900][ T1] gpiochip_irq_map+0x210/0x644

Signed-off-by: Schspa Shi <schspa@gmail.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Doug Berger <opendmb@gmail.com>
Acked-by: Serge Semin <fancer.lancer@gmail.com>
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>


# 448cf905 17-Dec-2021 Andy Shevchenko <andriy.shevchenko@linux.intel.com>

gpio: Get rid of duplicate of_node assignment in the drivers

GPIO library does copy the of_node from the parent device of
the GPIO chip, there is no need to repeat this in the individual
drivers. Remove these assignment all at once.

For the details one may look into the of_gpio_dev_init() implementation.

While at it, remove duplicate parent device assignment where it is the case.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-By: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>


# 9a2b5b30 14-Jan-2020 Shaokun Zhang <zhangshaokun@hisilicon.com>

gpio: Remove the unused flags

drivers/gpio/gpio-grgpio.c: In function ‘grgpio_remove’:
drivers/gpio/gpio-grgpio.c:438:16: warning: unused variable ‘flags’ [-Wunused-variable]
unsigned long flags;
^
Fixes: 25d071b3f6db ("gpio: gpio-grgpio: fix possible sleep-in-atomic-context bugs in grgpio_remove()")
Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
Link: https://lore.kernel.org/r/1579009062-7154-1-git-send-email-zhangshaokun@hisilicon.com
Reviewed-by: Bartosz Golaszewski <bgolaszewski@baylibre.com
Reviewed-by: Jia-Ju Bai <baijiaju1990@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>


# e36eaf94 18-Dec-2019 Jia-Ju Bai <baijiaju1990@gmail.com>

gpio: gpio-grgpio: fix possible sleep-in-atomic-context bugs in grgpio_irq_map/unmap()

The driver may sleep while holding a spinlock.
The function call path (from bottom to top) in Linux 4.19 is:

drivers/gpio/gpio-grgpio.c, 261:
request_irq in grgpio_irq_map
drivers/gpio/gpio-grgpio.c, 255:
_raw_spin_lock_irqsave in grgpio_irq_map

drivers/gpio/gpio-grgpio.c, 318:
free_irq in grgpio_irq_unmap
drivers/gpio/gpio-grgpio.c, 299:
_raw_spin_lock_irqsave in grgpio_irq_unmap

request_irq() and free_irq() can sleep at runtime.

To fix these bugs, request_irq() and free_irq() are called without
holding the spinlock.

These bugs are found by a static analysis tool STCheck written by myself.

Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com>
Link: https://lore.kernel.org/r/20191218132605.10594-1-baijiaju1990@gmail.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>


# 25d071b3 19-Dec-2019 Jia-Ju Bai <baijiaju1990@gmail.com>

gpio: gpio-grgpio: fix possible sleep-in-atomic-context bugs in grgpio_remove()

drivers/gpio/gpiolib-sysfs.c, 796:
mutex_lock in gpiochip_sysfs_unregister
drivers/gpio/gpiolib.c, 1455:
gpiochip_sysfs_unregister in gpiochip_remove
drivers/gpio/gpio-grgpio.c, 460:
gpiochip_remove in grgpio_remove
drivers/gpio/gpio-grgpio.c, 449:
_raw_spin_lock_irqsave in grgpio_remove

kernel/irq/irqdomain.c, 243:
mutex_lock in irq_domain_remove
drivers/gpio/gpio-grgpio.c, 463:
irq_domain_remove in grgpio_remove
drivers/gpio/gpio-grgpio.c, 449:
_raw_spin_lock_irqsave in grgpio_remove

mutex_lock() can sleep at runtime.

To fix these bugs, the lock is dropped in grgpio_remove(), because there
is no need for locking in remove() callbacks.

These bugs are found by a static analysis tool STCheck written by
myself.

Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com>
Link: https://lore.kernel.org/r/20191219131459.18640-1-baijiaju1990@gmail.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>


# 15bddb7d 30-Jul-2019 Stephen Boyd <swboyd@chromium.org>

gpio: Remove dev_err() usage after platform_get_irq()

We don't need dev_err() messages when platform_get_irq() fails now that
platform_get_irq() prints an error message itself when something goes
wrong. Let's remove these prints with a simple semantic patch.

// <smpl>
@@
expression ret;
struct platform_device *E;
@@

ret =
(
platform_get_irq(E, ...)
|
platform_get_irq_byname(E, ...)
);

if ( \( ret < 0 \| ret <= 0 \) )
{
(
-if (ret != -EPROBE_DEFER)
-{ ...
-dev_err(...);
-... }
|
...
-dev_err(...);
)
...
}
// </smpl>

While we're here, remove braces on if statements that only have one
statement (manually).

Cc: linux-gpio@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
Link: https://lore.kernel.org/r/20190730181557.90391-16-swboyd@chromium.org
Acked-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>


# 01d078aa 17-Jun-2019 Enrico Weigelt, metux IT consult <info@metux.net>

gpio: grgpio: Use devm_platform_ioremap_resource()

Use the new helper that wraps the calls to platform_get_resource()
and devm_ioremap_resource() together.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>


# 2874c5fd 27-May-2019 Thomas Gleixner <tglx@linutronix.de>

treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152

Based on 1 normalized pattern(s):

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 either version 2 of the license or at
your option any later version

extracted by the scancode license scanner the SPDX license identifier

GPL-2.0-or-later

has been chosen to replace the boilerplate/reference in 3029 file(s).

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Allison Randal <allison@lohutok.net>
Cc: linux-spdx@vger.kernel.org
Link: https://lkml.kernel.org/r/20190527070032.746973796@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>


# 8a9d000f 16-Nov-2018 Brajeswar Ghosh <brajeswar.linux@gmail.com>

drivers/gpio/gpio-grgpio.c: Remove duplicate header

Remove linux/gpio/driver.h which is included more than once

Signed-off-by: Brajeswar Ghosh <brajeswar.linux@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>


# 00d712a9 04-Mar-2018 Linus Walleij <linus.walleij@linaro.org>

gpio: grgpio: Include the right header

This driver is a pure GPIO driver and should only include
<linux/gpio/driver.h>.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>


# 5c7b0c4e 20-Oct-2017 Linus Walleij <linus.walleij@linaro.org>

gpio: grgpio: Do not use gc->pin2mask()

The pin2mask() accessor only shuffles BIT ORDER in big endian systems,
i.e. the bitstuffing is swizzled big endian so "bit 0" is bit 7 or
bit 15 or bit 31 or so.

The grgpio only uses big endian BYTE ORDER which will be taken car of
by the ->write_reg() callback.

Just use BIT(offset) to assign the bit.

Acked-by: Andreas Larsson <andreas@gaisler.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>


# 7eb6ce2f 18-Jul-2017 Rob Herring <robh@kernel.org>

gpio: Convert to using %pOF instead of full_name

Now that we have a custom printf format specifier, convert users of
full_name to use %pOF instead. This is preparation to remove storing
of the full path string for each node.

Signed-off-by: Rob Herring <robh@kernel.org>
Cc: Tien Hock Loh <thloh@altera.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Alexandre Courbot <gnurou@gmail.com>
Cc: Brian Norris <computersforpeace@gmail.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Cc: bcm-kernel-feedback-list@broadcom.com
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: "Sören Brinkmann" <soren.brinkmann@xilinx.com>
Cc: linux-gpio@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Acked-by: Gregory Fong <gregory.0xf0@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>


# 0f4630f3 04-Dec-2015 Linus Walleij <linus.walleij@linaro.org>

gpio: generic: factor into gpio_chip struct

The separate struct bgpio_chip has been a pain to handle, both
by being confusingly similar in name to struct gpio_chip and
for being contained inside a struct so that struct gpio_chip
is contained in a struct contained in a struct, making several
steps of dereferencing necessary.

Make things simpler: include the fields directly into
<linux/gpio/driver.h>, #ifdef:ed for CONFIG_GENERIC_GPIO, and
get rid of the <linux/basic_mmio_gpio.h> altogether. Prefix
some of the member variables with bgpio_* and add proper
kerneldoc while we're at it.

Modify all users to handle the change and use a struct
gpio_chip directly. And while we're at it: replace all
container_of() dereferencing by gpiochip_get_data() and
registering the gpio_chip with gpiochip_add_data().

Cc: arm@kernel.org
Cc: Alexander Shiyan <shc_work@mail.ru>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Kukjin Kim <kgene@kernel.org>
Cc: Alexandre Courbot <gnurou@gmail.com>
Cc: Brian Norris <computersforpeace@gmail.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Nicolas Pitre <nicolas.pitre@linaro.org>
Cc: Olof Johansson <olof@lixom.net>
Cc: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
Cc: Rabin Vincent <rabin@rab.in>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-omap@vger.kernel.org
Cc: linux-samsung-soc@vger.kernel.org
Cc: bcm-kernel-feedback-list@broadcom.com
Acked-by: Gregory Fong <gregory.0xf0@gmail.com>
Acked-by: Liviu Dudau <Liviu.Dudau@arm.com>
Acked-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Acked-by: Tony Lindgren <tony@atomide.com>
Acked-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Acked-by: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>


# 7fa25937 17-Aug-2015 Alexandre Courbot <acourbot@nvidia.com>

gpio/grgpio: fix deadlock in grgpio_irq_unmap()

As reported by Alexey Khoroshilov:

grgpio_irq_unmap() code looks quite suspicious regarding usage of
priv->bgc.lock spinlock.

It locks the spinlock in line 310:

spin_lock_irqsave(&priv->bgc.lock, flags);

and then it can call grgpio_set_imask() in line 317:

grgpio_set_imask(priv, i, 0);

But grgpio_set_imask() unconditionally locks the spinlock by itself.

Fix this by moving the spinlock acquisition outside of
grgpio_set_imask().

Found by Linux Driver Verification project (linuxtesting.org).

Reported-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Cc: Alexey Khoroshilov <khoroshilov@ispras.ru>
Cc: Andreas Larsson <andreas@gaisler.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>


# 23393d49 27-Jul-2015 Rob Herring <robh@kernel.org>

gpio: kill off set_irq_flags usage

set_irq_flags is ARM specific with custom flags which have genirq
equivalents. Convert drivers to use the genirq interfaces directly, so we
can kill off set_irq_flags. The translation of flags is as follows:

IRQF_VALID -> !IRQ_NOREQUEST
IRQF_PROBE -> !IRQ_NOPROBE
IRQF_NOAUTOEN -> IRQ_NOAUTOEN

For IRQs managed by an irqdomain, the irqdomain core code handles clearing
and setting IRQ_NOREQUEST already, so there is no need to do this in
.map() functions and we can simply remove the set_irq_flags calls. Some
users also modify IRQ_NOPROBE and this has been maintained although it
is not clear that is really needed as most platforms don't use probing.
There appears to be a great deal of blind copy and paste of this code.

Signed-off-by: Rob Herring <robh@kernel.org>
Cc: Michael Hennerich <michael.hennerich@analog.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Cc: Alexandre Courbot <gnurou@gmail.com>
Cc: Ray Jui <rjui@broadcom.com>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: linux-gpio@vger.kernel.org
Cc: bcm-kernel-feedback-list@broadcom.com
Cc: linux-tegra@vger.kernel.org
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>


# 0b354dc4 27-Apr-2015 Krzysztof Kozlowski <krzk@kernel.org>

gpio: Constify irq_domain_ops

The irq_domain_ops are not modified by the driver and the irqdomain core
code accepts pointer to a const data.

Signed-off-by: Krzysztof Kozlowski <k.kozlowski.k@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>


# d3c2155c 16-Dec-2014 Dan Carpenter <dan.carpenter@oracle.com>

gpio: grgpio: off by one in grgpio_to_irq()

"gc->ngpio" is a number between 1 and GRGPIO_MAX_NGPIO. If "offset" is
GRGPIO_MAX_NGPIO then we're going one step beyond the end of the
priv->lirqs[] array.

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>


# 879828c6 20-Dec-2014 Axel Lin <axel.lin@ingics.com>

gpio: grgpio: Avoid potential NULL pointer dereference

irqmap is optional property, so priv->domain can be NULL if !irqmap.
Thus add NULL test for priv->domain before calling irq_domain_remove()
to prevent NULL pointer dereference.

Signed-off-by: Axel Lin <axel.lin@ingics.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>


# 65fdc966 01-Oct-2014 Pramod Gurav <pramod.gurav@smartplayin.com>

gpio: grgpio: remove irq_domain resources on failure

Call irq_domain_remove when gpiochip_add fails to release irq_domain
resources.

Signed-off-by: Pramod Gurav <pramod.gurav@smartplayin.com>
Acked-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>


# 4a3a950e 20-Oct-2014 Wolfram Sang <wsa@kernel.org>

gpio: drop owner assignment from platform_drivers

A platform_driver does not need to set an owner, it will be populated by the
driver core.

Signed-off-by: Wolfram Sang <wsa@the-dreams.de>


# 9f5132ae 12-Jul-2014 abdoulaye berthe <berthe.ab@gmail.com>

gpio: remove all usage of gpio_remove retval in driver/gpio

Signed-off-by: abdoulaye berthe <berthe.ab@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>


# f77b6448 07-May-2014 Jingoo Han <jg1.han@samsung.com>

gpio: grgpio: Make of_device_id array const

Make of_device_id array const, because all OF functions
handle it as const.

Signed-off-by: Jingoo Han <jg1.han@samsung.com>
Acked-by: Andreas Larsson <andreas@gaisler.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>


# 61e3884e 18-Jun-2013 Sachin Kamat <sachin.kamat@linaro.org>

gpio: grgpio: Staticize local symbols

Local symbols accessed only in this file are made static.

Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
Acked-by: Andreas Larsson <andreas@gaisler.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>


# 08ffb222 17-Apr-2013 Andreas Larsson <andreas@gaisler.com>

gpio: grgpio: Add irq support

The drivers sets up an irq domain and hands out unique irqs to irq
capable gpio lines regardless of how underlying irq maps to gpio
lines. Any gpio line can map to any one or none of the irqs of the
core, independently of each other.

Signed-off-by: Andreas Larsson <andreas@gaisler.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>


# ddb27f3b 17-Apr-2013 Andreas Larsson <andreas@gaisler.com>

gpio: grgpio: Add device driver for GRGPIO cores

This driver supports GRGPIO gpio cores available in the GRLIB VHDL IP
core library from Aeroflex Gaisler.

Signed-off-by: Andreas Larsson <andreas@gaisler.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>