]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 25 Jan 2021 16:36:23 +0000 (17:36 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 25 Jan 2021 16:36:23 +0000 (17:36 +0100)
added patches:
pinctrl-qcom-allow-socs-to-specify-a-gpio-function-that-s-not-0.patch
pinctrl-qcom-don-t-clear-pending-interrupts-when-enabling.patch
pinctrl-qcom-no-need-to-read-modify-write-the-interrupt-status.patch
pinctrl-qcom-properly-clear-intr_ack_high-interrupts-when-unmasking.patch

queue-5.10/pinctrl-qcom-allow-socs-to-specify-a-gpio-function-that-s-not-0.patch [new file with mode: 0644]
queue-5.10/pinctrl-qcom-don-t-clear-pending-interrupts-when-enabling.patch [new file with mode: 0644]
queue-5.10/pinctrl-qcom-no-need-to-read-modify-write-the-interrupt-status.patch [new file with mode: 0644]
queue-5.10/pinctrl-qcom-properly-clear-intr_ack_high-interrupts-when-unmasking.patch [new file with mode: 0644]
queue-5.10/series

diff --git a/queue-5.10/pinctrl-qcom-allow-socs-to-specify-a-gpio-function-that-s-not-0.patch b/queue-5.10/pinctrl-qcom-allow-socs-to-specify-a-gpio-function-that-s-not-0.patch
new file mode 100644 (file)
index 0000000..0783a22
--- /dev/null
@@ -0,0 +1,59 @@
+From a82e537807d5c85706cd4c16fd2de77a8495dc8d Mon Sep 17 00:00:00 2001
+From: Douglas Anderson <dianders@chromium.org>
+Date: Thu, 14 Jan 2021 19:16:21 -0800
+Subject: pinctrl: qcom: Allow SoCs to specify a GPIO function that's not 0
+
+From: Douglas Anderson <dianders@chromium.org>
+
+commit a82e537807d5c85706cd4c16fd2de77a8495dc8d upstream.
+
+There's currently a comment in the code saying function 0 is GPIO.
+Instead of hardcoding it, let's add a member where an SoC can specify
+it.  No known SoCs use a number other than 0, but this just makes the
+code clearer.  NOTE: no SoC code needs to be updated since we can rely
+on zero-initialization.
+
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: Stephen Boyd <swboyd@chromium.org>
+Reviewed-by: Maulik Shah <mkshah@codeaurora.org>
+Tested-by: Maulik Shah <mkshah@codeaurora.org>
+Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20210114191601.v7.1.I3ad184e3423d8e479bc3e86f5b393abb1704a1d1@changeid
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pinctrl/qcom/pinctrl-msm.c |    3 +--
+ drivers/pinctrl/qcom/pinctrl-msm.h |    2 ++
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/pinctrl/qcom/pinctrl-msm.c
++++ b/drivers/pinctrl/qcom/pinctrl-msm.c
+@@ -210,8 +210,7 @@ static int msm_pinmux_request_gpio(struc
+       if (!g->nfuncs)
+               return 0;
+-      /* For now assume function 0 is GPIO because it always is */
+-      return msm_pinmux_set_mux(pctldev, g->funcs[0], offset);
++      return msm_pinmux_set_mux(pctldev, g->funcs[pctrl->soc->gpio_func], offset);
+ }
+ static const struct pinmux_ops msm_pinmux_ops = {
+--- a/drivers/pinctrl/qcom/pinctrl-msm.h
++++ b/drivers/pinctrl/qcom/pinctrl-msm.h
+@@ -118,6 +118,7 @@ struct msm_gpio_wakeirq_map {
+  * @wakeirq_dual_edge_errata: If true then GPIOs using the wakeirq_map need
+  *                            to be aware that their parent can't handle dual
+  *                            edge interrupts.
++ * @gpio_func: Which function number is GPIO (usually 0).
+  */
+ struct msm_pinctrl_soc_data {
+       const struct pinctrl_pin_desc *pins;
+@@ -134,6 +135,7 @@ struct msm_pinctrl_soc_data {
+       const struct msm_gpio_wakeirq_map *wakeirq_map;
+       unsigned int nwakeirq_map;
+       bool wakeirq_dual_edge_errata;
++      unsigned int gpio_func;
+ };
+ extern const struct dev_pm_ops msm_pinctrl_dev_pm_ops;
diff --git a/queue-5.10/pinctrl-qcom-don-t-clear-pending-interrupts-when-enabling.patch b/queue-5.10/pinctrl-qcom-don-t-clear-pending-interrupts-when-enabling.patch
new file mode 100644 (file)
index 0000000..24e5e70
--- /dev/null
@@ -0,0 +1,256 @@
+From cf9d052aa6005f1e8dfaf491d83bf37f368af69e Mon Sep 17 00:00:00 2001
+From: Douglas Anderson <dianders@chromium.org>
+Date: Thu, 14 Jan 2021 19:16:24 -0800
+Subject: pinctrl: qcom: Don't clear pending interrupts when enabling
+
+From: Douglas Anderson <dianders@chromium.org>
+
+commit cf9d052aa6005f1e8dfaf491d83bf37f368af69e upstream.
+
+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>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pinctrl/qcom/pinctrl-msm.c |   74 +++++++++++++++++++++++++------------
+ 1 file changed, 50 insertions(+), 24 deletions(-)
+
+--- a/drivers/pinctrl/qcom/pinctrl-msm.c
++++ b/drivers/pinctrl/qcom/pinctrl-msm.c
+@@ -51,6 +51,7 @@
+  * @dual_edge_irqs: Bitmap of irqs that need sw emulated dual edge
+  *                  detection.
+  * @skip_wake_irqs: Skip IRQs that are handled by wakeup interrupt controller
++ * @disabled_for_mux: These IRQs were disabled because we muxed away.
+  * @soc:            Reference to soc_data of platform specific data.
+  * @regs:           Base addresses for the TLMM tiles.
+  * @phys_base:      Physical base address
+@@ -72,6 +73,7 @@ struct msm_pinctrl {
+       DECLARE_BITMAP(dual_edge_irqs, MAX_NR_GPIO);
+       DECLARE_BITMAP(enabled_irqs, MAX_NR_GPIO);
+       DECLARE_BITMAP(skip_wake_irqs, MAX_NR_GPIO);
++      DECLARE_BITMAP(disabled_for_mux, MAX_NR_GPIO);
+       const struct msm_pinctrl_soc_data *soc;
+       void __iomem *regs[MAX_NR_TILES];
+@@ -179,6 +181,10 @@ static int msm_pinmux_set_mux(struct pin
+                             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);
++      struct irq_data *d = irq_get_irq_data(irq);
++      unsigned int gpio_func = pctrl->soc->gpio_func;
+       const struct msm_pingroup *g;
+       unsigned long flags;
+       u32 val, mask;
+@@ -195,6 +201,20 @@ static int msm_pinmux_set_mux(struct pin
+       if (WARN_ON(i == g->nfuncs))
+               return -EINVAL;
++      /*
++       * If an GPIO interrupt is setup on this pin then we need special
++       * handling.  Specifically interrupt detection logic will still see
++       * the pin twiddle even when we're muxed away.
++       *
++       * When we see a pin with an interrupt setup on it then we'll disable
++       * (mask) interrupts on it when we mux away until we mux back.  Note
++       * that disable_irq() refcounts and interrupts are disabled as long as
++       * at least one disable_irq() has been called.
++       */
++      if (d && i != gpio_func &&
++          !test_and_set_bit(d->hwirq, pctrl->disabled_for_mux))
++              disable_irq(irq);
++
+       raw_spin_lock_irqsave(&pctrl->lock, flags);
+       val = msm_readl_ctl(pctrl, g);
+@@ -204,6 +224,20 @@ static int msm_pinmux_set_mux(struct pin
+       raw_spin_unlock_irqrestore(&pctrl->lock, flags);
++      if (d && i == gpio_func &&
++          test_and_clear_bit(d->hwirq, pctrl->disabled_for_mux)) {
++              /*
++               * Clear interrupts detected while not GPIO since we only
++               * masked things.
++               */
++              if (d->parent_data && test_bit(d->hwirq, pctrl->skip_wake_irqs))
++                      irq_chip_set_parent_state(d, IRQCHIP_STATE_PENDING, false);
++              else
++                      msm_ack_intr_status(pctrl, g);
++
++              enable_irq(irq);
++      }
++
+       return 0;
+ }
+@@ -781,7 +815,7 @@ static void msm_gpio_irq_mask(struct irq
+       raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+ }
+-static void msm_gpio_irq_clear_unmask(struct irq_data *d, bool status_clear)
++static void msm_gpio_irq_unmask(struct irq_data *d)
+ {
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       struct msm_pinctrl *pctrl = gpiochip_get_data(gc);
+@@ -799,14 +833,6 @@ static void msm_gpio_irq_clear_unmask(st
+       raw_spin_lock_irqsave(&pctrl->lock, flags);
+-      /*
+-       * clear the interrupt status bit before unmask to avoid
+-       * any erroneous interrupts that would have got latched
+-       * when the interrupt is not in use.
+-       */
+-      if (status_clear)
+-              msm_ack_intr_status(pctrl, g);
+-
+       val = msm_readl_intr_cfg(pctrl, g);
+       val |= BIT(g->intr_raw_status_bit);
+       val |= BIT(g->intr_enable_bit);
+@@ -826,7 +852,7 @@ static void msm_gpio_irq_enable(struct i
+               irq_chip_enable_parent(d);
+       if (!test_bit(d->hwirq, pctrl->skip_wake_irqs))
+-              msm_gpio_irq_clear_unmask(d, true);
++              msm_gpio_irq_unmask(d);
+ }
+ static void msm_gpio_irq_disable(struct irq_data *d)
+@@ -841,11 +867,6 @@ static void msm_gpio_irq_disable(struct
+               msm_gpio_irq_mask(d);
+ }
+-static void msm_gpio_irq_unmask(struct irq_data *d)
+-{
+-      msm_gpio_irq_clear_unmask(d, false);
+-}
+-
+ /**
+  * msm_gpio_update_dual_edge_parent() - Prime next edge for IRQs handled by parent.
+  * @d: The irq dta.
+@@ -934,6 +955,7 @@ static int msm_gpio_irq_set_type(struct
+       struct msm_pinctrl *pctrl = gpiochip_get_data(gc);
+       const struct msm_pingroup *g;
+       unsigned long flags;
++      bool was_enabled;
+       u32 val;
+       if (msm_gpio_needs_dual_edge_parent_workaround(d, type)) {
+@@ -995,6 +1017,7 @@ static int msm_gpio_irq_set_type(struct
+        * could cause the INTR_STATUS to be set for EDGE interrupts.
+        */
+       val = msm_readl_intr_cfg(pctrl, g);
++      was_enabled = val & BIT(g->intr_raw_status_bit);
+       val |= BIT(g->intr_raw_status_bit);
+       if (g->intr_detection_width == 2) {
+               val &= ~(3 << g->intr_detection_bit);
+@@ -1044,6 +1067,14 @@ static int msm_gpio_irq_set_type(struct
+       }
+       msm_writel_intr_cfg(val, pctrl, g);
++      /*
++       * The first time we set RAW_STATUS_EN it could trigger an interrupt.
++       * Clear the interrupt.  This is safe because we have
++       * IRQCHIP_SET_TYPE_MASKED.
++       */
++      if (!was_enabled)
++              msm_ack_intr_status(pctrl, g);
++
+       if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
+               msm_gpio_update_dual_edge_pos(pctrl, g, d);
+@@ -1097,16 +1128,11 @@ static int msm_gpio_irq_reqres(struct ir
+       }
+       /*
+-       * Clear the interrupt that may be pending before we enable
+-       * the line.
+-       * This is especially a problem with the GPIOs routed to the
+-       * PDC. These GPIOs are direct-connect interrupts to the GIC.
+-       * Disabling the interrupt line at the PDC does not prevent
+-       * the interrupt from being latched at the GIC. The state at
+-       * GIC needs to be cleared before enabling.
++       * The disable / clear-enable workaround we do in msm_pinmux_set_mux()
++       * only works if disable is not lazy since we only clear any bogus
++       * interrupt in hardware. Explicitly mark the interrupt as UNLAZY.
+        */
+-      if (d->parent_data && test_bit(d->hwirq, pctrl->skip_wake_irqs))
+-              irq_chip_set_parent_state(d, IRQCHIP_STATE_PENDING, 0);
++      irq_set_status_flags(d->irq, IRQ_DISABLE_UNLAZY);
+       return 0;
+ out:
diff --git a/queue-5.10/pinctrl-qcom-no-need-to-read-modify-write-the-interrupt-status.patch b/queue-5.10/pinctrl-qcom-no-need-to-read-modify-write-the-interrupt-status.patch
new file mode 100644 (file)
index 0000000..4ccf40f
--- /dev/null
@@ -0,0 +1,90 @@
+From 4079d35fa4fca4ee0ffd66968312fc86a5e8c290 Mon Sep 17 00:00:00 2001
+From: Douglas Anderson <dianders@chromium.org>
+Date: Thu, 14 Jan 2021 19:16:22 -0800
+Subject: pinctrl: qcom: No need to read-modify-write the interrupt status
+
+From: Douglas Anderson <dianders@chromium.org>
+
+commit 4079d35fa4fca4ee0ffd66968312fc86a5e8c290 upstream.
+
+When the Qualcomm pinctrl driver wants to Ack an interrupt, it does a
+read-modify-write on the interrupt status register.  On some SoCs it
+makes sure that the status bit is 1 to "Ack" and on others it makes
+sure that the bit is 0 to "Ack".  Presumably the first type of
+interrupt controller is a "write 1 to clear" type register and the
+second just let you directly set the interrupt status register.
+
+As far as I can tell from scanning structure definitions, the
+interrupt status bit is always in a register by itself.  Thus with
+both types of interrupt controllers it is safe to "Ack" interrupts
+without doing a read-modify-write.  We can do a simple write.
+
+It should be noted that if the interrupt status bit _was_ ever in a
+register with other things (like maybe status bits for other GPIOs):
+a) For "write 1 clear" type controllers then read-modify-write would
+   be totally wrong because we'd accidentally end up clearing
+   interrupts we weren't looking at.
+b) For "direct set" type controllers then read-modify-write would also
+   be wrong because someone setting one of the other bits in the
+   register might accidentally clear (or set) our interrupt.
+I say this simply to show that the current read-modify-write doesn't
+provide any sort of "future proofing" of the code.  In fact (for
+"write 1 clear" controllers) the new code is slightly more "future
+proof" since it would allow more than one interrupt status bits to
+share a register.
+
+NOTE: this code fixes no bugs--it simply avoids an extra register
+read.
+
+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>
+Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20210114191601.v7.2.I3635de080604e1feda770591c5563bd6e63dd39d@changeid
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pinctrl/qcom/pinctrl-msm.c |   23 ++++++++---------------
+ 1 file changed, 8 insertions(+), 15 deletions(-)
+
+--- a/drivers/pinctrl/qcom/pinctrl-msm.c
++++ b/drivers/pinctrl/qcom/pinctrl-msm.c
+@@ -791,16 +791,13 @@ static void msm_gpio_irq_clear_unmask(st
+       raw_spin_lock_irqsave(&pctrl->lock, flags);
+-      if (status_clear) {
+-              /*
+-               * clear the interrupt status bit before unmask to avoid
+-               * any erroneous interrupts that would have got latched
+-               * when the interrupt is not in use.
+-               */
+-              val = msm_readl_intr_status(pctrl, g);
+-              val &= ~BIT(g->intr_status_bit);
+-              msm_writel_intr_status(val, pctrl, g);
+-      }
++      /*
++       * clear the interrupt status bit before unmask to avoid
++       * any erroneous interrupts that would have got latched
++       * when the interrupt is not in use.
++       */
++      if (status_clear)
++              msm_writel_intr_status(0, pctrl, g);
+       val = msm_readl_intr_cfg(pctrl, g);
+       val |= BIT(g->intr_raw_status_bit);
+@@ -905,11 +902,7 @@ static void msm_gpio_irq_ack(struct irq_
+       raw_spin_lock_irqsave(&pctrl->lock, flags);
+-      val = msm_readl_intr_status(pctrl, g);
+-      if (g->intr_ack_high)
+-              val |= BIT(g->intr_status_bit);
+-      else
+-              val &= ~BIT(g->intr_status_bit);
++      val = g->intr_ack_high ? BIT(g->intr_status_bit) : 0;
+       msm_writel_intr_status(val, pctrl, g);
+       if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
diff --git a/queue-5.10/pinctrl-qcom-properly-clear-intr_ack_high-interrupts-when-unmasking.patch b/queue-5.10/pinctrl-qcom-properly-clear-intr_ack_high-interrupts-when-unmasking.patch
new file mode 100644 (file)
index 0000000..d7fa30f
--- /dev/null
@@ -0,0 +1,78 @@
+From a95881d6aa2c000e3649f27a1a7329cf356e6bb3 Mon Sep 17 00:00:00 2001
+From: Douglas Anderson <dianders@chromium.org>
+Date: Thu, 14 Jan 2021 19:16:23 -0800
+Subject: pinctrl: qcom: Properly clear "intr_ack_high" interrupts when unmasking
+
+From: Douglas Anderson <dianders@chromium.org>
+
+commit a95881d6aa2c000e3649f27a1a7329cf356e6bb3 upstream.
+
+In commit 4b7618fdc7e6 ("pinctrl: qcom: Add irq_enable callback for
+msm gpio") we tried to Ack interrupts during unmask.  However, that
+patch forgot to check "intr_ack_high" so, presumably, it only worked
+for a certain subset of SoCs.
+
+Let's add a small accessor so we don't need to open-code the logic in
+both places.
+
+This was found by code inspection.  I don't have any access to the
+hardware in question nor software that needs the Ack during unmask.
+
+Fixes: 4b7618fdc7e6 ("pinctrl: qcom: Add irq_enable callback for msm gpio")
+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>
+Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20210114191601.v7.3.I32d0f4e174d45363b49ab611a13c3da8f1e87d0f@changeid
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pinctrl/qcom/pinctrl-msm.c |   14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+--- a/drivers/pinctrl/qcom/pinctrl-msm.c
++++ b/drivers/pinctrl/qcom/pinctrl-msm.c
+@@ -96,6 +96,14 @@ MSM_ACCESSOR(intr_cfg)
+ MSM_ACCESSOR(intr_status)
+ MSM_ACCESSOR(intr_target)
++static void msm_ack_intr_status(struct msm_pinctrl *pctrl,
++                              const struct msm_pingroup *g)
++{
++      u32 val = g->intr_ack_high ? BIT(g->intr_status_bit) : 0;
++
++      msm_writel_intr_status(val, pctrl, g);
++}
++
+ static int msm_get_groups_count(struct pinctrl_dev *pctldev)
+ {
+       struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+@@ -797,7 +805,7 @@ static void msm_gpio_irq_clear_unmask(st
+        * when the interrupt is not in use.
+        */
+       if (status_clear)
+-              msm_writel_intr_status(0, pctrl, g);
++              msm_ack_intr_status(pctrl, g);
+       val = msm_readl_intr_cfg(pctrl, g);
+       val |= BIT(g->intr_raw_status_bit);
+@@ -890,7 +898,6 @@ static void msm_gpio_irq_ack(struct irq_
+       struct msm_pinctrl *pctrl = gpiochip_get_data(gc);
+       const struct msm_pingroup *g;
+       unsigned long flags;
+-      u32 val;
+       if (test_bit(d->hwirq, pctrl->skip_wake_irqs)) {
+               if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
+@@ -902,8 +909,7 @@ static void msm_gpio_irq_ack(struct irq_
+       raw_spin_lock_irqsave(&pctrl->lock, flags);
+-      val = g->intr_ack_high ? BIT(g->intr_status_bit) : 0;
+-      msm_writel_intr_status(val, pctrl, g);
++      msm_ack_intr_status(pctrl, g);
+       if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
+               msm_gpio_update_dual_edge_pos(pctrl, g, d);
index a7ad2c8a2cf6619e53cd298366b75fb950525a7a..9fce8153b9e67d9be9fcfead8bf79f6b8a2a9bd1 100644 (file)
@@ -180,3 +180,7 @@ tcp-do-not-mess-with-cloned-skbs-in-tcp_add_backlog.patch
 tcp-fix-tcp_user_timeout-with-zero-window.patch
 net-mscc-ocelot-fix-multicast-to-the-cpu-port.patch
 net-core-devlink-use-right-genl-user_ptr-when-handling-port-param-get-set.patch
+pinctrl-qcom-allow-socs-to-specify-a-gpio-function-that-s-not-0.patch
+pinctrl-qcom-no-need-to-read-modify-write-the-interrupt-status.patch
+pinctrl-qcom-properly-clear-intr_ack_high-interrupts-when-unmasking.patch
+pinctrl-qcom-don-t-clear-pending-interrupts-when-enabling.patch