Faster resume probing

Tom Loten tomloten at gmail.com
Wed Jan 6 21:37:52 UTC 2021


I've also been working with USB QMI modems (Quectel and Simcom) and
getting suspend-to-ram/resume working smoothly, so I figured perhaps I
can share some of the things I've learnt along the way. But do note
that I'm not by any means an expert here - this is my first foray into
usb & modems, so do take what I say with a grain of salt.

Firstly, I agree with Aleksander's opinion above - I think the
underlying problem is the fact that the USB connection is being reset
upon resume. I'd try to solve that first - disable MM & NM altogether
for now, and focus on the qmi & usb layers. Use qmicli to set up a
connection or at least check basic info with commands like
qmicli --device=/dev/cdc-wdm0 --device-open-proxy --dms-get-model
Then start looking at the USB side of things. The kernel docs
https://www.kernel.org/doc/html/v4.14/driver-api/usb/power-management.html
provide some good background info on this area.

If I had a pinephone or similar hardware to test with I might be able
to provide some more guidance, however I can perhaps shed some light
by showing what was required to get my particular device working.
My device is an IMX6ULL, and the modem is connected directly to the
USB host pins on the chip itself. No USB hub ICs involved. Power to
the modem is controlled externally (in my case it's always on).
USB info:
    root at imx6ul-var-dart:~# lsusb -tv
    /:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=ci_hdrc/1p, 480M
        ID 1d6b:0002 Linux Foundation 2.0 root hub
    /:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ci_hdrc/1p, 480M
        ID 1d6b:0002 Linux Foundation 2.0 root hub
        |__ Port 1: Dev 2, If 0, Class=Vendor Specific Class,
Driver=option, 480M
            ID 2c7c:0125 Quectel Wireless Solutions Co., Ltd. EC25 LTE modem
        |__ Port 1: Dev 2, If 1, Class=Vendor Specific Class,
Driver=option, 480M
            ID 2c7c:0125 Quectel Wireless Solutions Co., Ltd. EC25 LTE modem
        |__ Port 1: Dev 2, If 2, Class=Vendor Specific Class,
Driver=option, 480M
            ID 2c7c:0125 Quectel Wireless Solutions Co., Ltd. EC25 LTE modem
        |__ Port 1: Dev 2, If 3, Class=Vendor Specific Class,
Driver=option, 480M
            ID 2c7c:0125 Quectel Wireless Solutions Co., Ltd. EC25 LTE modem
        |__ Port 1: Dev 2, If 4, Class=Vendor Specific Class,
Driver=qmi_wwan, 480M
            ID 2c7c:0125 Quectel Wireless Solutions Co., Ltd. EC25 LTE modem

The following 3 tweaks are needed to get the modem persisting across a
suspend/resume:
   echo auto > /sys/bus/usb/devices/1-1/power/control
   echo enabled > /sys/bus/platform/devices/2184000.usb/power/wakeup
   echo enabled > /sys/bus/platform/devices/ci_hdrc.0/power/wakeup

Obviously your USB setup will be different so the above won't work,
but perhaps it might provide some direction. The first one - setting
control to auto - makes sense to me, but I cannot see why the other
two are needed. Having a good poke around the /sys/ tree is a good
start anyway - set control=auto and wakeup=enabled on all the usb
devices on/above the modem. Finding the equivalent of my 2nd line
might be trickier and need some datasheet or device-tree reading to
correctly identify it.
If you have USB hub devices in the chain then things will be more
complex, but I'd be surprised if they've set up the hardware that way.

Finally, to allow the modem to wakeup the host, the following two
tweaks were needed:
    echo enabled > /sys/bus/usb/devices/usb1/power/wakeup
    echo enabled > /sys/bus/usb/devices/1-1/power/wakeup

Also, note I'm suspending via the very raw
   echo mem > /sys/power/state
so I can be sure that no setup/teardown is occuring. But obviously
pm-suspend or systemctl suspend is the right way to do things for
production units.

Hopefully that's useful, and best of luck :)
Regards,
Tom


More information about the ModemManager-devel mailing list