Skip to content
Permalink
Browse files
usb: xhci-plat: Add remote wakeup support for xilinx
This patch adds support for enabling remote wakeup capability
to the host controller. If the device has wakeup capability,
then sets the wakeup flag and enable wakeup irq.

Added function registration and deregistration functionality,
to inform the dwc3 driver about the device wakeup capability.
This patch creates an interface between platform and dwc3-host.

Signed-off-by: Piyush Mehta <piyush.mehta@xilinx.com>
  • Loading branch information
Piyush Mehta authored and Michal Simek committed Sep 17, 2021
1 parent 6e383f5 commit 5b2efd9328312427b7830d41ce3c8dfec63457eb
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 0 deletions.
@@ -31,6 +31,8 @@ static struct hc_driver __read_mostly xhci_plat_hc_driver;
static int xhci_plat_setup(struct usb_hcd *hcd);
static int xhci_plat_start(struct usb_hcd *hcd);

static host_wakeup_t host_wakeup_fn;

static const struct xhci_driver_overrides xhci_plat_overrides __initconst = {
.extra_priv_size = sizeof(struct xhci_plat_priv),
.reset = xhci_plat_setup,
@@ -87,6 +89,17 @@ static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci)
xhci->quirks |= XHCI_PLAT | priv->quirks;
}

static void host_wakeup_register(host_wakeup_t func)
{
host_wakeup_fn = func;
}

static void host_wakeup_capable(struct device *dev, bool wakeup)
{
if (host_wakeup_fn)
host_wakeup_fn(dev, wakeup);
}

/* called during probe() after chip reset completes */
static int xhci_plat_setup(struct usb_hcd *hcd)
{
@@ -321,6 +334,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
}

device_set_wakeup_capable(&pdev->dev, true);
host_wakeup_register(dwc3_host_wakeup_capable);

xhci->main_hcd = hcd;
xhci->shared_hcd = __usb_create_hcd(driver, sysdev, &pdev->dev,
@@ -433,6 +447,7 @@ static int xhci_plat_remove(struct platform_device *dev)
xhci->shared_hcd = NULL;
usb_phy_shutdown(hcd->usb_phy);

host_wakeup_register(NULL);
usb_otg_set_host(&dev->dev, hcd, false);

usb_remove_hcd(hcd);
@@ -458,6 +473,15 @@ static int __maybe_unused xhci_plat_suspend(struct device *dev)
ret = xhci_priv_suspend_quirk(hcd);
if (ret)
return ret;

/* Inform dwc3 driver about the device wakeup capability */
if (device_may_wakeup(&hcd->self.root_hub->dev)) {
host_wakeup_capable(dev, true);
enable_irq_wake(hcd->irq);
} else {
host_wakeup_capable(dev, false);
}

/*
* xhci_suspend() needs `do_wakeup` to know whether host is allowed
* to do wakeup during suspend.
@@ -2063,6 +2063,8 @@ void xhci_free_container_ctx(struct xhci_hcd *xhci,

/* xHCI host controller glue */
typedef void (*xhci_get_quirks_t)(struct device *, struct xhci_hcd *);
typedef void (*host_wakeup_t)(struct device *dev, bool wakeup);
void dwc3_host_wakeup_capable(struct device *dev, bool wakeup);
int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, int usec);
void xhci_quiesce(struct xhci_hcd *xhci);
int xhci_halt(struct xhci_hcd *xhci);

0 comments on commit 5b2efd9

Please sign in to comment.