diff options
author | Chunfeng Yun <chunfeng.yun@mediatek.com> | 2021-04-10 13:10:02 +0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-04-14 16:41:34 +0200 |
commit | 82dad9fb68fbcce4986503ae446e409ba2aad699 (patch) | |
tree | d9ba1f2d4298e23ebe7ff0b3d4776e5b38a29aa1 /drivers | |
parent | 1373fefc6243cc96b3565f0ffffadfac4ccfb977 (diff) |
usb: xhci-mtk: check return value in suspend/resume hooks
Return error number if encounter errors during suspend and resume.
Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
Link: https://lore.kernel.org/r/1618031406-15347-1-git-send-email-chunfeng.yun@mediatek.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/host/xhci-mtk.c | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c index 744639d23fa8..d8a8d254d8fe 100644 --- a/drivers/usb/host/xhci-mtk.c +++ b/drivers/usb/host/xhci-mtk.c @@ -641,18 +641,12 @@ static int xhci_mtk_remove(struct platform_device *dev) return 0; } -/* - * 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 __maybe_unused 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); + int ret; xhci_dbg(xhci, "%s: stop port polling\n", __func__); clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); @@ -660,10 +654,21 @@ static int __maybe_unused xhci_mtk_suspend(struct device *dev) clear_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags); del_timer_sync(&xhci->shared_hcd->rh_timer); - xhci_mtk_host_disable(mtk); + ret = xhci_mtk_host_disable(mtk); + if (ret) + goto restart_poll_rh; + xhci_mtk_clks_disable(mtk); usb_wakeup_set(mtk, true); return 0; + +restart_poll_rh: + xhci_dbg(xhci, "%s: restart port polling\n", __func__); + set_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags); + usb_hcd_poll_rh_status(xhci->shared_hcd); + set_bit(HCD_FLAG_POLL_RH, &hcd->flags); + usb_hcd_poll_rh_status(hcd); + return ret; } static int __maybe_unused xhci_mtk_resume(struct device *dev) @@ -671,10 +676,16 @@ static int __maybe_unused 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); + int ret; usb_wakeup_set(mtk, false); - xhci_mtk_clks_enable(mtk); - xhci_mtk_host_enable(mtk); + ret = xhci_mtk_clks_enable(mtk); + if (ret) + goto enable_wakeup; + + ret = xhci_mtk_host_enable(mtk); + if (ret) + goto disable_clks; xhci_dbg(xhci, "%s: restart port polling\n", __func__); set_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags); @@ -682,6 +693,12 @@ static int __maybe_unused xhci_mtk_resume(struct device *dev) set_bit(HCD_FLAG_POLL_RH, &hcd->flags); usb_hcd_poll_rh_status(hcd); return 0; + +disable_clks: + xhci_mtk_clks_disable(mtk); +enable_wakeup: + usb_wakeup_set(mtk, true); + return ret; } static const struct dev_pm_ops xhci_mtk_pm_ops = { |