linux/drivers/pinctrl/qcom
Douglas Anderson cf9d052aa6 pinctrl: qcom: Don't clear pending interrupts when enabling
In Linux, if a driver does disable_irq() and later does enable_irq()
on its interrupt, I believe it's expecting these properties:
* If an interrupt was pending when the driver disabled then it will
  still be pending after the driver re-enables.
* If an edge-triggered interrupt comes in while an interrupt is
  disabled it should assert when the interrupt is re-enabled.

If you think that the above sounds a lot like the disable_irq() and
enable_irq() are supposed to be masking/unmasking the interrupt
instead of disabling/enabling it then you've made an astute
observation.  Specifically when talking about interrupts, "mask"
usually means to stop posting interrupts but keep tracking them and
"disable" means to fully shut off interrupt detection.  It's
unfortunate that this is so confusing, but presumably this is all the
way it is for historical reasons.

Perhaps more confusing than the above is that, even though clients of
IRQs themselves don't have a way to request mask/unmask
vs. disable/enable calls, IRQ chips themselves can implement both.
...and yet more confusing is that if an IRQ chip implements
disable/enable then they will be called when a client driver calls
disable_irq() / enable_irq().

It does feel like some of the above could be cleared up.  However,
without any other core interrupt changes it should be clear that when
an IRQ chip gets a request to "disable" an IRQ that it has to treat it
like a mask of that IRQ.

In any case, after that long interlude you can see that the "unmask
and clear" can break things.  Maulik tried to fix it so that we no
longer did "unmask and clear" in commit 71266d9d39 ("pinctrl: qcom:
Move clearing pending IRQ to .irq_request_resources callback"), but it
only handled the PDC case and it had problems (it caused
sc7180-trogdor devices to fail to suspend).  Let's fix.

>From my understanding the source of the phantom interrupt in the
were these two things:
1. One that could have been introduced in msm_gpio_irq_set_type()
   (only for the non-PDC case).
2. Edges could have been detected when a GPIO was muxed away.

Fixing case #1 is easy.  We can just add a clear in
msm_gpio_irq_set_type().

Fixing case #2 is harder.  Let's use a concrete example.  In
sc7180-trogdor.dtsi we configure the uart3 to have two pinctrl states,
sleep and default, and mux between the two during runtime PM and
system suspend (see geni_se_resources_{on,off}() for more
details). The difference between the sleep and default state is that
the RX pin is muxed to a GPIO during sleep and muxed to the UART
otherwise.

As per Qualcomm, when we mux the pin over to the UART function the PDC
(or the non-PDC interrupt detection logic) is still watching it /
latching edges.  These edges don't cause interrupts because the
current code masks the interrupt unless we're entering suspend.
However, as soon as we enter suspend we unmask the interrupt and it's
counted as a wakeup.

Let's deal with the problem like this:
* When we mux away, we'll mask our interrupt.  This isn't necessary in
  the above case since the client already masked us, but it's a good
  idea in general.
* When we mux back will clear any interrupts and unmask.

Fixes: 4b7618fdc7 ("pinctrl: qcom: Add irq_enable callback for msm gpio")
Fixes: 71266d9d39 ("pinctrl: qcom: Move clearing pending IRQ to .irq_request_resources callback")
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Maulik Shah <mkshah@codeaurora.org>
Tested-by: Maulik Shah <mkshah@codeaurora.org>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Link: https://lore.kernel.org/r/20210114191601.v7.4.I7cf3019783720feb57b958c95c2b684940264cd1@changeid
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2021-01-18 16:07:08 +01:00
..
Kconfig pinctrl: qcom: Add sm8250 lpass lpi pinctrl driver 2020-12-05 23:36:24 +01:00
Makefile pinctrl: qcom: Add sm8250 lpass lpi pinctrl driver 2020-12-05 23:36:24 +01:00
pinctrl-apq8064.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 284 2019-06-05 17:36:37 +02:00
pinctrl-apq8084.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 284 2019-06-05 17:36:37 +02:00
pinctrl-ipq4019.c pinctrl: qcom: ipq4019: add open drain support 2020-07-16 10:46:24 +02:00
pinctrl-ipq6018.c pinctrl: qcom: ipq6018 Add missing pins in qpic pin group 2020-06-20 22:05:24 +02:00
pinctrl-ipq8064.c ipq8064: pinctrl: Fixed missing RGMII pincontrol definitions 2020-02-21 16:23:26 +01:00
pinctrl-ipq8074.c pinctrl: qcom: ipq8074: route gpio interrupts to APPS 2020-07-11 23:11:00 +02:00
pinctrl-lpass-lpi.c pinctrl: qcom: Add sm8250 lpass lpi pinctrl driver 2020-12-05 23:36:24 +01:00
pinctrl-mdm9615.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 284 2019-06-05 17:36:37 +02:00
pinctrl-msm8x74.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 284 2019-06-05 17:36:37 +02:00
pinctrl-msm8226.c pinctrl: qcom: Add msm8226 pinctrl driver. 2020-08-27 10:27:14 +02:00
pinctrl-msm8660.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 284 2019-06-05 17:36:37 +02:00
pinctrl-msm8916.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 284 2019-06-05 17:36:37 +02:00
pinctrl-msm8953.c pinctrl: qcom: add pinctrl driver for msm8953 2020-11-10 14:58:14 +01:00
pinctrl-msm8960.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 284 2019-06-05 17:36:37 +02:00
pinctrl-msm8976.c pinctrl: qcom: pinctrl-msm8976: Remove unused variable 'nav_tsync_groups' 2020-07-16 15:12:38 +02:00
pinctrl-msm8994.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 284 2019-06-05 17:36:37 +02:00
pinctrl-msm8996.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 284 2019-06-05 17:36:37 +02:00
pinctrl-msm8998.c pinctrl: msm8998: Squash TSIF pins together 2019-07-29 23:28:57 +02:00
pinctrl-msm.c pinctrl: qcom: Don't clear pending interrupts when enabling 2021-01-18 16:07:08 +01:00
pinctrl-msm.h pinctrl: qcom: Allow SoCs to specify a GPIO function that's not 0 2021-01-18 16:07:08 +01:00
pinctrl-qcs404.c This is the bulk of pin control changes for the v5.1 kernel cycle. 2019-03-11 11:12:50 -07:00
pinctrl-qdf2xxx.c pinctrl: qdf2xxx: Switch to use device_property_count_uXX() 2019-08-05 12:01:45 +02:00
pinctrl-sc7180.c pinctrl: qcom: Handle broken/missing PDC dual edge IRQs on sc7180 2020-07-16 15:41:41 +02:00
pinctrl-sc7280.c pinctrl: qcom: Add sc7280 pinctrl driver 2020-11-24 09:37:03 +01:00
pinctrl-sdm660.c pinctrl: sdm660: Set tile property for pingroups 2018-11-19 15:40:55 +01:00
pinctrl-sdm845.c pinctrl/sdm845: Add PDC wakeup interrupt map for GPIOs 2019-11-16 10:23:48 +00:00
pinctrl-sdx55.c pinctrl: qcom: Add SDX55 pincontrol driver 2020-11-10 15:45:37 +01:00
pinctrl-sm8150.c pinctrl: qcom: Add SM8150 pinctrl driver 2019-07-04 09:47:13 +02:00
pinctrl-sm8250.c pinctrl: qcom: sm8250: Specify PDC map 2020-11-10 14:57:05 +01:00
pinctrl-spmi-gpio.c pinctrl: qcom-pmic-gpio: Add support for pmx55 2020-12-04 10:20:58 +01:00
pinctrl-spmi-mpp.c pinctrl: qcom: spmi-mpp: Add PM/PMI8950 compatible strings 2019-11-05 11:18:30 +01:00
pinctrl-ssbi-gpio.c pinctrl: qcom: spmi-gpio: Use fallthrough pseudo-keyword 2020-07-20 15:38:27 +02:00
pinctrl-ssbi-mpp.c pinctrl: ssbi-mpp: constify copied structure 2020-01-07 13:55:55 +01:00