hwmon-it87-fix-voltage-scaling-for-chips-with-10.9mv.patch
scsi-qla2xxx-synchronize-the-iocb-count-to-be-in-order.patch
scsi-qla2xxx-perform-lockless-command-completion-in-abort-path.patch
+smb3-lower-default-deferred-close-timeout-to-address-perf-regression.patch
+smb3-fix-unusable-share-after-force-unmount-failure.patch
+uas-add-us_fl_no_report_opcodes-for-jmicron-jms583gen-2.patch
+thunderbolt-use-scale-field-when-allocating-usb3-bandwidth.patch
+thunderbolt-call-tb_check_quirks-after-initializing-adapters.patch
+thunderbolt-add-quirk-to-disable-clx.patch
+thunderbolt-fix-memory-leak-in-margining.patch
+thunderbolt-disable-interrupt-auto-clear-for-rings.patch
+thunderbolt-add-missing-unset_inbound_sbtx-for-retimer-access.patch
+thunderbolt-use-const-qualifier-for-ring_interrupt_index.patch
+thunderbolt-rename-shadowed-variables-bit-to-interrupt_bit-and-auto_clear_bit.patch
--- /dev/null
+From 491eafce1a51c457701351a4bf40733799745314 Mon Sep 17 00:00:00 2001
+From: Steve French <stfrench@microsoft.com>
+Date: Thu, 23 Mar 2023 16:20:02 -0500
+Subject: smb3: fix unusable share after force unmount failure
+
+From: Steve French <stfrench@microsoft.com>
+
+commit 491eafce1a51c457701351a4bf40733799745314 upstream.
+
+If user does forced unmount ("umount -f") while files are still open
+on the share (as was seen in a Kubernetes example running on SMB3.1.1
+mount) then we were marking the share as "TID_EXITING" in umount_begin()
+which caused all subsequent operations (except write) to fail ... but
+unfortunately when umount_begin() is called we do not know yet that
+there are open files or active references on the share that would prevent
+unmount from succeeding. Kubernetes had example when they were doing
+umount -f when files were open which caused the share to become
+unusable until the files were closed (and the umount retried).
+
+Fix this so that TID_EXITING is not set until we are about to send
+the tree disconnect (not at the beginning of forced umounts in
+umount_begin) so that if "umount -f" fails (due to open files or
+references) the mount is still usable.
+
+Cc: stable@vger.kernel.org
+Reviewed-by: Shyam Prasad N <sprasad@microsoft.com>
+Reviewed-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/cifsfs.c | 9 ++++++---
+ fs/cifs/cifssmb.c | 6 ++----
+ fs/cifs/connect.c | 1 +
+ fs/cifs/smb2pdu.c | 8 ++------
+ 4 files changed, 11 insertions(+), 13 deletions(-)
+
+--- a/fs/cifs/cifsfs.c
++++ b/fs/cifs/cifsfs.c
+@@ -730,13 +730,16 @@ static void cifs_umount_begin(struct sup
+ spin_lock(&tcon->tc_lock);
+ if ((tcon->tc_count > 1) || (tcon->status == TID_EXITING)) {
+ /* we have other mounts to same share or we have
+- already tried to force umount this and woken up
++ already tried to umount this and woken up
+ all waiting network requests, nothing to do */
+ spin_unlock(&tcon->tc_lock);
+ spin_unlock(&cifs_tcp_ses_lock);
+ return;
+- } else if (tcon->tc_count == 1)
+- tcon->status = TID_EXITING;
++ }
++ /*
++ * can not set tcon->status to TID_EXITING yet since we don't know if umount -f will
++ * fail later (e.g. due to open files). TID_EXITING will be set just before tdis req sent
++ */
+ spin_unlock(&tcon->tc_lock);
+ spin_unlock(&cifs_tcp_ses_lock);
+
+--- a/fs/cifs/cifssmb.c
++++ b/fs/cifs/cifssmb.c
+@@ -85,13 +85,11 @@ cifs_reconnect_tcon(struct cifs_tcon *tc
+
+ /*
+ * only tree disconnect, open, and write, (and ulogoff which does not
+- * have tcon) are allowed as we start force umount
++ * have tcon) are allowed as we start umount
+ */
+ spin_lock(&tcon->tc_lock);
+ if (tcon->status == TID_EXITING) {
+- if (smb_command != SMB_COM_WRITE_ANDX &&
+- smb_command != SMB_COM_OPEN_ANDX &&
+- smb_command != SMB_COM_TREE_DISCONNECT) {
++ if (smb_command != SMB_COM_TREE_DISCONNECT) {
+ spin_unlock(&tcon->tc_lock);
+ cifs_dbg(FYI, "can not send cmd %d while umounting\n",
+ smb_command);
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -2363,6 +2363,7 @@ cifs_put_tcon(struct cifs_tcon *tcon)
+ WARN_ON(tcon->tc_count < 0);
+
+ list_del_init(&tcon->tcon_list);
++ tcon->status = TID_EXITING;
+ spin_unlock(&tcon->tc_lock);
+ spin_unlock(&cifs_tcp_ses_lock);
+
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -225,13 +225,9 @@ smb2_reconnect(__le16 smb2_command, stru
+ spin_lock(&tcon->tc_lock);
+ if (tcon->status == TID_EXITING) {
+ /*
+- * only tree disconnect, open, and write,
+- * (and ulogoff which does not have tcon)
+- * are allowed as we start force umount.
++ * only tree disconnect allowed when disconnecting ...
+ */
+- if ((smb2_command != SMB2_WRITE) &&
+- (smb2_command != SMB2_CREATE) &&
+- (smb2_command != SMB2_TREE_DISCONNECT)) {
++ if (smb2_command != SMB2_TREE_DISCONNECT) {
+ spin_unlock(&tcon->tc_lock);
+ cifs_dbg(FYI, "can not send cmd %d while umounting\n",
+ smb2_command);
--- /dev/null
+From 7e0e76d99079be13c9961dde7c93b2d1ee665af4 Mon Sep 17 00:00:00 2001
+From: Steve French <stfrench@microsoft.com>
+Date: Thu, 23 Mar 2023 15:10:26 -0500
+Subject: smb3: lower default deferred close timeout to address perf regression
+
+From: Steve French <stfrench@microsoft.com>
+
+commit 7e0e76d99079be13c9961dde7c93b2d1ee665af4 upstream.
+
+Performance tests with large number of threads noted that the change
+of the default closetimeo (deferred close timeout between when
+close is done by application and when client has to send the close
+to the server), to 5 seconds from 1 second, significantly degraded
+perf in some cases like this (in the filebench example reported,
+the stats show close requests on the wire taking twice as long,
+and 50% regression in filebench perf). This is stil configurable
+via mount parm closetimeo, but to be safe, decrease default back
+to its previous value of 1 second.
+
+Reported-by: Yin Fengwei <fengwei.yin@intel.com>
+Reported-by: kernel test robot <yujie.liu@intel.com>
+Link: https://lore.kernel.org/lkml/997614df-10d4-af53-9571-edec36b0e2f3@intel.com/
+Fixes: 5efdd9122eff ("smb3: allow deferred close timeout to be configurable")
+Cc: stable@vger.kernel.org # 6.0+
+Tested-by: Yin Fengwei <fengwei.yin@intel.com>
+Reviewed-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
+Reviewed-by: Shyam Prasad N <sprasad@microsoft.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/fs_context.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/cifs/fs_context.h
++++ b/fs/cifs/fs_context.h
+@@ -286,5 +286,5 @@ extern void smb3_update_mnt_flags(struct
+ * max deferred close timeout (jiffies) - 2^30
+ */
+ #define SMB3_MAX_DCLOSETIMEO (1 << 30)
+-#define SMB3_DEF_DCLOSETIMEO (5 * HZ) /* Can increase later, other clients use larger */
++#define SMB3_DEF_DCLOSETIMEO (1 * HZ) /* even 1 sec enough to help eg open/write/close/open/read */
+ #endif
--- /dev/null
+From cd0c1e582b055dea615001b8bd8eccaf6f69f7ce Mon Sep 17 00:00:00 2001
+From: Gil Fine <gil.fine@linux.intel.com>
+Date: Fri, 3 Mar 2023 00:17:24 +0200
+Subject: thunderbolt: Add missing UNSET_INBOUND_SBTX for retimer access
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Gil Fine <gil.fine@linux.intel.com>
+
+commit cd0c1e582b055dea615001b8bd8eccaf6f69f7ce upstream.
+
+According to USB4 retimer specification, the process of firmware update
+sequence requires issuing a SET_INBOUND_SBTX port operation that later
+shall be followed by UNSET_INBOUND_SBTX port operation. This last step
+is not currently issued by the driver but it is necessary to make sure
+the retimers are put back to passthrough mode even during enumeration.
+
+If this step is missing the link may not come up properly after
+soft-reboot for example.
+
+For this reason issue UNSET_INBOUND_SBTX after SET_INBOUND_SBTX for
+enumeration and also when the NVM upgrade is run.
+
+Reported-by: Christian Schaubschläger <christian.schaubschlaeger@gmx.at>
+Link: https://lore.kernel.org/linux-usb/b556f5ed-5ee8-9990-9910-afd60db93310@gmx.at/
+Cc: stable@vger.kernel.org
+Signed-off-by: Gil Fine <gil.fine@linux.intel.com>
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/thunderbolt/retimer.c | 23 +++++++++++++++++++++--
+ drivers/thunderbolt/sb_regs.h | 1 +
+ drivers/thunderbolt/tb.h | 1 +
+ drivers/thunderbolt/usb4.c | 14 ++++++++++++++
+ 4 files changed, 37 insertions(+), 2 deletions(-)
+
+--- a/drivers/thunderbolt/retimer.c
++++ b/drivers/thunderbolt/retimer.c
+@@ -187,6 +187,22 @@ static ssize_t nvm_authenticate_show(str
+ return ret;
+ }
+
++static void tb_retimer_set_inbound_sbtx(struct tb_port *port)
++{
++ int i;
++
++ for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++)
++ usb4_port_retimer_set_inbound_sbtx(port, i);
++}
++
++static void tb_retimer_unset_inbound_sbtx(struct tb_port *port)
++{
++ int i;
++
++ for (i = TB_MAX_RETIMER_INDEX; i >= 1; i--)
++ usb4_port_retimer_unset_inbound_sbtx(port, i);
++}
++
+ static ssize_t nvm_authenticate_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+ {
+@@ -213,6 +229,7 @@ static ssize_t nvm_authenticate_store(st
+ rt->auth_status = 0;
+
+ if (val) {
++ tb_retimer_set_inbound_sbtx(rt->port);
+ if (val == AUTHENTICATE_ONLY) {
+ ret = tb_retimer_nvm_authenticate(rt, true);
+ } else {
+@@ -232,6 +249,7 @@ static ssize_t nvm_authenticate_store(st
+ }
+
+ exit_unlock:
++ tb_retimer_unset_inbound_sbtx(rt->port);
+ mutex_unlock(&rt->tb->lock);
+ exit_rpm:
+ pm_runtime_mark_last_busy(&rt->dev);
+@@ -440,8 +458,7 @@ int tb_retimer_scan(struct tb_port *port
+ * Enable sideband channel for each retimer. We can do this
+ * regardless whether there is device connected or not.
+ */
+- for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++)
+- usb4_port_retimer_set_inbound_sbtx(port, i);
++ tb_retimer_set_inbound_sbtx(port);
+
+ /*
+ * Before doing anything else, read the authentication status.
+@@ -464,6 +481,8 @@ int tb_retimer_scan(struct tb_port *port
+ break;
+ }
+
++ tb_retimer_unset_inbound_sbtx(port);
++
+ if (!last_idx)
+ return 0;
+
+--- a/drivers/thunderbolt/sb_regs.h
++++ b/drivers/thunderbolt/sb_regs.h
+@@ -20,6 +20,7 @@ enum usb4_sb_opcode {
+ USB4_SB_OPCODE_ROUTER_OFFLINE = 0x4e45534c, /* "LSEN" */
+ USB4_SB_OPCODE_ENUMERATE_RETIMERS = 0x4d554e45, /* "ENUM" */
+ USB4_SB_OPCODE_SET_INBOUND_SBTX = 0x5055534c, /* "LSUP" */
++ USB4_SB_OPCODE_UNSET_INBOUND_SBTX = 0x50555355, /* "USUP" */
+ USB4_SB_OPCODE_QUERY_LAST_RETIMER = 0x5453414c, /* "LAST" */
+ USB4_SB_OPCODE_GET_NVM_SECTOR_SIZE = 0x53534e47, /* "GNSS" */
+ USB4_SB_OPCODE_NVM_SET_OFFSET = 0x53504f42, /* "BOPS" */
+--- a/drivers/thunderbolt/tb.h
++++ b/drivers/thunderbolt/tb.h
+@@ -1220,6 +1220,7 @@ int usb4_port_sw_margin(struct tb_port *
+ int usb4_port_sw_margin_errors(struct tb_port *port, u32 *errors);
+
+ int usb4_port_retimer_set_inbound_sbtx(struct tb_port *port, u8 index);
++int usb4_port_retimer_unset_inbound_sbtx(struct tb_port *port, u8 index);
+ int usb4_port_retimer_read(struct tb_port *port, u8 index, u8 reg, void *buf,
+ u8 size);
+ int usb4_port_retimer_write(struct tb_port *port, u8 index, u8 reg,
+--- a/drivers/thunderbolt/usb4.c
++++ b/drivers/thunderbolt/usb4.c
+@@ -1579,6 +1579,20 @@ int usb4_port_retimer_set_inbound_sbtx(s
+ }
+
+ /**
++ * usb4_port_retimer_unset_inbound_sbtx() - Disable sideband channel transactions
++ * @port: USB4 port
++ * @index: Retimer index
++ *
++ * Disables sideband channel transations on SBTX. The reverse of
++ * usb4_port_retimer_set_inbound_sbtx().
++ */
++int usb4_port_retimer_unset_inbound_sbtx(struct tb_port *port, u8 index)
++{
++ return usb4_port_retimer_op(port, index,
++ USB4_SB_OPCODE_UNSET_INBOUND_SBTX, 500);
++}
++
++/**
+ * usb4_port_retimer_read() - Read from retimer sideband registers
+ * @port: USB4 port
+ * @index: Retimer index
--- /dev/null
+From 7af9da8ce8f9a16221ecd8ba4280582f5bd452fc Mon Sep 17 00:00:00 2001
+From: Sanjay R Mehta <sanju.mehta@amd.com>
+Date: Tue, 14 Feb 2023 13:13:50 -0600
+Subject: thunderbolt: Add quirk to disable CLx
+
+From: Sanjay R Mehta <sanju.mehta@amd.com>
+
+commit 7af9da8ce8f9a16221ecd8ba4280582f5bd452fc upstream.
+
+Add QUIRK_NO_CLX to disable the CLx state for hardware which
+doesn't supports it.
+
+AMD Yellow Carp and Pink Sardine don't support CLx state,
+hence disabling it using QUIRK_NO_CLX.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Sanjay R Mehta <sanju.mehta@amd.com>
+Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+[mw: added debug log when the quirk is run]
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/thunderbolt/quirks.c | 13 +++++++++++++
+ drivers/thunderbolt/tb.h | 11 ++++++++---
+ 2 files changed, 21 insertions(+), 3 deletions(-)
+
+--- a/drivers/thunderbolt/quirks.c
++++ b/drivers/thunderbolt/quirks.c
+@@ -20,6 +20,12 @@ static void quirk_dp_credit_allocation(s
+ }
+ }
+
++static void quirk_clx_disable(struct tb_switch *sw)
++{
++ sw->quirks |= QUIRK_NO_CLX;
++ tb_sw_dbg(sw, "disabling CL states\n");
++}
++
+ struct tb_quirk {
+ u16 hw_vendor_id;
+ u16 hw_device_id;
+@@ -37,6 +43,13 @@ static const struct tb_quirk tb_quirks[]
+ * DP buffers.
+ */
+ { 0x8087, 0x0b26, 0x0000, 0x0000, quirk_dp_credit_allocation },
++ /*
++ * CLx is not supported on AMD USB4 Yellow Carp and Pink Sardine platforms.
++ */
++ { 0x0438, 0x0208, 0x0000, 0x0000, quirk_clx_disable },
++ { 0x0438, 0x0209, 0x0000, 0x0000, quirk_clx_disable },
++ { 0x0438, 0x020a, 0x0000, 0x0000, quirk_clx_disable },
++ { 0x0438, 0x020b, 0x0000, 0x0000, quirk_clx_disable },
+ };
+
+ /**
+--- a/drivers/thunderbolt/tb.h
++++ b/drivers/thunderbolt/tb.h
+@@ -23,6 +23,11 @@
+ #define NVM_MAX_SIZE SZ_512K
+ #define NVM_DATA_DWORDS 16
+
++/* Keep link controller awake during update */
++#define QUIRK_FORCE_POWER_LINK_CONTROLLER BIT(0)
++/* Disable CLx if not supported */
++#define QUIRK_NO_CLX BIT(1)
++
+ /**
+ * struct tb_nvm - Structure holding NVM information
+ * @dev: Owner of the NVM
+@@ -997,6 +1002,9 @@ static inline bool tb_switch_is_clx_enab
+ */
+ static inline bool tb_switch_is_clx_supported(const struct tb_switch *sw)
+ {
++ if (sw->quirks & QUIRK_NO_CLX)
++ return false;
++
+ return tb_switch_is_usb4(sw) || tb_switch_is_titan_ridge(sw);
+ }
+
+@@ -1254,9 +1262,6 @@ struct usb4_port *usb4_port_device_add(s
+ void usb4_port_device_remove(struct usb4_port *usb4);
+ int usb4_port_device_resume(struct usb4_port *usb4);
+
+-/* Keep link controller awake during update */
+-#define QUIRK_FORCE_POWER_LINK_CONTROLLER BIT(0)
+-
+ void tb_check_quirks(struct tb_switch *sw);
+
+ #ifdef CONFIG_ACPI
--- /dev/null
+From d2d6ddf188f609861489d5d188d545856a3ed399 Mon Sep 17 00:00:00 2001
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+Date: Fri, 3 Feb 2023 15:55:41 +0200
+Subject: thunderbolt: Call tb_check_quirks() after initializing adapters
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+commit d2d6ddf188f609861489d5d188d545856a3ed399 upstream.
+
+In order to apply quirks based on certain adapter types move call to
+tb_check_quirks() happen after the adapters are initialized. This should
+not affect the existing quirks.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/thunderbolt/switch.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/thunderbolt/switch.c
++++ b/drivers/thunderbolt/switch.c
+@@ -2960,8 +2960,6 @@ int tb_switch_add(struct tb_switch *sw)
+ dev_warn(&sw->dev, "reading DROM failed: %d\n", ret);
+ tb_sw_dbg(sw, "uid: %#llx\n", sw->uid);
+
+- tb_check_quirks(sw);
+-
+ ret = tb_switch_set_uuid(sw);
+ if (ret) {
+ dev_err(&sw->dev, "failed to set UUID\n");
+@@ -2980,6 +2978,8 @@ int tb_switch_add(struct tb_switch *sw)
+ }
+ }
+
++ tb_check_quirks(sw);
++
+ tb_switch_default_link_ports(sw);
+
+ ret = tb_switch_update_link_attributes(sw);
--- /dev/null
+From 468c49f44759720a312e52d44a71c3949ed63d7c Mon Sep 17 00:00:00 2001
+From: Mario Limonciello <mario.limonciello@amd.com>
+Date: Fri, 10 Mar 2023 11:20:50 -0600
+Subject: thunderbolt: Disable interrupt auto clear for rings
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+commit 468c49f44759720a312e52d44a71c3949ed63d7c upstream.
+
+When interrupt auto clear is programmed, any read to the interrupt
+status register will clear all interrupts. If two interrupts have
+come in before one can be serviced then this will cause lost interrupts.
+
+On AMD USB4 routers this has manifested in odd problems particularly
+with long strings of control tranfers such as reading the DROM via bit
+banging.
+
+Instead of clearing interrupts automatically, clear the bit corresponding
+to the given ring's interrupt in the ISR.
+
+Fixes: 7a1808f82a37 ("thunderbolt: Handle ring interrupt by reading interrupt status register")
+Cc: Sanju Mehta <Sanju.Mehta@amd.com>
+Cc: stable@vger.kernel.org
+Tested-by: Anson Tsao <anson.tsao@amd.com>
+Signed-off-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 | 40 +++++++++++++++++++++++++---------------
+ drivers/thunderbolt/nhi_regs.h | 6 ++++--
+ 2 files changed, 29 insertions(+), 17 deletions(-)
+
+--- a/drivers/thunderbolt/nhi.c
++++ b/drivers/thunderbolt/nhi.c
+@@ -71,24 +71,31 @@ static void ring_interrupt_active(struct
+ u32 step, shift, ivr, misc;
+ void __iomem *ivr_base;
+ int index;
++ int bit;
+
+ if (ring->is_tx)
+ index = ring->hop;
+ else
+ index = ring->hop + ring->nhi->hop_count;
+
+- if (ring->nhi->quirks & QUIRK_AUTO_CLEAR_INT) {
+- /*
+- * Ask the hardware to clear interrupt status
+- * bits automatically since we already know
+- * which interrupt was triggered.
+- */
+- misc = ioread32(ring->nhi->iobase + REG_DMA_MISC);
+- if (!(misc & REG_DMA_MISC_INT_AUTO_CLEAR)) {
+- misc |= REG_DMA_MISC_INT_AUTO_CLEAR;
+- iowrite32(misc, ring->nhi->iobase + REG_DMA_MISC);
+- }
+- }
++ /*
++ * Intel routers support a bit that isn't part of
++ * the USB4 spec to ask the hardware to clear
++ * interrupt status bits automatically since
++ * we already know which interrupt was triggered.
++ *
++ * Other routers explicitly disable auto-clear
++ * to prevent conditions that may occur where two
++ * MSIX interrupts are simultaneously active and
++ * reading the register clears both of them.
++ */
++ misc = ioread32(ring->nhi->iobase + REG_DMA_MISC);
++ if (ring->nhi->quirks & QUIRK_AUTO_CLEAR_INT)
++ bit = REG_DMA_MISC_INT_AUTO_CLEAR;
++ else
++ bit = REG_DMA_MISC_DISABLE_AUTO_CLEAR;
++ if (!(misc & bit))
++ iowrite32(misc | bit, ring->nhi->iobase + REG_DMA_MISC);
+
+ ivr_base = ring->nhi->iobase + REG_INT_VEC_ALLOC_BASE;
+ step = index / REG_INT_VEC_ALLOC_REGS * REG_INT_VEC_ALLOC_BITS;
+@@ -393,14 +400,17 @@ EXPORT_SYMBOL_GPL(tb_ring_poll_complete)
+
+ static void ring_clear_msix(const struct tb_ring *ring)
+ {
++ int bit;
++
+ if (ring->nhi->quirks & QUIRK_AUTO_CLEAR_INT)
+ return;
+
++ bit = ring_interrupt_index(ring) & 31;
+ if (ring->is_tx)
+- ioread32(ring->nhi->iobase + REG_RING_NOTIFY_BASE);
++ iowrite32(BIT(bit), ring->nhi->iobase + REG_RING_INT_CLEAR);
+ else
+- ioread32(ring->nhi->iobase + REG_RING_NOTIFY_BASE +
+- 4 * (ring->nhi->hop_count / 32));
++ iowrite32(BIT(bit), ring->nhi->iobase + REG_RING_INT_CLEAR +
++ 4 * (ring->nhi->hop_count / 32));
+ }
+
+ static irqreturn_t ring_msix(int irq, void *data)
+--- a/drivers/thunderbolt/nhi_regs.h
++++ b/drivers/thunderbolt/nhi_regs.h
+@@ -77,12 +77,13 @@ struct ring_desc {
+
+ /*
+ * three bitfields: tx, rx, rx overflow
+- * Every bitfield contains one bit for every hop (REG_HOP_COUNT). Registers are
+- * cleared on read. New interrupts are fired only after ALL registers have been
++ * Every bitfield contains one bit for every hop (REG_HOP_COUNT).
++ * New interrupts are fired only after ALL registers have been
+ * read (even those containing only disabled rings).
+ */
+ #define REG_RING_NOTIFY_BASE 0x37800
+ #define RING_NOTIFY_REG_COUNT(nhi) ((31 + 3 * nhi->hop_count) / 32)
++#define REG_RING_INT_CLEAR 0x37808
+
+ /*
+ * two bitfields: rx, tx
+@@ -105,6 +106,7 @@ struct ring_desc {
+
+ #define REG_DMA_MISC 0x39864
+ #define REG_DMA_MISC_INT_AUTO_CLEAR BIT(2)
++#define REG_DMA_MISC_DISABLE_AUTO_CLEAR BIT(17)
+
+ #define REG_INMAIL_DATA 0x39900
+
--- /dev/null
+From acec726473822bc6b585961f4ca2a11fa7f28341 Mon Sep 17 00:00:00 2001
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+Date: Fri, 3 Mar 2023 11:25:08 +0200
+Subject: thunderbolt: Fix memory leak in margining
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+commit acec726473822bc6b585961f4ca2a11fa7f28341 upstream.
+
+Memory for the usb4->margining needs to be relased for the upstream port
+of the router as well, even though the debugfs directory gets released
+with the router device removal. Fix this.
+
+Fixes: d0f1e0c2a699 ("thunderbolt: Add support for receiver lane margining")
+Cc: stable@vger.kernel.org
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/thunderbolt/debugfs.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/drivers/thunderbolt/debugfs.c
++++ b/drivers/thunderbolt/debugfs.c
+@@ -942,7 +942,8 @@ static void margining_port_remove(struct
+
+ snprintf(dir_name, sizeof(dir_name), "port%d", port->port);
+ parent = debugfs_lookup(dir_name, port->sw->debugfs_dir);
+- debugfs_remove_recursive(debugfs_lookup("margining", parent));
++ if (parent)
++ debugfs_remove_recursive(debugfs_lookup("margining", parent));
+
+ kfree(port->usb4->margining);
+ port->usb4->margining = NULL;
+@@ -967,19 +968,18 @@ static void margining_switch_init(struct
+
+ static void margining_switch_remove(struct tb_switch *sw)
+ {
++ struct tb_port *upstream, *downstream;
+ struct tb_switch *parent_sw;
+- struct tb_port *downstream;
+ u64 route = tb_route(sw);
+
+ if (!route)
+ return;
+
+- /*
+- * Upstream is removed with the router itself but we need to
+- * remove the downstream port margining directory.
+- */
++ upstream = tb_upstream_port(sw);
+ parent_sw = tb_switch_parent(sw);
+ downstream = tb_port_at(route, parent_sw);
++
++ margining_port_remove(upstream);
+ margining_port_remove(downstream);
+ }
+
--- /dev/null
+From 58cdfe6f58b35f17f56386f5fcf937168a423ad1 Mon Sep 17 00:00:00 2001
+From: Tom Rix <trix@redhat.com>
+Date: Wed, 15 Mar 2023 18:04:50 -0400
+Subject: thunderbolt: Rename shadowed variables bit to interrupt_bit and auto_clear_bit
+
+From: Tom Rix <trix@redhat.com>
+
+commit 58cdfe6f58b35f17f56386f5fcf937168a423ad1 upstream.
+
+cppcheck reports
+drivers/thunderbolt/nhi.c:74:7: style: Local variable 'bit' shadows outer variable [shadowVariable]
+ int bit;
+ ^
+drivers/thunderbolt/nhi.c:66:6: note: Shadowed declaration
+ int bit = ring_interrupt_index(ring) & 31;
+ ^
+drivers/thunderbolt/nhi.c:74:7: note: Shadow variable
+ int bit;
+ ^
+For readablity rename the outer to interrupt_bit and the innner
+to auto_clear_bit.
+
+Fixes: 468c49f44759 ("thunderbolt: Disable interrupt auto clear for ring")
+Cc: stable@vger.kernel.org
+Signed-off-by: Tom Rix <trix@redhat.com>
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/thunderbolt/nhi.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+--- a/drivers/thunderbolt/nhi.c
++++ b/drivers/thunderbolt/nhi.c
+@@ -63,15 +63,15 @@ static void ring_interrupt_active(struct
+ {
+ int reg = REG_RING_INTERRUPT_BASE +
+ ring_interrupt_index(ring) / 32 * 4;
+- int bit = ring_interrupt_index(ring) & 31;
+- int mask = 1 << bit;
++ int interrupt_bit = ring_interrupt_index(ring) & 31;
++ int mask = 1 << interrupt_bit;
+ u32 old, new;
+
+ if (ring->irq > 0) {
+ u32 step, shift, ivr, misc;
+ void __iomem *ivr_base;
++ int auto_clear_bit;
+ int index;
+- int bit;
+
+ if (ring->is_tx)
+ index = ring->hop;
+@@ -91,11 +91,12 @@ static void ring_interrupt_active(struct
+ */
+ misc = ioread32(ring->nhi->iobase + REG_DMA_MISC);
+ if (ring->nhi->quirks & QUIRK_AUTO_CLEAR_INT)
+- bit = REG_DMA_MISC_INT_AUTO_CLEAR;
++ auto_clear_bit = REG_DMA_MISC_INT_AUTO_CLEAR;
+ else
+- bit = REG_DMA_MISC_DISABLE_AUTO_CLEAR;
+- if (!(misc & bit))
+- iowrite32(misc | bit, ring->nhi->iobase + REG_DMA_MISC);
++ auto_clear_bit = REG_DMA_MISC_DISABLE_AUTO_CLEAR;
++ if (!(misc & auto_clear_bit))
++ iowrite32(misc | auto_clear_bit,
++ ring->nhi->iobase + REG_DMA_MISC);
+
+ ivr_base = ring->nhi->iobase + REG_INT_VEC_ALLOC_BASE;
+ step = index / REG_INT_VEC_ALLOC_REGS * REG_INT_VEC_ALLOC_BITS;
+@@ -115,7 +116,7 @@ static void ring_interrupt_active(struct
+
+ dev_dbg(&ring->nhi->pdev->dev,
+ "%s interrupt at register %#x bit %d (%#x -> %#x)\n",
+- active ? "enabling" : "disabling", reg, bit, old, new);
++ active ? "enabling" : "disabling", reg, interrupt_bit, old, new);
+
+ if (new == old)
+ dev_WARN(&ring->nhi->pdev->dev,
--- /dev/null
+From 1716efdb07938bd6510e1127d02012799112c433 Mon Sep 17 00:00:00 2001
+From: Mario Limonciello <mario.limonciello@amd.com>
+Date: Fri, 10 Mar 2023 11:20:49 -0600
+Subject: thunderbolt: Use const qualifier for `ring_interrupt_index`
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+commit 1716efdb07938bd6510e1127d02012799112c433 upstream.
+
+`ring_interrupt_index` doesn't change the data for `ring` so mark it as
+const. This is needed by the following patch that disables interrupt
+auto clear for rings.
+
+Cc: Sanju Mehta <Sanju.Mehta@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-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 | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/thunderbolt/nhi.c
++++ b/drivers/thunderbolt/nhi.c
+@@ -46,7 +46,7 @@
+ #define QUIRK_AUTO_CLEAR_INT BIT(0)
+ #define QUIRK_E2E BIT(1)
+
+-static int ring_interrupt_index(struct tb_ring *ring)
++static int ring_interrupt_index(const struct tb_ring *ring)
+ {
+ int bit = ring->hop;
+ if (!ring->is_tx)
--- /dev/null
+From c82510b1d87bdebfe916048857d2ef46f1778aa5 Mon Sep 17 00:00:00 2001
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+Date: Tue, 27 Dec 2022 11:55:26 +0200
+Subject: thunderbolt: Use scale field when allocating USB3 bandwidth
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+commit c82510b1d87bdebfe916048857d2ef46f1778aa5 upstream.
+
+When tunneling aggregated USB3 (20 Gb/s) the bandwidth values that are
+programmed to the ADP_USB3_CS_2 go higher than 4096 and that does not
+fit anymore to the 12-bit field. Fix this by scaling the value using
+the scale field accordingly.
+
+Fixes: 3b1d8d577ca8 ("thunderbolt: Implement USB3 bandwidth negotiation routines")
+Cc: stable@vger.kernel.org
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/thunderbolt/usb4.c | 22 +++++++++++++++++-----
+ 1 file changed, 17 insertions(+), 5 deletions(-)
+
+--- a/drivers/thunderbolt/usb4.c
++++ b/drivers/thunderbolt/usb4.c
+@@ -2067,18 +2067,30 @@ static int usb4_usb3_port_write_allocate
+ int downstream_bw)
+ {
+ u32 val, ubw, dbw, scale;
+- int ret;
++ int ret, max_bw;
+
+- /* Read the used scale, hardware default is 0 */
+- ret = tb_port_read(port, &scale, TB_CFG_PORT,
+- port->cap_adap + ADP_USB3_CS_3, 1);
++ /* Figure out suitable scale */
++ scale = 0;
++ max_bw = max(upstream_bw, downstream_bw);
++ while (scale < 64) {
++ if (mbps_to_usb3_bw(max_bw, scale) < 4096)
++ break;
++ scale++;
++ }
++
++ if (WARN_ON(scale >= 64))
++ return -EINVAL;
++
++ ret = tb_port_write(port, &scale, TB_CFG_PORT,
++ port->cap_adap + ADP_USB3_CS_3, 1);
+ if (ret)
+ return ret;
+
+- scale &= ADP_USB3_CS_3_SCALE_MASK;
+ ubw = mbps_to_usb3_bw(upstream_bw, scale);
+ dbw = mbps_to_usb3_bw(downstream_bw, scale);
+
++ tb_port_dbg(port, "scaled bandwidth %u/%u, scale %u\n", ubw, dbw, scale);
++
+ ret = tb_port_read(port, &val, TB_CFG_PORT,
+ port->cap_adap + ADP_USB3_CS_2, 1);
+ if (ret)
--- /dev/null
+From a37eb61b6ec064ac794b8a1e89fd33eb582fe51d Mon Sep 17 00:00:00 2001
+From: Yaroslav Furman <yaro330@gmail.com>
+Date: Sun, 12 Mar 2023 11:07:45 +0200
+Subject: uas: Add US_FL_NO_REPORT_OPCODES for JMicron JMS583Gen 2
+
+From: Yaroslav Furman <yaro330@gmail.com>
+
+commit a37eb61b6ec064ac794b8a1e89fd33eb582fe51d upstream.
+
+Just like other JMicron JMS5xx enclosures, it chokes on report-opcodes,
+let's avoid them.
+
+Signed-off-by: Yaroslav Furman <yaro330@gmail.com>
+Cc: stable <stable@kernel.org>
+Link: https://lore.kernel.org/r/20230312090745.47962-1-yaro330@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/storage/unusual_uas.h | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/usb/storage/unusual_uas.h
++++ b/drivers/usb/storage/unusual_uas.h
+@@ -111,6 +111,13 @@ UNUSUAL_DEV(0x152d, 0x0578, 0x0000, 0x99
+ USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+ US_FL_BROKEN_FUA),
+
++/* Reported by: Yaroslav Furman <yaro330@gmail.com> */
++UNUSUAL_DEV(0x152d, 0x0583, 0x0000, 0x9999,
++ "JMicron",
++ "JMS583Gen 2",
++ USB_SC_DEVICE, USB_PR_DEVICE, NULL,
++ US_FL_NO_REPORT_OPCODES),
++
+ /* Reported-by: Thinh Nguyen <thinhn@synopsys.com> */
+ UNUSUAL_DEV(0x154b, 0xf00b, 0x0000, 0x9999,
+ "PNY",