Skip to content

Commit 028e8ca

Browse files
Fomysvinodkoul
authored andcommitted
phy: rockchip: inno-usb2: fix disconnection in gadget mode
When the OTG USB port is used to power the SoC, configured as peripheral and used in gadget mode, there is a disconnection 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 problem happens because of the PHY driver code flow, summarized as: * UDC start code (triggered via configfs at any time after boot) -> phy_init -> rockchip_usb2phy_init -> schedule_delayed_work(otg_sm_work [A], 6 sec) -> phy_power_on -> rockchip_usb2phy_power_on -> enable clock -> rockchip_usb2phy_reset * Now the gadget interface is up and running. * 6 seconds later otg_sm_work starts [A] -> rockchip_usb2phy_otg_sm_work(): if (B_IDLE state && VBUS present && ...): schedule_delayed_work(&rport->chg_work [B], 0); * immediately the chg_detect_work starts [B] -> rockchip_chg_detect_work(): if chg_state is UNDEFINED: if (!rport->suspended): rockchip_usb2phy_power_off() <--- [X] At [X], the PHY is powered off, causing a disconnection. This quickly triggers a new connection and following re-enumeration, but any connection that had been established during the 6 seconds is broken. The code already checks for !rport->suspended (which, somewhat counter-intuitively, means the PHY is powered on), so add a guard for VBUS as well to avoid a disconnection when a cable is connected. 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: Louis Chauvet <louis.chauvet@bootlin.com> Co-developed-by: Luca Ceresoli <luca.ceresoli@bootlin.com> 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-1-dac8a02cd2ca@bootlin.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
1 parent 4914d67 commit 028e8ca

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
@@ -821,14 +821,16 @@ static void rockchip_chg_detect_work(struct work_struct *work)
821821
container_of(work, struct rockchip_usb2phy_port, chg_work.work);
822822
struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
823823
struct regmap *base = get_reg_base(rphy);
824-
bool is_dcd, tmout, vout;
824+
bool is_dcd, tmout, vout, vbus_attach;
825825
unsigned long delay;
826826

827+
vbus_attach = property_enabled(rphy->grf, &rport->port_cfg->utmi_bvalid);
828+
827829
dev_dbg(&rport->phy->dev, "chg detection work state = %d\n",
828830
rphy->chg_state);
829831
switch (rphy->chg_state) {
830832
case USB_CHG_STATE_UNDEFINED:
831-
if (!rport->suspended)
833+
if (!rport->suspended && !vbus_attach)
832834
rockchip_usb2phy_power_off(rport->phy);
833835
/* put the controller in non-driving mode */
834836
property_enable(base, &rphy->phy_cfg->chg_det.opmode, false);

0 commit comments

Comments
 (0)