Commit 0f25fda8 authored by Marek Vasut's avatar Marek Vasut Committed by Linus Walleij

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: default avatarMarek Vasut <marek.vasut+renesas@gmail.com>
Cc: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 49427232
...@@ -142,7 +142,6 @@ static const struct pca953x_reg_config pca957x_regs = { ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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, &reg_val, off); ret = regmap_read(chip->regmap, dirreg, &reg_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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment