Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dc281958 authored by Hemant Kumar's avatar Hemant Kumar Committed by Mayank Rana
Browse files

usb: xhci-plat: Add runtime autosuspend delay



When 2.0 Hub device is connected to a suspended root hub,
pm_runtime_idle/suspend is executed right after
pm_runtime_resume resulting in xhci_suspend before connect
interrupt is properly handled. xhci_suspend() clears the
HCD_FLAG_HW_ACCESSIBLE flag as a result when xhci_irq()
comes it does not get handled resulting into interrupt
storm causing watchdog bark. Even if xhci interrupt is
allowed to handle upon xhci suspend causing device
enumeration failure as controller becomes unresponsive and
enable slot command times out and phy does not go to IN L2.
Fix this issue by adding 1 second autosuspend delay which
aborts the pm_runtime_idle() to prevent xhci_suspend()in the
middle of device enumeration.

CRs-Fixed: 847142
Change-Id: Icbcab76510b732731d61fc212d9079f4c9a92e5f
Signed-off-by: default avatarHemant Kumar <hemantk@codeaurora.org>
Signed-off-by: default avatarMayank Rana <mrana@codeaurora.org>
parent c67f84f6
Loading
Loading
Loading
Loading
+19 −3
Original line number Diff line number Diff line
@@ -135,6 +135,8 @@ static int xhci_plat_probe(struct platform_device *pdev)
	if (pdev->dev.parent)
		pm_runtime_resume(pdev->dev.parent);

	pm_runtime_use_autosuspend(&pdev->dev);
	pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
	pm_runtime_set_active(&pdev->dev);
	pm_runtime_enable(&pdev->dev);
	pm_runtime_get_sync(&pdev->dev);
@@ -174,7 +176,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
	if (ret)
		goto put_usb3_hcd;

	pm_runtime_put(&pdev->dev);
	pm_runtime_put_autosuspend(&pdev->dev);

	return 0;

@@ -240,6 +242,16 @@ static int xhci_plat_resume(struct device *dev)
}

#ifdef CONFIG_PM_RUNTIME
static int xhci_plat_runtime_idle(struct device *dev)
{
	if (pm_runtime_autosuspend_expiration(dev)) {
		pm_runtime_autosuspend(dev);
		return -EAGAIN;
	}

	return 0;
}

static int xhci_plat_runtime_suspend(struct device *dev)
{
	struct usb_hcd *hcd = dev_get_drvdata(dev);
@@ -257,20 +269,24 @@ static int xhci_plat_runtime_resume(struct device *dev)
{
	struct usb_hcd *hcd = dev_get_drvdata(dev);
	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
	int ret;

	if (!xhci)
		return 0;

	dev_dbg(dev, "xhci-plat runtime resume\n");

	return xhci_resume(xhci, false);
	ret = xhci_resume(xhci, false);
	pm_runtime_mark_last_busy(dev);

	return ret;
}
#endif

static const struct dev_pm_ops xhci_plat_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(xhci_plat_suspend, xhci_plat_resume)
	SET_RUNTIME_PM_OPS(xhci_plat_runtime_suspend, xhci_plat_runtime_resume,
			   NULL)
			   xhci_plat_runtime_idle)
};
#define DEV_PM_OPS	(&xhci_plat_pm_ops)
#else