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
*/
#include <linux/cleanup.h>
#include <linux/gpio/driver.h>
#include <linux/i2c.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);
mutex_lock(&adnp->i2c_lock);
guard(mutex)(&adnp->i2c_lock);
__adnp_gpio_set(adnp, offset, value);
mutex_unlock(&adnp->i2c_lock);
}
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;
int err;
mutex_lock(&adnp->i2c_lock);
guard(mutex)(&adnp->i2c_lock);
err = adnp_read(adnp, GPIO_DDR(adnp) + reg, &value);
if (err < 0)
goto out;
return err;
value &= ~BIT(pos);
err = adnp_write(adnp, GPIO_DDR(adnp) + reg, value);
if (err < 0)
goto out;
return err;
err = adnp_read(adnp, GPIO_DDR(adnp) + reg, &value);
if (err < 0)
goto out;
return err;
if (value & BIT(pos)) {
err = -EPERM;
goto out;
}
if (value & BIT(pos))
return -EPERM;
err = 0;
out:
mutex_unlock(&adnp->i2c_lock);
return err;
return 0;
}
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;
u8 val;
mutex_lock(&adnp->i2c_lock);
guard(mutex)(&adnp->i2c_lock);
err = adnp_read(adnp, GPIO_DDR(adnp) + reg, &val);
if (err < 0)
goto out;
return err;
val |= BIT(pos);
err = adnp_write(adnp, GPIO_DDR(adnp) + reg, val);
if (err < 0)
goto out;
return err;
err = adnp_read(adnp, GPIO_DDR(adnp) + reg, &val);
if (err < 0)
goto out;
return err;
if (!(val & BIT(pos))) {
err = -EPERM;
goto out;
}
if (!(val & BIT(pos)))
return -EPERM;
__adnp_gpio_set(adnp, offset, value);
err = 0;
out:
mutex_unlock(&adnp->i2c_lock);
return err;
return 0;
}
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;
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);
if (err < 0)
return;
err = adnp_read(adnp, GPIO_DDR(adnp) + i, &ddr);
if (err < 0)
goto unlock;
err = adnp_read(adnp, GPIO_PLR(adnp) + i, &plr);
if (err < 0)
return;
err = adnp_read(adnp, GPIO_PLR(adnp) + i, &plr);
if (err < 0)
goto unlock;
err = adnp_read(adnp, GPIO_IER(adnp) + i, &ier);
if (err < 0)
return;
err = adnp_read(adnp, GPIO_IER(adnp) + i, &ier);
if (err < 0)
goto unlock;
err = adnp_read(adnp, GPIO_ISR(adnp) + i, &isr);
if (err < 0)
return;
err = adnp_read(adnp, GPIO_ISR(adnp) + i, &isr);
if (err < 0)
goto unlock;
mutex_unlock(&adnp->i2c_lock);
}
for (j = 0; j < 8; 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);
}
}
return;
unlock:
mutex_unlock(&adnp->i2c_lock);
}
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++) {
unsigned int base = i << adnp->reg_shift, bit;
u8 changed, level, isr, ier;
u8 changed, level = 0, isr = 0, ier = 0;
unsigned long pending;
int err;
mutex_lock(&adnp->i2c_lock);
scoped_guard(mutex, &adnp->i2c_lock) {
err = adnp_read(adnp, GPIO_PLR(adnp) + i, &level);
if (err < 0)
continue;
err = adnp_read(adnp, GPIO_PLR(adnp) + i, &level);
if (err < 0) {
mutex_unlock(&adnp->i2c_lock);
continue;
err = adnp_read(adnp, GPIO_ISR(adnp) + i, &isr);
if (err < 0)
continue;
err = adnp_read(adnp, GPIO_IER(adnp) + i, &ier);
if (err < 0)
continue;
}
err = adnp_read(adnp, GPIO_ISR(adnp) + i, &isr);
if (err < 0) {
mutex_unlock(&adnp->i2c_lock);
continue;
}
err = adnp_read(adnp, GPIO_IER(adnp) + i, &ier);
if (err < 0) {
mutex_unlock(&adnp->i2c_lock);
continue;
}
mutex_unlock(&adnp->i2c_lock);
/* determine pins that changed levels */
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);
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++)
adnp_write(adnp, GPIO_IER(adnp) + i,
adnp->irq_enable[i]);
}
for (i = 0; i < num_regs; i++)
adnp_write(adnp, GPIO_IER(adnp) + i, adnp->irq_enable[i]);
mutex_unlock(&adnp->i2c_lock);
mutex_unlock(&adnp->irq_lock);
}