[PATCH net] net: wwan: iosm: Re-bind the driver around system suspend too

From
Zev Paneth <hidden>
Date
2026-11-05 10:22:28
On some platforms the modem loses power during suspend-to-idle even
though the driver keeps the device in D0 and its s2idle resume path
only sends a wake-up command. After a long enough s2idle cycle (about
five minutes or more on the test platform) the device comes back in
its boot ROM stage: resume logs "msg timeout", ModemManager then fails
to open the ports ("PORT open refused, phase A-ROM", "Failed to find
primary AT port"), and once userspace has touched the ports the modem
stays dead until a full reboot. This is the same failure mode that
commit 0b6f6593aa8c ("net: wwan: iosm: Fix hibernation by re-binding
the driver around it") addressed for hibernation.

Extend that approach to system suspend: unbind the driver on
PM_SUSPEND_PREPARE and re-bind it on PM_POST_SUSPEND, so the device is
re-initialized from scratch on resume, exactly as it is at boot.

The cost is a full modem re-enumeration after every suspend (about
50 seconds until reconnected on the test platform), also on platforms
where the modem does survive s2idle. If that is considered too heavy,
this could instead be gated by a DMI quirk for the affected platforms.

Tested on a Fibocom L860-GL-16 (Intel XMM7560, 8086:7560) in an
HP ProBook 450 G10 (BIOS V72 01.13.01) with kernel 7.0: with this
change the modem survives an 11-minute lid-closed s2idle and
reconnects automatically; without it, any s2idle longer than roughly
five minutes left the modem in A-ROM until reboot.

Signed-off-by: Zev Paneth <redacted>
---
 drivers/net/wwan/iosm/iosm_ipc_pcie.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wwan/iosm/iosm_ipc_pcie.c b/drivers/net/wwan/iosm/iosm_ipc_pcie.c
index 49052eb51..ebd4c45e1 100644
--- a/drivers/net/wwan/iosm/iosm_ipc_pcie.c
+++ b/drivers/net/wwan/iosm/iosm_ipc_pcie.c
@@ -534,12 +534,14 @@ void ipc_pcie_kfree_skb(struct iosm_pcie *ipc_pcie, struct sk_buff *skb)
 
 static int pm_notify(struct notifier_block *nb, unsigned long mode, void *_unused)
 {
-	if (mode == PM_HIBERNATION_PREPARE || mode == PM_RESTORE_PREPARE) {
+	if (mode == PM_HIBERNATION_PREPARE || mode == PM_RESTORE_PREPARE ||
+	    mode == PM_SUSPEND_PREPARE) {
 		if (pci_registered) {
 			pci_unregister_driver(&iosm_ipc_driver);
 			pci_registered = false;
 		}
-	} else if (mode == PM_POST_HIBERNATION || mode == PM_POST_RESTORE) {
+	} else if (mode == PM_POST_HIBERNATION || mode == PM_POST_RESTORE ||
+		   mode == PM_POST_SUSPEND) {
 		if (!pci_registered) {
 			int ret;
 
-- 
2.53.0
Thread (3 messages) 3 messages, 3 authors, last reply 3d ago
Keyboard shortcuts
hback out one level
jnext message in thread / next series-diff position
kprevious message in thread / previous series-diff position
ldrill in
Escclose help / fold thread tree
?toggle this help