> >cdns3 has some special PM sequence between xhci_bus_suspend and >xhci_suspend, add quirk to implement it. > >Signed-off-by: Peter Chen <peter.chen@xxxxxxx> >--- > drivers/usb/cdns3/host-export.h | 6 +++++ > drivers/usb/cdns3/host.c | 40 +++++++++++++++++++++++++++++++++ > 2 files changed, 46 insertions(+) > >diff --git a/drivers/usb/cdns3/host-export.h b/drivers/usb/cdns3/host-export.h >index ae11810f8826..26041718a086 100644 >--- a/drivers/usb/cdns3/host-export.h >+++ b/drivers/usb/cdns3/host-export.h >@@ -9,9 +9,11 @@ > #ifndef __LINUX_CDNS3_HOST_EXPORT > #define __LINUX_CDNS3_HOST_EXPORT > >+struct usb_hcd; > #ifdef CONFIG_USB_CDNS3_HOST > > int cdns3_host_init(struct cdns3 *cdns); >+int xhci_cdns3_suspend_quirk(struct usb_hcd *hcd); > > #else > >@@ -21,6 +23,10 @@ static inline int cdns3_host_init(struct cdns3 *cdns) > } > > static inline void cdns3_host_exit(struct cdns3 *cdns) { } >+static inline int xhci_cdns3_suspend_quirk(struct usb_hcd *hcd) >+{ >+ return 0; >+} > > #endif /* CONFIG_USB_CDNS3_HOST */ > >diff --git a/drivers/usb/cdns3/host.c b/drivers/usb/cdns3/host.c >index b579ef15f4e0..030d6421abd3 100644 >--- a/drivers/usb/cdns3/host.c >+++ b/drivers/usb/cdns3/host.c >@@ -14,6 +14,18 @@ > #include "drd.h" > #include "host-export.h" > #include <linux/usb/hcd.h> >+#include "../host/xhci.h" >+#include "../host/xhci-plat.h" >+ >+#define XECP_PORT_CAP_REG 0x8000 >+#define XECP_AUX_CTRL_REG1 0x8120 >+ >+#define CFG_RXDET_P3_EN (1 << 15) >+#define LPM_2_STB_SWITCH_EN (1 << 25) >+ Please use BIT(15) and BIT(25) Reviewed-by: Pawel Laszczak <pawell@xxxxxxxxxxx> Regards Pawel >+static const struct xhci_plat_priv xhci_plat_cdns3_xhci = { >+ .suspend_quirk = xhci_cdns3_suspend_quirk, >+}; > > static int __cdns3_host_init(struct cdns3 *cdns) > { >@@ -39,6 +51,11 @@ static int __cdns3_host_init(struct cdns3 *cdns) > goto err1; > } > >+ ret = platform_device_add_data(xhci, &xhci_plat_cdns3_xhci, >+ sizeof(struct xhci_plat_priv)); >+ if (ret) >+ goto err1; >+ > ret = platform_device_add(xhci); > if (ret) { > dev_err(cdns->dev, "failed to register xHCI device\n"); >@@ -56,6 +73,29 @@ static int __cdns3_host_init(struct cdns3 *cdns) > return ret; > } > >+int xhci_cdns3_suspend_quirk(struct usb_hcd *hcd) >+{ >+ struct xhci_hcd *xhci = hcd_to_xhci(hcd); >+ u32 value; >+ >+ /* set usbcmd.EU3S */ >+ value = readl(&xhci->op_regs->command); >+ value |= CMD_PM_INDEX; >+ writel(value, &xhci->op_regs->command); >+ >+ if (hcd->regs) { >+ value = readl(hcd->regs + XECP_AUX_CTRL_REG1); >+ value |= CFG_RXDET_P3_EN; >+ writel(value, hcd->regs + XECP_AUX_CTRL_REG1); >+ >+ value = readl(hcd->regs + XECP_PORT_CAP_REG); >+ value |= LPM_2_STB_SWITCH_EN; >+ writel(value, hcd->regs + XECP_PORT_CAP_REG); >+ } >+ >+ return 0; >+} >+ > static void cdns3_host_exit(struct cdns3 *cdns) > { > platform_device_unregister(cdns->host_dev); >-- >2.17.1