Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 71266d9d3936 ("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: 4b7618fdc7e6 ("pinctrl: qcom: Add irq_enable callback for msm gpio")
Fixes: 71266d9d3936 ("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>

authored by

Douglas Anderson and committed by
Linus Walleij
cf9d052a a95881d6

+50 -24
+50 -24
drivers/pinctrl/qcom/pinctrl-msm.c
··· 51 51 * @dual_edge_irqs: Bitmap of irqs that need sw emulated dual edge 52 52 * detection. 53 53 * @skip_wake_irqs: Skip IRQs that are handled by wakeup interrupt controller 54 + * @disabled_for_mux: These IRQs were disabled because we muxed away. 54 55 * @soc: Reference to soc_data of platform specific data. 55 56 * @regs: Base addresses for the TLMM tiles. 56 57 * @phys_base: Physical base address ··· 73 72 DECLARE_BITMAP(dual_edge_irqs, MAX_NR_GPIO); 74 73 DECLARE_BITMAP(enabled_irqs, MAX_NR_GPIO); 75 74 DECLARE_BITMAP(skip_wake_irqs, MAX_NR_GPIO); 75 + DECLARE_BITMAP(disabled_for_mux, MAX_NR_GPIO); 76 76 77 77 const struct msm_pinctrl_soc_data *soc; 78 78 void __iomem *regs[MAX_NR_TILES]; ··· 181 179 unsigned group) 182 180 { 183 181 struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 182 + struct gpio_chip *gc = &pctrl->chip; 183 + unsigned int irq = irq_find_mapping(gc->irq.domain, group); 184 + struct irq_data *d = irq_get_irq_data(irq); 185 + unsigned int gpio_func = pctrl->soc->gpio_func; 184 186 const struct msm_pingroup *g; 185 187 unsigned long flags; 186 188 u32 val, mask; ··· 201 195 if (WARN_ON(i == g->nfuncs)) 202 196 return -EINVAL; 203 197 198 + /* 199 + * If an GPIO interrupt is setup on this pin then we need special 200 + * handling. Specifically interrupt detection logic will still see 201 + * the pin twiddle even when we're muxed away. 202 + * 203 + * When we see a pin with an interrupt setup on it then we'll disable 204 + * (mask) interrupts on it when we mux away until we mux back. Note 205 + * that disable_irq() refcounts and interrupts are disabled as long as 206 + * at least one disable_irq() has been called. 207 + */ 208 + if (d && i != gpio_func && 209 + !test_and_set_bit(d->hwirq, pctrl->disabled_for_mux)) 210 + disable_irq(irq); 211 + 204 212 raw_spin_lock_irqsave(&pctrl->lock, flags); 205 213 206 214 val = msm_readl_ctl(pctrl, g); ··· 223 203 msm_writel_ctl(val, pctrl, g); 224 204 225 205 raw_spin_unlock_irqrestore(&pctrl->lock, flags); 206 + 207 + if (d && i == gpio_func && 208 + test_and_clear_bit(d->hwirq, pctrl->disabled_for_mux)) { 209 + /* 210 + * Clear interrupts detected while not GPIO since we only 211 + * masked things. 212 + */ 213 + if (d->parent_data && test_bit(d->hwirq, pctrl->skip_wake_irqs)) 214 + irq_chip_set_parent_state(d, IRQCHIP_STATE_PENDING, false); 215 + else 216 + msm_ack_intr_status(pctrl, g); 217 + 218 + enable_irq(irq); 219 + } 226 220 227 221 return 0; 228 222 } ··· 815 781 raw_spin_unlock_irqrestore(&pctrl->lock, flags); 816 782 } 817 783 818 - static void msm_gpio_irq_clear_unmask(struct irq_data *d, bool status_clear) 784 + static void msm_gpio_irq_unmask(struct irq_data *d) 819 785 { 820 786 struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 821 787 struct msm_pinctrl *pctrl = gpiochip_get_data(gc); ··· 832 798 g = &pctrl->soc->groups[d->hwirq]; 833 799 834 800 raw_spin_lock_irqsave(&pctrl->lock, flags); 835 - 836 - /* 837 - * clear the interrupt status bit before unmask to avoid 838 - * any erroneous interrupts that would have got latched 839 - * when the interrupt is not in use. 840 - */ 841 - if (status_clear) 842 - msm_ack_intr_status(pctrl, g); 843 801 844 802 val = msm_readl_intr_cfg(pctrl, g); 845 803 val |= BIT(g->intr_raw_status_bit); ··· 852 826 irq_chip_enable_parent(d); 853 827 854 828 if (!test_bit(d->hwirq, pctrl->skip_wake_irqs)) 855 - msm_gpio_irq_clear_unmask(d, true); 829 + msm_gpio_irq_unmask(d); 856 830 } 857 831 858 832 static void msm_gpio_irq_disable(struct irq_data *d) ··· 865 839 866 840 if (!test_bit(d->hwirq, pctrl->skip_wake_irqs)) 867 841 msm_gpio_irq_mask(d); 868 - } 869 - 870 - static void msm_gpio_irq_unmask(struct irq_data *d) 871 - { 872 - msm_gpio_irq_clear_unmask(d, false); 873 842 } 874 843 875 844 /** ··· 955 934 struct msm_pinctrl *pctrl = gpiochip_get_data(gc); 956 935 const struct msm_pingroup *g; 957 936 unsigned long flags; 937 + bool was_enabled; 958 938 u32 val; 959 939 960 940 if (msm_gpio_needs_dual_edge_parent_workaround(d, type)) { ··· 1017 995 * could cause the INTR_STATUS to be set for EDGE interrupts. 1018 996 */ 1019 997 val = msm_readl_intr_cfg(pctrl, g); 998 + was_enabled = val & BIT(g->intr_raw_status_bit); 1020 999 val |= BIT(g->intr_raw_status_bit); 1021 1000 if (g->intr_detection_width == 2) { 1022 1001 val &= ~(3 << g->intr_detection_bit); ··· 1066 1043 BUG(); 1067 1044 } 1068 1045 msm_writel_intr_cfg(val, pctrl, g); 1046 + 1047 + /* 1048 + * The first time we set RAW_STATUS_EN it could trigger an interrupt. 1049 + * Clear the interrupt. This is safe because we have 1050 + * IRQCHIP_SET_TYPE_MASKED. 1051 + */ 1052 + if (!was_enabled) 1053 + msm_ack_intr_status(pctrl, g); 1069 1054 1070 1055 if (test_bit(d->hwirq, pctrl->dual_edge_irqs)) 1071 1056 msm_gpio_update_dual_edge_pos(pctrl, g, d); ··· 1128 1097 } 1129 1098 1130 1099 /* 1131 - * Clear the interrupt that may be pending before we enable 1132 - * the line. 1133 - * This is especially a problem with the GPIOs routed to the 1134 - * PDC. These GPIOs are direct-connect interrupts to the GIC. 1135 - * Disabling the interrupt line at the PDC does not prevent 1136 - * the interrupt from being latched at the GIC. The state at 1137 - * GIC needs to be cleared before enabling. 1100 + * The disable / clear-enable workaround we do in msm_pinmux_set_mux() 1101 + * only works if disable is not lazy since we only clear any bogus 1102 + * interrupt in hardware. Explicitly mark the interrupt as UNLAZY. 1138 1103 */ 1139 - if (d->parent_data && test_bit(d->hwirq, pctrl->skip_wake_irqs)) 1140 - irq_chip_set_parent_state(d, IRQCHIP_STATE_PENDING, 0); 1104 + irq_set_status_flags(d->irq, IRQ_DISABLE_UNLAZY); 1141 1105 1142 1106 return 0; 1143 1107 out: