summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl
diff options
context:
space:
mode:
authorHailong Fan <hailong.fan@mediatek.com>2021-01-25 12:17:53 +0800
committerLinus Walleij <linus.walleij@linaro.org>2021-02-15 05:52:01 +0100
commitb40b760aa2a9587cdcde62759642b4e99c40dedc (patch)
tree834c9bf2dbfc93ab103fc378f6cc56a28c43771e /drivers/pinctrl
parent74f2dd447900256e8aa986be868bcd835d3c60d1 (diff)
downloadlinux-b40b760aa2a9587cdcde62759642b4e99c40dedc.tar.gz
linux-b40b760aa2a9587cdcde62759642b4e99c40dedc.tar.bz2
linux-b40b760aa2a9587cdcde62759642b4e99c40dedc.zip
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>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r--drivers/pinctrl/mediatek/mtk-eint.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/pinctrl/mediatek/mtk-eint.c b/drivers/pinctrl/mediatek/mtk-eint.c
index 22736f60c16c..3b9b5dbd7968 100644
--- a/drivers/pinctrl/mediatek/mtk-eint.c
+++ b/drivers/pinctrl/mediatek/mtk-eint.c
@@ -157,6 +157,7 @@ static void mtk_eint_ack(struct irq_data *d)
static int mtk_eint_set_type(struct irq_data *d, unsigned int type)
{
struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
+ bool masked;
u32 mask = BIT(d->hwirq & 0x1f);
void __iomem *reg;
@@ -173,6 +174,13 @@ static int mtk_eint_set_type(struct irq_data *d, unsigned int type)
else
eint->dual_edge[d->hwirq] = 0;
+ if (!mtk_eint_get_mask(eint, d->hwirq)) {
+ mtk_eint_mask(d);
+ masked = false;
+ } else {
+ masked = true;
+ }
+
if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING)) {
reg = mtk_eint_get_offset(eint, d->hwirq, eint->regs->pol_clr);
writel(mask, reg);
@@ -189,8 +197,9 @@ static int mtk_eint_set_type(struct irq_data *d, unsigned int type)
writel(mask, reg);
}
- if (eint->dual_edge[d->hwirq])
- mtk_eint_flip_edge(eint, d->hwirq);
+ mtk_eint_ack(d);
+ if (!masked)
+ mtk_eint_unmask(d);
return 0;
}