From 4f519feed0d9e268447981b3699ab02d9d454256 Mon Sep 17 00:00:00 2001 From: William Wu Date: Thu, 20 Jul 2017 15:02:02 +0800 Subject: [PATCH] phy: rockchip-inno-usb2: delay suspending phy if plug out device The otg_sm_work will suspend the usb2 phy immediately if it detects disconnection from host. However, the usb2 controller(e.g. DWC2) may need to reinit registers and reset usb core after usb disconnect, and it needs to keep the usb2 phy stay in power on state to get utmi clk for these usb controller operation. We don't have a good synchronization mechanism to operate usb2 phy between usb2 phy driver and usb2 controller driver, so we delay 4s to suspend phy if detect otg device disconnect from host, this can make sure that usb2 controller completes reinitialization before suspend usb2 phy. Change-Id: I79288b8c7b141bb16e6d96d80cfee75f7558d2c0 Signed-off-by: William Wu --- drivers/phy/phy-rockchip-inno-usb2.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/phy/phy-rockchip-inno-usb2.c b/drivers/phy/phy-rockchip-inno-usb2.c index 1fbcc5180047..fbcf8f3b2081 100644 --- a/drivers/phy/phy-rockchip-inno-usb2.c +++ b/drivers/phy/phy-rockchip-inno-usb2.c @@ -886,19 +886,17 @@ static void rockchip_usb2phy_otg_sm_work(struct work_struct *work) } else { rphy->chg_state = USB_CHG_STATE_UNDEFINED; rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN; + mutex_unlock(&rport->mutex); + rockchip_usb2phy_power_off(rport->phy); + mutex_lock(&rport->mutex); } break; case OTG_STATE_B_PERIPHERAL: if (!rport->vbus_attached) { dev_dbg(&rport->phy->dev, "usb disconnect\n"); - rphy->chg_state = USB_CHG_STATE_UNDEFINED; - rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN; rport->state = OTG_STATE_B_IDLE; rport->perip_connected = false; - delay = 0; - mutex_unlock(&rport->mutex); - rockchip_usb2phy_power_off(rport->phy); - mutex_lock(&rport->mutex); + delay = OTG_SCHEDULE_DELAY * 2; wake_unlock(&rport->wakelock); } sch_work = true; @@ -1246,6 +1244,7 @@ static irqreturn_t rockchip_usb2phy_bvalid_irq(int irq, void *data) mutex_unlock(&rport->mutex); + cancel_delayed_work_sync(&rport->otg_sm_work); rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work); return IRQ_HANDLED; @@ -1324,6 +1323,7 @@ static int rockchip_otg_event(struct notifier_block *nb, struct rockchip_usb2phy_port *rport = container_of(nb, struct rockchip_usb2phy_port, event_nb); + cancel_delayed_work_sync(&rport->otg_sm_work); schedule_delayed_work(&rport->otg_sm_work, OTG_SCHEDULE_DELAY); return NOTIFY_DONE; -- 2.34.1