|
@@ -696,9 +696,24 @@ static int xhci_mtk_remove(struct platform_device *dev)
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_PM_SLEEP
|
|
|
+/*
|
|
|
+ * if ip sleep fails, and all clocks are disabled, access register will hang
|
|
|
+ * AHB bus, so stop polling roothubs to avoid regs access on bus suspend.
|
|
|
+ * and no need to check whether ip sleep failed or not; this will cause SPM
|
|
|
+ * to wake up system immediately after system suspend complete if ip sleep
|
|
|
+ * fails, it is what we wanted.
|
|
|
+ */
|
|
|
static int xhci_mtk_suspend(struct device *dev)
|
|
|
{
|
|
|
struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev);
|
|
|
+ struct usb_hcd *hcd = mtk->hcd;
|
|
|
+ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
|
|
+
|
|
|
+ xhci_dbg(xhci, "%s: stop port polling\n", __func__);
|
|
|
+ clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
|
|
|
+ del_timer_sync(&hcd->rh_timer);
|
|
|
+ clear_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags);
|
|
|
+ del_timer_sync(&xhci->shared_hcd->rh_timer);
|
|
|
|
|
|
xhci_mtk_host_disable(mtk);
|
|
|
xhci_mtk_phy_power_off(mtk);
|
|
@@ -710,11 +725,19 @@ static int xhci_mtk_suspend(struct device *dev)
|
|
|
static int xhci_mtk_resume(struct device *dev)
|
|
|
{
|
|
|
struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev);
|
|
|
+ struct usb_hcd *hcd = mtk->hcd;
|
|
|
+ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
|
|
|
|
|
usb_wakeup_disable(mtk);
|
|
|
xhci_mtk_clks_enable(mtk);
|
|
|
xhci_mtk_phy_power_on(mtk);
|
|
|
xhci_mtk_host_enable(mtk);
|
|
|
+
|
|
|
+ xhci_dbg(xhci, "%s: restart port polling\n", __func__);
|
|
|
+ set_bit(HCD_FLAG_POLL_RH, &hcd->flags);
|
|
|
+ usb_hcd_poll_rh_status(hcd);
|
|
|
+ set_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags);
|
|
|
+ usb_hcd_poll_rh_status(xhci->shared_hcd);
|
|
|
return 0;
|
|
|
}
|
|
|
|