Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

phy: rockchip: inno-usb2: fix communication disruption in gadget mode

When the OTG USB port is used to power to SoC, configured as peripheral and
used in gadget mode, communication stops without notice about 6 seconds
after the gadget is configured and enumerated.

The problem was observed on a Radxa Rock Pi S board, which can only be
powered by the only USB-C connector. That connector is the only one usable
in gadget mode. This implies the USB cable is connected from before boot
and never disconnects while the kernel runs.

The related code flow in the PHY driver code can be summarized as:

* the first time chg_detect_work starts (6 seconds after gadget is
configured and enumerated)
-> rockchip_chg_detect_work():
if chg_state is UNDEFINED:
property_enable(base, &rphy->phy_cfg->chg_det.opmode, false); [Y]

* rockchip_chg_detect_work() changes state and re-triggers itself a few
times until it reaches the DETECTED state:
-> rockchip_chg_detect_work():
if chg_state is DETECTED:
property_enable(base, &rphy->phy_cfg->chg_det.opmode, true); [Z]

At [Y] all existing communications stop. E.g. using a CDC serial gadget,
the /dev/tty* devices are still present on both host and device, but no
data is transferred anymore. The later call with a 'true' argument at [Z]
does not restore it.

Due to the lack of documentation, what chg_det.opmode does exactly is not
clear, however by code inspection it seems reasonable that is disables
something needed to keep the communication working, and testing proves that
disabling these lines lets gadget mode keep working. So prevent changes to
chg_det.opmode when there is a cable connected (VBUS present).

Fixes: 98898f3bc83c ("phy: rockchip-inno-usb2: support otg-port for rk3399")
Cc: stable@vger.kernel.org
Closes: https://lore.kernel.org/lkml/20250414185458.7767aabc@booty/
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Reviewed-by: Théo Lebrun <theo.lebrun@bootlin.com>
Link: https://patch.msgid.link/20251127-rk3308-fix-usb-gadget-phy-disconnect-v2-2-dac8a02cd2ca@bootlin.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Luca Ceresoli and committed by
Vinod Koul
7d8f725b 028e8ca7

+4 -2
+4 -2
drivers/phy/rockchip/phy-rockchip-inno-usb2.c
··· 833 833 if (!rport->suspended && !vbus_attach) 834 834 rockchip_usb2phy_power_off(rport->phy); 835 835 /* put the controller in non-driving mode */ 836 - property_enable(base, &rphy->phy_cfg->chg_det.opmode, false); 836 + if (!vbus_attach) 837 + property_enable(base, &rphy->phy_cfg->chg_det.opmode, false); 837 838 /* Start DCD processing stage 1 */ 838 839 rockchip_chg_enable_dcd(rphy, true); 839 840 rphy->chg_state = USB_CHG_STATE_WAIT_FOR_DCD; ··· 897 896 fallthrough; 898 897 case USB_CHG_STATE_DETECTED: 899 898 /* put the controller in normal mode */ 900 - property_enable(base, &rphy->phy_cfg->chg_det.opmode, true); 899 + if (!vbus_attach) 900 + property_enable(base, &rphy->phy_cfg->chg_det.opmode, true); 901 901 rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work); 902 902 dev_dbg(&rport->phy->dev, "charger = %s\n", 903 903 chg_to_string(rphy->chg_type));