summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/dwc3/dwc3-am62.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/drivers/usb/dwc3/dwc3-am62.c b/drivers/usb/dwc3/dwc3-am62.c
index 859b48279658..b22fb78bc8e7 100644
--- a/drivers/usb/dwc3/dwc3-am62.c
+++ b/drivers/usb/dwc3/dwc3-am62.c
@@ -60,6 +60,13 @@
#define USBSS_WAKEUP_CFG_SESSVALID_EN BIT(1)
#define USBSS_WAKEUP_CFG_VBUSVALID_EN BIT(0)
+#define USBSS_WAKEUP_CFG_ALL (USBSS_WAKEUP_CFG_VBUSVALID_EN | \
+ USBSS_WAKEUP_CFG_SESSVALID_EN | \
+ USBSS_WAKEUP_CFG_LINESTATE_EN | \
+ USBSS_WAKEUP_CFG_OVERCURRENT_EN)
+
+#define USBSS_WAKEUP_CFG_NONE 0
+
/* WAKEUP STAT register bits */
#define USBSS_WAKEUP_STAT_OVERCURRENT BIT(4)
#define USBSS_WAKEUP_STAT_LINESTATE BIT(3)
@@ -103,6 +110,7 @@ struct dwc3_data {
struct regmap *syscon;
unsigned int offset;
unsigned int vbus_divider;
+ u32 wakeup_stat;
};
static const int dwc3_ti_rate_table[] = { /* in KHZ */
@@ -302,12 +310,17 @@ static int dwc3_ti_suspend_common(struct device *dev)
/* Set wakeup config enable bits */
reg = dwc3_ti_readl(data, USBSS_WAKEUP_CONFIG);
if (current_prtcap_dir == DWC3_GCTL_PRTCAP_HOST) {
- reg |= USBSS_WAKEUP_CFG_LINESTATE_EN | USBSS_WAKEUP_CFG_OVERCURRENT_EN;
+ reg = USBSS_WAKEUP_CFG_LINESTATE_EN | USBSS_WAKEUP_CFG_OVERCURRENT_EN;
} else {
- reg |= USBSS_WAKEUP_CFG_OVERCURRENT_EN | USBSS_WAKEUP_CFG_LINESTATE_EN |
- USBSS_WAKEUP_CFG_VBUSVALID_EN;
+ reg = USBSS_WAKEUP_CFG_VBUSVALID_EN | USBSS_WAKEUP_CFG_SESSVALID_EN;
+ /*
+ * Enable LINESTATE wake up only if connected to bus
+ * and in U2/L3 state else it causes spurious wake-up.
+ */
}
dwc3_ti_writel(data, USBSS_WAKEUP_CONFIG, reg);
+ /* clear wakeup status so we know what caused the wake up */
+ dwc3_ti_writel(data, USBSS_WAKEUP_STAT, USBSS_WAKEUP_STAT_CLR);
}
clk_disable_unprepare(data->usb2_refclk);
@@ -324,16 +337,11 @@ static int dwc3_ti_resume_common(struct device *dev)
if (device_may_wakeup(dev)) {
/* Clear wakeup config enable bits */
- reg = dwc3_ti_readl(data, USBSS_WAKEUP_CONFIG);
- reg &= ~(USBSS_WAKEUP_CFG_OVERCURRENT_EN | USBSS_WAKEUP_CFG_LINESTATE_EN |
- USBSS_WAKEUP_CFG_VBUSVALID_EN);
- dwc3_ti_writel(data, USBSS_WAKEUP_CONFIG, reg);
+ dwc3_ti_writel(data, USBSS_WAKEUP_CONFIG, USBSS_WAKEUP_CFG_NONE);
}
reg = dwc3_ti_readl(data, USBSS_WAKEUP_STAT);
- /* Clear the wakeup status with wakeup clear bit */
- reg |= USBSS_WAKEUP_STAT_CLR;
- dwc3_ti_writel(data, USBSS_WAKEUP_STAT, reg);
+ data->wakeup_stat = reg;
return 0;
}