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

Commit c79ef74a authored by Sriharsha Allenki's avatar Sriharsha Allenki Committed by Gerrit - the friendly Code Review server
Browse files

xhci-plat: Add hibernation support to xhci platform



Add hibernation support to xhci platform by adding
the proper PM ops freeze and restore.
Also set the hibernated argument to xhci_resume which
will trigger the reset-resume of the connected
root-hubs and the devices.

Change-Id: Ib536bb2485928326f34bfc3422b672cc62309efe
Signed-off-by: default avatarSriharsha Allenki <sallenki@codeaurora.org>
parent 3ec8544d
Loading
Loading
Loading
Loading
+36 −1
Original line number Diff line number Diff line
@@ -439,6 +439,39 @@ static int xhci_plat_runtime_idle(struct device *dev)
	return -EBUSY;
}

static int xhci_plat_pm_freeze(struct device *dev)
{
	struct usb_hcd *hcd = dev_get_drvdata(dev);
	struct xhci_hcd *xhci = hcd_to_xhci(hcd);

	if (!xhci)
		return 0;

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

	return xhci_suspend(xhci, false);
}

static int xhci_plat_pm_restore(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 restore\n");

	ret = xhci_resume(xhci, true);
	pm_runtime_disable(dev);
	pm_runtime_set_active(dev);
	pm_runtime_enable(dev);
	pm_runtime_mark_last_busy(dev);

	return ret;
}

static int xhci_plat_runtime_suspend(struct device *dev)
{
	struct usb_hcd *hcd = dev_get_drvdata(dev);
@@ -470,7 +503,9 @@ static int xhci_plat_runtime_resume(struct device *dev)
}

static const struct dev_pm_ops xhci_plat_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(NULL, NULL)
	.freeze		= xhci_plat_pm_freeze,
	.restore	= xhci_plat_pm_restore,
	.thaw		= xhci_plat_pm_restore,
	SET_RUNTIME_PM_OPS(xhci_plat_runtime_suspend, xhci_plat_runtime_resume,
			   xhci_plat_runtime_idle)
};
+4 −2
Original line number Diff line number Diff line
@@ -947,7 +947,7 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
	struct usb_hcd		*hcd = xhci_to_hcd(xhci);
	u32			command;

	if (!hcd->state)
	if (!hcd->state || xhci->suspended)
		return 0;

	if (hcd->state != HC_STATE_SUSPENDED ||
@@ -1017,6 +1017,7 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
	/* step 5: remove core well power */
	/* synchronize irq when using MSI-X */
	xhci_msix_sync_irqs(xhci);
	xhci->suspended = true;

	return rc;
}
@@ -1036,7 +1037,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
	int			retval = 0;
	bool			comp_timer_running = false;

	if (!hcd->state)
	if (!hcd->state || !xhci->suspended)
		return 0;

	/* Wait a bit if either of the roothubs need to settle from the
@@ -1173,6 +1174,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)

	/* Re-enable port polling. */
	xhci_dbg(xhci, "%s: starting port polling.\n", __func__);
	xhci->suspended = false;
	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);
+1 −0
Original line number Diff line number Diff line
@@ -1697,6 +1697,7 @@ struct xhci_hcd {
	/* Compliance Mode Recovery Data */
	struct timer_list	comp_mode_recovery_timer;
	u32			port_status_u0;
	bool			suspended;
/* Compliance Mode Timer Triggered every 2 seconds */
#define COMP_MODE_RCVRY_MSECS 2000