--- /dev/null
+From 23200a4c8ac284f8b4263d7cecaefecaa3ad6732 Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Thu, 11 May 2023 12:58:33 +0200
+Subject: clk: pxa: fix NULL pointer dereference in pxa3xx_clk_update_accr
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+commit 23200a4c8ac284f8b4263d7cecaefecaa3ad6732 upstream.
+
+sparse points out an embarrasing bug in an older patch of mine,
+which uses the register offset instead of an __iomem pointer:
+
+drivers/clk/pxa/clk-pxa3xx.c:167:9: sparse: sparse: Using plain integer as NULL pointer
+
+Unlike sparse, gcc and clang ignore this bug and fail to warn
+because a literal '0' is considered a valid representation of
+a NULL pointer.
+
+Fixes: 3c816d950a49 ("ARM: pxa: move clk register definitions to driver")
+Cc: stable@vger.kernel.org
+Reported-by: kernel test robot <lkp@intel.com>
+Link: https://lore.kernel.org/oe-kbuild-all/202305111301.RAHohdob-lkp@intel.com/
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Link: https://lore.kernel.org/r/20230511105845.299859-1-arnd@kernel.org
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/clk/pxa/clk-pxa3xx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/clk/pxa/clk-pxa3xx.c
++++ b/drivers/clk/pxa/clk-pxa3xx.c
+@@ -164,7 +164,7 @@ void pxa3xx_clk_update_accr(u32 disable,
+ accr &= ~disable;
+ accr |= enable;
+
+- writel(accr, ACCR);
++ writel(accr, clk_regs + ACCR);
+ if (xclkcfg)
+ __asm__("mcr p14, 0, %0, c6, c0, 0\n" : : "r"(xclkcfg));
+
--- /dev/null
+From 306320034e8fbe7ee1cc4f5269c55658b4612048 Mon Sep 17 00:00:00 2001
+From: Bernhard Seibold <mail@bernhard-seibold.de>
+Date: Fri, 2 Jun 2023 15:30:29 +0200
+Subject: serial: lantiq: add missing interrupt ack
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Bernhard Seibold <mail@bernhard-seibold.de>
+
+commit 306320034e8fbe7ee1cc4f5269c55658b4612048 upstream.
+
+Currently, the error interrupt is never acknowledged, so once active it
+will stay active indefinitely, causing the handler to be called in an
+infinite loop.
+
+Fixes: 2f0fc4159a6a ("SERIAL: Lantiq: Add driver for MIPS Lantiq SOCs.")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Bernhard Seibold <mail@bernhard-seibold.de>
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Message-ID: <20230602133029.546-1-mail@bernhard-seibold.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/lantiq.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/tty/serial/lantiq.c
++++ b/drivers/tty/serial/lantiq.c
+@@ -250,6 +250,7 @@ lqasc_err_int(int irq, void *_port)
+ struct ltq_uart_port *ltq_port = to_ltq_uart_port(port);
+
+ spin_lock_irqsave(<q_port->lock, flags);
++ __raw_writel(ASC_IRNCR_EIR, port->membase + LTQ_ASC_IRNCR);
+ /* clear any pending interrupts */
+ asc_update_bits(0, ASCWHBSTATE_CLRPE | ASCWHBSTATE_CLRFE |
+ ASCWHBSTATE_CLRROE, port->membase + LTQ_ASC_WHBSTATE);
drm-amdgpu-implement-gfx9-patch-functions-for-resubmission.patch
drm-amdgpu-modify-indirect-buffer-packages-for-resubmission.patch
alsa-hda-realtek-add-a-quirk-for-compaq-n14jp6.patch
+thunderbolt-increase-displayport-connection-manager-handshake-timeout.patch
+thunderbolt-do-not-touch-cl-state-configuration-during-discovery.patch
+thunderbolt-dma_test-use-correct-value-for-absent-rings-when-creating-paths.patch
+thunderbolt-mask-ring-interrupt-on-intel-hardware-as-well.patch
+clk-pxa-fix-null-pointer-dereference-in-pxa3xx_clk_update_accr.patch
+usb-serial-option-add-quectel-em061kgl-series.patch
+serial-lantiq-add-missing-interrupt-ack.patch
+tty-serial-fsl_lpuart-reduce-rx-watermark-to-0-on-ls1028a.patch
+usb-typec-ucsi-fix-command-cancellation.patch
+usb-typec-fix-fast_role_swap_current-show-function.patch
+usb-gadget-udc-core-offload-usb_udc_vbus_handler-processing.patch
+usb-gadget-udc-core-prevent-soft_connect_store-race.patch
+usb-gadget-udc-renesas_usb3-fix-rz-v2m-modprobe-bind-error.patch
+usb-dwc3-qcom-fix-null-deref-on-suspend.patch
+usb-dwc3-fix-use-after-free-on-core-driver-unbind.patch
+usb-dwc3-gadget-reset-num-trbs-before-giving-back-the-request.patch
--- /dev/null
+From 70c2e03e9aaf17496c63f6e42333c012f5ae5307 Mon Sep 17 00:00:00 2001
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+Date: Wed, 29 Mar 2023 13:23:04 +0300
+Subject: thunderbolt: dma_test: Use correct value for absent rings when creating paths
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+commit 70c2e03e9aaf17496c63f6e42333c012f5ae5307 upstream.
+
+Both tb_xdomain_enable_paths() and tb_xdomain_disable_paths() expect -1,
+not 0, if the corresponding ring is not needed. For this reason change
+the driver to use correct value for the rings that are not needed.
+
+Fixes: 180b0689425c ("thunderbolt: Allow multiple DMA tunnels over a single XDomain connection")
+Cc: stable@vger.kernel.org
+Reported-by: Pengfei Xu <pengfei.xu@intel.com>
+Tested-by: Pengfei Xu <pengfei.xu@intel.com>
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/thunderbolt/dma_test.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/thunderbolt/dma_test.c
++++ b/drivers/thunderbolt/dma_test.c
+@@ -192,9 +192,9 @@ static int dma_test_start_rings(struct d
+ }
+
+ ret = tb_xdomain_enable_paths(dt->xd, dt->tx_hopid,
+- dt->tx_ring ? dt->tx_ring->hop : 0,
++ dt->tx_ring ? dt->tx_ring->hop : -1,
+ dt->rx_hopid,
+- dt->rx_ring ? dt->rx_ring->hop : 0);
++ dt->rx_ring ? dt->rx_ring->hop : -1);
+ if (ret) {
+ dma_test_free_rings(dt);
+ return ret;
+@@ -218,9 +218,9 @@ static void dma_test_stop_rings(struct d
+ tb_ring_stop(dt->tx_ring);
+
+ ret = tb_xdomain_disable_paths(dt->xd, dt->tx_hopid,
+- dt->tx_ring ? dt->tx_ring->hop : 0,
++ dt->tx_ring ? dt->tx_ring->hop : -1,
+ dt->rx_hopid,
+- dt->rx_ring ? dt->rx_ring->hop : 0);
++ dt->rx_ring ? dt->rx_ring->hop : -1);
+ if (ret)
+ dev_warn(&dt->svc->dev, "failed to disable DMA paths\n");
+
--- /dev/null
+From 3fe95742af29b8b4eccab2ba94bc521805c6e10c Mon Sep 17 00:00:00 2001
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+Date: Wed, 24 May 2023 13:47:04 +0300
+Subject: thunderbolt: Do not touch CL state configuration during discovery
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+commit 3fe95742af29b8b4eccab2ba94bc521805c6e10c upstream.
+
+If the boot firmware has already established tunnels, especially ones
+that have special requirements from the link such as DisplayPort, we
+should not blindly enable CL states (nor change the TMU configuration).
+Otherwise the existing tunnels may not work as expected.
+
+For this reason, skip the CL state enabling when we go over the existing
+topology. This will also keep the TMU settings untouched because we do
+not change the TMU configuration when CL states are not enabled.
+
+Reported-by: Koba Ko <koba.ko@canonical.com>
+Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/7831
+Cc: stable@vger.kernel.org # v6.0+
+Acked-By: Yehezkel Bernat <YehezkelShB@gmail.com>
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/thunderbolt/tb.c | 17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+--- a/drivers/thunderbolt/tb.c
++++ b/drivers/thunderbolt/tb.c
+@@ -737,6 +737,7 @@ static void tb_scan_port(struct tb_port
+ {
+ struct tb_cm *tcm = tb_priv(port->sw->tb);
+ struct tb_port *upstream_port;
++ bool discovery = false;
+ struct tb_switch *sw;
+ int ret;
+
+@@ -804,8 +805,10 @@ static void tb_scan_port(struct tb_port
+ * tunnels and know which switches were authorized already by
+ * the boot firmware.
+ */
+- if (!tcm->hotplug_active)
++ if (!tcm->hotplug_active) {
+ dev_set_uevent_suppress(&sw->dev, true);
++ discovery = true;
++ }
+
+ /*
+ * At the moment Thunderbolt 2 and beyond (devices with LC) we
+@@ -835,10 +838,14 @@ static void tb_scan_port(struct tb_port
+ * CL0s and CL1 are enabled and supported together.
+ * Silently ignore CLx enabling in case CLx is not supported.
+ */
+- ret = tb_switch_enable_clx(sw, TB_CL1);
+- if (ret && ret != -EOPNOTSUPP)
+- tb_sw_warn(sw, "failed to enable %s on upstream port\n",
+- tb_switch_clx_name(TB_CL1));
++ if (discovery) {
++ tb_sw_dbg(sw, "discovery, not touching CL states\n");
++ } else {
++ ret = tb_switch_enable_clx(sw, TB_CL1);
++ if (ret && ret != -EOPNOTSUPP)
++ tb_sw_warn(sw, "failed to enable %s on upstream port\n",
++ tb_switch_clx_name(TB_CL1));
++ }
+
+ if (tb_switch_is_clx_enabled(sw, TB_CL1))
+ /*
--- /dev/null
+From b6d572aeb58a5e0be86bd51ea514c4feba996cc4 Mon Sep 17 00:00:00 2001
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+Date: Wed, 24 May 2023 10:41:57 +0300
+Subject: thunderbolt: Increase DisplayPort Connection Manager handshake timeout
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+commit b6d572aeb58a5e0be86bd51ea514c4feba996cc4 upstream.
+
+It turns out that when plugging in VGA cable through USB-C to VGA/DVI
+dongle the Connection Manager handshake can take longer time, at least
+on Intel Titan Ridge based docks such as Dell WD91TB. This leads to
+following error in the dmesg:
+
+ thunderbolt 0000:00:0d.3: 3:10: DP tunnel activation failed, aborting
+
+and the display stays blank (because we failed to establish the tunnel).
+For this reason increase the timeout to 3s.
+
+Reported-by: Koba Ko <koba.ko@canonical.com>
+Cc: stable@vger.kernel.org
+Acked-By: Yehezkel Bernat <YehezkelShB@gmail.com>
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/thunderbolt/tunnel.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/thunderbolt/tunnel.c
++++ b/drivers/thunderbolt/tunnel.c
+@@ -526,7 +526,7 @@ static int tb_dp_xchg_caps(struct tb_tun
+ * Perform connection manager handshake between IN and OUT ports
+ * before capabilities exchange can take place.
+ */
+- ret = tb_dp_cm_handshake(in, out, 1500);
++ ret = tb_dp_cm_handshake(in, out, 3000);
+ if (ret)
+ return ret;
+
--- /dev/null
+From 9f9666e65359d5047089aef97ac87c50f624ecb0 Mon Sep 17 00:00:00 2001
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+Date: Tue, 30 May 2023 08:48:29 +0300
+Subject: thunderbolt: Mask ring interrupt on Intel hardware as well
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+commit 9f9666e65359d5047089aef97ac87c50f624ecb0 upstream.
+
+When resuming from system sleep states the driver issues following
+warning on Intel hardware:
+
+ thunderbolt 0000:07:00.0: interrupt for TX ring 0 is already enabled
+
+The reason for this is that the commit in question did not mask the ring
+interrupt on Intel hardware leaving the interrupt active. Fix this by
+masking it also in Intel hardware.
+
+Reported-by: beld zhang <beldzhang@gmail.com>
+Tested-by: beld zhang <beldzhang@gmail.com>
+Closes: https://lore.kernel.org/linux-usb/ZHKW5NeabmfhgLbY@debian.me/
+Fixes: c4af8e3fecd0 ("thunderbolt: Clear registers properly when auto clear isn't in use")
+Cc: stable@vger.kernel.org
+Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/thunderbolt/nhi.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+--- a/drivers/thunderbolt/nhi.c
++++ b/drivers/thunderbolt/nhi.c
+@@ -56,9 +56,14 @@ static int ring_interrupt_index(const st
+
+ static void nhi_mask_interrupt(struct tb_nhi *nhi, int mask, int ring)
+ {
+- if (nhi->quirks & QUIRK_AUTO_CLEAR_INT)
+- return;
+- iowrite32(mask, nhi->iobase + REG_RING_INTERRUPT_MASK_CLEAR_BASE + ring);
++ if (nhi->quirks & QUIRK_AUTO_CLEAR_INT) {
++ u32 val;
++
++ val = ioread32(nhi->iobase + REG_RING_INTERRUPT_BASE + ring);
++ iowrite32(val & ~mask, nhi->iobase + REG_RING_INTERRUPT_BASE + ring);
++ } else {
++ iowrite32(mask, nhi->iobase + REG_RING_INTERRUPT_MASK_CLEAR_BASE + ring);
++ }
+ }
+
+ static void nhi_clear_interrupt(struct tb_nhi *nhi, int ring)
--- /dev/null
+From a82c3df955f8c1c726e4976527aa6ae924a67dd9 Mon Sep 17 00:00:00 2001
+From: Robert Hodaszi <robert.hodaszi@digi.com>
+Date: Fri, 9 Jun 2023 14:13:34 +0200
+Subject: tty: serial: fsl_lpuart: reduce RX watermark to 0 on LS1028A
+
+From: Robert Hodaszi <robert.hodaszi@digi.com>
+
+commit a82c3df955f8c1c726e4976527aa6ae924a67dd9 upstream.
+
+LS1028A is using DMA with LPUART. Having RX watermark set to 1, means
+DMA transactions are started only after receiving the second character.
+
+On other platforms with newer LPUART IP, Receiver Idle Empty function
+initiates the DMA request after the receiver is idling for 4 characters.
+But this feature is missing on LS1028A, which is causing a 1-character
+delay in the RX direction on this platform.
+
+Set RX watermark to 0 to initiate RX DMA after each character.
+
+Link: https://lore.kernel.org/linux-serial/20230607103459.1222426-1-robert.hodaszi@digi.com/
+Fixes: 9ad9df844754 ("tty: serial: fsl_lpuart: Fix the wrong RXWATER setting for rx dma case")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Robert Hodaszi <robert.hodaszi@digi.com>
+Message-ID: <20230609121334.1878626-1-robert.hodaszi@digi.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/fsl_lpuart.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/tty/serial/fsl_lpuart.c
++++ b/drivers/tty/serial/fsl_lpuart.c
+@@ -310,7 +310,7 @@ static const struct lpuart_soc_data ls10
+ static const struct lpuart_soc_data ls1028a_data = {
+ .devtype = LS1028A_LPUART,
+ .iotype = UPIO_MEM32,
+- .rx_watermark = 1,
++ .rx_watermark = 0,
+ };
+
+ static struct lpuart_soc_data imx7ulp_data = {
--- /dev/null
+From e3dbb657571509044be15184a13134fa7c1fdca1 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan+linaro@kernel.org>
+Date: Wed, 7 Jun 2023 12:05:40 +0200
+Subject: USB: dwc3: fix use-after-free on core driver unbind
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+commit e3dbb657571509044be15184a13134fa7c1fdca1 upstream.
+
+Some dwc3 glue drivers are currently accessing the driver data of the
+child core device directly, which is clearly a bad idea as the child may
+not have probed yet or may have been unbound from its driver.
+
+As a workaround until the glue drivers have been fixed, clear the driver
+data pointer before allowing the glue parent device to runtime suspend
+to prevent its driver from accessing data that has been freed during
+unbind.
+
+Fixes: 6dd2565989b4 ("usb: dwc3: add imx8mp dwc3 glue layer driver")
+Fixes: 6895ea55c385 ("usb: dwc3: qcom: Configure wakeup interrupts during suspend")
+Cc: stable@vger.kernel.org # 5.12
+Cc: Li Jun <jun.li@nxp.com>
+Cc: Sandeep Maheswaram <quic_c_sanm@quicinc.com>
+Cc: Krishna Kurapati <quic_kriskura@quicinc.com>
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Message-ID: <20230607100540.31045-3-johan+linaro@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/core.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -1982,6 +1982,11 @@ static int dwc3_remove(struct platform_d
+ pm_runtime_allow(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_put_noidle(&pdev->dev);
++ /*
++ * HACK: Clear the driver data, which is currently accessed by parent
++ * glue drivers, before allowing the parent to suspend.
++ */
++ platform_set_drvdata(pdev, NULL);
+ pm_runtime_set_suspended(&pdev->dev);
+
+ dwc3_free_event_buffers(dwc);
--- /dev/null
+From 00f8205ffcf112dcef14f8151d78075d38d22c08 Mon Sep 17 00:00:00 2001
+From: Elson Roy Serrao <quic_eserrao@quicinc.com>
+Date: Thu, 1 Jun 2023 14:27:30 -0700
+Subject: usb: dwc3: gadget: Reset num TRBs before giving back the request
+
+From: Elson Roy Serrao <quic_eserrao@quicinc.com>
+
+commit 00f8205ffcf112dcef14f8151d78075d38d22c08 upstream.
+
+Consider a scenario where cable disconnect happens when there is an active
+usb reqest queued to the UDC. As part of the disconnect we would issue an
+end transfer with no interrupt-on-completion before giving back this
+request. Since we are giving back the request without skipping TRBs the
+num_trbs field of dwc3_request still holds the stale value previously used.
+Function drivers re-use same request for a given bind-unbind session and
+hence their dwc3_request context gets preserved across cable
+disconnect/connect. When such a request gets re-queued after cable connect,
+we would increase the num_trbs field on top of the previous stale value
+thus incorrectly representing the number of TRBs used. Fix this by
+resetting num_trbs field before giving back the request.
+
+Fixes: 09fe1f8d7e2f ("usb: dwc3: gadget: track number of TRBs per request")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Elson Roy Serrao <quic_eserrao@quicinc.com>
+Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Message-ID: <1685654850-8468-1-git-send-email-quic_eserrao@quicinc.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/gadget.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -180,6 +180,7 @@ static void dwc3_gadget_del_and_unmap_re
+ list_del(&req->list);
+ req->remaining = 0;
+ req->needs_extra_trb = false;
++ req->num_trbs = 0;
+
+ if (req->request.status == -EINPROGRESS)
+ req->request.status = status;
--- /dev/null
+From d2d69354226de0b333d4405981f3d9c41ba8430a Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan+linaro@kernel.org>
+Date: Wed, 7 Jun 2023 12:05:39 +0200
+Subject: USB: dwc3: qcom: fix NULL-deref on suspend
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+commit d2d69354226de0b333d4405981f3d9c41ba8430a upstream.
+
+The Qualcomm dwc3 glue driver is currently accessing the driver data of
+the child core device during suspend and on wakeup interrupts. This is
+clearly a bad idea as the child may not have probed yet or could have
+been unbound from its driver.
+
+The first such layering violation was part of the initial version of the
+driver, but this was later made worse when the hack that accesses the
+driver data of the grand child xhci device to configure the wakeup
+interrupts was added.
+
+Fixing this properly is not that easily done, so add a sanity check to
+make sure that the child driver data is non-NULL before dereferencing it
+for now.
+
+Note that this relies on subtleties like the fact that driver core is
+making sure that the parent is not suspended while the child is probing.
+
+Reported-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/all/20230325165217.31069-4-manivannan.sadhasivam@linaro.org/
+Fixes: d9152161b4bf ("usb: dwc3: Add Qualcomm DWC3 glue layer driver")
+Fixes: 6895ea55c385 ("usb: dwc3: qcom: Configure wakeup interrupts during suspend")
+Cc: stable@vger.kernel.org # 3.18: a872ab303d5d: "usb: dwc3: qcom: fix use-after-free on runtime-PM wakeup"
+Cc: Sandeep Maheswaram <quic_c_sanm@quicinc.com>
+Cc: Krishna Kurapati <quic_kriskura@quicinc.com>
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Message-ID: <20230607100540.31045-2-johan+linaro@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/dwc3-qcom.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/dwc3/dwc3-qcom.c
++++ b/drivers/usb/dwc3/dwc3-qcom.c
+@@ -308,7 +308,16 @@ static void dwc3_qcom_interconnect_exit(
+ /* Only usable in contexts where the role can not change. */
+ static bool dwc3_qcom_is_host(struct dwc3_qcom *qcom)
+ {
+- struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3);
++ struct dwc3 *dwc;
++
++ /*
++ * FIXME: Fix this layering violation.
++ */
++ dwc = platform_get_drvdata(qcom->dwc3);
++
++ /* Core driver may not have probed yet. */
++ if (!dwc)
++ return false;
+
+ return dwc->xhci;
+ }
--- /dev/null
+From 50966da807c81c5eb3bdfd392990fe0bba94d1ee Mon Sep 17 00:00:00 2001
+From: Badhri Jagan Sridharan <badhri@google.com>
+Date: Fri, 9 Jun 2023 01:02:26 +0000
+Subject: usb: gadget: udc: core: Offload usb_udc_vbus_handler processing
+
+From: Badhri Jagan Sridharan <badhri@google.com>
+
+commit 50966da807c81c5eb3bdfd392990fe0bba94d1ee upstream.
+
+usb_udc_vbus_handler() can be invoked from interrupt context by irq
+handlers of the gadget drivers, however, usb_udc_connect_control() has
+to run in non-atomic context due to the following:
+a. Some of the gadget driver implementations expect the ->pullup
+ callback to be invoked in non-atomic context.
+b. usb_gadget_disconnect() acquires udc_lock which is a mutex.
+
+Hence offload invocation of usb_udc_connect_control()
+to workqueue.
+
+UDC should not be pulled up unless gadget driver is bound. The new flag
+"allow_connect" is now set by gadget_bind_driver() and cleared by
+gadget_unbind_driver(). This prevents work item to pull up the gadget
+even if queued when the gadget driver is already unbound.
+
+Cc: stable@vger.kernel.org
+Fixes: 1016fc0c096c ("USB: gadget: Fix obscure lockdep violation for udc_mutex")
+Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
+Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
+Message-ID: <20230609010227.978661-1-badhri@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/udc/core.c | 29 +++++++++++++++++++++++++++--
+ 1 file changed, 27 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/gadget/udc/core.c
++++ b/drivers/usb/gadget/udc/core.c
+@@ -37,6 +37,9 @@ static struct bus_type gadget_bus_type;
+ * @vbus: for udcs who care about vbus status, this value is real vbus status;
+ * for udcs who do not care about vbus status, this value is always true
+ * @started: the UDC's started state. True if the UDC had started.
++ * @allow_connect: Indicates whether UDC is allowed to be pulled up.
++ * Set/cleared by gadget_(un)bind_driver() after gadget driver is bound or
++ * unbound.
+ *
+ * This represents the internal data structure which is used by the UDC-class
+ * to hold information about udc driver and gadget together.
+@@ -48,6 +51,8 @@ struct usb_udc {
+ struct list_head list;
+ bool vbus;
+ bool started;
++ bool allow_connect;
++ struct work_struct vbus_work;
+ };
+
+ static struct class *udc_class;
+@@ -679,7 +684,7 @@ int usb_gadget_connect(struct usb_gadget
+ goto out;
+ }
+
+- if (gadget->deactivated) {
++ if (gadget->deactivated || !gadget->udc->allow_connect) {
+ /*
+ * If gadget is deactivated we only save new state.
+ * Gadget will be connected automatically after activation.
+@@ -1059,6 +1064,13 @@ static void usb_udc_connect_control(stru
+ usb_gadget_disconnect(udc->gadget);
+ }
+
++static void vbus_event_work(struct work_struct *work)
++{
++ struct usb_udc *udc = container_of(work, struct usb_udc, vbus_work);
++
++ usb_udc_connect_control(udc);
++}
++
+ /**
+ * usb_udc_vbus_handler - updates the udc core vbus status, and try to
+ * connect or disconnect gadget
+@@ -1067,6 +1079,14 @@ static void usb_udc_connect_control(stru
+ *
+ * The udc driver calls it when it wants to connect or disconnect gadget
+ * according to vbus status.
++ *
++ * This function can be invoked from interrupt context by irq handlers of
++ * the gadget drivers, however, usb_udc_connect_control() has to run in
++ * non-atomic context due to the following:
++ * a. Some of the gadget driver implementations expect the ->pullup
++ * callback to be invoked in non-atomic context.
++ * b. usb_gadget_disconnect() acquires udc_lock which is a mutex.
++ * Hence offload invocation of usb_udc_connect_control() to workqueue.
+ */
+ void usb_udc_vbus_handler(struct usb_gadget *gadget, bool status)
+ {
+@@ -1074,7 +1094,7 @@ void usb_udc_vbus_handler(struct usb_gad
+
+ if (udc) {
+ udc->vbus = status;
+- usb_udc_connect_control(udc);
++ schedule_work(&udc->vbus_work);
+ }
+ }
+ EXPORT_SYMBOL_GPL(usb_udc_vbus_handler);
+@@ -1301,6 +1321,7 @@ int usb_add_gadget(struct usb_gadget *ga
+ mutex_lock(&udc_lock);
+ list_add_tail(&udc->list, &udc_list);
+ mutex_unlock(&udc_lock);
++ INIT_WORK(&udc->vbus_work, vbus_event_work);
+
+ ret = device_add(&udc->dev);
+ if (ret)
+@@ -1432,6 +1453,7 @@ void usb_del_gadget(struct usb_gadget *g
+ flush_work(&gadget->work);
+ device_del(&gadget->dev);
+ ida_free(&gadget_id_numbers, gadget->id_number);
++ cancel_work_sync(&udc->vbus_work);
+ device_unregister(&udc->dev);
+ }
+ EXPORT_SYMBOL_GPL(usb_del_gadget);
+@@ -1500,6 +1522,7 @@ static int gadget_bind_driver(struct dev
+ if (ret)
+ goto err_start;
+ usb_gadget_enable_async_callbacks(udc);
++ udc->allow_connect = true;
+ usb_udc_connect_control(udc);
+
+ kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
+@@ -1531,6 +1554,8 @@ static void gadget_unbind_driver(struct
+
+ kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
+
++ udc->allow_connect = false;
++ cancel_work_sync(&udc->vbus_work);
+ usb_gadget_disconnect(gadget);
+ usb_gadget_disable_async_callbacks(udc);
+ if (gadget->irq)
--- /dev/null
+From 286d9975a838d0a54da049765fa1d1fb96b89682 Mon Sep 17 00:00:00 2001
+From: Badhri Jagan Sridharan <badhri@google.com>
+Date: Fri, 9 Jun 2023 01:02:27 +0000
+Subject: usb: gadget: udc: core: Prevent soft_connect_store() race
+
+From: Badhri Jagan Sridharan <badhri@google.com>
+
+commit 286d9975a838d0a54da049765fa1d1fb96b89682 upstream.
+
+usb_udc_connect_control(), soft_connect_store() and
+usb_gadget_deactivate() can potentially race against each other to invoke
+usb_gadget_connect()/usb_gadget_disconnect(). To prevent this, guard
+udc->started, gadget->allow_connect, gadget->deactivate and
+gadget->connect with connect_lock so that ->pullup() is only invoked when
+the gadget is bound, started and not deactivated. The routines
+usb_gadget_connect_locked(), usb_gadget_disconnect_locked(),
+usb_udc_connect_control_locked(), usb_gadget_udc_start_locked(),
+usb_gadget_udc_stop_locked() are called with this lock held.
+
+An earlier version of this commit was reverted due to the crash reported in
+https://lore.kernel.org/all/ZF4BvgsOyoKxdPFF@francesco-nb.int.toradex.com/.
+commit 16737e78d190 ("usb: gadget: udc: core: Offload usb_udc_vbus_handler processing")
+addresses the crash reported.
+
+Cc: stable@vger.kernel.org
+Fixes: 628ef0d273a6 ("usb: udc: add usb_udc_vbus_handler")
+Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
+Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
+Message-ID: <20230609010227.978661-2-badhri@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/udc/core.c | 155 ++++++++++++++++++++++++++++--------------
+ 1 file changed, 106 insertions(+), 49 deletions(-)
+
+--- a/drivers/usb/gadget/udc/core.c
++++ b/drivers/usb/gadget/udc/core.c
+@@ -40,6 +40,11 @@ static struct bus_type gadget_bus_type;
+ * @allow_connect: Indicates whether UDC is allowed to be pulled up.
+ * Set/cleared by gadget_(un)bind_driver() after gadget driver is bound or
+ * unbound.
++ * @connect_lock: protects udc->started, gadget->connect,
++ * gadget->allow_connect and gadget->deactivate. The routines
++ * usb_gadget_connect_locked(), usb_gadget_disconnect_locked(),
++ * usb_udc_connect_control_locked(), usb_gadget_udc_start_locked() and
++ * usb_gadget_udc_stop_locked() are called with this lock held.
+ *
+ * This represents the internal data structure which is used by the UDC-class
+ * to hold information about udc driver and gadget together.
+@@ -53,6 +58,7 @@ struct usb_udc {
+ bool started;
+ bool allow_connect;
+ struct work_struct vbus_work;
++ struct mutex connect_lock;
+ };
+
+ static struct class *udc_class;
+@@ -665,17 +671,8 @@ out:
+ }
+ EXPORT_SYMBOL_GPL(usb_gadget_vbus_disconnect);
+
+-/**
+- * usb_gadget_connect - software-controlled connect to USB host
+- * @gadget:the peripheral being connected
+- *
+- * Enables the D+ (or potentially D-) pullup. The host will start
+- * enumerating this gadget when the pullup is active and a VBUS session
+- * is active (the link is powered).
+- *
+- * Returns zero on success, else negative errno.
+- */
+-int usb_gadget_connect(struct usb_gadget *gadget)
++static int usb_gadget_connect_locked(struct usb_gadget *gadget)
++ __must_hold(&gadget->udc->connect_lock)
+ {
+ int ret = 0;
+
+@@ -684,10 +681,12 @@ int usb_gadget_connect(struct usb_gadget
+ goto out;
+ }
+
+- if (gadget->deactivated || !gadget->udc->allow_connect) {
++ if (gadget->deactivated || !gadget->udc->allow_connect || !gadget->udc->started) {
+ /*
+- * If gadget is deactivated we only save new state.
+- * Gadget will be connected automatically after activation.
++ * If the gadget isn't usable (because it is deactivated,
++ * unbound, or not yet started), we only save the new state.
++ * The gadget will be connected automatically when it is
++ * activated/bound/started.
+ */
+ gadget->connected = true;
+ goto out;
+@@ -702,22 +701,31 @@ out:
+
+ return ret;
+ }
+-EXPORT_SYMBOL_GPL(usb_gadget_connect);
+
+ /**
+- * usb_gadget_disconnect - software-controlled disconnect from USB host
+- * @gadget:the peripheral being disconnected
+- *
+- * Disables the D+ (or potentially D-) pullup, which the host may see
+- * as a disconnect (when a VBUS session is active). Not all systems
+- * support software pullup controls.
++ * usb_gadget_connect - software-controlled connect to USB host
++ * @gadget:the peripheral being connected
+ *
+- * Following a successful disconnect, invoke the ->disconnect() callback
+- * for the current gadget driver so that UDC drivers don't need to.
++ * Enables the D+ (or potentially D-) pullup. The host will start
++ * enumerating this gadget when the pullup is active and a VBUS session
++ * is active (the link is powered).
+ *
+ * Returns zero on success, else negative errno.
+ */
+-int usb_gadget_disconnect(struct usb_gadget *gadget)
++int usb_gadget_connect(struct usb_gadget *gadget)
++{
++ int ret;
++
++ mutex_lock(&gadget->udc->connect_lock);
++ ret = usb_gadget_connect_locked(gadget);
++ mutex_unlock(&gadget->udc->connect_lock);
++
++ return ret;
++}
++EXPORT_SYMBOL_GPL(usb_gadget_connect);
++
++static int usb_gadget_disconnect_locked(struct usb_gadget *gadget)
++ __must_hold(&gadget->udc->connect_lock)
+ {
+ int ret = 0;
+
+@@ -729,7 +737,7 @@ int usb_gadget_disconnect(struct usb_gad
+ if (!gadget->connected)
+ goto out;
+
+- if (gadget->deactivated) {
++ if (gadget->deactivated || !gadget->udc->started) {
+ /*
+ * If gadget is deactivated we only save new state.
+ * Gadget will stay disconnected after activation.
+@@ -752,6 +760,30 @@ out:
+
+ return ret;
+ }
++
++/**
++ * usb_gadget_disconnect - software-controlled disconnect from USB host
++ * @gadget:the peripheral being disconnected
++ *
++ * Disables the D+ (or potentially D-) pullup, which the host may see
++ * as a disconnect (when a VBUS session is active). Not all systems
++ * support software pullup controls.
++ *
++ * Following a successful disconnect, invoke the ->disconnect() callback
++ * for the current gadget driver so that UDC drivers don't need to.
++ *
++ * Returns zero on success, else negative errno.
++ */
++int usb_gadget_disconnect(struct usb_gadget *gadget)
++{
++ int ret;
++
++ mutex_lock(&gadget->udc->connect_lock);
++ ret = usb_gadget_disconnect_locked(gadget);
++ mutex_unlock(&gadget->udc->connect_lock);
++
++ return ret;
++}
+ EXPORT_SYMBOL_GPL(usb_gadget_disconnect);
+
+ /**
+@@ -769,13 +801,14 @@ int usb_gadget_deactivate(struct usb_gad
+ {
+ int ret = 0;
+
++ mutex_lock(&gadget->udc->connect_lock);
+ if (gadget->deactivated)
+- goto out;
++ goto unlock;
+
+ if (gadget->connected) {
+- ret = usb_gadget_disconnect(gadget);
++ ret = usb_gadget_disconnect_locked(gadget);
+ if (ret)
+- goto out;
++ goto unlock;
+
+ /*
+ * If gadget was being connected before deactivation, we want
+@@ -785,7 +818,8 @@ int usb_gadget_deactivate(struct usb_gad
+ }
+ gadget->deactivated = true;
+
+-out:
++unlock:
++ mutex_unlock(&gadget->udc->connect_lock);
+ trace_usb_gadget_deactivate(gadget, ret);
+
+ return ret;
+@@ -805,8 +839,9 @@ int usb_gadget_activate(struct usb_gadge
+ {
+ int ret = 0;
+
++ mutex_lock(&gadget->udc->connect_lock);
+ if (!gadget->deactivated)
+- goto out;
++ goto unlock;
+
+ gadget->deactivated = false;
+
+@@ -815,9 +850,11 @@ int usb_gadget_activate(struct usb_gadge
+ * while it was being deactivated, we call usb_gadget_connect().
+ */
+ if (gadget->connected)
+- ret = usb_gadget_connect(gadget);
++ ret = usb_gadget_connect_locked(gadget);
++ mutex_unlock(&gadget->udc->connect_lock);
+
+-out:
++unlock:
++ mutex_unlock(&gadget->udc->connect_lock);
+ trace_usb_gadget_activate(gadget, ret);
+
+ return ret;
+@@ -1056,19 +1093,22 @@ EXPORT_SYMBOL_GPL(usb_gadget_set_state);
+
+ /* ------------------------------------------------------------------------- */
+
+-static void usb_udc_connect_control(struct usb_udc *udc)
++/* Acquire connect_lock before calling this function. */
++static void usb_udc_connect_control_locked(struct usb_udc *udc) __must_hold(&udc->connect_lock)
+ {
+ if (udc->vbus)
+- usb_gadget_connect(udc->gadget);
++ usb_gadget_connect_locked(udc->gadget);
+ else
+- usb_gadget_disconnect(udc->gadget);
++ usb_gadget_disconnect_locked(udc->gadget);
+ }
+
+ static void vbus_event_work(struct work_struct *work)
+ {
+ struct usb_udc *udc = container_of(work, struct usb_udc, vbus_work);
+
+- usb_udc_connect_control(udc);
++ mutex_lock(&udc->connect_lock);
++ usb_udc_connect_control_locked(udc);
++ mutex_unlock(&udc->connect_lock);
+ }
+
+ /**
+@@ -1117,7 +1157,7 @@ void usb_gadget_udc_reset(struct usb_gad
+ EXPORT_SYMBOL_GPL(usb_gadget_udc_reset);
+
+ /**
+- * usb_gadget_udc_start - tells usb device controller to start up
++ * usb_gadget_udc_start_locked - tells usb device controller to start up
+ * @udc: The UDC to be started
+ *
+ * This call is issued by the UDC Class driver when it's about
+@@ -1128,8 +1168,11 @@ EXPORT_SYMBOL_GPL(usb_gadget_udc_reset);
+ * necessary to have it powered on.
+ *
+ * Returns zero on success, else negative errno.
++ *
++ * Caller should acquire connect_lock before invoking this function.
+ */
+-static inline int usb_gadget_udc_start(struct usb_udc *udc)
++static inline int usb_gadget_udc_start_locked(struct usb_udc *udc)
++ __must_hold(&udc->connect_lock)
+ {
+ int ret;
+
+@@ -1146,7 +1189,7 @@ static inline int usb_gadget_udc_start(s
+ }
+
+ /**
+- * usb_gadget_udc_stop - tells usb device controller we don't need it anymore
++ * usb_gadget_udc_stop_locked - tells usb device controller we don't need it anymore
+ * @udc: The UDC to be stopped
+ *
+ * This call is issued by the UDC Class driver after calling
+@@ -1155,8 +1198,11 @@ static inline int usb_gadget_udc_start(s
+ * The details are implementation specific, but it can go as
+ * far as powering off UDC completely and disable its data
+ * line pullups.
++ *
++ * Caller should acquire connect lock before invoking this function.
+ */
+-static inline void usb_gadget_udc_stop(struct usb_udc *udc)
++static inline void usb_gadget_udc_stop_locked(struct usb_udc *udc)
++ __must_hold(&udc->connect_lock)
+ {
+ if (!udc->started) {
+ dev_err(&udc->dev, "UDC had already stopped\n");
+@@ -1315,6 +1361,7 @@ int usb_add_gadget(struct usb_gadget *ga
+
+ udc->gadget = gadget;
+ gadget->udc = udc;
++ mutex_init(&udc->connect_lock);
+
+ udc->started = false;
+
+@@ -1518,12 +1565,16 @@ static int gadget_bind_driver(struct dev
+ if (ret)
+ goto err_bind;
+
+- ret = usb_gadget_udc_start(udc);
+- if (ret)
++ mutex_lock(&udc->connect_lock);
++ ret = usb_gadget_udc_start_locked(udc);
++ if (ret) {
++ mutex_unlock(&udc->connect_lock);
+ goto err_start;
++ }
+ usb_gadget_enable_async_callbacks(udc);
+ udc->allow_connect = true;
+- usb_udc_connect_control(udc);
++ usb_udc_connect_control_locked(udc);
++ mutex_unlock(&udc->connect_lock);
+
+ kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
+ return 0;
+@@ -1556,12 +1607,14 @@ static void gadget_unbind_driver(struct
+
+ udc->allow_connect = false;
+ cancel_work_sync(&udc->vbus_work);
+- usb_gadget_disconnect(gadget);
++ mutex_lock(&udc->connect_lock);
++ usb_gadget_disconnect_locked(gadget);
+ usb_gadget_disable_async_callbacks(udc);
+ if (gadget->irq)
+ synchronize_irq(gadget->irq);
+ udc->driver->unbind(gadget);
+- usb_gadget_udc_stop(udc);
++ usb_gadget_udc_stop_locked(udc);
++ mutex_unlock(&udc->connect_lock);
+
+ mutex_lock(&udc_lock);
+ driver->is_bound = false;
+@@ -1647,11 +1700,15 @@ static ssize_t soft_connect_store(struct
+ }
+
+ if (sysfs_streq(buf, "connect")) {
+- usb_gadget_udc_start(udc);
+- usb_gadget_connect(udc->gadget);
++ mutex_lock(&udc->connect_lock);
++ usb_gadget_udc_start_locked(udc);
++ usb_gadget_connect_locked(udc->gadget);
++ mutex_unlock(&udc->connect_lock);
+ } else if (sysfs_streq(buf, "disconnect")) {
+- usb_gadget_disconnect(udc->gadget);
+- usb_gadget_udc_stop(udc);
++ mutex_lock(&udc->connect_lock);
++ usb_gadget_disconnect_locked(udc->gadget);
++ usb_gadget_udc_stop_locked(udc);
++ mutex_unlock(&udc->connect_lock);
+ } else {
+ dev_err(dev, "unsupported command '%s'\n", buf);
+ ret = -EINVAL;
--- /dev/null
+From 3e6ac852fbc71a234de24b5455086f6b98d3d958 Mon Sep 17 00:00:00 2001
+From: Biju Das <biju.das.jz@bp.renesas.com>
+Date: Tue, 30 May 2023 17:17:20 +0100
+Subject: usb: gadget: udc: renesas_usb3: Fix RZ/V2M {modprobe,bind} error
+
+From: Biju Das <biju.das.jz@bp.renesas.com>
+
+commit 3e6ac852fbc71a234de24b5455086f6b98d3d958 upstream.
+
+Currently {modprobe, bind} after {rmmod, unbind} results in probe failure.
+
+genirq: Flags mismatch irq 22. 00000004 (85070400.usb3drd) vs. 00000004 (85070400.usb3drd)
+renesas_usb3: probe of 85070000.usb3peri failed with error -16
+
+The reason is, it is trying to register an interrupt handler for the same
+IRQ twice. The devm_request_irq() was called with the parent device.
+So the interrupt handler won't be unregistered when the usb3-peri device
+is unbound.
+
+Fix this issue by replacing "parent dev"->"dev" as the irq resource
+is managed by this driver.
+
+Fixes: 9cad72dfc556 ("usb: gadget: Add support for RZ/V2M USB3DRD driver")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Message-ID: <20230530161720.179927-1-biju.das.jz@bp.renesas.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/udc/renesas_usb3.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/gadget/udc/renesas_usb3.c
++++ b/drivers/usb/gadget/udc/renesas_usb3.c
+@@ -2898,9 +2898,9 @@ static int renesas_usb3_probe(struct pla
+ struct rzv2m_usb3drd *ddata = dev_get_drvdata(pdev->dev.parent);
+
+ usb3->drd_reg = ddata->reg;
+- ret = devm_request_irq(ddata->dev, ddata->drd_irq,
++ ret = devm_request_irq(&pdev->dev, ddata->drd_irq,
+ renesas_usb3_otg_irq, 0,
+- dev_name(ddata->dev), usb3);
++ dev_name(&pdev->dev), usb3);
+ if (ret < 0)
+ return ret;
+ }
--- /dev/null
+From f1832e2b5e498e258b090af3b065b85cf8cc5161 Mon Sep 17 00:00:00 2001
+From: Jerry Meng <jerry-meng@foxmail.com>
+Date: Wed, 31 May 2023 11:51:16 +0800
+Subject: USB: serial: option: add Quectel EM061KGL series
+
+From: Jerry Meng <jerry-meng@foxmail.com>
+
+commit f1832e2b5e498e258b090af3b065b85cf8cc5161 upstream.
+
+Add support for Quectel EM061KGL series which are based on Qualcomm
+SDX12 chip:
+
+EM061KGL_LTA(0x2c7c / 0x0123): MBIM + GNSS + DIAG + NMEA + AT + QDSS + DPL
+EM061KGL_LMS(0x2c7c / 0x0124): MBIM + GNSS + DIAG + NMEA + AT + QDSS + DPL
+EM061KGL_LWW(0x2c7c / 0x6008): MBIM + GNSS + DIAG + NMEA + AT + QDSS + DPL
+EM061KGL_LCN(0x2c7c / 0x6009): MBIM + GNSS + DIAG + NMEA + AT + QDSS + DPL
+
+Above products use the exact same interface layout and
+option driver is for interfaces DIAG, NMEA and AT.
+
+T: Bus=03 Lev=01 Prnt=01 Port=01 Cnt=02 Dev#= 5 Spd=480 MxCh= 0
+D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
+P: Vendor=2c7c ProdID=6008 Rev= 5.04
+S: Manufacturer=Quectel
+S: Product=Quectel EM061K-GL
+S: SerialNumber=f6fa08b6
+C:* #Ifs= 8 Cfg#= 1 Atr=a0 MxPwr=500mA
+A: FirstIf#= 0 IfCount= 2 Cls=02(comm.) Sub=0e Prot=00
+I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=0e Prot=00 Driver=cdc_mbim
+E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=32ms
+I: If#= 1 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim
+I:* If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim
+E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=0f(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I:* If#= 2 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
+E: Ad=82(I) Atr=03(Int.) MxPS= 64 Ivl=32ms
+I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option
+E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=40 Driver=option
+E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
+E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I:* If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
+E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
+E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I:* If#= 6 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=70 Driver=(none)
+E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I:* If#= 7 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none)
+E: Ad=8f(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+
+Signed-off-by: Jerry Meng <jerry-meng@foxmail.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/serial/option.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -248,6 +248,8 @@ static void option_instat_callback(struc
+ #define QUECTEL_VENDOR_ID 0x2c7c
+ /* These Quectel products use Quectel's vendor ID */
+ #define QUECTEL_PRODUCT_EC21 0x0121
++#define QUECTEL_PRODUCT_EM061K_LTA 0x0123
++#define QUECTEL_PRODUCT_EM061K_LMS 0x0124
+ #define QUECTEL_PRODUCT_EC25 0x0125
+ #define QUECTEL_PRODUCT_EG91 0x0191
+ #define QUECTEL_PRODUCT_EG95 0x0195
+@@ -266,6 +268,8 @@ static void option_instat_callback(struc
+ #define QUECTEL_PRODUCT_RM520N 0x0801
+ #define QUECTEL_PRODUCT_EC200U 0x0901
+ #define QUECTEL_PRODUCT_EC200S_CN 0x6002
++#define QUECTEL_PRODUCT_EM061K_LWW 0x6008
++#define QUECTEL_PRODUCT_EM061K_LCN 0x6009
+ #define QUECTEL_PRODUCT_EC200T 0x6026
+ #define QUECTEL_PRODUCT_RM500K 0x7001
+
+@@ -1189,6 +1193,18 @@ static const struct usb_device_id option
+ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0x00, 0x40) },
+ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x30) },
+ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x40) },
++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0xff, 0x30) },
++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0x00, 0x40) },
++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0xff, 0x40) },
++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LMS, 0xff, 0xff, 0x30) },
++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LMS, 0xff, 0x00, 0x40) },
++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LMS, 0xff, 0xff, 0x40) },
++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LTA, 0xff, 0xff, 0x30) },
++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LTA, 0xff, 0x00, 0x40) },
++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LTA, 0xff, 0xff, 0x40) },
++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LWW, 0xff, 0xff, 0x30) },
++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LWW, 0xff, 0x00, 0x40) },
++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LWW, 0xff, 0xff, 0x40) },
+ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0xff, 0xff),
+ .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 },
+ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0, 0) },
--- /dev/null
+From 92c9c3baad6b1fd584fbabeaa4756f9b77926cb5 Mon Sep 17 00:00:00 2001
+From: Pavan Holla <pholla@chromium.org>
+Date: Wed, 7 Jun 2023 19:33:26 +0000
+Subject: usb: typec: Fix fast_role_swap_current show function
+
+From: Pavan Holla <pholla@chromium.org>
+
+commit 92c9c3baad6b1fd584fbabeaa4756f9b77926cb5 upstream.
+
+The current implementation mistakenly performs a & operation on
+the output of sysfs_emit. This patch performs the & operation before
+calling sysfs_emit.
+
+Fixes: 662a60102c12 ("usb: typec: Separate USB Power Delivery from USB Type-C")
+Cc: stable <stable@kernel.org>
+Reported-by: Benson Leung <bleung@chromium.org>
+Signed-off-by: Pavan Holla <pholla@chromium.org>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Reviewed-by: Benson Leung <bleung@chromium.org>
+Message-ID: <20230607193328.3359487-1-pholla@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/pd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/typec/pd.c
++++ b/drivers/usb/typec/pd.c
+@@ -96,7 +96,7 @@ peak_current_show(struct device *dev, st
+ static ssize_t
+ fast_role_swap_current_show(struct device *dev, struct device_attribute *attr, char *buf)
+ {
+- return sysfs_emit(buf, "%u\n", to_pdo(dev)->pdo >> PDO_FIXED_FRS_CURR_SHIFT) & 3;
++ return sysfs_emit(buf, "%u\n", (to_pdo(dev)->pdo >> PDO_FIXED_FRS_CURR_SHIFT) & 3);
+ }
+ static DEVICE_ATTR_RO(fast_role_swap_current);
+
--- /dev/null
+From c4a8bfabefed706bb9150867db528ceefd5cb5fe Mon Sep 17 00:00:00 2001
+From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Date: Tue, 6 Jun 2023 14:58:02 +0300
+Subject: usb: typec: ucsi: Fix command cancellation
+
+From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+
+commit c4a8bfabefed706bb9150867db528ceefd5cb5fe upstream.
+
+The Cancel command was passed to the write callback as the
+offset instead of as the actual command which caused NULL
+pointer dereference.
+
+Reported-by: Stephan Bolten <stephan.bolten@gmx.net>
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217517
+Fixes: 094902bc6a3c ("usb: typec: ucsi: Always cancel the command if PPM reports BUSY condition")
+Cc: stable@vger.kernel.org
+Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Message-ID: <20230606115802.79339-1-heikki.krogerus@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/ucsi/ucsi.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/typec/ucsi/ucsi.c
++++ b/drivers/usb/typec/ucsi/ucsi.c
+@@ -132,10 +132,8 @@ static int ucsi_exec_command(struct ucsi
+ if (ret)
+ return ret;
+
+- if (cci & UCSI_CCI_BUSY) {
+- ucsi->ops->async_write(ucsi, UCSI_CANCEL, NULL, 0);
+- return -EBUSY;
+- }
++ if (cmd != UCSI_CANCEL && cci & UCSI_CCI_BUSY)
++ return ucsi_exec_command(ucsi, UCSI_CANCEL);
+
+ if (!(cci & UCSI_CCI_COMMAND_COMPLETE))
+ return -EIO;
+@@ -149,6 +147,11 @@ static int ucsi_exec_command(struct ucsi
+ return ucsi_read_error(ucsi);
+ }
+
++ if (cmd == UCSI_CANCEL && cci & UCSI_CCI_CANCEL_COMPLETE) {
++ ret = ucsi_acknowledge_command(ucsi);
++ return ret ? ret : -EBUSY;
++ }
++
+ return UCSI_CCI_LENGTH(cci);
+ }
+