Message ID | 20241010-gpio-notify-in-kernel-events-v2-2-b560411f7c59@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | gpio: notify user-space about config changes in the kernel | expand |
On Thu, Oct 10, 2024 at 11:10:23AM +0200, Bartosz Golaszewski wrote: > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> > > In order to prepare gpio_desc_to_lineinfo() to being called from atomic > context, add a new argument - bool atomic - which, if set, indicates > that no sleeping functions must be called (currently: only > pinctrl_gpio_can_use_line()). > > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> > --- > drivers/gpio/gpiolib-cdev.c | 16 ++++++++++------ > 1 file changed, 10 insertions(+), 6 deletions(-) > > diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c > index b0050250ac3a..8c48a53b4fa8 100644 > --- a/drivers/gpio/gpiolib-cdev.c > +++ b/drivers/gpio/gpiolib-cdev.c > @@ -2361,7 +2361,7 @@ static void gpio_v2_line_info_changed_to_v1( > #endif /* CONFIG_GPIO_CDEV_V1 */ > > static void gpio_desc_to_lineinfo(struct gpio_desc *desc, > - struct gpio_v2_line_info *info) > + struct gpio_v2_line_info *info, bool atomic) > { > unsigned long dflags; > const char *label; > @@ -2402,9 +2402,13 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc, > test_bit(FLAG_USED_AS_IRQ, &dflags) || > test_bit(FLAG_EXPORT, &dflags) || > test_bit(FLAG_SYSFS, &dflags) || > - !gpiochip_line_is_valid(guard.gc, info->offset) || > - !pinctrl_gpio_can_use_line(guard.gc, info->offset)) > + !gpiochip_line_is_valid(guard.gc, info->offset)) > info->flags |= GPIO_V2_LINE_FLAG_USED; > + > + if (!atomic) { > + if (!pinctrl_gpio_can_use_line(guard.gc, info->offset)) > + info->flags |= GPIO_V2_LINE_FLAG_USED; > + } > Should be else if. Cheers, Kent. > if (test_bit(FLAG_IS_OUT, &dflags)) > info->flags |= GPIO_V2_LINE_FLAG_OUTPUT; > @@ -2502,7 +2506,7 @@ static int lineinfo_get_v1(struct gpio_chardev_data *cdev, void __user *ip, > return -EBUSY; > } > > - gpio_desc_to_lineinfo(desc, &lineinfo_v2); > + gpio_desc_to_lineinfo(desc, &lineinfo_v2, false); > gpio_v2_line_info_to_v1(&lineinfo_v2, &lineinfo); > > if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) { > @@ -2539,7 +2543,7 @@ static int lineinfo_get(struct gpio_chardev_data *cdev, void __user *ip, > if (test_and_set_bit(lineinfo.offset, cdev->watched_lines)) > return -EBUSY; > } > - gpio_desc_to_lineinfo(desc, &lineinfo); > + gpio_desc_to_lineinfo(desc, &lineinfo, false); > supinfo_to_lineinfo(desc, &lineinfo); > > if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) { > @@ -2632,7 +2636,7 @@ static int lineinfo_changed_notify(struct notifier_block *nb, > memset(&chg, 0, sizeof(chg)); > chg.event_type = action; > chg.timestamp_ns = ktime_get_ns(); > - gpio_desc_to_lineinfo(desc, &chg.info); > + gpio_desc_to_lineinfo(desc, &chg.info, false); > supinfo_to_lineinfo(desc, &chg.info); > > ret = kfifo_in_spinlocked(&cdev->events, &chg, 1, &cdev->wait.lock); > > -- > 2.43.0 >
On Mon, Oct 14, 2024 at 3:58 AM Kent Gibson <warthog618@gmail.com> wrote: > > On Thu, Oct 10, 2024 at 11:10:23AM +0200, Bartosz Golaszewski wrote: > > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> > > > > In order to prepare gpio_desc_to_lineinfo() to being called from atomic > > context, add a new argument - bool atomic - which, if set, indicates > > that no sleeping functions must be called (currently: only > > pinctrl_gpio_can_use_line()). > > > > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> > > --- > > unsigned long dflags; > > const char *label; > > @@ -2402,9 +2402,13 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc, > > test_bit(FLAG_USED_AS_IRQ, &dflags) || > > test_bit(FLAG_EXPORT, &dflags) || > > test_bit(FLAG_SYSFS, &dflags) || > > - !gpiochip_line_is_valid(guard.gc, info->offset) || > > - !pinctrl_gpio_can_use_line(guard.gc, info->offset)) > > + !gpiochip_line_is_valid(guard.gc, info->offset)) > > info->flags |= GPIO_V2_LINE_FLAG_USED; > > + > > + if (!atomic) { > > + if (!pinctrl_gpio_can_use_line(guard.gc, info->offset)) > > + info->flags |= GPIO_V2_LINE_FLAG_USED; > > + } > > > > Should be else if. > If we're not atomic, let's call pinctrl_gpio_can_use_line() and update the flag accordingly. If we're in atomic, just don't do it. In any case do the rest. Looks good to me, am I missing something? Bart > > > if (test_bit(FLAG_IS_OUT, &dflags)) > > info->flags |= GPIO_V2_LINE_FLAG_OUTPUT; > > @@ -2502,7 +2506,7 @@ static int lineinfo_get_v1(struct gpio_chardev_data *cdev, void __user *ip, > > return -EBUSY; > > } > >
On Mon, Oct 14, 2024 at 09:45:19AM +0200, Bartosz Golaszewski wrote: > On Mon, Oct 14, 2024 at 3:58 AM Kent Gibson <warthog618@gmail.com> wrote: > > > > On Thu, Oct 10, 2024 at 11:10:23AM +0200, Bartosz Golaszewski wrote: > > > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> > > > > > > In order to prepare gpio_desc_to_lineinfo() to being called from atomic > > > context, add a new argument - bool atomic - which, if set, indicates > > > that no sleeping functions must be called (currently: only > > > pinctrl_gpio_can_use_line()). > > > > > > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> > > > --- > > > unsigned long dflags; > > > const char *label; > > > @@ -2402,9 +2402,13 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc, > > > test_bit(FLAG_USED_AS_IRQ, &dflags) || > > > test_bit(FLAG_EXPORT, &dflags) || > > > test_bit(FLAG_SYSFS, &dflags) || > > > - !gpiochip_line_is_valid(guard.gc, info->offset) || > > > - !pinctrl_gpio_can_use_line(guard.gc, info->offset)) > > > + !gpiochip_line_is_valid(guard.gc, info->offset)) > > > info->flags |= GPIO_V2_LINE_FLAG_USED; > > > + > > > + if (!atomic) { > > > + if (!pinctrl_gpio_can_use_line(guard.gc, info->offset)) > > > + info->flags |= GPIO_V2_LINE_FLAG_USED; > > > + } > > > > > > > Should be else if. > > > > If we're not atomic, let's call pinctrl_gpio_can_use_line() and update > the flag accordingly. If we're in atomic, just don't do it. In any > case do the rest. Looks good to me, am I missing something? > Previously the preceding if short circuits and doesn't perform the pinctl check if ANY of the preceding checks are true. The pinctrl check should be in an else-if to get the same behaviour. I am refering to the if (!atomic), btw, not the if in its body. (that is why my comment is placed after the closing bracket) Cheers, Kent.
On Mon, Oct 14, 2024 at 10:32 AM Kent Gibson <warthog618@gmail.com> wrote: > > On Mon, Oct 14, 2024 at 09:45:19AM +0200, Bartosz Golaszewski wrote: > > On Mon, Oct 14, 2024 at 3:58 AM Kent Gibson <warthog618@gmail.com> wrote: > > > > > > On Thu, Oct 10, 2024 at 11:10:23AM +0200, Bartosz Golaszewski wrote: > > > > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> > > > > > > > > In order to prepare gpio_desc_to_lineinfo() to being called from atomic > > > > context, add a new argument - bool atomic - which, if set, indicates > > > > that no sleeping functions must be called (currently: only > > > > pinctrl_gpio_can_use_line()). > > > > > > > > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> > > > > --- > > > > unsigned long dflags; > > > > const char *label; > > > > @@ -2402,9 +2402,13 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc, > > > > test_bit(FLAG_USED_AS_IRQ, &dflags) || > > > > test_bit(FLAG_EXPORT, &dflags) || > > > > test_bit(FLAG_SYSFS, &dflags) || > > > > - !gpiochip_line_is_valid(guard.gc, info->offset) || > > > > - !pinctrl_gpio_can_use_line(guard.gc, info->offset)) > > > > + !gpiochip_line_is_valid(guard.gc, info->offset)) > > > > info->flags |= GPIO_V2_LINE_FLAG_USED; > > > > + > > > > + if (!atomic) { > > > > + if (!pinctrl_gpio_can_use_line(guard.gc, info->offset)) > > > > + info->flags |= GPIO_V2_LINE_FLAG_USED; > > > > + } > > > > > > > > > > Should be else if. > > > > > > > If we're not atomic, let's call pinctrl_gpio_can_use_line() and update > > the flag accordingly. If we're in atomic, just don't do it. In any > > case do the rest. Looks good to me, am I missing something? > > > > Previously the preceding if short circuits and doesn't perform the > pinctl check if ANY of the preceding checks are true. > The pinctrl check should be in an else-if to get the same behaviour. > > I am refering to the if (!atomic), btw, not the if in its body. > (that is why my comment is placed after the closing bracket) > Ok, got it. Bartosz
diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index b0050250ac3a..8c48a53b4fa8 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -2361,7 +2361,7 @@ static void gpio_v2_line_info_changed_to_v1( #endif /* CONFIG_GPIO_CDEV_V1 */ static void gpio_desc_to_lineinfo(struct gpio_desc *desc, - struct gpio_v2_line_info *info) + struct gpio_v2_line_info *info, bool atomic) { unsigned long dflags; const char *label; @@ -2402,9 +2402,13 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc, test_bit(FLAG_USED_AS_IRQ, &dflags) || test_bit(FLAG_EXPORT, &dflags) || test_bit(FLAG_SYSFS, &dflags) || - !gpiochip_line_is_valid(guard.gc, info->offset) || - !pinctrl_gpio_can_use_line(guard.gc, info->offset)) + !gpiochip_line_is_valid(guard.gc, info->offset)) info->flags |= GPIO_V2_LINE_FLAG_USED; + + if (!atomic) { + if (!pinctrl_gpio_can_use_line(guard.gc, info->offset)) + info->flags |= GPIO_V2_LINE_FLAG_USED; + } if (test_bit(FLAG_IS_OUT, &dflags)) info->flags |= GPIO_V2_LINE_FLAG_OUTPUT; @@ -2502,7 +2506,7 @@ static int lineinfo_get_v1(struct gpio_chardev_data *cdev, void __user *ip, return -EBUSY; } - gpio_desc_to_lineinfo(desc, &lineinfo_v2); + gpio_desc_to_lineinfo(desc, &lineinfo_v2, false); gpio_v2_line_info_to_v1(&lineinfo_v2, &lineinfo); if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) { @@ -2539,7 +2543,7 @@ static int lineinfo_get(struct gpio_chardev_data *cdev, void __user *ip, if (test_and_set_bit(lineinfo.offset, cdev->watched_lines)) return -EBUSY; } - gpio_desc_to_lineinfo(desc, &lineinfo); + gpio_desc_to_lineinfo(desc, &lineinfo, false); supinfo_to_lineinfo(desc, &lineinfo); if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) { @@ -2632,7 +2636,7 @@ static int lineinfo_changed_notify(struct notifier_block *nb, memset(&chg, 0, sizeof(chg)); chg.event_type = action; chg.timestamp_ns = ktime_get_ns(); - gpio_desc_to_lineinfo(desc, &chg.info); + gpio_desc_to_lineinfo(desc, &chg.info, false); supinfo_to_lineinfo(desc, &chg.info); ret = kfifo_in_spinlocked(&cdev->events, &chg, 1, &cdev->wait.lock);