Commit fcc8b637 authored by Bartosz Golaszewski's avatar Bartosz Golaszewski
Browse files

gpiolib: switch the line state notifier to atomic



With everything else ready, we can now switch to using the atomic
notifier for line state events which will allow us to notify user-space
about direction changes from atomic context.

Reviewed-by: default avatarKent Gibson <warthog618@gmail.com>
Link: https://lore.kernel.org/r/20241018-gpio-notify-in-kernel-events-v5-7-c79135e58a1c@linaro.org


Signed-off-by: default avatarBartosz Golaszewski <bartosz.golaszewski@linaro.org>
parent 40b7c499
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -2729,7 +2729,7 @@ static int gpio_chrdev_open(struct inode *inode, struct file *file)
	cdev->gdev = gpio_device_get(gdev);

	cdev->lineinfo_changed_nb.notifier_call = lineinfo_changed_notify;
	ret = blocking_notifier_chain_register(&gdev->line_state_notifier,
	ret = atomic_notifier_chain_register(&gdev->line_state_notifier,
					     &cdev->lineinfo_changed_nb);
	if (ret)
		goto out_free_bitmap;
@@ -2754,7 +2754,7 @@ static int gpio_chrdev_open(struct inode *inode, struct file *file)
	blocking_notifier_chain_unregister(&gdev->device_notifier,
					   &cdev->device_unregistered_nb);
out_unregister_line_notifier:
	blocking_notifier_chain_unregister(&gdev->line_state_notifier,
	atomic_notifier_chain_unregister(&gdev->line_state_notifier,
					 &cdev->lineinfo_changed_nb);
out_free_bitmap:
	gpio_device_put(gdev);
@@ -2779,7 +2779,7 @@ static int gpio_chrdev_release(struct inode *inode, struct file *file)

	blocking_notifier_chain_unregister(&gdev->device_notifier,
					   &cdev->device_unregistered_nb);
	blocking_notifier_chain_unregister(&gdev->line_state_notifier,
	atomic_notifier_chain_unregister(&gdev->line_state_notifier,
					 &cdev->lineinfo_changed_nb);
	bitmap_free(cdev->watched_lines);
	gpio_device_put(gdev);
+3 −3
Original line number Diff line number Diff line
@@ -1026,7 +1026,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
		}
	}

	BLOCKING_INIT_NOTIFIER_HEAD(&gdev->line_state_notifier);
	ATOMIC_INIT_NOTIFIER_HEAD(&gdev->line_state_notifier);
	BLOCKING_INIT_NOTIFIER_HEAD(&gdev->device_notifier);

	ret = init_srcu_struct(&gdev->srcu);
@@ -4098,7 +4098,7 @@ EXPORT_SYMBOL_GPL(gpiod_set_array_value_cansleep);

void gpiod_line_state_notify(struct gpio_desc *desc, unsigned long action)
{
	blocking_notifier_call_chain(&desc->gdev->line_state_notifier,
	atomic_notifier_call_chain(&desc->gdev->line_state_notifier,
				   action, desc);
}

+1 −1
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@ struct gpio_device {
	const char		*label;
	void			*data;
	struct list_head        list;
	struct blocking_notifier_head line_state_notifier;
	struct atomic_notifier_head line_state_notifier;
	struct workqueue_struct	*line_state_wq;
	struct blocking_notifier_head device_notifier;
	struct srcu_struct	srcu;