From: Bartosz Golaszewski <brgl@bgdev.pl>
To: Linus Walleij <linus.walleij@linaro.org>,
Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
Mika Westerberg <mika.westerberg@linux.intel.com>
Cc: linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-acpi@vger.kernel.org,
Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Subject: [PATCH v4 03/11] gpiolib: provide gpio_device_find()
Date: Wed, 27 Sep 2023 16:29:23 +0200 [thread overview]
Message-ID: <20230927142931.19798-4-brgl@bgdev.pl> (raw)
In-Reply-To: <20230927142931.19798-1-brgl@bgdev.pl>
From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
gpiochip_find() is wrong and its kernel doc is misleading as the
function doesn't return a reference to the gpio_chip but just a raw
pointer. The chip itself is not guaranteed to stay alive, in fact it can
be deleted at any point. Also: other than GPIO drivers themselves,
nobody else has any business accessing gpio_chip structs.
Provide a new gpio_device_find() function that returns a real reference
to the opaque gpio_device structure that is guaranteed to stay alive for
as long as there are active users of it.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/gpio/gpiolib.c | 71 +++++++++++++++++++++++++++----------
include/linux/gpio/driver.h | 3 ++
2 files changed, 56 insertions(+), 18 deletions(-)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index f84ad54d8dbd..0371d23f0a46 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1014,16 +1014,10 @@ void gpiochip_remove(struct gpio_chip *gc)
}
EXPORT_SYMBOL_GPL(gpiochip_remove);
-/**
- * gpiochip_find() - iterator for locating a specific gpio_chip
- * @data: data to pass to match function
- * @match: Callback function to check gpio_chip
+/*
+ * FIXME: This will be removed soon.
*
- * Similar to bus_find_device. It returns a reference to a gpio_chip as
- * determined by a user supplied @match callback. The callback should return
- * 0 if the device doesn't match and non-zero if it does. If the callback is
- * non-zero, this function will return to the caller and not iterate over any
- * more gpio_chips.
+ * This function is depracated, don't use.
*/
struct gpio_chip *gpiochip_find(void *data,
int (*match)(struct gpio_chip *gc,
@@ -1031,21 +1025,62 @@ struct gpio_chip *gpiochip_find(void *data,
{
struct gpio_device *gdev;
struct gpio_chip *gc = NULL;
- unsigned long flags;
- spin_lock_irqsave(&gpio_lock, flags);
- list_for_each_entry(gdev, &gpio_devices, list)
- if (gdev->chip && match(gdev->chip, data)) {
- gc = gdev->chip;
- break;
- }
-
- spin_unlock_irqrestore(&gpio_lock, flags);
+ gdev = gpio_device_find(data, match);
+ if (gdev) {
+ gc = gdev->chip;
+ gpio_device_put(gdev);
+ }
return gc;
}
EXPORT_SYMBOL_GPL(gpiochip_find);
+/**
+ * gpio_device_find() - find a specific GPIO device
+ * @data: data to pass to match function
+ * @match: Callback function to check gpio_chip
+ *
+ * Returns:
+ * New reference to struct gpio_device.
+ *
+ * Similar to bus_find_device(). It returns a reference to a gpio_device as
+ * determined by a user supplied @match callback. The callback should return
+ * 0 if the device doesn't match and non-zero if it does. If the callback
+ * returns non-zero, this function will return to the caller and not iterate
+ * over any more gpio_devices.
+ *
+ * The callback takes the GPIO chip structure as argument. During the execution
+ * of the callback function the chip is protected from being freed. TODO: This
+ * actually has yet to be implemented.
+ *
+ * If the function returns non-NULL, the returned reference must be freed by
+ * the caller using gpio_device_put().
+ */
+struct gpio_device *gpio_device_find(void *data,
+ int (*match)(struct gpio_chip *gc,
+ void *data))
+{
+ struct gpio_device *gdev;
+
+ /*
+ * Not yet but in the future the spinlock below will become a mutex.
+ * Annotate this function before anyone tries to use it in interrupt
+ * context like it happened with gpiochip_find().
+ */
+ might_sleep();
+
+ guard(spinlock_irqsave)(&gpio_lock);
+
+ list_for_each_entry(gdev, &gpio_devices, list) {
+ if (gdev->chip && match(gdev->chip, data))
+ return gpio_device_get(gdev);
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(gpio_device_find);
+
static int gpiochip_match_name(struct gpio_chip *gc, void *data)
{
const char *name = data;
diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
index 1cedbc3d3200..6ad1f1a8ef2e 100644
--- a/include/linux/gpio/driver.h
+++ b/include/linux/gpio/driver.h
@@ -608,6 +608,9 @@ int devm_gpiochip_add_data_with_key(struct device *dev, struct gpio_chip *gc,
struct gpio_chip *gpiochip_find(void *data,
int (*match)(struct gpio_chip *gc, void *data));
+struct gpio_device *gpio_device_find(void *data,
+ int (*match)(struct gpio_chip *gc, void *data));
+
struct gpio_device *gpio_device_get(struct gpio_device *gdev);
void gpio_device_put(struct gpio_device *gdev);
--
2.39.2
next prev parent reply other threads:[~2023-09-27 14:29 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-27 14:29 [PATCH v4 00/11] gpiolib: work towards removing gpiochip_find() Bartosz Golaszewski
2023-09-27 14:29 ` [PATCH v4 01/11] gpiolib: make gpio_device_get() and gpio_device_put() public Bartosz Golaszewski
2023-10-02 9:39 ` Andy Shevchenko
2023-09-27 14:29 ` [PATCH v4 02/11] gpiolib: add support for scope-based management to gpio_device Bartosz Golaszewski
2023-10-02 9:39 ` Andy Shevchenko
2023-09-27 14:29 ` Bartosz Golaszewski [this message]
2023-10-02 9:42 ` [PATCH v4 03/11] gpiolib: provide gpio_device_find() Andy Shevchenko
2023-10-02 9:52 ` Bartosz Golaszewski
2023-10-02 9:57 ` Andy Shevchenko
2023-10-02 9:59 ` Bartosz Golaszewski
2023-09-27 14:29 ` [PATCH v4 04/11] gpiolib: provide gpio_device_find_by_label() Bartosz Golaszewski
2023-10-02 9:44 ` Andy Shevchenko
2023-10-02 9:53 ` Bartosz Golaszewski
2023-10-03 12:44 ` Bartosz Golaszewski
2023-09-27 14:29 ` [PATCH v4 05/11] gpiolib: provide gpio_device_get_desc() Bartosz Golaszewski
2023-10-02 9:46 ` Andy Shevchenko
2023-10-02 9:54 ` Bartosz Golaszewski
2023-10-02 9:58 ` Andy Shevchenko
2023-09-27 14:29 ` [PATCH v4 06/11] gpiolib: reluctantly provide gpio_device_get_chip() Bartosz Golaszewski
2023-09-27 14:29 ` [PATCH v4 07/11] gpiolib: replace find_chip_by_name() with gpio_device_find_by_label() Bartosz Golaszewski
2023-09-27 14:29 ` [PATCH v4 08/11] gpio: of: replace gpiochip_find_* with gpio_device_find_* Bartosz Golaszewski
2023-09-27 14:29 ` [PATCH v4 09/11] gpio: acpi: replace gpiochip_find() with gpio_device_find() Bartosz Golaszewski
2023-09-27 14:29 ` [PATCH v4 10/11] gpio: swnode: replace gpiochip_find() with gpio_device_find_by_label() Bartosz Golaszewski
2023-09-27 14:29 ` [PATCH v4 11/11] gpio: sysfs: drop the mention of gpiochip_find() from sysfs code Bartosz Golaszewski
2023-10-04 11:58 ` [PATCH v4 00/11] gpiolib: work towards removing gpiochip_find() Bartosz Golaszewski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230927142931.19798-4-brgl@bgdev.pl \
--to=brgl@bgdev.pl \
--cc=andriy.shevchenko@linux.intel.com \
--cc=bartosz.golaszewski@linaro.org \
--cc=linus.walleij@linaro.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mika.westerberg@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.