Re: [PATCH v2] usb: port: add delay after usb_hub_set_port_power()

From: Fabio Estevam

Date: Wed Feb 25 2026 - 15:13:52 EST


Hi Xu Yang,

On Wed, Feb 25, 2026 at 4:47 AM Xu Yang <xu.yang_2@xxxxxxx> wrote:
>
> Hi Fabio,
>
> On Tue, Feb 24, 2026 at 09:19:51AM -0300, Fabio Estevam wrote:
> > Hi Xu Yang,
> >
> > On Tue, Feb 24, 2026 at 12:17 AM Xu Yang <xu.yang_2@xxxxxxx> wrote:
> > >
> > > When a port is disabled, an attached device will be disconnected. This
> > > causes a port-status-change event, which will race with hub autosuspend
> > > (if the disabled port was the only connected port on its hub), causing
> > > an immediate resume and a second autosuspend. Both of these can be
> > > avoided by adding a short delay after the call to
> > > usb_hub_set_port_power().
> > >
> > > Below log shows what is happening:
> > >
> > > $ echo 1 > usb1-port1/disable
> > > [ 37.958239] usb 1-1: USB disconnect, device number 2
> > > [ 37.964101] usb 1-1: unregistering device
> > > [ 37.970070] hub 1-0:1.0: hub_suspend
> > > [ 37.971305] hub 1-0:1.0: state 7 ports 1 chg 0000 evt 0002
> > > [ 37.974412] usb usb1: bus auto-suspend, wakeup 1
> > > [ 37.988175] usb usb1: suspend raced with wakeup event <---
> > > [ 37.993947] usb usb1: usb auto-resume
> > > [ 37.998401] hub 1-0:1.0: hub_resume
> > > [ 38.105688] usb usb1-port1: status 0000, change 0000, 12 Mb/s
> > > [ 38.112399] hub 1-0:1.0: state 7 ports 1 chg 0000 evt 0000
> > > [ 38.118645] hub 1-0:1.0: hub_suspend
> > > [ 38.122963] usb usb1: bus auto-suspend, wakeup 1
> > > [ 38.200368] usb usb1: usb wakeup-resume
> > > [ 38.204982] usb usb1: usb auto-resume
> > > [ 38.209376] hub 1-0:1.0: hub_resume
> > > [ 38.213676] usb usb1-port1: status 0101 change 0001
> > > [ 38.321552] hub 1-0:1.0: state 7 ports 1 chg 0002 evt 0000
> > > [ 38.327978] usb usb1-port1: status 0101, change 0000, 12 Mb/s
> > > [ 38.457429] usb 1-1: new high-speed USB device number 3 using ci_hdrc
> > >
> > > Then, port change bit will be fixed to the final state and
> > > usb_clear_port_feature() can correctly clear it after this period. This
> > > will also avoid usb runtime suspend routine to run because
> > > usb_autopm_put_interface() not run yet.
> > >
> > > Fixes: f061f43d7418 ("usb: hub: port: add sysfs entry to switch port power")
> > > Cc: stable@xxxxxxxxxx
> > > Signed-off-by: Xu Yang <xu.yang_2@xxxxxxx>
> >
> > On an imx6x-sdb board, I still get the inconsistency below even after
> > applying your patch:
> >
> > # echo 1 > /sys/bus/usb/devices/1-0\:1.0/usb1-port1/disable
> > [ 20.656414] usb 1-1: USB disconnect, device number 2
> >
> > # echo 1 > /sys/bus/usb/devices/1-0\:1.0/usb1-port1/disable
> > [ 28.263516] usb 1-1: new high-speed USB device number 3 using ci_hdrc
> > [ 28.466813] usb 1-1: New USB device found, idVendor=0457,
> > idProduct=0151, bcdDevice= 1.00
> > [ 28.466949] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
> > [ 28.467039] usb 1-1: Product: USB Mass Storage Device
> > [ 28.467086] usb 1-1: Manufacturer: USBest Technology
> > [ 28.467126] usb 1-1: SerialNumber: 000000000003FF
> > [ 28.501826] usb-storage 1-1:1.0: USB Mass Storage device detected
> > [ 28.510452] usb-storage 1-1:1.0: Quirks match for vid 0457 pid 0151: 80
> > [ 28.517597] scsi host0: usb-storage 1-1:1.0
> > [ 28.524066] usb 1-1: USB disconnect, device number 3
>
> It's another different problem.
>
> For ports which VBUS are not controlled by PORTSC.PP (always on VBUS
> regulator or Type-C controlled VBUS), they are still powered on after
> you disable the ports. This will cause PORTSC.CCS still be set after it.
>
> When usb_autopm_get_interface() gets called, hub_resume will check CCS
> bit and check new connection again. So you see new device is reported.
>
> Below patch will be a workaround for the issue when you disable the port
> many times:
> https://lore.kernel.org/linux-usb/20260223-v6-16-topic-usb-onboard-dev-v5-1-28d3018a8026@xxxxxxxxxxxxxx/

I applied Marco's patch, and it fixes the inconsistent state that I
reported before on the imx6sx-sdb:

# echo 1 > /sys/bus/usb/devices/1-0\:1.0/usb1-port1/disable
[ 110.494838] usb 1-1: USB disconnect, device number 3
# echo 1 > /sys/bus/usb/devices/1-0\:1.0/usb1-port1/disable
# echo 1 > /sys/bus/usb/devices/1-0\:1.0/usb1-port1/disable
# echo 1 > /sys/bus/usb/devices/1-0\:1.0/usb1-port1/disable
# echo 1 > /sys/bus/usb/devices/1-0\:1.0/usb1-port1/disable
# echo 1 > /sys/bus/usb/devices/1-0\:1.0/usb1-port1/disable

Now I want the USB OTG2 VBUS to be turned off.

I understand that the chipidea driver does not turn off VBUS when
vbus-supply is passed, so I tried using the pin as
MX6SX_PAD_GPIO1_IO12__USB_OTG2_PWR:

--- a/arch/arm/boot/dts/nxp/imx/imx6sx-sdb.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6sx-sdb.dtsi
@@ -70,17 +70,6 @@ reg_usb_otg1_vbus: regulator-usb-otg1-vbus {
enable-active-high;
};

- reg_usb_otg2_vbus: regulator-usb-otg2-vbus {
- compatible = "regulator-fixed";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usb_otg2>;
- regulator-name = "usb_otg2_vbus";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
- enable-active-high;
- };
-
reg_psu_5v: regulator-psu-5v {
compatible = "regulator-fixed";
regulator-name = "PSU-5V0";
@@ -347,7 +336,8 @@ &usbotg1 {
};

&usbotg2 {
- vbus-supply = <&reg_usb_otg2_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_otg2>;
dr_mode = "host";
status = "okay";
};
@@ -636,7 +626,7 @@ MX6SX_PAD_GPIO1_IO10__ANATOP_OTG1_ID 0x17059

pinctrl_usb_otg2: usbot2ggrp {
fsl,pins = <
- MX6SX_PAD_GPIO1_IO12__GPIO1_IO_12 0x10b0
+ MX6SX_PAD_GPIO1_IO12__USB_OTG2_PWR 0x10b0
>;
};

This works in the opposite way:

# echo 1 > /sys/bus/usb/devices/1-0\:1.0/usb1-port1/disable
# [ 48.509650] mxs_phy 20c9000.usbphy: vbus is not valid
[ 48.940605] usb 1-1: new high-speed USB device number 3 using ci_hdrc
[ 49.144001] usb 1-1: New USB device found, idVendor=0457,
idProduct=0151, bcdDevice= 1.00
[ 49.144133] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 49.144225] usb 1-1: Product: USB Mass Storage Device
[ 49.144273] usb 1-1: Manufacturer: USBest Technology
[ 49.144314] usb 1-1: SerialNumber: 000000000003FF
[ 49.179136] usb-storage 1-1:1.0: USB Mass Storage device detected
[ 49.188023] usb-storage 1-1:1.0: Quirks match for vid 0457 pid 0151: 80
[ 49.195308] scsi host0: usb-storage 1-1:1.0
[ 50.252746] scsi 0:0:0:0: Direct-Access Ut163
USB2FlashStorage 0.00 PQ: 0 ANSI: 2
[ 50.291866] sd 0:0:0:0: [sda] 248000 512-byte logical blocks: (127
MB/121 MiB)
[ 50.301593] sd 0:0:0:0: [sda] Write Protect is off
[ 50.308917] sd 0:0:0:0: [sda] Asking for cache data failed
[ 50.309042] sd 0:0:0:0: [sda] Assuming drive cache: write through
[ 50.342155] sda: sda1
[ 50.345288] sd 0:0:0:0: [sda] Attached SCSI removable disk

#
#
# echo 0 > /sys/bus/usb/devices/1-0\:1.0/usb1-port1/disable
# [ 57.161272] usb 1-1: USB disconnect, device number 3

Then I passed the 'power-active-high' property, but it failed:

# echo 1 > /sys/bus/usb/devices/1-0\:1.0/usb1-port1/disable
[ 16.892793] usb 1-1: USB disconnect, device number 2
# [ 18.330848] usb usb1-port1: Cannot enable. Maybe the USB cable is bad?
[ 19.240797] usb usb1-port1: Cannot enable. Maybe the USB cable is bad?
[ 19.248159] usb usb1-port1: attempt power cycle
[ 20.520852] usb usb1-port1: Cannot enable. Maybe the USB cable is bad?
[ 21.430861] usb usb1-port1: Cannot enable. Maybe the USB cable is bad?
[ 21.437883] usb usb1-port1: unable to enumerate USB device

Any ideas on how to properly turn off the OTG2 VBUS?

Thanks