From: Bartosz Golaszewski <brgl@bgdev.pl>
To: Linus Walleij <linus.walleij@linaro.org>,
Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
Kent Gibson <warthog618@gmail.com>
Cc: linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org,
Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Subject: [PATCH 5/5] gpio: cdev: wake up lineevent poll() on device unbind
Date: Wed, 16 Aug 2023 14:20:32 +0200 [thread overview]
Message-ID: <20230816122032.15548-6-brgl@bgdev.pl> (raw)
In-Reply-To: <20230816122032.15548-1-brgl@bgdev.pl>
From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Extend struct lineevent_data with a notifier block and use it to receive
the GPIO device unregister event. Upon reception, wake up the wait queue
so that the user-space be forced out of poll() and need to go into a new
system call which will then fail due to the chip being gone.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
drivers/gpio/gpiolib-cdev.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c
index 0b21ea04fa52..bb6a011f7857 100644
--- a/drivers/gpio/gpiolib-cdev.c
+++ b/drivers/gpio/gpiolib-cdev.c
@@ -1830,9 +1830,15 @@ struct lineevent_state {
int irq;
wait_queue_head_t wait;
DECLARE_KFIFO(events, struct gpioevent_data, 16);
+ struct notifier_block nb;
u64 timestamp;
};
+static struct lineevent_state *to_lineevent_state(struct notifier_block *nb)
+{
+ return container_of(nb, struct lineevent_state, nb);
+}
+
#define GPIOEVENT_REQUEST_VALID_FLAGS \
(GPIOEVENT_REQUEST_RISING_EDGE | \
GPIOEVENT_REQUEST_FALLING_EDGE)
@@ -1947,6 +1953,9 @@ static ssize_t lineevent_read(struct file *file, char __user *buf,
static void lineevent_free(struct lineevent_state *le)
{
+ if (le->nb.notifier_call)
+ blocking_notifier_chain_unregister(&le->gdev->notifier,
+ &le->nb);
if (le->irq)
free_irq(le->irq, le);
if (le->desc)
@@ -2084,6 +2093,22 @@ static irqreturn_t lineevent_irq_handler(int irq, void *p)
return IRQ_WAKE_THREAD;
}
+static int lineevent_notify(struct notifier_block *nb, unsigned long action,
+ void *data)
+{
+ struct lineevent_state *le = to_lineevent_state(nb);
+
+ switch (action) {
+ case GPIO_CDEV_UNREGISTERED:
+ wake_up_poll(&le->wait, EPOLLIN | EPOLLERR);
+ break;
+ default:
+ return NOTIFY_DONE;
+ }
+
+ return NOTIFY_OK;
+}
+
static int lineevent_create(struct gpio_device *gdev, void __user *ip)
{
struct gpioevent_request eventreq;
@@ -2175,6 +2200,11 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip)
INIT_KFIFO(le->events);
init_waitqueue_head(&le->wait);
+ le->nb.notifier_call = lineevent_notify;
+ ret = blocking_notifier_chain_register(&gdev->notifier, &le->nb);
+ if (ret)
+ goto out_free_le;
+
/* Request a thread to read the events */
ret = request_threaded_irq(irq,
lineevent_irq_handler,
--
2.39.2
next prev parent reply other threads:[~2023-08-16 12:21 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-16 12:20 [PATCH 0/5] gpio: cdev: bail out of poll() if the device goes down Bartosz Golaszewski
2023-08-16 12:20 ` [PATCH 1/5] gpio: cdev: ignore notifications other than line status changes Bartosz Golaszewski
2023-08-16 12:20 ` [PATCH 2/5] gpio: cdev: rename the notifier block and notify callback Bartosz Golaszewski
2023-08-16 12:20 ` [PATCH 3/5] gpio: cdev: wake up chardev poll() on device unbind Bartosz Golaszewski
2023-08-16 12:20 ` [PATCH 4/5] gpio: cdev: wake up linereq " Bartosz Golaszewski
2023-08-16 12:20 ` Bartosz Golaszewski [this message]
2023-08-17 9:12 ` [PATCH 5/5] gpio: cdev: wake up lineevent " kernel test robot
2023-08-16 21:41 ` [PATCH 0/5] gpio: cdev: bail out of poll() if the device goes down Linus Walleij
2023-08-17 4:41 ` Kent Gibson
2023-08-17 7:00 ` Linus Walleij
2023-08-17 7:27 ` Bartosz Golaszewski
2023-08-17 7:37 ` Kent Gibson
2023-08-17 7:41 ` 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=20230816122032.15548-6-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-gpio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=warthog618@gmail.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.