Commit 5a2a46ae authored by Andy Shevchenko's avatar Andy Shevchenko Committed by Bartosz Golaszewski

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: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
parent 9fe5fcd6
...@@ -73,6 +73,8 @@ ...@@ -73,6 +73,8 @@
enum ctrl_register { enum ctrl_register {
CTRL_IN, CTRL_IN,
CTRL_OUT, CTRL_OUT,
IRQ_STATUS,
IRQ_MASK,
}; };
/* /*
...@@ -112,18 +114,25 @@ static inline int to_reg(int gpio, enum ctrl_register reg_type) ...@@ -112,18 +114,25 @@ static inline int to_reg(int gpio, enum ctrl_register reg_type)
return reg; 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) { if (gpio < GROUP0_NR_IRQS) {
reg = IRQ_MASK_BASE; reg += 0;
mask = BIT(gpio % GROUP0_NR_IRQS); *mask = BIT(gpio);
} else { } else {
reg = IRQ_MASK_BASE + 1; reg += 1;
mask = BIT((gpio - GROUP0_NR_IRQS) % GROUP1_NR_IRQS); *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) if (wg->set_irq_mask)
regmap_set_bits(wg->regmap, reg, mask); regmap_set_bits(wg->regmap, reg, mask);
else else
...@@ -324,7 +333,7 @@ static struct irq_chip wcove_irqchip = { ...@@ -324,7 +333,7 @@ static struct irq_chip wcove_irqchip = {
static irqreturn_t wcove_gpio_irq_handler(int irq, void *data) static irqreturn_t wcove_gpio_irq_handler(int irq, void *data)
{ {
struct wcove_gpio *wg = (struct wcove_gpio *)data; struct wcove_gpio *wg = (struct wcove_gpio *)data;
unsigned int virq, gpio, mask, offset; unsigned int virq, gpio;
unsigned long pending; unsigned long pending;
u8 p[2]; u8 p[2];
...@@ -341,12 +350,11 @@ static irqreturn_t wcove_gpio_irq_handler(int irq, void *data) ...@@ -341,12 +350,11 @@ static irqreturn_t wcove_gpio_irq_handler(int irq, void *data)
while (pending) { while (pending) {
/* One iteration is for all pending bits */ /* One iteration is for all pending bits */
for_each_set_bit(gpio, &pending, WCOVE_GPIO_NUM) { for_each_set_bit(gpio, &pending, WCOVE_GPIO_NUM) {
offset = (gpio > GROUP0_NR_IRQS) ? 1 : 0; unsigned int mask, reg = to_ireg(gpio, IRQ_STATUS, &mask);
mask = (offset == 1) ? BIT(gpio - GROUP0_NR_IRQS) :
BIT(gpio);
virq = irq_find_mapping(wg->chip.irq.domain, gpio); virq = irq_find_mapping(wg->chip.irq.domain, gpio);
handle_nested_irq(virq); handle_nested_irq(virq);
regmap_set_bits(wg->regmap, IRQ_STATUS_BASE + offset, mask); regmap_set_bits(wg->regmap, reg, mask);
} }
/* Next iteration */ /* Next iteration */
...@@ -366,30 +374,26 @@ static void wcove_gpio_dbg_show(struct seq_file *s, ...@@ -366,30 +374,26 @@ static void wcove_gpio_dbg_show(struct seq_file *s,
{ {
unsigned int ctlo, ctli, irq_mask, irq_status; unsigned int ctlo, ctli, irq_mask, irq_status;
struct wcove_gpio *wg = gpiochip_get_data(chip); 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++) { 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_OUT), &ctlo);
ret += regmap_read(wg->regmap, to_reg(gpio, CTRL_IN), &ctli); ret += regmap_read(wg->regmap, to_reg(gpio, CTRL_IN), &ctli);
ret += regmap_read(wg->regmap, IRQ_MASK_BASE + group, ret += regmap_read(wg->regmap, to_ireg(gpio, IRQ_MASK, &mask), &irq_mask);
&irq_mask); ret += regmap_read(wg->regmap, to_ireg(gpio, IRQ_STATUS, &mask), &irq_status);
ret += regmap_read(wg->regmap, IRQ_STATUS_BASE + group,
&irq_status);
if (ret) { if (ret) {
pr_err("Failed to read registers: ctrl out/in or irq status/mask\n"); pr_err("Failed to read registers: ctrl out/in or irq status/mask\n");
break; break;
} }
offset = gpio % 8;
seq_printf(s, " gpio-%-2d %s %s %s %s ctlo=%2x,%s %s\n", seq_printf(s, " gpio-%-2d %s %s %s %s ctlo=%2x,%s %s\n",
gpio, ctlo & CTLO_DIR_OUT ? "out" : "in ", gpio, ctlo & CTLO_DIR_OUT ? "out" : "in ",
ctli & 0x1 ? "hi" : "lo", ctli & 0x1 ? "hi" : "lo",
ctli & CTLI_INTCNT_NE ? "fall" : " ", ctli & CTLI_INTCNT_NE ? "fall" : " ",
ctli & CTLI_INTCNT_PE ? "rise" : " ", ctli & CTLI_INTCNT_PE ? "rise" : " ",
ctlo, ctlo,
irq_mask & BIT(offset) ? "mask " : "unmask", irq_mask & mask ? "mask " : "unmask",
irq_status & BIT(offset) ? "pending" : " "); irq_status & mask ? "pending" : " ");
} }
} }
......
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