linux/drivers/pinctrl
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
..
actions pinctrl: actions: pinctrl-s500: Constify s500_padinfo[] 2020-12-04 09:06:33 +01:00
aspeed pinctrl: aspeed: g6: Fix PWMG0 pinctrl setting 2021-01-04 16:02:28 +01:00
bcm pinctrl: bcm: fix kconfig dependency warning when !GPIOLIB 2020-09-29 14:58:56 +02:00
berlin
cirrus
freescale pinctrl: imx21: Remove the driver 2020-11-17 22:13:00 +01:00
intel This is the bulk of pin control changes for the v5.11 kernel: 2020-12-16 15:02:49 -08:00
mediatek pinctrl: mediatek: Fix fallback call path 2021-01-06 00:20:31 +01:00
meson pinctrl/meson: enable building as modules 2020-11-05 14:51:38 +01:00
mvebu Pin control bulk changes for the v5.10 kernel cycle 2020-10-14 15:25:04 -07:00
nomadik pinctrl: nomadik: Remove unused variable in nmk_gpio_dbg_show_one 2021-01-06 00:20:14 +01:00
nuvoton pinctrl: nuvoton: npcm7xx: Constify static ops structs 2020-09-30 10:37:52 +02:00
pxa pinctrl: pxa: pxa2xx: Remove 'pxa2xx_pinctrl_exit()' which is unused and broken 2020-06-04 00:05:13 +02:00
qcom pinctrl: qcom: Don't clear pending interrupts when enabling 2021-01-18 16:07:08 +01:00
ralink pinctrl: ralink: add a pinctrl driver for the rt2880 family 2020-12-08 09:58:01 +01:00
renesas pinctrl: renesas: Fix fall-through warnings for Clang 2020-11-23 09:47:28 +01:00
samsung pinctrl: samsung: s3c24xx: remove unneeded break 2020-10-26 20:23:29 +01:00
sirf pinctrl: sirf: pinctrl-atlas7: Fix a bunch of documentation misdemeanours 2020-07-16 15:12:38 +02:00
spear pinctrl/spear: simplify the return expression of spear300_pinctrl_probe() 2020-12-12 01:42:06 +01:00
sprd pinctrl: sprd: use module_platform_driver to simplify the code 2020-09-29 14:53:11 +02:00
stm32 pinctrl: stm32: use the hwspin_lock_timeout_in_atomic() API 2020-07-23 15:19:28 +02:00
sunxi pinctrl: sunxi: Always call chained_irq_{enter, exit} in sunxi_pinctrl_irq_handler 2020-11-24 09:41:29 +01:00
tegra This is the bulk of the pin control changes for the v5.9 2020-08-09 12:52:28 -07:00
ti pinctl: ti: iodelay: Replace HTTP links with HTTPS ones 2020-07-20 16:15:59 +02:00
uniphier
visconti pinctrl: visconti: PINCTRL_TMPV7700 should depend on ARCH_VISCONTI 2020-10-07 11:48:44 +02:00
vt8500
zte pinctrl: fix several typos 2020-04-28 13:26:49 +02:00
core.c pinctrl: core: Add missing #ifdef CONFIG_GPIOLIB 2020-11-05 14:52:23 +01:00
core.h
devicetree.c pinctrl: devicetree: Keep deferring even on timeout 2020-09-12 18:19:53 +02:00
devicetree.h
Kconfig This is the bulk of pin control changes for the v5.11 kernel: 2020-12-16 15:02:49 -08:00
Makefile This is the bulk of pin control changes for the v5.11 kernel: 2020-12-16 15:02:49 -08:00
pinconf-generic.c pinctrl: pinconf-generic: Add function parameter description 'pctldev' 2020-07-16 15:12:39 +02:00
pinconf.c
pinconf.h
pinctrl-amd.c This is the bulk of pin control changes for the v5.11 kernel: 2020-12-16 15:02:49 -08:00
pinctrl-amd.h pinctrl: amd: Add missing pins to the pin group list 2020-10-07 15:37:17 +02:00
pinctrl-artpec6.c
pinctrl-as3722.c
pinctrl-at91-pio4.c pinctrl: at91-pio4: add support for fewer lines on last PIO bank 2020-11-24 16:03:51 +01:00
pinctrl-at91.c pinctrl: pinctrl-at91: Demote non-kerneldoc header and complete another 2020-07-16 15:13:55 +02:00
pinctrl-at91.h
pinctrl-axp209.c
pinctrl-bm1880.c pinctrl: pinctrl-bm1880: Rename ill documented struct attribute entries 2020-07-16 15:13:55 +02:00
pinctrl-coh901.c
pinctrl-coh901.h
pinctrl-da850-pupd.c
pinctrl-da9062.c
pinctrl-digicolor.c
pinctrl-equilibrium.c
pinctrl-equilibrium.h
pinctrl-falcon.c pinctrl: falcon: add missing put_device() call in pinctrl_falcon_probe() 2020-12-04 09:17:51 +01:00
pinctrl-gemini.c
pinctrl-ingenic.c pinctrl: ingenic: Rename registers from JZ4760_GPIO_* to JZ4770_GPIO_* 2021-01-04 15:34:16 +01:00
pinctrl-lantiq.c pinctrl: fix several typos 2020-04-28 13:26:49 +02:00
pinctrl-lantiq.h
pinctrl-lpc18xx.c pinctrl: lpc18xx: Use fallthrough pseudo-keyword 2020-07-17 14:04:57 +02:00
pinctrl-max77620.c
pinctrl-mcp23s08_i2c.c pinctrl: mcp23s08: Split to three parts: core, I²C, SPI 2020-04-16 14:21:23 +02:00
pinctrl-mcp23s08_spi.c pinctrl: mcp23s08: Print error message when regmap init fails 2020-11-05 11:30:31 +01:00
pinctrl-mcp23s08.c pinctrl: mcp23s08: Fix mcp23x17 precious range 2020-09-12 11:31:19 +02:00
pinctrl-mcp23s08.h pinctrl: mcp23s08: Split to three parts: core, I²C, SPI 2020-04-16 14:21:23 +02:00
pinctrl-microchip-sgpio.c pinctrl: pinctrl-microchip-sgpio: Add irq support (for sparx5) 2020-12-11 23:48:52 +01:00
pinctrl-ocelot.c pinctrl: ocelot: Add support for Serval platforms 2020-11-10 15:10:54 +01:00
pinctrl-oxnas.c
pinctrl-palmas.c
pinctrl-pic32.c
pinctrl-pic32.h
pinctrl-pistachio.c
pinctrl-rk805.c pinctrl: rk805: Constify rk805_gpio_cfgs 2020-05-12 13:35:33 +02:00
pinctrl-rockchip.c pinctrl: rockchip: create irq mapping in gpio_to_irq 2020-11-04 15:00:28 +01:00
pinctrl-single.c pinctrl: single: fix debug output when #pinctrl-cells = 2 2020-10-01 10:04:53 +02:00
pinctrl-st.c
pinctrl-stmfx.c pinctrl: stmfx: Use irqchip template 2020-08-04 01:29:10 +02:00
pinctrl-sx150x.c pinctrl: sx150x: Fix pinctrl enablement order bug 2020-09-12 18:11:09 +02:00
pinctrl-tb10x.c
pinctrl-u300.c
pinctrl-utils.c pinctrl: use krealloc_array() 2020-12-15 12:13:37 -08:00
pinctrl-utils.h
pinctrl-xway.c
pinctrl-zynq.c
pinmux.c pinctrl: pinmux: Add some missing parameter descriptions 2020-07-16 15:12:38 +02:00
pinmux.h