sched-change-nr_uninterruptible-type-to-unsigned-long.patch
clone_private_mnt-make-sure-that-caller-has-cap_sys_admin-in-the-right-userns.patch
btrfs-fix-block-group-refcount-race-in-btrfs_create_pending_block_groups.patch
+usb-hub-fix-detection-of-high-tier-usb3-devices-behind-suspended-hubs.patch
+usb-hub-fix-flushing-and-scheduling-of-delayed-work-that-tunes-runtime-pm.patch
+usb-hub-fix-flushing-of-delayed-work-used-for-post-resume-purposes.patch
+usb-hub-don-t-try-to-recover-devices-lost-during-warm-reset.patch
--- /dev/null
+From 2521106fc732b0b75fd3555c689b1ed1d29d273c Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Mon, 23 Jun 2025 16:39:47 +0300
+Subject: usb: hub: Don't try to recover devices lost during warm reset.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit 2521106fc732b0b75fd3555c689b1ed1d29d273c upstream.
+
+Hub driver warm-resets ports in SS.Inactive or Compliance mode to
+recover a possible connected device. The port reset code correctly
+detects if a connection is lost during reset, but hub driver
+port_event() fails to take this into account in some cases.
+port_event() ends up using stale values and assumes there is a
+connected device, and will try all means to recover it, including
+power-cycling the port.
+
+Details:
+This case was triggered when xHC host was suspended with DbC (Debug
+Capability) enabled and connected. DbC turns one xHC port into a simple
+usb debug device, allowing debugging a system with an A-to-A USB debug
+cable.
+
+xhci DbC code disables DbC when xHC is system suspended to D3, and
+enables it back during resume.
+We essentially end up with two hosts connected to each other during
+suspend, and, for a short while during resume, until DbC is enabled back.
+The suspended xHC host notices some activity on the roothub port, but
+can't train the link due to being suspended, so xHC hardware sets a CAS
+(Cold Attach Status) flag for this port to inform xhci host driver that
+the port needs to be warm reset once xHC resumes.
+
+CAS is xHCI specific, and not part of USB specification, so xhci driver
+tells usb core that the port has a connection and link is in compliance
+mode. Recovery from complinace mode is similar to CAS recovery.
+
+xhci CAS driver support that fakes a compliance mode connection was added
+in commit 8bea2bd37df0 ("usb: Add support for root hub port status CAS")
+
+Once xHCI resumes and DbC is enabled back, all activity on the xHC
+roothub host side port disappears. The hub driver will anyway think
+port has a connection and link is in compliance mode, and hub driver
+will try to recover it.
+
+The port power-cycle during recovery seems to cause issues to the active
+DbC connection.
+
+Fix this by clearing connect_change flag if hub_port_reset() returns
+-ENOTCONN, thus avoiding the whole unnecessary port recovery and
+initialization attempt.
+
+Cc: stable@vger.kernel.org
+Fixes: 8bea2bd37df0 ("usb: Add support for root hub port status CAS")
+Tested-by: Ćukasz Bartosik <ukaszb@chromium.org>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://lore.kernel.org/r/20250623133947.3144608-1-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/core/hub.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -5749,6 +5749,7 @@ static void port_event(struct usb_hub *h
+ struct usb_device *hdev = hub->hdev;
+ u16 portstatus, portchange;
+ int i = 0;
++ int err;
+
+ connect_change = test_bit(port1, hub->change_bits);
+ clear_bit(port1, hub->event_bits);
+@@ -5845,8 +5846,11 @@ static void port_event(struct usb_hub *h
+ } else if (!udev || !(portstatus & USB_PORT_STAT_CONNECTION)
+ || udev->state == USB_STATE_NOTATTACHED) {
+ dev_dbg(&port_dev->dev, "do warm reset, port only\n");
+- if (hub_port_reset(hub, port1, NULL,
+- HUB_BH_RESET_TIME, true) < 0)
++ err = hub_port_reset(hub, port1, NULL,
++ HUB_BH_RESET_TIME, true);
++ if (!udev && err == -ENOTCONN)
++ connect_change = 0;
++ else if (err < 0)
+ hub_port_disable(hub, port1, 1);
+ } else {
+ dev_dbg(&port_dev->dev, "do warm reset, full device\n");
--- /dev/null
+From 8f5b7e2bec1c36578fdaa74a6951833541103e27 Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Wed, 11 Jun 2025 14:24:41 +0300
+Subject: usb: hub: fix detection of high tier USB3 devices behind suspended hubs
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit 8f5b7e2bec1c36578fdaa74a6951833541103e27 upstream.
+
+USB3 devices connected behind several external suspended hubs may not
+be detected when plugged in due to aggressive hub runtime pm suspend.
+
+The hub driver immediately runtime-suspends hubs if there are no
+active children or port activity.
+
+There is a delay between the wake signal causing hub resume, and driver
+visible port activity on the hub downstream facing ports.
+Most of the LFPS handshake, resume signaling and link training done
+on the downstream ports is not visible to the hub driver until completed,
+when device then will appear fully enabled and running on the port.
+
+This delay between wake signal and detectable port change is even more
+significant with chained suspended hubs where the wake signal will
+propagate upstream first. Suspended hubs will only start resuming
+downstream ports after upstream facing port resumes.
+
+The hub driver may resume a USB3 hub, read status of all ports, not
+yet see any activity, and runtime suspend back the hub before any
+port activity is visible.
+
+This exact case was seen when conncting USB3 devices to a suspended
+Thunderbolt dock.
+
+USB3 specification defines a 100ms tU3WakeupRetryDelay, indicating
+USB3 devices expect to be resumed within 100ms after signaling wake.
+if not then device will resend the wake signal.
+
+Give the USB3 hubs twice this time (200ms) to detect any port
+changes after resume, before allowing hub to runtime suspend again.
+
+Cc: stable <stable@kernel.org>
+Fixes: 2839f5bcfcfc ("USB: Turn on auto-suspend for USB 3.0 hubs.")
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20250611112441.2267883-1-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/core/hub.c | 33 ++++++++++++++++++++++++++++++++-
+ 1 file changed, 32 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -67,6 +67,12 @@
+ */
+ #define USB_SHORT_SET_ADDRESS_REQ_TIMEOUT 500 /* ms */
+
++/*
++ * Give SS hubs 200ms time after wake to train downstream links before
++ * assuming no port activity and allowing hub to runtime suspend back.
++ */
++#define USB_SS_PORT_U0_WAKE_TIME 200 /* ms */
++
+ /* Protect struct usb_device->state and ->children members
+ * Note: Both are also protected by ->dev.sem, except that ->state can
+ * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */
+@@ -1067,11 +1073,12 @@ int usb_remove_device(struct usb_device
+
+ enum hub_activation_type {
+ HUB_INIT, HUB_INIT2, HUB_INIT3, /* INITs must come first */
+- HUB_POST_RESET, HUB_RESUME, HUB_RESET_RESUME,
++ HUB_POST_RESET, HUB_RESUME, HUB_RESET_RESUME, HUB_POST_RESUME,
+ };
+
+ static void hub_init_func2(struct work_struct *ws);
+ static void hub_init_func3(struct work_struct *ws);
++static void hub_post_resume(struct work_struct *ws);
+
+ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
+ {
+@@ -1094,6 +1101,13 @@ static void hub_activate(struct usb_hub
+ goto init2;
+ goto init3;
+ }
++
++ if (type == HUB_POST_RESUME) {
++ usb_autopm_put_interface_async(to_usb_interface(hub->intfdev));
++ hub_put(hub);
++ return;
++ }
++
+ hub_get(hub);
+
+ /* The superspeed hub except for root hub has to use Hub Depth
+@@ -1342,6 +1356,16 @@ static void hub_activate(struct usb_hub
+ device_unlock(&hdev->dev);
+ }
+
++ if (type == HUB_RESUME && hub_is_superspeed(hub->hdev)) {
++ /* give usb3 downstream links training time after hub resume */
++ INIT_DELAYED_WORK(&hub->init_work, hub_post_resume);
++ queue_delayed_work(system_power_efficient_wq, &hub->init_work,
++ msecs_to_jiffies(USB_SS_PORT_U0_WAKE_TIME));
++ usb_autopm_get_interface_no_resume(
++ to_usb_interface(hub->intfdev));
++ return;
++ }
++
+ hub_put(hub);
+ }
+
+@@ -1360,6 +1384,13 @@ static void hub_init_func3(struct work_s
+ hub_activate(hub, HUB_INIT3);
+ }
+
++static void hub_post_resume(struct work_struct *ws)
++{
++ struct usb_hub *hub = container_of(ws, struct usb_hub, init_work.work);
++
++ hub_activate(hub, HUB_POST_RESUME);
++}
++
+ enum hub_quiescing_type {
+ HUB_DISCONNECT, HUB_PRE_RESET, HUB_SUSPEND
+ };
--- /dev/null
+From a49e1e2e785fb3621f2d748581881b23a364998a Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Thu, 26 Jun 2025 16:01:02 +0300
+Subject: usb: hub: Fix flushing and scheduling of delayed work that tunes runtime pm
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit a49e1e2e785fb3621f2d748581881b23a364998a upstream.
+
+Delayed work to prevent USB3 hubs from runtime-suspending immediately
+after resume was added in commit 8f5b7e2bec1c ("usb: hub: fix detection
+of high tier USB3 devices behind suspended hubs").
+
+This delayed work needs be flushed if system suspends, or hub needs to
+be quiesced for other reasons right after resume. Not flushing it
+triggered issues on QC SC8280XP CRD board during suspend/resume testing.
+
+Fix it by flushing the delayed resume work in hub_quiesce()
+
+The delayed work item that allow hub runtime suspend is also scheduled
+just before calling autopm get. Alan pointed out there is a small risk
+that work is run before autopm get, which would call autopm put before
+get, and mess up the runtime pm usage order.
+Swap the order of work sheduling and calling autopm get to solve this.
+
+Cc: stable <stable@kernel.org>
+Fixes: 8f5b7e2bec1c ("usb: hub: fix detection of high tier USB3 devices behind suspended hubs")
+Reported-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Closes: https://lore.kernel.org/linux-usb/acaaa928-832c-48ca-b0ea-d202d5cd3d6c@oss.qualcomm.com
+Reported-by: Alan Stern <stern@rowland.harvard.edu>
+Closes: https://lore.kernel.org/linux-usb/c73fbead-66d7-497a-8fa1-75ea4761090a@rowland.harvard.edu
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20250626130102.3639861-2-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/core/hub.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -1358,11 +1358,12 @@ static void hub_activate(struct usb_hub
+
+ if (type == HUB_RESUME && hub_is_superspeed(hub->hdev)) {
+ /* give usb3 downstream links training time after hub resume */
++ usb_autopm_get_interface_no_resume(
++ to_usb_interface(hub->intfdev));
++
+ INIT_DELAYED_WORK(&hub->init_work, hub_post_resume);
+ queue_delayed_work(system_power_efficient_wq, &hub->init_work,
+ msecs_to_jiffies(USB_SS_PORT_U0_WAKE_TIME));
+- usb_autopm_get_interface_no_resume(
+- to_usb_interface(hub->intfdev));
+ return;
+ }
+
+@@ -1416,6 +1417,7 @@ static void hub_quiesce(struct usb_hub *
+
+ /* Stop hub_wq and related activity */
+ del_timer_sync(&hub->irq_urb_retry);
++ flush_delayed_work(&hub->init_work);
+ usb_kill_urb(hub->urb);
+ if (hub->has_indicators)
+ cancel_delayed_work_sync(&hub->leds);
--- /dev/null
+From 9bd9c8026341f75f25c53104eb7e656e357ca1a2 Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Fri, 27 Jun 2025 19:43:48 +0300
+Subject: usb: hub: Fix flushing of delayed work used for post resume purposes
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit 9bd9c8026341f75f25c53104eb7e656e357ca1a2 upstream.
+
+Delayed work that prevents USB3 hubs from runtime-suspending too early
+needed to be flushed in hub_quiesce() to resolve issues detected on
+QC SC8280XP CRD board during suspend resume testing.
+
+This flushing did however trigger new issues on Raspberry Pi 3B+, which
+doesn't have USB3 ports, and doesn't queue any post resume delayed work.
+
+The flushed 'hub->init_work' item is used for several purposes, and
+is originally initialized with a 'NULL' work function. The work function
+is also changed on the fly, which may contribute to the issue.
+
+Solve this by creating a dedicated delayed work item for post resume work,
+and flush that delayed work in hub_quiesce()
+
+Cc: stable <stable@kernel.org>
+Fixes: a49e1e2e785f ("usb: hub: Fix flushing and scheduling of delayed work that tunes runtime pm")
+Reported-by: Mark Brown <broonie@kernel.org>
+Closes: https://lore.kernel.org/linux-usb/aF5rNp1l0LWITnEB@finisterre.sirena.org.uk
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Tested-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com> # SC8280XP CRD
+Tested-by: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/r/20250627164348.3982628-2-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/core/hub.c | 21 ++++++++-------------
+ drivers/usb/core/hub.h | 1 +
+ 2 files changed, 9 insertions(+), 13 deletions(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -1073,12 +1073,11 @@ int usb_remove_device(struct usb_device
+
+ enum hub_activation_type {
+ HUB_INIT, HUB_INIT2, HUB_INIT3, /* INITs must come first */
+- HUB_POST_RESET, HUB_RESUME, HUB_RESET_RESUME, HUB_POST_RESUME,
++ HUB_POST_RESET, HUB_RESUME, HUB_RESET_RESUME,
+ };
+
+ static void hub_init_func2(struct work_struct *ws);
+ static void hub_init_func3(struct work_struct *ws);
+-static void hub_post_resume(struct work_struct *ws);
+
+ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
+ {
+@@ -1102,12 +1101,6 @@ static void hub_activate(struct usb_hub
+ goto init3;
+ }
+
+- if (type == HUB_POST_RESUME) {
+- usb_autopm_put_interface_async(to_usb_interface(hub->intfdev));
+- hub_put(hub);
+- return;
+- }
+-
+ hub_get(hub);
+
+ /* The superspeed hub except for root hub has to use Hub Depth
+@@ -1361,8 +1354,8 @@ static void hub_activate(struct usb_hub
+ usb_autopm_get_interface_no_resume(
+ to_usb_interface(hub->intfdev));
+
+- INIT_DELAYED_WORK(&hub->init_work, hub_post_resume);
+- queue_delayed_work(system_power_efficient_wq, &hub->init_work,
++ queue_delayed_work(system_power_efficient_wq,
++ &hub->post_resume_work,
+ msecs_to_jiffies(USB_SS_PORT_U0_WAKE_TIME));
+ return;
+ }
+@@ -1387,9 +1380,10 @@ static void hub_init_func3(struct work_s
+
+ static void hub_post_resume(struct work_struct *ws)
+ {
+- struct usb_hub *hub = container_of(ws, struct usb_hub, init_work.work);
++ struct usb_hub *hub = container_of(ws, struct usb_hub, post_resume_work.work);
+
+- hub_activate(hub, HUB_POST_RESUME);
++ usb_autopm_put_interface_async(to_usb_interface(hub->intfdev));
++ hub_put(hub);
+ }
+
+ enum hub_quiescing_type {
+@@ -1417,7 +1411,7 @@ static void hub_quiesce(struct usb_hub *
+
+ /* Stop hub_wq and related activity */
+ del_timer_sync(&hub->irq_urb_retry);
+- flush_delayed_work(&hub->init_work);
++ flush_delayed_work(&hub->post_resume_work);
+ usb_kill_urb(hub->urb);
+ if (hub->has_indicators)
+ cancel_delayed_work_sync(&hub->leds);
+@@ -1976,6 +1970,7 @@ static int hub_probe(struct usb_interfac
+ hub->hdev = hdev;
+ INIT_DELAYED_WORK(&hub->leds, led_work);
+ INIT_DELAYED_WORK(&hub->init_work, NULL);
++ INIT_DELAYED_WORK(&hub->post_resume_work, hub_post_resume);
+ INIT_WORK(&hub->events, hub_event);
+ INIT_LIST_HEAD(&hub->onboard_devs);
+ spin_lock_init(&hub->irq_urb_lock);
+--- a/drivers/usb/core/hub.h
++++ b/drivers/usb/core/hub.h
+@@ -70,6 +70,7 @@ struct usb_hub {
+ u8 indicator[USB_MAXCHILDREN];
+ struct delayed_work leds;
+ struct delayed_work init_work;
++ struct delayed_work post_resume_work;
+ struct work_struct events;
+ spinlock_t irq_urb_lock;
+ struct timer_list irq_urb_retry;