From: Marc Zyngier <maz@kernel.org>
To: Maulik Shah <mkshah@codeaurora.org>
Cc: Douglas Anderson <dianders@chromium.org>,
Thomas Gleixner <tglx@linutronix.de>,
Jason Cooper <jason@lakedaemon.net>,
Linus Walleij <linus.walleij@linaro.org>,
Srinivas Ramana <sramana@codeaurora.org>,
Neeraj Upadhyay <neeraju@codeaurora.org>,
Rajendra Nayak <rnayak@codeaurora.org>,
linux-gpio@vger.kernel.org, linux-arm-msm@vger.kernel.org,
Bjorn Andersson <bjorn.andersson@linaro.org>,
Stephen Boyd <swboyd@chromium.org>,
Andy Gross <agross@kernel.org>,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH 3/3] pinctrl: qcom: Clear possible pending irq when remuxing GPIOs
Date: Tue, 24 Nov 2020 13:06:11 +0000 [thread overview]
Message-ID: <a15efffeb81fc491bbb53a43ae3f8400@kernel.org> (raw)
In-Reply-To: <bc0337f1-4b8e-7a3a-22fd-ff6f8cbaffca@codeaurora.org>
On 2020-11-24 12:43, Maulik Shah wrote:
> Hi Marc,
>
> On 11/24/2020 4:45 PM, Marc Zyngier wrote:
>> On 2020-11-24 10:37, Maulik Shah wrote:
>>
>> [...]
>>
>>>> static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev,
>>>> unsigned function,
>>>> unsigned group)
>>>> {
>>>> struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
>>>> + struct gpio_chip *gc = &pctrl->chip;
>>>> + unsigned int irq = irq_find_mapping(gc->irq.domain, group);
>>>> const struct msm_pingroup *g;
>>>> unsigned long flags;
>>>> u32 val, mask;
>>>> + u32 oldval;
>>>> + u32 old_i;
>>>> int i;
>>>> g = &pctrl->soc->groups[group];
>>>> @@ -187,15 +215,26 @@ static int msm_pinmux_set_mux(struct
>>>> pinctrl_dev *pctldev,
>>>> if (WARN_ON(i == g->nfuncs))
>>>> return -EINVAL;
>>>> - raw_spin_lock_irqsave(&pctrl->lock, flags);
>>>> + disable_irq(irq);
>>>> - val = msm_readl_ctl(pctrl, g);
>>>> + raw_spin_lock_irqsave(&pctrl->lock, flags);
>>>> + oldval = val = msm_readl_ctl(pctrl, g);
>>>> val &= ~mask;
>>>> val |= i << g->mux_bit;
>>>> msm_writel_ctl(val, pctrl, g);
>>>> -
>>>> raw_spin_unlock_irqrestore(&pctrl->lock, flags);
>>>> + /*
>>>> + * Clear IRQs if switching to/from GPIO mode since muxing
>>>> to/from
>>>> + * the GPIO path can cause phantom edges.
>>>> + */
>>>> + old_i = (oldval & mask) >> g->mux_bit;
>>>> + if (old_i != i &&
>>>> + (i == pctrl->soc->gpio_func || old_i ==
>>>> pctrl->soc->gpio_func))
>>>> + msm_pinctrl_clear_pending_irq(pctrl, group, irq);
>>>
>>> disable_irq() and enable_irq() should be moved inside this if loop.
>>> as
>>> only use for this is to mask the IRQ when switching back to gpio IRQ
>>> mode?
>>>
>>> i also don't think we should leave IRQ enabled at the end of this
>>> function by default, probably need to check if IRQ was already
>>> unmasked before disabling it, then only call enable_irq().
>>
>> Why? It looks to me that this reproduces the behaviour of
>> IRQCHIP_SET_TYPE_MASKED, which is highly desirable. What
>> problem are you trying to address with this?
>
> Correct, here trying to reproduce the behaviour of
> IRQCHIP_SET_TYPE_MASKED which i guess is ok once its moved inside if
> loop as this is the place its switching to IRQ mode.
>
> but there is a problem to leave it enabled at the end of set_direction
> callbacks, see below.
>
>>
>>>
>>>> +
>>>> + enable_irq(irq);
>>>> +
>>>> return 0;
>>>> }
>>>> @@ -456,32 +495,45 @@ static const struct pinconf_ops
>>>> msm_pinconf_ops = {
>>>> static int msm_gpio_direction_input(struct gpio_chip *chip,
>>>> unsigned offset)
>>>> {
>>>> const struct msm_pingroup *g;
>>>> + unsigned int irq = irq_find_mapping(chip->irq.domain, offset);
>>>> struct msm_pinctrl *pctrl = gpiochip_get_data(chip);
>>>> unsigned long flags;
>>>> + u32 oldval;
>>>> u32 val;
>>>> g = &pctrl->soc->groups[offset];
>>>> + disable_irq(irq);
>>>> +
>>>> raw_spin_lock_irqsave(&pctrl->lock, flags);
>>>> - val = msm_readl_ctl(pctrl, g);
>>>> + oldval = val = msm_readl_ctl(pctrl, g);
>>>> val &= ~BIT(g->oe_bit);
>>>> msm_writel_ctl(val, pctrl, g);
>>>> raw_spin_unlock_irqrestore(&pctrl->lock, flags);
>>>> + if (oldval != val)
>>>> + msm_pinctrl_clear_pending_irq(pctrl, offset, irq);
>>>> +
>>>> + enable_irq(irq);
>>>
>>> i do not think we need disable_irq() and enable_irq() here, changing
>>> direction to input does not mean its being used for interrupt only,
>>> it
>>> may be set to use something like Rx mode in UART.
>>>
>>> the client driver should enable IRQ when needed.
>>
>> And the kernel doesn't expect random interrupts to fire. Again, what
>> are you trying to fix by removing these?
>
> I see leaving IRQ enabled here can cause problems. For example in
> qcom_geni_serial.c driver before requesting IRQ, it sets the
> IRQ_NOAUTOEN flag to not keep it enabled.
>
> see the below snippet
> irq_set_status_flags(uport->irq, IRQ_NOAUTOEN);
> ret = devm_request_irq(uport->dev, uport->irq,
> qcom_geni_serial_isr,
> IRQF_TRIGGER_HIGH, port->name, uport);
>
> later when this devm_request_irq() invokes .irq_request_resources
> callback it will reach msm_gpio_irq_reqres() from
> where msm_gpio_direction_input() is called which leaves the irq
> enabled at the end with enable_irq() which was not expected by driver.
No it doesn't. disable_irq()/enable_irq() are designed to nest.
If the interrupt line was disabled before the disable/enable
sequence, it will still be disabled after.
> It will cause is IRQ storm since the UART geni driver uses GPIO in Rx
> mode when out of suspend. The IRQ mode in GPIO is enabled
> with suspend entry only. During resume the IRQ will again be disabled
> and GPIO will be switched to Rx mode.
I don't see how this contradicts what is above. If the interrupt was
disabled before hitting this sequence, it will still be disabled after.
Am I missing something? Have you actually seen the problem on HW?
M.
--
Jazz is not dead. It just smells funny...
next prev parent reply other threads:[~2020-11-24 13:06 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-11-24 0:01 [PATCH 1/3] irqchip: qcom-pdc: Fix phantom irq when changing between rising/falling Douglas Anderson
2020-11-24 0:01 ` [PATCH 2/3] pinctrl: qcom: Allow SoCs to specify a GPIO function that's not 0 Douglas Anderson
2020-11-24 0:01 ` [PATCH 3/3] pinctrl: qcom: Clear possible pending irq when remuxing GPIOs Douglas Anderson
2020-11-24 8:27 ` Linus Walleij
2020-11-24 10:37 ` Maulik Shah
2020-11-24 11:15 ` Marc Zyngier
2020-11-24 12:43 ` Maulik Shah
2020-11-24 13:06 ` Marc Zyngier [this message]
2020-11-24 17:33 ` Doug Anderson
2020-11-24 7:03 ` [PATCH 1/3] irqchip: qcom-pdc: Fix phantom irq when changing between rising/falling Maulik Shah
2020-11-24 8:28 ` Linus Walleij
2020-11-24 16:55 ` Doug Anderson
2020-11-24 17:42 ` Maulik Shah
2020-11-24 17:46 ` Doug Anderson
2020-11-24 9:00 ` Marc Zyngier
2020-11-24 17:01 ` Doug Anderson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=a15efffeb81fc491bbb53a43ae3f8400@kernel.org \
--to=maz@kernel.org \
--cc=agross@kernel.org \
--cc=bjorn.andersson@linaro.org \
--cc=dianders@chromium.org \
--cc=jason@lakedaemon.net \
--cc=linus.walleij@linaro.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mkshah@codeaurora.org \
--cc=neeraju@codeaurora.org \
--cc=rnayak@codeaurora.org \
--cc=sramana@codeaurora.org \
--cc=swboyd@chromium.org \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.