Skip to content

Commit 7d8f725

Browse files
lucaceresolivinodkoul
authored andcommitted
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: 98898f3 ("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>
1 parent 028e8ca commit 7d8f725

1 file changed

Lines changed: 4 additions & 2 deletions

File tree

drivers/phy/rockchip/phy-rockchip-inno-usb2.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -833,7 +833,8 @@ static void rockchip_chg_detect_work(struct work_struct *work)
833833
if (!rport->suspended && !vbus_attach)
834834
rockchip_usb2phy_power_off(rport->phy);
835835
/* 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);
837838
/* Start DCD processing stage 1 */
838839
rockchip_chg_enable_dcd(rphy, true);
839840
rphy->chg_state = USB_CHG_STATE_WAIT_FOR_DCD;
@@ -896,7 +897,8 @@ static void rockchip_chg_detect_work(struct work_struct *work)
896897
fallthrough;
897898
case USB_CHG_STATE_DETECTED:
898899
/* put the controller in normal mode */
899-
property_enable(base, &rphy->phy_cfg->chg_det.opmode, true);
900+
if (!vbus_attach)
901+
property_enable(base, &rphy->phy_cfg->chg_det.opmode, true);
900902
rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work);
901903
dev_dbg(&rport->phy->dev, "charger = %s\n",
902904
chg_to_string(rphy->chg_type));

0 commit comments

Comments
 (0)