Commit 4cdc1912 authored by Bartosz Golaszewski's avatar Bartosz Golaszewski
Browse files

gpio: aspeed: use lock guards

Reduce the code complexity by using automatic lock guards with the raw
spinlock.

Link: https://lore.kernel.org/r/20250303-gpiochip-set-conversion-v1-12-1d5cceeebf8b@linaro.org


Signed-off-by: default avatarBartosz Golaszewski <bartosz.golaszewski@linaro.org>
parent 74ab4523
Loading
Loading
Loading
Loading
+38 −63
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
 * Joel Stanley <joel@jms.id.au>
 */

#include <linux/cleanup.h>
#include <linux/clk.h>
#include <linux/gpio/aspeed.h>
#include <linux/gpio/driver.h>
@@ -427,37 +428,33 @@ static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset,
			    int val)
{
	struct aspeed_gpio *gpio = gpiochip_get_data(gc);
	unsigned long flags;
	bool copro = false;

	raw_spin_lock_irqsave(&gpio->lock, flags);
	guard(raw_spinlock_irqsave)(&gpio->lock);

	copro = aspeed_gpio_copro_request(gpio, offset);

	__aspeed_gpio_set(gc, offset, val);

	if (copro)
		aspeed_gpio_copro_release(gpio, offset);
	raw_spin_unlock_irqrestore(&gpio->lock, flags);
}

static int aspeed_gpio_dir_in(struct gpio_chip *gc, unsigned int offset)
{
	struct aspeed_gpio *gpio = gpiochip_get_data(gc);
	unsigned long flags;
	bool copro = false;

	if (!have_input(gpio, offset))
		return -ENOTSUPP;

	raw_spin_lock_irqsave(&gpio->lock, flags);
	guard(raw_spinlock_irqsave)(&gpio->lock);

	copro = aspeed_gpio_copro_request(gpio, offset);
	gpio->config->llops->reg_bit_set(gpio, offset, reg_dir, 0);
	if (copro)
		aspeed_gpio_copro_release(gpio, offset);

	raw_spin_unlock_irqrestore(&gpio->lock, flags);

	return 0;
}

@@ -465,13 +462,12 @@ static int aspeed_gpio_dir_out(struct gpio_chip *gc,
			       unsigned int offset, int val)
{
	struct aspeed_gpio *gpio = gpiochip_get_data(gc);
	unsigned long flags;
	bool copro = false;

	if (!have_output(gpio, offset))
		return -ENOTSUPP;

	raw_spin_lock_irqsave(&gpio->lock, flags);
	guard(raw_spinlock_irqsave)(&gpio->lock);

	copro = aspeed_gpio_copro_request(gpio, offset);
	__aspeed_gpio_set(gc, offset, val);
@@ -479,7 +475,6 @@ static int aspeed_gpio_dir_out(struct gpio_chip *gc,

	if (copro)
		aspeed_gpio_copro_release(gpio, offset);
	raw_spin_unlock_irqrestore(&gpio->lock, flags);

	return 0;
}
@@ -487,7 +482,6 @@ static int aspeed_gpio_dir_out(struct gpio_chip *gc,
static int aspeed_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
{
	struct aspeed_gpio *gpio = gpiochip_get_data(gc);
	unsigned long flags;
	u32 val;

	if (!have_input(gpio, offset))
@@ -496,12 +490,10 @@ static int aspeed_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
	if (!have_output(gpio, offset))
		return GPIO_LINE_DIRECTION_IN;

	raw_spin_lock_irqsave(&gpio->lock, flags);
	guard(raw_spinlock_irqsave)(&gpio->lock);

	val = gpio->config->llops->reg_bit_get(gpio, offset, reg_dir);

	raw_spin_unlock_irqrestore(&gpio->lock, flags);

	return val ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
}

@@ -527,7 +519,6 @@ static inline int irqd_to_aspeed_gpio_data(struct irq_data *d,
static void aspeed_gpio_irq_ack(struct irq_data *d)
{
	struct aspeed_gpio *gpio;
	unsigned long flags;
	int rc, offset;
	bool copro = false;

@@ -535,20 +526,19 @@ static void aspeed_gpio_irq_ack(struct irq_data *d)
	if (rc)
		return;

	raw_spin_lock_irqsave(&gpio->lock, flags);
	guard(raw_spinlock_irqsave)(&gpio->lock);

	copro = aspeed_gpio_copro_request(gpio, offset);

	gpio->config->llops->reg_bit_set(gpio, offset, reg_irq_status, 1);

	if (copro)
		aspeed_gpio_copro_release(gpio, offset);
	raw_spin_unlock_irqrestore(&gpio->lock, flags);
}

static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set)
{
	struct aspeed_gpio *gpio;
	unsigned long flags;
	int rc, offset;
	bool copro = false;

@@ -560,14 +550,14 @@ static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set)
	if (set)
		gpiochip_enable_irq(&gpio->chip, irqd_to_hwirq(d));

	raw_spin_lock_irqsave(&gpio->lock, flags);
	guard(raw_spinlock_irqsave)(&gpio->lock);

	copro = aspeed_gpio_copro_request(gpio, offset);

	gpio->config->llops->reg_bit_set(gpio, offset, reg_irq_enable, set);

	if (copro)
		aspeed_gpio_copro_release(gpio, offset);
	raw_spin_unlock_irqrestore(&gpio->lock, flags);

	/* Masking the IRQ */
	if (!set)
@@ -591,7 +581,6 @@ static int aspeed_gpio_set_type(struct irq_data *d, unsigned int type)
	u32 type2 = 0;
	irq_flow_handler_t handler;
	struct aspeed_gpio *gpio;
	unsigned long flags;
	int rc, offset;
	bool copro = false;

@@ -620,16 +609,19 @@ static int aspeed_gpio_set_type(struct irq_data *d, unsigned int type)
		return -EINVAL;
	}

	raw_spin_lock_irqsave(&gpio->lock, flags);
	scoped_guard(raw_spinlock_irqsave, &gpio->lock) {
		copro = aspeed_gpio_copro_request(gpio, offset);

	gpio->config->llops->reg_bit_set(gpio, offset, reg_irq_type0, type0);
	gpio->config->llops->reg_bit_set(gpio, offset, reg_irq_type1, type1);
	gpio->config->llops->reg_bit_set(gpio, offset, reg_irq_type2, type2);
		gpio->config->llops->reg_bit_set(gpio, offset, reg_irq_type0,
						 type0);
		gpio->config->llops->reg_bit_set(gpio, offset, reg_irq_type1,
						 type1);
		gpio->config->llops->reg_bit_set(gpio, offset, reg_irq_type2,
						 type2);

		if (copro)
			aspeed_gpio_copro_release(gpio, offset);
	raw_spin_unlock_irqrestore(&gpio->lock, flags);
	}

	irq_set_handler_locked(d, handler);

@@ -686,17 +678,16 @@ static int aspeed_gpio_reset_tolerance(struct gpio_chip *chip,
					unsigned int offset, bool enable)
{
	struct aspeed_gpio *gpio = gpiochip_get_data(chip);
	unsigned long flags;
	bool copro = false;

	raw_spin_lock_irqsave(&gpio->lock, flags);
	guard(raw_spinlock_irqsave)(&gpio->lock);

	copro = aspeed_gpio_copro_request(gpio, offset);

	gpio->config->llops->reg_bit_set(gpio, offset, reg_tolerance, enable);

	if (copro)
		aspeed_gpio_copro_release(gpio, offset);
	raw_spin_unlock_irqrestore(&gpio->lock, flags);

	return 0;
}
@@ -798,7 +789,6 @@ static int enable_debounce(struct gpio_chip *chip, unsigned int offset,
{
	struct aspeed_gpio *gpio = gpiochip_get_data(chip);
	u32 requested_cycles;
	unsigned long flags;
	int rc;
	int i;

@@ -812,12 +802,12 @@ static int enable_debounce(struct gpio_chip *chip, unsigned int offset,
		return rc;
	}

	raw_spin_lock_irqsave(&gpio->lock, flags);
	guard(raw_spinlock_irqsave)(&gpio->lock);

	if (timer_allocation_registered(gpio, offset)) {
		rc = unregister_allocated_timer(gpio, offset);
		if (rc < 0)
			goto out;
			return rc;
	}

	/* Try to find a timer already configured for the debounce period */
@@ -855,7 +845,7 @@ static int enable_debounce(struct gpio_chip *chip, unsigned int offset,
			 * consistency.
			 */
			configure_timer(gpio, offset, 0);
			goto out;
			return rc;
		}

		i = j;
@@ -863,34 +853,26 @@ static int enable_debounce(struct gpio_chip *chip, unsigned int offset,
		iowrite32(requested_cycles, gpio->base + gpio->config->debounce_timers_array[i]);
	}

	if (WARN(i == 0, "Cannot register index of disabled timer\n")) {
		rc = -EINVAL;
		goto out;
	}
	if (WARN(i == 0, "Cannot register index of disabled timer\n"))
		return -EINVAL;

	register_allocated_timer(gpio, offset, i);
	configure_timer(gpio, offset, i);

out:
	raw_spin_unlock_irqrestore(&gpio->lock, flags);

	return rc;
}

static int disable_debounce(struct gpio_chip *chip, unsigned int offset)
{
	struct aspeed_gpio *gpio = gpiochip_get_data(chip);
	unsigned long flags;
	int rc;

	raw_spin_lock_irqsave(&gpio->lock, flags);
	guard(raw_spinlock_irqsave)(&gpio->lock);

	rc = unregister_allocated_timer(gpio, offset);
	if (!rc)
		configure_timer(gpio, offset, 0);

	raw_spin_unlock_irqrestore(&gpio->lock, flags);

	return rc;
}

@@ -961,7 +943,6 @@ int aspeed_gpio_copro_grab_gpio(struct gpio_desc *desc,
	struct aspeed_gpio *gpio = gpiochip_get_data(chip);
	int rc = 0, bindex, offset = gpio_chip_hwgpio(desc);
	const struct aspeed_gpio_bank *bank = to_bank(offset);
	unsigned long flags;

	if (!aspeed_gpio_support_copro(gpio))
		return -EOPNOTSUPP;
@@ -974,13 +955,12 @@ int aspeed_gpio_copro_grab_gpio(struct gpio_desc *desc,
		return -EINVAL;
	bindex = offset >> 3;

	raw_spin_lock_irqsave(&gpio->lock, flags);
	guard(raw_spinlock_irqsave)(&gpio->lock);

	/* Sanity check, this shouldn't happen */
	if (gpio->cf_copro_bankmap[bindex] == 0xff) {
		rc = -EIO;
		goto bail;
	}
	if (gpio->cf_copro_bankmap[bindex] == 0xff)
		return -EIO;

	gpio->cf_copro_bankmap[bindex]++;

	/* Switch command source */
@@ -994,8 +974,6 @@ int aspeed_gpio_copro_grab_gpio(struct gpio_desc *desc,
		*dreg_offset = bank->rdata_reg;
	if (bit)
		*bit = GPIO_OFFSET(offset);
 bail:
	raw_spin_unlock_irqrestore(&gpio->lock, flags);
	return rc;
}
EXPORT_SYMBOL_GPL(aspeed_gpio_copro_grab_gpio);
@@ -1009,7 +987,6 @@ int aspeed_gpio_copro_release_gpio(struct gpio_desc *desc)
	struct gpio_chip *chip = gpiod_to_chip(desc);
	struct aspeed_gpio *gpio = gpiochip_get_data(chip);
	int rc = 0, bindex, offset = gpio_chip_hwgpio(desc);
	unsigned long flags;

	if (!aspeed_gpio_support_copro(gpio))
		return -EOPNOTSUPP;
@@ -1021,21 +998,19 @@ int aspeed_gpio_copro_release_gpio(struct gpio_desc *desc)
		return -EINVAL;
	bindex = offset >> 3;

	raw_spin_lock_irqsave(&gpio->lock, flags);
	guard(raw_spinlock_irqsave)(&gpio->lock);

	/* Sanity check, this shouldn't happen */
	if (gpio->cf_copro_bankmap[bindex] == 0) {
		rc = -EIO;
		goto bail;
	}
	if (gpio->cf_copro_bankmap[bindex] == 0)
		return -EIO;

	gpio->cf_copro_bankmap[bindex]--;

	/* Switch command source */
	if (gpio->cf_copro_bankmap[bindex] == 0)
		aspeed_gpio_change_cmd_source(gpio, offset,
					      GPIO_CMDSRC_ARM);
 bail:
	raw_spin_unlock_irqrestore(&gpio->lock, flags);

	return rc;
}
EXPORT_SYMBOL_GPL(aspeed_gpio_copro_release_gpio);