From: William Wu Date: Thu, 20 Jul 2017 07:02:02 +0000 (+0800) Subject: phy: rockchip-inno-usb2: delay suspending phy if plug out device X-Git-Tag: release-20171130_firefly~4^2~131 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=4f519feed0d9e268447981b3699ab02d9d454256;p=firefly-linux-kernel-4.4.55.git 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 --- 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;