Skip to content

Commit a81668d

Browse files
committed
Merge tag 'gpio-fixes-for-v6.19-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux
Pull gpio fixes from Bartosz Golaszewski: "There are several ordinary driver fixes and a fix to a race between the registration of two chips that causes a crash in GPIO core. The bulk of the changed lines however, concerns the management of shared GPIOs that landed in v6.19-rc1. Enabling it for ARCH_QCOM enabled it in defconfig which effectively enabled it for all arm64 platforms and exposed the code to quite a lot of testing (which is good, right? :)). As a resukt, I received a number of bug reports, which I progressively fixed over the course of last weeks. This explains the number of lines higher than what I normally aim for at this stage. - balance superio enter/exit calls in error path in gpio-it87 - fix a race where we try to take the SRCU read lock of the GPIO device before it's been initialized causing a NULL-pointer dereference - fix handling of short-pulse interrupts in gpio-pca053x - fix a reference leak in error path in gpio-mpsse - mark the GPIO controller as sleeping (it calls sleeping functions) in gpio-rockchip - fix several issues in management of shared GPIOs" * tag 'gpio-fixes-for-v6.19-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux: gpio: shared: fix a false-positive sharing detection with reset-gpios gpiolib: fix lookup table matching gpio: shared: don't allocate the lookup table until we really need it gpio: shared: fix a race condition gpio: shared: assign the correct firmware node for reset-gpio use-case gpio: rockchip: mark the GPIO controller as sleeping gpio: mpsse: fix reference leak in gpio_mpsse_probe() error paths gpio: pca953x: handle short interrupt pulses on PCAL devices gpiolib: fix race condition for gdev->srcu gpio: shared: allow sharing a reset-gpios pin between reset-gpio and gpiolib gpio: shared: verify con_id when adding proxy lookup gpiolib: allow multiple lookup tables per consumer gpio: it87: balance superio enter/exit calls in error path
2 parents cbd4480 + d578b31 commit a81668d

7 files changed

Lines changed: 300 additions & 138 deletions

File tree

drivers/gpio/gpio-it87.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1414

15+
#include <linux/cleanup.h>
1516
#include <linux/init.h>
1617
#include <linux/kernel.h>
1718
#include <linux/module.h>
@@ -241,23 +242,17 @@ static int it87_gpio_direction_out(struct gpio_chip *chip,
241242
mask = 1 << (gpio_num % 8);
242243
group = (gpio_num / 8);
243244

244-
spin_lock(&it87_gpio->lock);
245+
guard(spinlock)(&it87_gpio->lock);
245246

246247
rc = superio_enter();
247248
if (rc)
248-
goto exit;
249+
return rc;
249250

250251
/* set the output enable bit */
251252
superio_set_mask(mask, group + it87_gpio->output_base);
252253

253254
rc = it87_gpio_set(chip, gpio_num, val);
254-
if (rc)
255-
goto exit;
256-
257255
superio_exit();
258-
259-
exit:
260-
spin_unlock(&it87_gpio->lock);
261256
return rc;
262257
}
263258

drivers/gpio/gpio-mpsse.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,13 @@ static void gpio_mpsse_ida_remove(void *data)
548548
ida_free(&gpio_mpsse_ida, priv->id);
549549
}
550550

551+
static void gpio_mpsse_usb_put_dev(void *data)
552+
{
553+
struct mpsse_priv *priv = data;
554+
555+
usb_put_dev(priv->udev);
556+
}
557+
551558
static int mpsse_init_valid_mask(struct gpio_chip *chip,
552559
unsigned long *valid_mask,
553560
unsigned int ngpios)
@@ -592,6 +599,10 @@ static int gpio_mpsse_probe(struct usb_interface *interface,
592599
INIT_LIST_HEAD(&priv->workers);
593600

594601
priv->udev = usb_get_dev(interface_to_usbdev(interface));
602+
err = devm_add_action_or_reset(dev, gpio_mpsse_usb_put_dev, priv);
603+
if (err)
604+
return err;
605+
595606
priv->intf = interface;
596607
priv->intf_id = interface->cur_altsetting->desc.bInterfaceNumber;
597608

@@ -713,7 +724,6 @@ static void gpio_mpsse_disconnect(struct usb_interface *intf)
713724

714725
priv->intf = NULL;
715726
usb_set_intfdata(intf, NULL);
716-
usb_put_dev(priv->udev);
717727
}
718728

719729
static struct usb_driver gpio_mpsse_driver = {

drivers/gpio/gpio-pca953x.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -943,14 +943,35 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, unsigned long *pendin
943943
DECLARE_BITMAP(old_stat, MAX_LINE);
944944
DECLARE_BITMAP(cur_stat, MAX_LINE);
945945
DECLARE_BITMAP(new_stat, MAX_LINE);
946+
DECLARE_BITMAP(int_stat, MAX_LINE);
946947
DECLARE_BITMAP(trigger, MAX_LINE);
947948
DECLARE_BITMAP(edges, MAX_LINE);
948949
int ret;
949950

951+
if (chip->driver_data & PCA_PCAL) {
952+
/* Read INT_STAT before it is cleared by the input-port read. */
953+
ret = pca953x_read_regs(chip, PCAL953X_INT_STAT, int_stat);
954+
if (ret)
955+
return false;
956+
}
957+
950958
ret = pca953x_read_regs(chip, chip->regs->input, cur_stat);
951959
if (ret)
952960
return false;
953961

962+
if (chip->driver_data & PCA_PCAL) {
963+
/* Detect short pulses via INT_STAT. */
964+
bitmap_and(trigger, int_stat, chip->irq_mask, gc->ngpio);
965+
966+
/* Apply filter for rising/falling edge selection. */
967+
bitmap_replace(new_stat, chip->irq_trig_fall, chip->irq_trig_raise,
968+
cur_stat, gc->ngpio);
969+
970+
bitmap_and(int_stat, new_stat, trigger, gc->ngpio);
971+
} else {
972+
bitmap_zero(int_stat, gc->ngpio);
973+
}
974+
954975
/* Remove output pins from the equation */
955976
pca953x_read_regs(chip, chip->regs->direction, reg_direction);
956977

@@ -964,14 +985,16 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, unsigned long *pendin
964985

965986
if (bitmap_empty(chip->irq_trig_level_high, gc->ngpio) &&
966987
bitmap_empty(chip->irq_trig_level_low, gc->ngpio)) {
967-
if (bitmap_empty(trigger, gc->ngpio))
988+
if (bitmap_empty(trigger, gc->ngpio) &&
989+
bitmap_empty(int_stat, gc->ngpio))
968990
return false;
969991
}
970992

971993
bitmap_and(cur_stat, chip->irq_trig_fall, old_stat, gc->ngpio);
972994
bitmap_and(old_stat, chip->irq_trig_raise, new_stat, gc->ngpio);
973995
bitmap_or(edges, old_stat, cur_stat, gc->ngpio);
974996
bitmap_and(pending, edges, trigger, gc->ngpio);
997+
bitmap_or(pending, pending, int_stat, gc->ngpio);
975998

976999
bitmap_and(cur_stat, new_stat, chip->irq_trig_level_high, gc->ngpio);
9771000
bitmap_and(cur_stat, cur_stat, chip->irq_mask, gc->ngpio);

drivers/gpio/gpio-rockchip.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,7 @@ static int rockchip_gpiolib_register(struct rockchip_pin_bank *bank)
593593
gc->ngpio = bank->nr_pins;
594594
gc->label = bank->name;
595595
gc->parent = bank->dev;
596+
gc->can_sleep = true;
596597

597598
ret = gpiochip_add_data(gc, bank);
598599
if (ret) {

0 commit comments

Comments
 (0)