USB: dwc_otg_310: modify usb mode change detect bug

When dwc controller change mode form device to host, may check_vbus_work is running
on other cpu, but we don't have a good synchronization id_status_change and
check_vbus_work, as a result, phy and clk may in incorrect state. So modify it.

Signed-off-by: Feng Mingli <fml@rock-chips.com>
Signed-off-by: lyz <lyz@rock-chips.com>

Conflicts:
	drivers/usb/dwc_otg_310/dwc_otg_pcd_linux.c
This commit is contained in:
Feng Mingli
2015-08-17 09:24:49 +08:00
committed by lyz
parent 743b40f9bd
commit 954898839e

View File

@@ -1561,7 +1561,7 @@ static void id_status_change(dwc_otg_core_if_t *p, bool current_id)
core_if->op_state = A_HOST;
dwc_otg_set_force_mode(core_if, USB_MODE_FORCE_HOST);
cancel_delayed_work(&pcd->check_vbus_work);
cancel_delayed_work_sync(&pcd->check_vbus_work);
/*
* Initialize the Core for Host mode.
@@ -1590,11 +1590,8 @@ static void check_id(struct work_struct *work)
pldata->phy_suspend(pldata, USB_PHY_ENABLED);
}
if (!id) { /* Force Host */
id_status_change(otg_dev->core_if, id);
} else { /* Force Device */
id_status_change(otg_dev->core_if, id);
}
/* Force Device or Host by id */
id_status_change(otg_dev->core_if, id);
}
last_id = id;
schedule_delayed_work(&_pcd->check_id_work, (HZ));
@@ -1662,10 +1659,12 @@ static void dwc_otg_pcd_check_vbus_work(struct work_struct *work)
if (pldata->phy_status == USB_PHY_ENABLED) {
/* release wake lock */
dwc_otg_msc_unlock(_pcd);
/* no vbus detect here , close usb phy */
pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
udelay(3);
pldata->clock_enable(pldata, 0);
if (pldata->get_status(USB_STATUS_ID)) {
/* no vbus detect here , close usb phy */
pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
udelay(3);
pldata->clock_enable(pldata, 0);
}
}
/* usb phy bypass to uart mode */
@@ -1673,7 +1672,8 @@ static void dwc_otg_pcd_check_vbus_work(struct work_struct *work)
pldata->dwc_otg_uart_mode(pldata, PHY_UART_MODE);
}
schedule_delayed_work(&_pcd->check_vbus_work, HZ);
if (pldata->get_status(USB_STATUS_ID))
schedule_delayed_work(&_pcd->check_vbus_work, HZ);
return;
connect: