Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6e66a659 authored by Axel Lin's avatar Axel Lin Committed by Linus Walleij
Browse files

gpio: tpic2810: Make sure cached buffer has consistent status with h/w status



i2c_smbus_write_byte_data() can fail. To ensure the
cached buffer has consistent status with h/w status, don't
update the cached gpio->buffer if write fails.

Also refactor the code a bit by adding a tpic2810_set_mask_bits()
helper and use it to simplify the code.

Signed-off-by: default avatarAxel Lin <axel.lin@ingics.com>
Reviewed-by: default avatarAlexandre Courbot <acourbot@nvidia.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 18fb0a98
Loading
Loading
Loading
Loading
+15 −20
Original line number Diff line number Diff line
@@ -57,39 +57,34 @@ static int tpic2810_direction_output(struct gpio_chip *chip,
	return 0;
}

static void tpic2810_set(struct gpio_chip *chip, unsigned offset, int value)
static void tpic2810_set_mask_bits(struct gpio_chip *chip, u8 mask, u8 bits)
{
	struct tpic2810 *gpio = gpiochip_get_data(chip);
	u8 buffer;
	int err;

	mutex_lock(&gpio->lock);

	if (value)
		gpio->buffer |= BIT(offset);
	else
		gpio->buffer &= ~BIT(offset);
	buffer = gpio->buffer & ~mask;
	buffer |= (mask & bits);

	i2c_smbus_write_byte_data(gpio->client, TPIC2810_WS_COMMAND,
				  gpio->buffer);
	err = i2c_smbus_write_byte_data(gpio->client, TPIC2810_WS_COMMAND,
					buffer);
	if (!err)
		gpio->buffer = buffer;

	mutex_unlock(&gpio->lock);
}

static void tpic2810_set(struct gpio_chip *chip, unsigned offset, int value)
{
	tpic2810_set_mask_bits(chip, BIT(offset), value ? BIT(offset) : 0);
}

static void tpic2810_set_multiple(struct gpio_chip *chip, unsigned long *mask,
				  unsigned long *bits)
{
	struct tpic2810 *gpio = gpiochip_get_data(chip);

	mutex_lock(&gpio->lock);

	/* clear bits under mask */
	gpio->buffer &= ~(*mask);
	/* set bits under mask */
	gpio->buffer |= ((*mask) & (*bits));

	i2c_smbus_write_byte_data(gpio->client, TPIC2810_WS_COMMAND,
				  gpio->buffer);

	mutex_unlock(&gpio->lock);
	tpic2810_set_mask_bits(chip, *mask, *bits);
}

static struct gpio_chip template_chip = {