diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index bf701766f4d05ca8703e287b922adb86834c6821..52f81dbf39c32ad6bd96f24bd37683788b359e68 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -517,15 +517,23 @@ static int pca953x_read_regs(struct pca953x_chip *chip, int reg, unsigned long * return 0; } -static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off) +static int pca953x_gpio_direction_input_unlocked(struct gpio_chip *gc, + unsigned int off) { struct pca953x_chip *chip = gpiochip_get_data(gc); u8 dirreg = chip->recalc_addr(chip, chip->regs->direction, off); u8 bit = BIT(off % BANK_SZ); + return regmap_write_bits(chip->regmap, dirreg, bit, bit); +} + +static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned int off) +{ + struct pca953x_chip *chip = gpiochip_get_data(gc); + guard(mutex)(&chip->i2c_lock); - return regmap_write_bits(chip->regmap, dirreg, bit, bit); + return pca953x_gpio_direction_input_unlocked(gc, off); } static int pca953x_gpio_direction_output(struct gpio_chip *gc, @@ -753,9 +761,9 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d) DECLARE_BITMAP(reg_direction, MAX_LINE); int level; - if (chip->driver_data & PCA_PCAL) { - guard(mutex)(&chip->i2c_lock); + guard(mutex)(&chip->i2c_lock); + if (chip->driver_data & PCA_PCAL) { /* Enable latch on interrupt-enabled inputs */ pca953x_write_regs(chip, PCAL953X_IN_LATCH, chip->irq_mask); @@ -775,8 +783,8 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d) bitmap_and(irq_mask, irq_mask, reg_direction, gc->ngpio); /* Look for any newly setup interrupt */ - for_each_set_bit(level, irq_mask, gc->ngpio) - pca953x_gpio_direction_input(&chip->gpio_chip, level); + for_each_andnot_bit(level, irq_mask, reg_direction, gc->ngpio) + pca953x_gpio_direction_input_unlocked(&chip->gpio_chip, level); mutex_unlock(&chip->irq_lock); }