Entering KSLEEP=0 after triggering OTG Host is broken

Hello,
I am trying to make a WP7607 go into sleep mode with an OTG ethernet controller connected to it.
I have tried a whole bunch of things, and at last the sequence that I found that takes me ever so close to success is the following:
0. I have recompiled the kernel, enabling debug user control of the OTG mode (host and peripheral) by overriding the following in the WP7607 device tree.

&soc {
    usb_otg: usb@78d9000 {
        qcom,hsusb-otg-otg-control = <3>; /* User control */
        //qcom,hsusb-otg-delay-lpm;
    };
};

This lets me control via /sys/kernel/debug/msm_otg/mode the OTG configuration as follows.

  1. I plug my OTG ethernet controller/flash drive/keyboard or nothing at all and turn on my device (This also works on the reference MangOH Red board)
  2. I check via lsusb that no Bus 001 Device 001: ID 1d6b:0002 is shown.
  3. I set it on peripheral mode, by cutting VBUS power and by sending echo -n peripheral > /sys/kernel/debug/msm_otg/mode; sleep 1; cat /sys/kernel/debug/msm_otg/mode, then I give VBUS power again.
    The kernel prints me back this:
[   77.035243] msm_otg 78d9000.usb: Could not get usb power_supply
[   77.035284] msm_otg 78d9000.usb: Could not get usb power_supply
[   77.039999] msm_otg 78d9000.usb: Could not get usb power_supply
[   77.040010] msm_otg 78d9000.usb: Could not get usb power_supply
  1. I send AT+KSLEEP=0, the device sleeps as expected.
  2. I wake up the device. It does so as expected.
  3. I put the device on host mode, by unpowering VBUS, then echo -n host > /sys/kernel/debug/msm_otg/mode; sleep 1; cat /sys/kernel/debug/msm_otg/mode and giving VBUS power again.
    The kernel prints me this:
[  264.151050] usb usb1: runtime PM trying to activate child device usb1 but parent (msm_hsusb_host) is not active
  1. I check via lsusb that both the ID 1d6b:0002 and the OTG device is present.
  2. If I go to sleep at this stage, the OTG device prevents me from going, as expected.
  3. I turn off the VBUS power again, get back into echo -n peripheral > /sys/kernel/debug/msm_otg/mode; sleep 1; cat /sys/kernel/debug/msm_otg/mode .
  4. When the device goes to sleep now, it will enter a strange state, where the CPU is actually sleeping but I still get echo loop from the serial UART interface. If I then try to wake up with an interrupt, the device gets stuck until I unpower and power back the device.

To make it short, every time the device enters host mode and gets back into peripheral mode, no matter if an OTG device is plugged or not / the VBUS has the power cut or not / If I go to sleep during each stage or skip it. Nothing I do makes an obvious difference, it all leads to a total block of the CPU, unless I reboot the device, then the device is able to sleep. I suspect that something is not configured back correctly in kernel/drivers/usb/phy/phy-msm-usb.c when hopping between work modes.
Thank you for your help.

Is problem happening in both r16.3 and r17?

Btw, for r17, you need to apply the patch for usb otg

Thank you for your reply. I forgot to add that I was already using the patch that you linked.

diff --git a/arch/arm64/boot/dts/qcom/mdm9607-swi.dtsi b/arch/arm64/boot/dts/qcom/mdm9607-swi.dtsi
index 9a5644ec4dea..815b3305ffd9 100644
--- a/arch/arm64/boot/dts/qcom/mdm9607-swi.dtsi
+++ b/arch/arm64/boot/dts/qcom/mdm9607-swi.dtsi
@@ -162,9 +162,6 @@
 	qcom,hsusb-otg-phy-init-seq =
 		<0x44 0x80 0x30 0x81 0x24 0x82 0x13 0x83 0xffffffff>;
 	/delete-property/ vbus_otg-supply;
-	/delete-property/ qcom,usbid-gpio;
-	/delete-property/ pinctrl-names;
-	/delete-property/ pinctrl-0;
 };

 &hsic_host {
diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c
index 94a2e443ec47..55027522e561 100644
--- a/drivers/usb/phy/phy-msm-usb.c
+++ b/drivers/usb/phy/phy-msm-usb.c
@@ -4325,8 +4325,8 @@ static int msm_otg_probe(struct platform_device *pdev)
 	phy->set_power = msm_otg_set_power;
 	phy->set_suspend = msm_otg_set_suspend;
 	phy->dbg_event = msm_otg_dbg_log_event;
-	phy->vbus_nb.notifier_call = msm_otg_vbus_notifier;
-	phy->id_nb.notifier_call = msm_otg_id_notifier;
+	// phy->vbus_nb.notifier_call = msm_otg_vbus_notifier;
+	// phy->id_nb.notifier_call = msm_otg_id_notifier;

 	phy->io_ops = &msm_otg_io_ops;

Without applying this patch, even if I’m in peripheral mode, if I got an OTG device connected, the device will never enter sleep mode, but it doesn’t affect the issue that I’m encountering, switching from host mode to peripheral mode breaks sleep mode, and the CPU never wakes, unless I reboot via command or I unplug the device.
In regards of R16.3, I cannot use it, since I’m relying on the “newer” 4.14 kernel for some of my device functionalities.
Thank you for your time.

I am thinking that if this is regression bug in r17 …

If there are tests to do and patches you want me to apply, I will be more than happy to assist and help you. I’m not particularly skilled in C, but I suspect there’s something that gets configured by kernel/drivers/usb/phy/phy-msm-usb.c when hopping into host mode and that it doesn’t go back as it should when going back into peripheral mode, causing this mayhem.

I mean if it works in r16.3, that means the bug is introduced when porting to kernel 4.14, probably that can give a clue

Btw, can you cut the vbus power by hardware instead of using the command?

Thank you for your reply. I was already unpowering VBUS via hardware, I am not aware of a method to cut power to VBUS via a console command.
Regarding R16.3, I guess I can download it, apply the manual OTG control patch in the first post and try if it works there. I want to reiterate that, even if OTG sleep works there, downgrading to R16.3 is not a solution to my issue, since I need most of the changes that were made in the 4.14 Kernel.

What if not setting “peripheral” but just cut powerof vbus?
Will that be the same as as removing device from the uab otg directly?

I am thinking you can start with usb thumb drive
Once remove the drive physically, can the module go to sleep mode?
And then if you cc onbect the usb thumb drive after that, can it be working?

Btw, since your module now in r17, it cannot go back to r16.3.
You need to take another module to test

I found that I have similar test before in FW R16:

At that time, in order to go to sleep mode, I need to first connect to a PC host so that /sys/kernel/debug/msm_otg/otg_state from a_host to b_peripheral

(BTW, I saw you just echo host / peripheral, but not sure if it should be a_host / b_peripheral)

Lastly, have you tried to use the USB port in mangoh red board which is using HSIC instead of using the USB OTG cable like this in mangoh green board?