Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

pinctrl: nsp: Set irq handler based on trig type

Rather than always using handle_simple_irq() as the gpio_irq_chip
handler, set a more appropriate handler based on the IRQ trigger type
requested. This is important for level triggered interrupts which need
to be masked during handling. Also, fix the interrupt acknowledge so
that it clears only one interrupt instead of all interrupts which are
currently active. Finally there is no need to clear the interrupt during
the interrupt handler, since the edge-triggered handler will do that for
us.

Signed-off-by: Mark Tomlinson <mark.tomlinson@alliedtelesis.co.nz>
Reviewed-by: Ray Jui <ray.jui@broadcom.com>
Link: https://lore.kernel.org/r/20200703011830.15655-1-mark.tomlinson@alliedtelesis.co.nz
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

authored by

Mark Tomlinson and committed by
Linus Walleij
94c70241 5f4962dd

+9 -9
+9 -9
drivers/pinctrl/bcm/pinctrl-nsp-gpio.c
··· 154 154 level &= readl(chip->base + NSP_GPIO_INT_MASK); 155 155 int_bits = level | event; 156 156 157 - for_each_set_bit(bit, &int_bits, gc->ngpio) { 158 - /* 159 - * Clear the interrupt before invoking the 160 - * handler, so we do not leave any window 161 - */ 162 - writel(BIT(bit), chip->base + NSP_GPIO_EVENT); 157 + for_each_set_bit(bit, &int_bits, gc->ngpio) 163 158 generic_handle_irq( 164 159 irq_linear_revmap(gc->irq.domain, bit)); 165 - } 166 160 } 167 161 168 162 return int_bits ? IRQ_HANDLED : IRQ_NONE; ··· 172 178 173 179 trigger_type = irq_get_trigger_type(d->irq); 174 180 if (trigger_type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) 175 - nsp_set_bit(chip, REG, NSP_GPIO_EVENT, gpio, val); 181 + writel(val, chip->base + NSP_GPIO_EVENT); 176 182 } 177 183 178 184 /* ··· 256 262 257 263 nsp_set_bit(chip, REG, NSP_GPIO_EVENT_INT_POLARITY, gpio, falling); 258 264 nsp_set_bit(chip, REG, NSP_GPIO_INT_POLARITY, gpio, level_low); 265 + 266 + if (type & IRQ_TYPE_EDGE_BOTH) 267 + irq_set_handler_locked(d, handle_edge_irq); 268 + else 269 + irq_set_handler_locked(d, handle_level_irq); 270 + 259 271 raw_spin_unlock_irqrestore(&chip->lock, flags); 260 272 261 273 dev_dbg(chip->dev, "gpio:%u level_low:%s falling:%s\n", gpio, ··· 691 691 girq->num_parents = 0; 692 692 girq->parents = NULL; 693 693 girq->default_type = IRQ_TYPE_NONE; 694 - girq->handler = handle_simple_irq; 694 + girq->handler = handle_bad_irq; 695 695 } 696 696 697 697 ret = devm_gpiochip_add_data(dev, gc, chip);