Skip to content

Commit 3455135

Browse files
committed
Merge tag 'gpio-fixes-for-v6.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux
Pull gpio fixes from Bartosz Golaszewski: "Apart from some regular driver fixes there's a relatively big revert of the locking changes that were introduced to GPIOLIB in this merge window. This is because it turned out that some legacy GPIO interfaces - that need to translate a number from the global GPIO numberspace to the address of the relevant descriptor, thus running a GPIO device lookup and taking the GPIO device list lock - are still used in old code from atomic context resulting in "scheduling while atomic" errors. I'll try to make the read-only part of the list access entirely lockless using SRCU but this will take some time so let's go back to the old global spinlock for now. Summary: - revert the changes aiming to use a read-write semaphore to protect the list of GPIO devices due to calls to legacy API taking that lock from atomic context in old code - fix inverted logic in DEFINE_FREE() for GPIO device references - check the return value of bgpio_init() in gpio-mlxbf3 - fix node address in the DT bindings example for gpio-xilinx - fix signedness bug in gpio-rtd - fix kernel-doc warnings in gpio-en7523" * tag 'gpio-fixes-for-v6.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux: gpiolib: revert the attempt to protect the GPIO device list with an rwsem gpio: EN7523: fix kernel-doc warnings gpiolib: Fix scope-based gpio_device refcounting gpio: mlxbf3: add an error code check in mlxbf3_gpio_probe dt-bindings: gpio: xilinx: Fix node address in gpio gpio: rtd: Fix signedness bug in probe
2 parents 5c93506 + efb8235 commit 3455135

File tree

9 files changed

+113
-100
lines changed

9 files changed

+113
-100
lines changed

Documentation/devicetree/bindings/gpio/xlnx,gpio-xilinx.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ examples:
126126
- |
127127
#include <dt-bindings/interrupt-controller/arm-gic.h>
128128
129-
gpio@e000a000 {
129+
gpio@a0020000 {
130130
compatible = "xlnx,xps-gpio-1.00.a";
131131
reg = <0xa0020000 0x10000>;
132132
#gpio-cells = <2>;

drivers/gpio/gpio-en7523.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@
1212
#define AIROHA_GPIO_MAX 32
1313

1414
/**
15-
* airoha_gpio_ctrl - Airoha GPIO driver data
15+
* struct airoha_gpio_ctrl - Airoha GPIO driver data
1616
* @gc: Associated gpio_chip instance.
1717
* @data: The data register.
18-
* @dir0: The direction register for the lower 16 pins.
19-
* @dir1: The direction register for the higher 16 pins.
18+
* @dir: [0] The direction register for the lower 16 pins.
19+
* [1]: The direction register for the higher 16 pins.
2020
* @output: The output enable register.
2121
*/
2222
struct airoha_gpio_ctrl {

drivers/gpio/gpio-mlxbf3.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,8 @@ static int mlxbf3_gpio_probe(struct platform_device *pdev)
215215
gs->gpio_clr_io + MLXBF_GPIO_FW_DATA_OUT_CLEAR,
216216
gs->gpio_set_io + MLXBF_GPIO_FW_OUTPUT_ENABLE_SET,
217217
gs->gpio_clr_io + MLXBF_GPIO_FW_OUTPUT_ENABLE_CLEAR, 0);
218+
if (ret)
219+
return dev_err_probe(dev, ret, "%s: bgpio_init() failed", __func__);
218220

219221
gc->request = gpiochip_generic_request;
220222
gc->free = gpiochip_generic_free;

drivers/gpio/gpio-rtd.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -525,18 +525,21 @@ static int rtd_gpio_probe(struct platform_device *pdev)
525525
struct device *dev = &pdev->dev;
526526
struct gpio_irq_chip *irq_chip;
527527
struct rtd_gpio *data;
528+
int ret;
528529

529530
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
530531
if (!data)
531532
return -ENOMEM;
532533

533-
data->irqs[0] = platform_get_irq(pdev, 0);
534-
if (data->irqs[0] < 0)
535-
return data->irqs[0];
534+
ret = platform_get_irq(pdev, 0);
535+
if (ret < 0)
536+
return ret;
537+
data->irqs[0] = ret;
536538

537-
data->irqs[1] = platform_get_irq(pdev, 1);
538-
if (data->irqs[1] < 0)
539-
return data->irqs[1];
539+
ret = platform_get_irq(pdev, 1);
540+
if (ret < 0)
541+
return ret;
542+
data->irqs[1] = ret;
540543

541544
data->info = device_get_match_data(dev);
542545
if (!data->info)

drivers/gpio/gpiolib-sysfs.c

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -768,25 +768,6 @@ int gpiochip_sysfs_register(struct gpio_device *gdev)
768768
return 0;
769769
}
770770

771-
int gpiochip_sysfs_register_all(void)
772-
{
773-
struct gpio_device *gdev;
774-
int ret;
775-
776-
guard(rwsem_read)(&gpio_devices_sem);
777-
778-
list_for_each_entry(gdev, &gpio_devices, list) {
779-
if (gdev->mockdev)
780-
continue;
781-
782-
ret = gpiochip_sysfs_register(gdev);
783-
if (ret)
784-
return ret;
785-
}
786-
787-
return 0;
788-
}
789-
790771
void gpiochip_sysfs_unregister(struct gpio_device *gdev)
791772
{
792773
struct gpio_desc *desc;
@@ -811,7 +792,9 @@ void gpiochip_sysfs_unregister(struct gpio_device *gdev)
811792

812793
static int __init gpiolib_sysfs_init(void)
813794
{
814-
int status;
795+
int status;
796+
unsigned long flags;
797+
struct gpio_device *gdev;
815798

816799
status = class_register(&gpio_class);
817800
if (status < 0)
@@ -823,6 +806,26 @@ static int __init gpiolib_sysfs_init(void)
823806
* We run before arch_initcall() so chip->dev nodes can have
824807
* registered, and so arch_initcall() can always gpiod_export().
825808
*/
826-
return gpiochip_sysfs_register_all();
809+
spin_lock_irqsave(&gpio_lock, flags);
810+
list_for_each_entry(gdev, &gpio_devices, list) {
811+
if (gdev->mockdev)
812+
continue;
813+
814+
/*
815+
* TODO we yield gpio_lock here because
816+
* gpiochip_sysfs_register() acquires a mutex. This is unsafe
817+
* and needs to be fixed.
818+
*
819+
* Also it would be nice to use gpio_device_find() here so we
820+
* can keep gpio_chips local to gpiolib.c, but the yield of
821+
* gpio_lock prevents us from doing this.
822+
*/
823+
spin_unlock_irqrestore(&gpio_lock, flags);
824+
status = gpiochip_sysfs_register(gdev);
825+
spin_lock_irqsave(&gpio_lock, flags);
826+
}
827+
spin_unlock_irqrestore(&gpio_lock, flags);
828+
829+
return status;
827830
}
828831
postcore_initcall(gpiolib_sysfs_init);

drivers/gpio/gpiolib-sysfs.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ struct gpio_device;
88
#ifdef CONFIG_GPIO_SYSFS
99

1010
int gpiochip_sysfs_register(struct gpio_device *gdev);
11-
int gpiochip_sysfs_register_all(void);
1211
void gpiochip_sysfs_unregister(struct gpio_device *gdev);
1312

1413
#else
@@ -18,11 +17,6 @@ static inline int gpiochip_sysfs_register(struct gpio_device *gdev)
1817
return 0;
1918
}
2019

21-
static inline int gpiochip_sysfs_register_all(void)
22-
{
23-
return 0;
24-
}
25-
2620
static inline void gpiochip_sysfs_unregister(struct gpio_device *gdev)
2721
{
2822
}

drivers/gpio/gpiolib.c

Lines changed: 73 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
#include <linux/acpi.h>
44
#include <linux/bitmap.h>
5-
#include <linux/cleanup.h>
65
#include <linux/compat.h>
76
#include <linux/debugfs.h>
87
#include <linux/device.h>
@@ -16,7 +15,6 @@
1615
#include <linux/kernel.h>
1716
#include <linux/list.h>
1817
#include <linux/module.h>
19-
#include <linux/mutex.h>
2018
#include <linux/of.h>
2119
#include <linux/pinctrl/consumer.h>
2220
#include <linux/seq_file.h>
@@ -83,9 +81,7 @@ DEFINE_SPINLOCK(gpio_lock);
8381

8482
static DEFINE_MUTEX(gpio_lookup_lock);
8583
static LIST_HEAD(gpio_lookup_list);
86-
8784
LIST_HEAD(gpio_devices);
88-
DECLARE_RWSEM(gpio_devices_sem);
8985

9086
static DEFINE_MUTEX(gpio_machine_hogs_mutex);
9187
static LIST_HEAD(gpio_machine_hogs);
@@ -117,15 +113,20 @@ static inline void desc_set_label(struct gpio_desc *d, const char *label)
117113
struct gpio_desc *gpio_to_desc(unsigned gpio)
118114
{
119115
struct gpio_device *gdev;
116+
unsigned long flags;
117+
118+
spin_lock_irqsave(&gpio_lock, flags);
120119

121-
scoped_guard(rwsem_read, &gpio_devices_sem) {
122-
list_for_each_entry(gdev, &gpio_devices, list) {
123-
if (gdev->base <= gpio &&
124-
gdev->base + gdev->ngpio > gpio)
125-
return &gdev->descs[gpio - gdev->base];
120+
list_for_each_entry(gdev, &gpio_devices, list) {
121+
if (gdev->base <= gpio &&
122+
gdev->base + gdev->ngpio > gpio) {
123+
spin_unlock_irqrestore(&gpio_lock, flags);
124+
return &gdev->descs[gpio - gdev->base];
126125
}
127126
}
128127

128+
spin_unlock_irqrestore(&gpio_lock, flags);
129+
129130
if (!gpio_is_valid(gpio))
130131
pr_warn("invalid GPIO %d\n", gpio);
131132

@@ -398,21 +399,26 @@ static int gpiodev_add_to_list_unlocked(struct gpio_device *gdev)
398399
static struct gpio_desc *gpio_name_to_desc(const char * const name)
399400
{
400401
struct gpio_device *gdev;
402+
unsigned long flags;
401403

402404
if (!name)
403405
return NULL;
404406

405-
guard(rwsem_read)(&gpio_devices_sem);
407+
spin_lock_irqsave(&gpio_lock, flags);
406408

407409
list_for_each_entry(gdev, &gpio_devices, list) {
408410
struct gpio_desc *desc;
409411

410412
for_each_gpio_desc(gdev->chip, desc) {
411-
if (desc->name && !strcmp(desc->name, name))
413+
if (desc->name && !strcmp(desc->name, name)) {
414+
spin_unlock_irqrestore(&gpio_lock, flags);
412415
return desc;
416+
}
413417
}
414418
}
415419

420+
spin_unlock_irqrestore(&gpio_lock, flags);
421+
416422
return NULL;
417423
}
418424

@@ -807,6 +813,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
807813
struct lock_class_key *request_key)
808814
{
809815
struct gpio_device *gdev;
816+
unsigned long flags;
810817
unsigned int i;
811818
int base = 0;
812819
int ret = 0;
@@ -871,46 +878,49 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
871878

872879
gdev->ngpio = gc->ngpio;
873880

874-
scoped_guard(rwsem_write, &gpio_devices_sem) {
875-
/*
876-
* TODO: this allocates a Linux GPIO number base in the global
877-
* GPIO numberspace for this chip. In the long run we want to
878-
* get *rid* of this numberspace and use only descriptors, but
879-
* it may be a pipe dream. It will not happen before we get rid
880-
* of the sysfs interface anyways.
881-
*/
882-
base = gc->base;
881+
spin_lock_irqsave(&gpio_lock, flags);
883882

883+
/*
884+
* TODO: this allocates a Linux GPIO number base in the global
885+
* GPIO numberspace for this chip. In the long run we want to
886+
* get *rid* of this numberspace and use only descriptors, but
887+
* it may be a pipe dream. It will not happen before we get rid
888+
* of the sysfs interface anyways.
889+
*/
890+
base = gc->base;
891+
if (base < 0) {
892+
base = gpiochip_find_base_unlocked(gc->ngpio);
884893
if (base < 0) {
885-
base = gpiochip_find_base_unlocked(gc->ngpio);
886-
if (base < 0) {
887-
ret = base;
888-
base = 0;
889-
goto err_free_label;
890-
}
891-
/*
892-
* TODO: it should not be necessary to reflect the assigned
893-
* base outside of the GPIO subsystem. Go over drivers and
894-
* see if anyone makes use of this, else drop this and assign
895-
* a poison instead.
896-
*/
897-
gc->base = base;
898-
} else {
899-
dev_warn(&gdev->dev,
900-
"Static allocation of GPIO base is deprecated, use dynamic allocation.\n");
901-
}
902-
gdev->base = base;
903-
904-
ret = gpiodev_add_to_list_unlocked(gdev);
905-
if (ret) {
906-
chip_err(gc, "GPIO integer space overlap, cannot add chip\n");
894+
spin_unlock_irqrestore(&gpio_lock, flags);
895+
ret = base;
896+
base = 0;
907897
goto err_free_label;
908898
}
899+
/*
900+
* TODO: it should not be necessary to reflect the assigned
901+
* base outside of the GPIO subsystem. Go over drivers and
902+
* see if anyone makes use of this, else drop this and assign
903+
* a poison instead.
904+
*/
905+
gc->base = base;
906+
} else {
907+
dev_warn(&gdev->dev,
908+
"Static allocation of GPIO base is deprecated, use dynamic allocation.\n");
909+
}
910+
gdev->base = base;
909911

910-
for (i = 0; i < gc->ngpio; i++)
911-
gdev->descs[i].gdev = gdev;
912+
ret = gpiodev_add_to_list_unlocked(gdev);
913+
if (ret) {
914+
spin_unlock_irqrestore(&gpio_lock, flags);
915+
chip_err(gc, "GPIO integer space overlap, cannot add chip\n");
916+
goto err_free_label;
912917
}
913918

919+
for (i = 0; i < gc->ngpio; i++)
920+
gdev->descs[i].gdev = gdev;
921+
922+
spin_unlock_irqrestore(&gpio_lock, flags);
923+
914924
BLOCKING_INIT_NOTIFIER_HEAD(&gdev->line_state_notifier);
915925
BLOCKING_INIT_NOTIFIER_HEAD(&gdev->device_notifier);
916926
init_rwsem(&gdev->sem);
@@ -1001,8 +1011,9 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
10011011
goto err_print_message;
10021012
}
10031013
err_remove_from_list:
1004-
scoped_guard(rwsem_write, &gpio_devices_sem)
1005-
list_del(&gdev->list);
1014+
spin_lock_irqsave(&gpio_lock, flags);
1015+
list_del(&gdev->list);
1016+
spin_unlock_irqrestore(&gpio_lock, flags);
10061017
err_free_label:
10071018
kfree_const(gdev->label);
10081019
err_free_descs:
@@ -1065,7 +1076,7 @@ void gpiochip_remove(struct gpio_chip *gc)
10651076
dev_crit(&gdev->dev,
10661077
"REMOVING GPIOCHIP WITH GPIOS STILL REQUESTED\n");
10671078

1068-
scoped_guard(rwsem_write, &gpio_devices_sem)
1079+
scoped_guard(spinlock_irqsave, &gpio_lock)
10691080
list_del(&gdev->list);
10701081

10711082
/*
@@ -1114,7 +1125,7 @@ struct gpio_device *gpio_device_find(void *data,
11141125
*/
11151126
might_sleep();
11161127

1117-
guard(rwsem_read)(&gpio_devices_sem);
1128+
guard(spinlock_irqsave)(&gpio_lock);
11181129

11191130
list_for_each_entry(gdev, &gpio_devices, list) {
11201131
if (gdev->chip && match(gdev->chip, data))
@@ -4725,33 +4736,35 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_device *gdev)
47254736

47264737
static void *gpiolib_seq_start(struct seq_file *s, loff_t *pos)
47274738
{
4739+
unsigned long flags;
47284740
struct gpio_device *gdev = NULL;
47294741
loff_t index = *pos;
47304742

47314743
s->private = "";
47324744

4733-
guard(rwsem_read)(&gpio_devices_sem);
4734-
4735-
list_for_each_entry(gdev, &gpio_devices, list) {
4736-
if (index-- == 0)
4745+
spin_lock_irqsave(&gpio_lock, flags);
4746+
list_for_each_entry(gdev, &gpio_devices, list)
4747+
if (index-- == 0) {
4748+
spin_unlock_irqrestore(&gpio_lock, flags);
47374749
return gdev;
4738-
}
4750+
}
4751+
spin_unlock_irqrestore(&gpio_lock, flags);
47394752

47404753
return NULL;
47414754
}
47424755

47434756
static void *gpiolib_seq_next(struct seq_file *s, void *v, loff_t *pos)
47444757
{
4758+
unsigned long flags;
47454759
struct gpio_device *gdev = v;
47464760
void *ret = NULL;
47474761

4748-
scoped_guard(rwsem_read, &gpio_devices_sem) {
4749-
if (list_is_last(&gdev->list, &gpio_devices))
4750-
ret = NULL;
4751-
else
4752-
ret = list_first_entry(&gdev->list, struct gpio_device,
4753-
list);
4754-
}
4762+
spin_lock_irqsave(&gpio_lock, flags);
4763+
if (list_is_last(&gdev->list, &gpio_devices))
4764+
ret = NULL;
4765+
else
4766+
ret = list_first_entry(&gdev->list, struct gpio_device, list);
4767+
spin_unlock_irqrestore(&gpio_lock, flags);
47554768

47564769
s->private = "\n";
47574770
++*pos;

0 commit comments

Comments
 (0)