diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c index cccbaea1dec2..fc2b9bef7efc 100644 --- a/drivers/gpio/gpio-davinci.c +++ b/drivers/gpio/gpio-davinci.c @@ -611,10 +611,10 @@ static void davinci_gpio_save_context(struct davinci_gpio_controller *chips, context->set_data = readl_relaxed(&g->set_data); context->set_rising = readl_relaxed(&g->set_rising); context->set_falling = readl_relaxed(&g->set_falling); - } - /* Clear all interrupt status registers */ - writel_relaxed(GENMASK(31, 0), &g->intstat); + /* Clear stale interrupt status for this bank. */ + writel_relaxed(GENMASK(31, 0), &g->intstat); + } } static void davinci_gpio_restore_context(struct davinci_gpio_controller *chips, diff --git a/drivers/gpio/gpio-lpc32xx.c b/drivers/gpio/gpio-lpc32xx.c index 37fc54fc7385..7fb46262e18c 100644 --- a/drivers/gpio/gpio-lpc32xx.c +++ b/drivers/gpio/gpio-lpc32xx.c @@ -510,7 +510,7 @@ static int lpc32xx_of_xlate(struct gpio_chip *gc, static int lpc32xx_gpio_probe(struct platform_device *pdev) { - int i; + int i, ret; void __iomem *reg_base; reg_base = devm_platform_ioremap_resource(pdev, 0); @@ -524,8 +524,11 @@ static int lpc32xx_gpio_probe(struct platform_device *pdev) lpc32xx_gpiochip[i].chip.of_gpio_n_cells = 3; lpc32xx_gpiochip[i].reg_base = reg_base; } - devm_gpiochip_add_data(&pdev->dev, &lpc32xx_gpiochip[i].chip, - &lpc32xx_gpiochip[i]); + ret = devm_gpiochip_add_data(&pdev->dev, &lpc32xx_gpiochip[i].chip, + &lpc32xx_gpiochip[i]); + if (ret) + return dev_err_probe(&pdev->dev, ret, + "failed to register gpio chip %d\n", i); } return 0; diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index aac9ea7520b6..afec5ec23696 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -838,13 +838,18 @@ static int pca953x_irq_set_wake(struct irq_data *d, unsigned int on) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct pca953x_chip *chip = gpiochip_get_data(gc); + int ret; + + ret = irq_set_irq_wake(chip->client->irq, on); + if (ret) + return ret; if (on) atomic_inc(&chip->wakeup_path); else atomic_dec(&chip->wakeup_path); - return irq_set_irq_wake(chip->client->irq, on); + return 0; } static void pca953x_irq_bus_lock(struct irq_data *d) @@ -862,6 +867,7 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d) DECLARE_BITMAP(irq_mask, MAX_LINE); DECLARE_BITMAP(reg_direction, MAX_LINE); int level; + int ret; guard(mutex)(&chip->i2c_lock); @@ -880,7 +886,9 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d) } /* Switch direction to input if needed */ - pca953x_read_regs(chip, chip->regs->direction, reg_direction); + ret = pca953x_read_regs(chip, chip->regs->direction, reg_direction); + if (ret) + goto out; bitmap_or(irq_mask, chip->irq_trig_fall, chip->irq_trig_raise, gc->ngpio); bitmap_or(irq_mask, irq_mask, chip->irq_trig_level_high, gc->ngpio); @@ -890,6 +898,7 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d) for_each_andnot_bit(level, irq_mask, reg_direction, gc->ngpio) pca953x_gpio_direction_input_unlocked(&chip->gpio_chip, level); +out: mutex_unlock(&chip->irq_lock); } @@ -984,7 +993,9 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, unsigned long *pendin } /* Remove output pins from the equation */ - pca953x_read_regs(chip, chip->regs->direction, reg_direction); + ret = pca953x_read_regs(chip, chip->regs->direction, reg_direction); + if (ret) + return false; bitmap_copy(old_stat, chip->irq_stat, gc->ngpio); @@ -1084,7 +1095,9 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, int irq_base) * interrupt. We have to rely on the previous read for * this purpose. */ - pca953x_read_regs(chip, chip->regs->direction, reg_direction); + ret = pca953x_read_regs(chip, chip->regs->direction, reg_direction); + if (ret) + return ret; bitmap_and(chip->irq_stat, irq_stat, reg_direction, gc->ngpio); mutex_init(&chip->irq_lock); diff --git a/drivers/gpio/gpiolib-acpi-quirks.c b/drivers/gpio/gpiolib-acpi-quirks.c index 9a523871800d..3f89a87601c1 100644 --- a/drivers/gpio/gpiolib-acpi-quirks.c +++ b/drivers/gpio/gpiolib-acpi-quirks.c @@ -359,6 +359,20 @@ static const struct dmi_system_id gpiolib_acpi_quirks[] __initconst = { .ignore_interrupt = "AMDI0030:00@11", }, }, + { + /* + * Same camera power enable on GPIO 11 as the Acer Nitro V 16S AI + * above. It also powers the internal microphones. + * Found in BIOS V1.53 + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_FAMILY, "Acer Nitro 16S AI"), + }, + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { + .ignore_interrupt = "AMDI0030:00@11", + }, + }, { /* * Wakeup only works when keyboard backlight is turned off @@ -372,6 +386,23 @@ static const struct dmi_system_id gpiolib_acpi_quirks[] __initconst = { .ignore_interrupt = "AMDI0030:00@8", }, }, + { + /* + * ACPI incorrectly declares GPIO 11 as an interrupt in _AEI, + * although the EC uses the pin to control the Caps Lock LED. + * Requesting the interrupt configures the pin as an input and + * prevents the LED from working. + * Found in BIOS R1QET54W (1.40). + * https://lore.kernel.org/linux-gpio/CAAUQFRPW-rbcZV-=qV1NMjF_358sdJTiGvQuRxRqAsehY+J9Qg@mail.gmail.com/ + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "21AB"), + }, + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { + .ignore_interrupt = "AMDI0030:00@11", + }, + }, { /* * Spurious wakeups from TP_ATTN# pin diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index a30564d1525a..3f1f8c9acfc3 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -1231,11 +1231,6 @@ static void gpio_v2_line_config_flags_to_desc_flags(u64 lflags, assign_bit(GPIOD_FLAG_ACTIVE_LOW, &flags, lflags & GPIO_V2_LINE_FLAG_ACTIVE_LOW); - if (lflags & GPIO_V2_LINE_FLAG_OUTPUT) - set_bit(GPIOD_FLAG_IS_OUT, &flags); - else if (lflags & GPIO_V2_LINE_FLAG_INPUT) - clear_bit(GPIOD_FLAG_IS_OUT, &flags); - assign_bit(GPIOD_FLAG_EDGE_RISING, &flags, lflags & GPIO_V2_LINE_FLAG_EDGE_RISING); assign_bit(GPIOD_FLAG_EDGE_FALLING, &flags, diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index c880686f5fd7..fbdeda2f2787 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -2648,10 +2648,13 @@ int gpiod_request_commit(struct gpio_desc *desc, const char *label) ret = desc_set_label(desc, label ? : "?"); if (ret) - goto out_clear_bit; + goto out_free_gpio; return 0; +out_free_gpio: + if (guard.gc->free) + guard.gc->free(guard.gc, offset); out_clear_bit: clear_bit(GPIOD_FLAG_REQUESTED, &desc->flags); return ret; @@ -2700,6 +2703,8 @@ void gpiod_free_commit(struct gpio_desc *desc) clear_bit(GPIOD_FLAG_BIAS_DISABLE, &flags); clear_bit(GPIOD_FLAG_EDGE_RISING, &flags); clear_bit(GPIOD_FLAG_EDGE_FALLING, &flags); + clear_bit(GPIOD_FLAG_EVENT_CLOCK_REALTIME, &flags); + clear_bit(GPIOD_FLAG_EVENT_CLOCK_HTE, &flags); clear_bit(GPIOD_FLAG_IS_HOGGED, &flags); #ifdef CONFIG_OF_DYNAMIC WRITE_ONCE(desc->hog, NULL); @@ -2737,6 +2742,7 @@ void gpiod_free(struct gpio_desc *desc) char *gpiochip_dup_line_label(struct gpio_chip *gc, unsigned int offset) { struct gpio_desc *desc; + const char *name; char *label; desc = gpiochip_get_desc(gc, offset); @@ -2748,7 +2754,11 @@ char *gpiochip_dup_line_label(struct gpio_chip *gc, unsigned int offset) guard(srcu)(&desc->gdev->desc_srcu); - label = kstrdup(gpiod_get_label(desc), GFP_KERNEL); + name = gpiod_get_label(desc); + if (!name) + return NULL; + + label = kstrdup(name, GFP_KERNEL); if (!label) return ERR_PTR(-ENOMEM); @@ -3863,7 +3873,7 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep, unsigned long *value_bitmap) { struct gpio_chip *gc; - int i = 0, ret; + int i = 0, ret = 0; /* * Validate array_info against desc_array and its size. @@ -3941,8 +3951,10 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep, int hwgpio = gpiod_hwgpio(desc); int value = test_bit(i, value_bitmap); - if (unlikely(!test_bit(GPIOD_FLAG_IS_OUT, &desc->flags))) - return -EPERM; + if (unlikely(!test_bit(GPIOD_FLAG_IS_OUT, &desc->flags))) { + ret = -EPERM; + goto cleanup_bitmap; + } /* * Pins applicable for fast input but not for @@ -3959,9 +3971,13 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep, * open drain and open source outputs are set individually */ if (test_bit(GPIOD_FLAG_OPEN_DRAIN, &desc->flags) && !raw) { - gpio_set_open_drain_value_commit(desc, value); + ret = gpio_set_open_drain_value_commit(desc, value); + if (ret) + goto cleanup_bitmap; } else if (test_bit(GPIOD_FLAG_OPEN_SOURCE, &desc->flags) && !raw) { - gpio_set_open_source_value_commit(desc, value); + ret = gpio_set_open_source_value_commit(desc, value); + if (ret) + goto cleanup_bitmap; } else { __set_bit(hwgpio, mask); __assign_bit(hwgpio, bits, value); @@ -3975,10 +3991,10 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep, } while ((i < array_size) && gpio_device_chip_cmp(desc_array[i]->gdev, guard.gc)); /* push collected bits to outputs */ - ret = 0; if (count != 0) ret = gpiochip_set_multiple(guard.gc, mask, bits); +cleanup_bitmap: if (mask != fastpath_mask) bitmap_free(mask); if (bits != fastpath_bits)