Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'gpio-fixes-for-v6.14-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux

Pull gpio fixes from Bartosz Golaszewski:
"The first fix is a backport from my v6.15-rc1 queue that turned out to
be needed in v6.14 as well but as the former diverged from my fixes
branch I had to adjust the patch a bit.

The second one fixes a regression observed in user-space where closing
a file descriptor associated with a GPIO device results in a ~10ms
delay due to the atomic notifier calling rcu_synchronize() when
unregistering.

Summary:

- don't check the return value of gpio_chip::get_direction() when
registering a GPIO chip

- use raw notifier for line state events"

* tag 'gpio-fixes-for-v6.14-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux:
gpio: cdev: use raw notifier for line state events
gpiolib: don't check the retval of get_direction() when registering a chip

+29 -26
+9 -6
drivers/gpio/gpiolib-cdev.c
··· 2729 2729 cdev->gdev = gpio_device_get(gdev); 2730 2730 2731 2731 cdev->lineinfo_changed_nb.notifier_call = lineinfo_changed_notify; 2732 - ret = atomic_notifier_chain_register(&gdev->line_state_notifier, 2733 - &cdev->lineinfo_changed_nb); 2732 + scoped_guard(write_lock_irqsave, &gdev->line_state_lock) 2733 + ret = raw_notifier_chain_register(&gdev->line_state_notifier, 2734 + &cdev->lineinfo_changed_nb); 2734 2735 if (ret) 2735 2736 goto out_free_bitmap; 2736 2737 ··· 2755 2754 blocking_notifier_chain_unregister(&gdev->device_notifier, 2756 2755 &cdev->device_unregistered_nb); 2757 2756 out_unregister_line_notifier: 2758 - atomic_notifier_chain_unregister(&gdev->line_state_notifier, 2759 - &cdev->lineinfo_changed_nb); 2757 + scoped_guard(write_lock_irqsave, &gdev->line_state_lock) 2758 + raw_notifier_chain_unregister(&gdev->line_state_notifier, 2759 + &cdev->lineinfo_changed_nb); 2760 2760 out_free_bitmap: 2761 2761 gpio_device_put(gdev); 2762 2762 bitmap_free(cdev->watched_lines); ··· 2781 2779 2782 2780 blocking_notifier_chain_unregister(&gdev->device_notifier, 2783 2781 &cdev->device_unregistered_nb); 2784 - atomic_notifier_chain_unregister(&gdev->line_state_notifier, 2785 - &cdev->lineinfo_changed_nb); 2782 + scoped_guard(write_lock_irqsave, &gdev->line_state_lock) 2783 + raw_notifier_chain_unregister(&gdev->line_state_notifier, 2784 + &cdev->lineinfo_changed_nb); 2786 2785 bitmap_free(cdev->watched_lines); 2787 2786 gpio_device_put(gdev); 2788 2787 kfree(cdev);
+16 -19
drivers/gpio/gpiolib.c
··· 1025 1025 } 1026 1026 } 1027 1027 1028 - ATOMIC_INIT_NOTIFIER_HEAD(&gdev->line_state_notifier); 1028 + rwlock_init(&gdev->line_state_lock); 1029 + RAW_INIT_NOTIFIER_HEAD(&gdev->line_state_notifier); 1029 1030 BLOCKING_INIT_NOTIFIER_HEAD(&gdev->device_notifier); 1030 1031 1031 1032 ret = init_srcu_struct(&gdev->srcu); ··· 1057 1056 1058 1057 desc->gdev = gdev; 1059 1058 1060 - if (gc->get_direction && gpiochip_line_is_valid(gc, desc_index)) { 1061 - ret = gc->get_direction(gc, desc_index); 1062 - if (ret < 0) 1063 - /* 1064 - * FIXME: Bail-out here once all GPIO drivers 1065 - * are updated to not return errors in 1066 - * situations that can be considered normal 1067 - * operation. 1068 - */ 1069 - dev_warn(&gdev->dev, 1070 - "%s: get_direction failed: %d\n", 1071 - __func__, ret); 1072 - 1073 - assign_bit(FLAG_IS_OUT, &desc->flags, !ret); 1074 - } else { 1059 + /* 1060 + * We would typically want to check the return value of 1061 + * get_direction() here but we must not check the return value 1062 + * and bail-out as pin controllers can have pins configured to 1063 + * alternate functions and return -EINVAL. Also: there's no 1064 + * need to take the SRCU lock here. 1065 + */ 1066 + if (gc->get_direction && gpiochip_line_is_valid(gc, desc_index)) 1067 + assign_bit(FLAG_IS_OUT, &desc->flags, 1068 + !gc->get_direction(gc, desc_index)); 1069 + else 1075 1070 assign_bit(FLAG_IS_OUT, 1076 1071 &desc->flags, !gc->direction_input); 1077 - } 1078 1072 } 1079 1073 1080 1074 ret = of_gpiochip_add(gc); ··· 4189 4193 4190 4194 void gpiod_line_state_notify(struct gpio_desc *desc, unsigned long action) 4191 4195 { 4192 - atomic_notifier_call_chain(&desc->gdev->line_state_notifier, 4193 - action, desc); 4196 + guard(read_lock_irqsave)(&desc->gdev->line_state_lock); 4197 + 4198 + raw_notifier_call_chain(&desc->gdev->line_state_notifier, action, desc); 4194 4199 } 4195 4200 4196 4201 /**
+4 -1
drivers/gpio/gpiolib.h
··· 16 16 #include <linux/gpio/driver.h> 17 17 #include <linux/module.h> 18 18 #include <linux/notifier.h> 19 + #include <linux/spinlock.h> 19 20 #include <linux/srcu.h> 20 21 #include <linux/workqueue.h> 21 22 ··· 46 45 * @list: links gpio_device:s together for traversal 47 46 * @line_state_notifier: used to notify subscribers about lines being 48 47 * requested, released or reconfigured 48 + * @line_state_lock: RW-spinlock protecting the line state notifier 49 49 * @line_state_wq: used to emit line state events from a separate thread in 50 50 * process context 51 51 * @device_notifier: used to notify character device wait queues about the GPIO ··· 74 72 const char *label; 75 73 void *data; 76 74 struct list_head list; 77 - struct atomic_notifier_head line_state_notifier; 75 + struct raw_notifier_head line_state_notifier; 76 + rwlock_t line_state_lock; 78 77 struct workqueue_struct *line_state_wq; 79 78 struct blocking_notifier_head device_notifier; 80 79 struct srcu_struct srcu;