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

pinctrl: mediatek: Fix trigger type setting follow for unexpected interrupt

When flipping the polarity will be generated interrupt under certain
circumstances, but GPIO external signal has not changed.
Then, mask the interrupt before polarity setting, and clear the
unexpected interrupt after trigger type setting completed.

Remove mtk_eint_flip_edge: because mtk_eint_unmask already calls it.

Signed-off-by: Hailong Fan <hailong.fan@mediatek.com>
Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
Link: https://lore.kernel.org/r/20210125041753.2214-1-hailong.fan@mediatek.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

authored by

Hailong Fan and committed by
Linus Walleij
b40b760a 74f2dd44

+11 -2
+11 -2
drivers/pinctrl/mediatek/mtk-eint.c
··· 157 157 static int mtk_eint_set_type(struct irq_data *d, unsigned int type) 158 158 { 159 159 struct mtk_eint *eint = irq_data_get_irq_chip_data(d); 160 + bool masked; 160 161 u32 mask = BIT(d->hwirq & 0x1f); 161 162 void __iomem *reg; 162 163 ··· 173 172 eint->dual_edge[d->hwirq] = 1; 174 173 else 175 174 eint->dual_edge[d->hwirq] = 0; 175 + 176 + if (!mtk_eint_get_mask(eint, d->hwirq)) { 177 + mtk_eint_mask(d); 178 + masked = false; 179 + } else { 180 + masked = true; 181 + } 176 182 177 183 if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING)) { 178 184 reg = mtk_eint_get_offset(eint, d->hwirq, eint->regs->pol_clr); ··· 197 189 writel(mask, reg); 198 190 } 199 191 200 - if (eint->dual_edge[d->hwirq]) 201 - mtk_eint_flip_edge(eint, d->hwirq); 192 + mtk_eint_ack(d); 193 + if (!masked) 194 + mtk_eint_unmask(d); 202 195 203 196 return 0; 204 197 }