gpio: adnp: use lock guards for the I2C lock

Reduce the code complexity by using automatic lock guards with the I2C
mutex.

Link: https://lore.kernel.org/r/20250306-gpiochip-set-conversion-v2-1-a76e72e21425@linaro.org
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
This commit is contained in:
Bartosz Golaszewski 2025-03-06 18:19:26 +01:00
parent 460560100a
commit c7fe19ed39

View File

@ -3,6 +3,7 @@
* Copyright (C) 2011-2012 Avionic Design GmbH * Copyright (C) 2011-2012 Avionic Design GmbH
*/ */
#include <linux/cleanup.h>
#include <linux/gpio/driver.h> #include <linux/gpio/driver.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
@ -102,9 +103,9 @@ static void adnp_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{ {
struct adnp *adnp = gpiochip_get_data(chip); struct adnp *adnp = gpiochip_get_data(chip);
mutex_lock(&adnp->i2c_lock); guard(mutex)(&adnp->i2c_lock);
__adnp_gpio_set(adnp, offset, value); __adnp_gpio_set(adnp, offset, value);
mutex_unlock(&adnp->i2c_lock);
} }
static int adnp_gpio_direction_input(struct gpio_chip *chip, unsigned offset) static int adnp_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
@ -115,32 +116,26 @@ static int adnp_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
u8 value; u8 value;
int err; int err;
mutex_lock(&adnp->i2c_lock); guard(mutex)(&adnp->i2c_lock);
err = adnp_read(adnp, GPIO_DDR(adnp) + reg, &value); err = adnp_read(adnp, GPIO_DDR(adnp) + reg, &value);
if (err < 0) if (err < 0)
goto out; return err;
value &= ~BIT(pos); value &= ~BIT(pos);
err = adnp_write(adnp, GPIO_DDR(adnp) + reg, value); err = adnp_write(adnp, GPIO_DDR(adnp) + reg, value);
if (err < 0) if (err < 0)
goto out; return err;
err = adnp_read(adnp, GPIO_DDR(adnp) + reg, &value); err = adnp_read(adnp, GPIO_DDR(adnp) + reg, &value);
if (err < 0) if (err < 0)
goto out;
if (value & BIT(pos)) {
err = -EPERM;
goto out;
}
err = 0;
out:
mutex_unlock(&adnp->i2c_lock);
return err; return err;
if (value & BIT(pos))
return -EPERM;
return 0;
} }
static int adnp_gpio_direction_output(struct gpio_chip *chip, unsigned offset, static int adnp_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
@ -152,33 +147,28 @@ static int adnp_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
int err; int err;
u8 val; u8 val;
mutex_lock(&adnp->i2c_lock); guard(mutex)(&adnp->i2c_lock);
err = adnp_read(adnp, GPIO_DDR(adnp) + reg, &val); err = adnp_read(adnp, GPIO_DDR(adnp) + reg, &val);
if (err < 0) if (err < 0)
goto out; return err;
val |= BIT(pos); val |= BIT(pos);
err = adnp_write(adnp, GPIO_DDR(adnp) + reg, val); err = adnp_write(adnp, GPIO_DDR(adnp) + reg, val);
if (err < 0) if (err < 0)
goto out; return err;
err = adnp_read(adnp, GPIO_DDR(adnp) + reg, &val); err = adnp_read(adnp, GPIO_DDR(adnp) + reg, &val);
if (err < 0) if (err < 0)
goto out; return err;
if (!(val & BIT(pos))) { if (!(val & BIT(pos)))
err = -EPERM; return -EPERM;
goto out;
}
__adnp_gpio_set(adnp, offset, value); __adnp_gpio_set(adnp, offset, value);
err = 0;
out: return 0;
mutex_unlock(&adnp->i2c_lock);
return err;
} }
static void adnp_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) static void adnp_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
@ -188,27 +178,26 @@ static void adnp_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
int err; int err;
for (i = 0; i < num_regs; i++) { for (i = 0; i < num_regs; i++) {
u8 ddr, plr, ier, isr; u8 ddr = 0, plr = 0, ier = 0, isr = 0;
mutex_lock(&adnp->i2c_lock);
scoped_guard(mutex, &adnp->i2c_lock) {
err = adnp_read(adnp, GPIO_DDR(adnp) + i, &ddr); err = adnp_read(adnp, GPIO_DDR(adnp) + i, &ddr);
if (err < 0) if (err < 0)
goto unlock; return;
err = adnp_read(adnp, GPIO_PLR(adnp) + i, &plr); err = adnp_read(adnp, GPIO_PLR(adnp) + i, &plr);
if (err < 0) if (err < 0)
goto unlock; return;
err = adnp_read(adnp, GPIO_IER(adnp) + i, &ier); err = adnp_read(adnp, GPIO_IER(adnp) + i, &ier);
if (err < 0) if (err < 0)
goto unlock; return;
err = adnp_read(adnp, GPIO_ISR(adnp) + i, &isr); err = adnp_read(adnp, GPIO_ISR(adnp) + i, &isr);
if (err < 0) if (err < 0)
goto unlock; return;
mutex_unlock(&adnp->i2c_lock); }
for (j = 0; j < 8; j++) { for (j = 0; j < 8; j++) {
unsigned int bit = (i << adnp->reg_shift) + j; unsigned int bit = (i << adnp->reg_shift) + j;
@ -233,11 +222,6 @@ static void adnp_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
direction, level, interrupt, pending); direction, level, interrupt, pending);
} }
} }
return;
unlock:
mutex_unlock(&adnp->i2c_lock);
} }
static irqreturn_t adnp_irq(int irq, void *data) static irqreturn_t adnp_irq(int irq, void *data)
@ -249,32 +233,24 @@ static irqreturn_t adnp_irq(int irq, void *data)
for (i = 0; i < num_regs; i++) { for (i = 0; i < num_regs; i++) {
unsigned int base = i << adnp->reg_shift, bit; unsigned int base = i << adnp->reg_shift, bit;
u8 changed, level, isr, ier; u8 changed, level = 0, isr = 0, ier = 0;
unsigned long pending; unsigned long pending;
int err; int err;
mutex_lock(&adnp->i2c_lock); scoped_guard(mutex, &adnp->i2c_lock) {
err = adnp_read(adnp, GPIO_PLR(adnp) + i, &level); err = adnp_read(adnp, GPIO_PLR(adnp) + i, &level);
if (err < 0) { if (err < 0)
mutex_unlock(&adnp->i2c_lock);
continue; continue;
}
err = adnp_read(adnp, GPIO_ISR(adnp) + i, &isr); err = adnp_read(adnp, GPIO_ISR(adnp) + i, &isr);
if (err < 0) { if (err < 0)
mutex_unlock(&adnp->i2c_lock);
continue; continue;
}
err = adnp_read(adnp, GPIO_IER(adnp) + i, &ier); err = adnp_read(adnp, GPIO_IER(adnp) + i, &ier);
if (err < 0) { if (err < 0)
mutex_unlock(&adnp->i2c_lock);
continue; continue;
} }
mutex_unlock(&adnp->i2c_lock);
/* determine pins that changed levels */ /* determine pins that changed levels */
changed = level ^ adnp->irq_level[i]; changed = level ^ adnp->irq_level[i];
@ -366,12 +342,12 @@ static void adnp_irq_bus_unlock(struct irq_data *d)
struct adnp *adnp = gpiochip_get_data(gc); struct adnp *adnp = gpiochip_get_data(gc);
unsigned int num_regs = 1 << adnp->reg_shift, i; unsigned int num_regs = 1 << adnp->reg_shift, i;
mutex_lock(&adnp->i2c_lock); scoped_guard(mutex, &adnp->i2c_lock) {
for (i = 0; i < num_regs; i++) for (i = 0; i < num_regs; i++)
adnp_write(adnp, GPIO_IER(adnp) + i, adnp->irq_enable[i]); adnp_write(adnp, GPIO_IER(adnp) + i,
adnp->irq_enable[i]);
}
mutex_unlock(&adnp->i2c_lock);
mutex_unlock(&adnp->irq_lock); mutex_unlock(&adnp->irq_lock);
} }