提交 6e66a659 编写于 作者: A Axel Lin 提交者: Linus Walleij

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: NAxel Lin <axel.lin@ingics.com>
Reviewed-by: NAlexandre Courbot <acourbot@nvidia.com>
Signed-off-by: NLinus Walleij <linus.walleij@linaro.org>
上级 18fb0a98
...@@ -57,39 +57,34 @@ static int tpic2810_direction_output(struct gpio_chip *chip, ...@@ -57,39 +57,34 @@ static int tpic2810_direction_output(struct gpio_chip *chip,
return 0; 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); struct tpic2810 *gpio = gpiochip_get_data(chip);
u8 buffer;
int err;
mutex_lock(&gpio->lock); mutex_lock(&gpio->lock);
if (value) buffer = gpio->buffer & ~mask;
gpio->buffer |= BIT(offset); buffer |= (mask & bits);
else
gpio->buffer &= ~BIT(offset);
i2c_smbus_write_byte_data(gpio->client, TPIC2810_WS_COMMAND, err = i2c_smbus_write_byte_data(gpio->client, TPIC2810_WS_COMMAND,
gpio->buffer); buffer);
if (!err)
gpio->buffer = buffer;
mutex_unlock(&gpio->lock); 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, static void tpic2810_set_multiple(struct gpio_chip *chip, unsigned long *mask,
unsigned long *bits) unsigned long *bits)
{ {
struct tpic2810 *gpio = gpiochip_get_data(chip); tpic2810_set_mask_bits(chip, *mask, *bits);
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);
} }
static struct gpio_chip template_chip = { static struct gpio_chip template_chip = {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册