diff options
author | Andy Shevchenko <andriy.shevchenko@linux.intel.com> | 2020-10-14 17:13:23 +0300 |
---|---|---|
committer | Bartosz Golaszewski <bgolaszewski@baylibre.com> | 2021-02-15 11:43:32 +0100 |
commit | 5a2a46ae4b26501aab068a9a94dc581af040c7ed (patch) | |
tree | 99b1734e2f82e8dcaf6bd7e987b8992d0700a5f9 /drivers/gpio | |
parent | 9fe5fcd640359c113060676174039b8940f588e1 (diff) |
gpio: wcove: Split out to_ireg() helper and deduplicate the code
There are a few places in the code where IRQ status and mask register
values are being updated. Use a new exctracted helper to deduplicate
the code.
While at it, get rid of unnecessary divisions.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/gpio-wcove.c | 44 |
1 files changed, 24 insertions, 20 deletions
diff --git a/drivers/gpio/gpio-wcove.c b/drivers/gpio/gpio-wcove.c index 8097c8726790..a19eeef6cf1e 100644 --- a/drivers/gpio/gpio-wcove.c +++ b/drivers/gpio/gpio-wcove.c @@ -73,6 +73,8 @@ enum ctrl_register { CTRL_IN, CTRL_OUT, + IRQ_STATUS, + IRQ_MASK, }; /* @@ -112,18 +114,25 @@ static inline int to_reg(int gpio, enum ctrl_register reg_type) return reg; } -static void wcove_update_irq_mask(struct wcove_gpio *wg, int gpio) +static inline int to_ireg(int gpio, enum ctrl_register type, unsigned int *mask) { - unsigned int reg, mask; + unsigned int reg = type == IRQ_STATUS ? IRQ_STATUS_BASE : IRQ_MASK_BASE; if (gpio < GROUP0_NR_IRQS) { - reg = IRQ_MASK_BASE; - mask = BIT(gpio % GROUP0_NR_IRQS); + reg += 0; + *mask = BIT(gpio); } else { - reg = IRQ_MASK_BASE + 1; - mask = BIT((gpio - GROUP0_NR_IRQS) % GROUP1_NR_IRQS); + reg += 1; + *mask = BIT(gpio - GROUP0_NR_IRQS); } + return reg; +} + +static void wcove_update_irq_mask(struct wcove_gpio *wg, int gpio) +{ + unsigned int mask, reg = to_ireg(gpio, IRQ_MASK, &mask); + if (wg->set_irq_mask) regmap_set_bits(wg->regmap, reg, mask); else @@ -324,7 +333,7 @@ static struct irq_chip wcove_irqchip = { static irqreturn_t wcove_gpio_irq_handler(int irq, void *data) { struct wcove_gpio *wg = (struct wcove_gpio *)data; - unsigned int virq, gpio, mask, offset; + unsigned int virq, gpio; unsigned long pending; u8 p[2]; @@ -341,12 +350,11 @@ static irqreturn_t wcove_gpio_irq_handler(int irq, void *data) while (pending) { /* One iteration is for all pending bits */ for_each_set_bit(gpio, &pending, WCOVE_GPIO_NUM) { - offset = (gpio > GROUP0_NR_IRQS) ? 1 : 0; - mask = (offset == 1) ? BIT(gpio - GROUP0_NR_IRQS) : - BIT(gpio); + unsigned int mask, reg = to_ireg(gpio, IRQ_STATUS, &mask); + virq = irq_find_mapping(wg->chip.irq.domain, gpio); handle_nested_irq(virq); - regmap_set_bits(wg->regmap, IRQ_STATUS_BASE + offset, mask); + regmap_set_bits(wg->regmap, reg, mask); } /* Next iteration */ @@ -366,30 +374,26 @@ static void wcove_gpio_dbg_show(struct seq_file *s, { unsigned int ctlo, ctli, irq_mask, irq_status; struct wcove_gpio *wg = gpiochip_get_data(chip); - int gpio, offset, group, ret = 0; + int gpio, mask, ret = 0; for (gpio = 0; gpio < WCOVE_GPIO_NUM; gpio++) { - group = gpio < GROUP0_NR_IRQS ? 0 : 1; ret += regmap_read(wg->regmap, to_reg(gpio, CTRL_OUT), &ctlo); ret += regmap_read(wg->regmap, to_reg(gpio, CTRL_IN), &ctli); - ret += regmap_read(wg->regmap, IRQ_MASK_BASE + group, - &irq_mask); - ret += regmap_read(wg->regmap, IRQ_STATUS_BASE + group, - &irq_status); + ret += regmap_read(wg->regmap, to_ireg(gpio, IRQ_MASK, &mask), &irq_mask); + ret += regmap_read(wg->regmap, to_ireg(gpio, IRQ_STATUS, &mask), &irq_status); if (ret) { pr_err("Failed to read registers: ctrl out/in or irq status/mask\n"); break; } - offset = gpio % 8; seq_printf(s, " gpio-%-2d %s %s %s %s ctlo=%2x,%s %s\n", gpio, ctlo & CTLO_DIR_OUT ? "out" : "in ", ctli & 0x1 ? "hi" : "lo", ctli & CTLI_INTCNT_NE ? "fall" : " ", ctli & CTLI_INTCNT_PE ? "rise" : " ", ctlo, - irq_mask & BIT(offset) ? "mask " : "unmask", - irq_status & BIT(offset) ? "pending" : " "); + irq_mask & mask ? "mask " : "unmask", + irq_status & mask ? "pending" : " "); } } |