[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20210121075149.1310-1-hailong.fan@mediatek.com>
Date: Thu, 21 Jan 2021 15:51:49 +0800
From: Hailong Fan <hailong.fan@...iatek.com>
To: Sean Wang <sean.wang@...nel.org>,
Linus Walleij <linus.walleij@...aro.org>,
Matthias Brugger <matthias.bgg@...il.com>
CC: <linux-mediatek@...ts.infradead.org>, <linux-gpio@...r.kernel.org>,
<linux-arm-kernel@...ts.infradead.org>,
<linux-kernel@...r.kernel.org>, <youlin.pei@...iatek.com>,
Nicolas Boichat <drinkcat@...omium.org>,
<srv_heupstream@...iatek.com>, <chentsung@...omium.org>,
<gtk_pangao@...iatek.com>, <hanks.chen@...iatek.com>,
<yong.wu@...iatek.com>, Hailong Fan <hailong.fan@...iatek.com>
Subject: [PATCH RESEND] 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.
Signed-off-by: Hailong Fan <hailong.fan@...iatek.com>
---
Resend since some server reject.
---
drivers/pinctrl/mediatek/mtk-eint.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/pinctrl/mediatek/mtk-eint.c b/drivers/pinctrl/mediatek/mtk-eint.c
index 22736f60c16c..3acda6bb401e 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);
+ unsigned int unmask;
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);
+ unmask = 1;
+ } else {
+ unmask = 0;
+ }
+
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 (unmask == 1)
+ mtk_eint_unmask(d);
return 0;
}
--
2.18.0
Powered by blists - more mailing lists