mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	gpio: pca953x: Zap ad-hoc reg_direction cache
Replace the ad-hoc reg_direction direction register caching with generic regcache cache. This reduces code duplication. Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com> Cc: Bartosz Golaszewski <bgolaszewski@baylibre.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
		
							parent
							
								
									4942723276
								
							
						
					
					
						commit
						0f25fda840
					
				
					 1 changed files with 31 additions and 24 deletions
				
			
		| 
						 | 
					@ -142,7 +142,6 @@ static const struct pca953x_reg_config pca957x_regs = {
 | 
				
			||||||
struct pca953x_chip {
 | 
					struct pca953x_chip {
 | 
				
			||||||
	unsigned gpio_start;
 | 
						unsigned gpio_start;
 | 
				
			||||||
	u8 reg_output[MAX_BANK];
 | 
						u8 reg_output[MAX_BANK];
 | 
				
			||||||
	u8 reg_direction[MAX_BANK];
 | 
					 | 
				
			||||||
	struct mutex i2c_lock;
 | 
						struct mutex i2c_lock;
 | 
				
			||||||
	struct regmap *regmap;
 | 
						struct regmap *regmap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -387,18 +386,13 @@ static int pca953x_read_regs(struct pca953x_chip *chip, int reg, u8 *val)
 | 
				
			||||||
static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off)
 | 
					static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct pca953x_chip *chip = gpiochip_get_data(gc);
 | 
						struct pca953x_chip *chip = gpiochip_get_data(gc);
 | 
				
			||||||
	u8 reg_val;
 | 
						u8 dirreg = pca953x_recalc_addr(chip, chip->regs->direction, off,
 | 
				
			||||||
 | 
										true, false);
 | 
				
			||||||
 | 
						u8 bit = BIT(off % BANK_SZ);
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mutex_lock(&chip->i2c_lock);
 | 
						mutex_lock(&chip->i2c_lock);
 | 
				
			||||||
	reg_val = chip->reg_direction[off / BANK_SZ] | (1u << (off % BANK_SZ));
 | 
						ret = regmap_write_bits(chip->regmap, dirreg, bit, bit);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	ret = pca953x_write_single(chip, chip->regs->direction, reg_val, off);
 | 
					 | 
				
			||||||
	if (ret)
 | 
					 | 
				
			||||||
		goto exit;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	chip->reg_direction[off / BANK_SZ] = reg_val;
 | 
					 | 
				
			||||||
exit:
 | 
					 | 
				
			||||||
	mutex_unlock(&chip->i2c_lock);
 | 
						mutex_unlock(&chip->i2c_lock);
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -407,6 +401,9 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
 | 
				
			||||||
		unsigned off, int val)
 | 
							unsigned off, int val)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct pca953x_chip *chip = gpiochip_get_data(gc);
 | 
						struct pca953x_chip *chip = gpiochip_get_data(gc);
 | 
				
			||||||
 | 
						u8 dirreg = pca953x_recalc_addr(chip, chip->regs->direction, off,
 | 
				
			||||||
 | 
										true, false);
 | 
				
			||||||
 | 
						u8 bit = BIT(off % BANK_SZ);
 | 
				
			||||||
	u8 reg_val;
 | 
						u8 reg_val;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -426,12 +423,7 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
 | 
				
			||||||
	chip->reg_output[off / BANK_SZ] = reg_val;
 | 
						chip->reg_output[off / BANK_SZ] = reg_val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* then direction */
 | 
						/* then direction */
 | 
				
			||||||
	reg_val = chip->reg_direction[off / BANK_SZ] & ~(1u << (off % BANK_SZ));
 | 
						ret = regmap_write_bits(chip->regmap, dirreg, bit, 0);
 | 
				
			||||||
	ret = pca953x_write_single(chip, chip->regs->direction, reg_val, off);
 | 
					 | 
				
			||||||
	if (ret)
 | 
					 | 
				
			||||||
		goto exit;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	chip->reg_direction[off / BANK_SZ] = reg_val;
 | 
					 | 
				
			||||||
exit:
 | 
					exit:
 | 
				
			||||||
	mutex_unlock(&chip->i2c_lock);
 | 
						mutex_unlock(&chip->i2c_lock);
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
| 
						 | 
					@ -483,16 +475,19 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
 | 
				
			||||||
static int pca953x_gpio_get_direction(struct gpio_chip *gc, unsigned off)
 | 
					static int pca953x_gpio_get_direction(struct gpio_chip *gc, unsigned off)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct pca953x_chip *chip = gpiochip_get_data(gc);
 | 
						struct pca953x_chip *chip = gpiochip_get_data(gc);
 | 
				
			||||||
 | 
						u8 dirreg = pca953x_recalc_addr(chip, chip->regs->direction, off,
 | 
				
			||||||
 | 
										true, false);
 | 
				
			||||||
 | 
						u8 bit = BIT(off % BANK_SZ);
 | 
				
			||||||
	u32 reg_val;
 | 
						u32 reg_val;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mutex_lock(&chip->i2c_lock);
 | 
						mutex_lock(&chip->i2c_lock);
 | 
				
			||||||
	ret = pca953x_read_single(chip, chip->regs->direction, ®_val, off);
 | 
						ret = regmap_read(chip->regmap, dirreg, ®_val);
 | 
				
			||||||
	mutex_unlock(&chip->i2c_lock);
 | 
						mutex_unlock(&chip->i2c_lock);
 | 
				
			||||||
	if (ret < 0)
 | 
						if (ret < 0)
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return !!(reg_val & (1u << (off % BANK_SZ)));
 | 
						return !!(reg_val & bit);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void pca953x_gpio_set_multiple(struct gpio_chip *gc,
 | 
					static void pca953x_gpio_set_multiple(struct gpio_chip *gc,
 | 
				
			||||||
| 
						 | 
					@ -580,6 +575,10 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d)
 | 
				
			||||||
	u8 new_irqs;
 | 
						u8 new_irqs;
 | 
				
			||||||
	int level, i;
 | 
						int level, i;
 | 
				
			||||||
	u8 invert_irq_mask[MAX_BANK];
 | 
						u8 invert_irq_mask[MAX_BANK];
 | 
				
			||||||
 | 
						int reg_direction[MAX_BANK];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						regmap_bulk_read(chip->regmap, chip->regs->direction, reg_direction,
 | 
				
			||||||
 | 
								 NBANK(chip));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (chip->driver_data & PCA_PCAL) {
 | 
						if (chip->driver_data & PCA_PCAL) {
 | 
				
			||||||
		/* Enable latch on interrupt-enabled inputs */
 | 
							/* Enable latch on interrupt-enabled inputs */
 | 
				
			||||||
| 
						 | 
					@ -595,7 +594,7 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d)
 | 
				
			||||||
	/* Look for any newly setup interrupt */
 | 
						/* Look for any newly setup interrupt */
 | 
				
			||||||
	for (i = 0; i < NBANK(chip); i++) {
 | 
						for (i = 0; i < NBANK(chip); i++) {
 | 
				
			||||||
		new_irqs = chip->irq_trig_fall[i] | chip->irq_trig_raise[i];
 | 
							new_irqs = chip->irq_trig_fall[i] | chip->irq_trig_raise[i];
 | 
				
			||||||
		new_irqs &= ~chip->reg_direction[i];
 | 
							new_irqs &= reg_direction[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		while (new_irqs) {
 | 
							while (new_irqs) {
 | 
				
			||||||
			level = __ffs(new_irqs);
 | 
								level = __ffs(new_irqs);
 | 
				
			||||||
| 
						 | 
					@ -660,6 +659,7 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, u8 *pending)
 | 
				
			||||||
	bool pending_seen = false;
 | 
						bool pending_seen = false;
 | 
				
			||||||
	bool trigger_seen = false;
 | 
						bool trigger_seen = false;
 | 
				
			||||||
	u8 trigger[MAX_BANK];
 | 
						u8 trigger[MAX_BANK];
 | 
				
			||||||
 | 
						int reg_direction[MAX_BANK];
 | 
				
			||||||
	int ret, i;
 | 
						int ret, i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (chip->driver_data & PCA_PCAL) {
 | 
						if (chip->driver_data & PCA_PCAL) {
 | 
				
			||||||
| 
						 | 
					@ -690,8 +690,10 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, u8 *pending)
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Remove output pins from the equation */
 | 
						/* Remove output pins from the equation */
 | 
				
			||||||
 | 
						regmap_bulk_read(chip->regmap, chip->regs->direction, reg_direction,
 | 
				
			||||||
 | 
								 NBANK(chip));
 | 
				
			||||||
	for (i = 0; i < NBANK(chip); i++)
 | 
						for (i = 0; i < NBANK(chip); i++)
 | 
				
			||||||
		cur_stat[i] &= chip->reg_direction[i];
 | 
							cur_stat[i] &= reg_direction[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memcpy(old_stat, chip->irq_stat, NBANK(chip));
 | 
						memcpy(old_stat, chip->irq_stat, NBANK(chip));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -745,6 +747,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
 | 
				
			||||||
			     int irq_base)
 | 
								     int irq_base)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct i2c_client *client = chip->client;
 | 
						struct i2c_client *client = chip->client;
 | 
				
			||||||
 | 
						int reg_direction[MAX_BANK];
 | 
				
			||||||
	int ret, i;
 | 
						int ret, i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (client->irq && irq_base != -1
 | 
						if (client->irq && irq_base != -1
 | 
				
			||||||
| 
						 | 
					@ -759,8 +762,10 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
 | 
				
			||||||
		 * interrupt.  We have to rely on the previous read for
 | 
							 * interrupt.  We have to rely on the previous read for
 | 
				
			||||||
		 * this purpose.
 | 
							 * this purpose.
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
 | 
							regmap_bulk_read(chip->regmap, chip->regs->direction,
 | 
				
			||||||
 | 
									 reg_direction, NBANK(chip));
 | 
				
			||||||
		for (i = 0; i < NBANK(chip); i++)
 | 
							for (i = 0; i < NBANK(chip); i++)
 | 
				
			||||||
			chip->irq_stat[i] &= chip->reg_direction[i];
 | 
								chip->irq_stat[i] &= reg_direction[i];
 | 
				
			||||||
		mutex_init(&chip->irq_lock);
 | 
							mutex_init(&chip->irq_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ret = devm_request_threaded_irq(&client->dev,
 | 
							ret = devm_request_threaded_irq(&client->dev,
 | 
				
			||||||
| 
						 | 
					@ -817,9 +822,9 @@ static int device_pca95xx_init(struct pca953x_chip *chip, u32 invert)
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = pca953x_read_regs(chip, chip->regs->direction,
 | 
						ret = regcache_sync_region(chip->regmap, chip->regs->direction,
 | 
				
			||||||
				chip->reg_direction);
 | 
									   chip->regs->direction + NBANK(chip));
 | 
				
			||||||
	if (ret)
 | 
						if (ret != 0)
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* set platform specific polarity inversion */
 | 
						/* set platform specific polarity inversion */
 | 
				
			||||||
| 
						 | 
					@ -937,6 +942,8 @@ static int pca953x_probe(struct i2c_client *client,
 | 
				
			||||||
		goto err_exit;
 | 
							goto err_exit;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						regcache_mark_dirty(chip->regmap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mutex_init(&chip->i2c_lock);
 | 
						mutex_init(&chip->i2c_lock);
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * In case we have an i2c-mux controlled by a GPIO provided by an
 | 
						 * In case we have an i2c-mux controlled by a GPIO provided by an
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue