Merge "USB: dwc3: msm: Don't disable/enable clocks if in lpm during block reset"
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 475729c..35334c0 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -1057,6 +1057,7 @@
}
EXPORT_SYMBOL(dwc3_tx_fifo_resize_request);
+static int dwc3_msm_link_clk_reset(struct dwc3_msm *mdwc, bool assert);
static void dwc3_resume_work(struct work_struct *w);
static void dwc3_msm_block_reset(struct dwc3_ext_xceiv *xceiv, bool core_reset);
@@ -1067,6 +1068,7 @@
struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);
enum dwc3_chg_type chg_type;
unsigned timeout = 50;
+ int ret = 0;
dev_dbg(mdwc->dev, "%s\n", __func__);
@@ -1104,7 +1106,15 @@
/* perform block reset after ERROR events */
if (dwc->err_evt_seen) {
dev_dbg(mdwc->dev, "%s initiating block reset\n", __func__);
- dwc3_msm_block_reset(&mdwc->ext_xceiv, true);
+ ret = dwc3_msm_link_clk_reset(mdwc, 1);
+ if (ret)
+ dev_err(mdwc->dev, "%s: clk assert failed\n", __func__);
+
+ usleep_range(1000, 1200);
+ ret = dwc3_msm_link_clk_reset(mdwc, 0);
+ if (ret)
+ dev_err(mdwc->dev, "%s:clk deassrt failed\n", __func__);
+ usleep_range(10000, 12000);
}
dwc->err_evt_seen = false;
/* Force reconnect only if cable is still connected */
@@ -1400,9 +1410,11 @@
if (assert) {
/* Using asynchronous block reset to the hardware */
dev_dbg(mdwc->dev, "block_reset ASSERT\n");
- clk_disable_unprepare(mdwc->ref_clk);
- clk_disable_unprepare(mdwc->iface_clk);
- clk_disable_unprepare(mdwc->core_clk);
+ if (!atomic_read(&mdwc->in_lpm)) {
+ clk_disable_unprepare(mdwc->ref_clk);
+ clk_disable_unprepare(mdwc->iface_clk);
+ clk_disable_unprepare(mdwc->core_clk);
+ }
ret = clk_reset(mdwc->core_clk, CLK_RESET_ASSERT);
if (ret)
dev_err(mdwc->dev, "dwc3 core_clk assert failed\n");
@@ -1410,9 +1422,11 @@
dev_dbg(mdwc->dev, "block_reset DEASSERT\n");
ret = clk_reset(mdwc->core_clk, CLK_RESET_DEASSERT);
ndelay(200);
- clk_prepare_enable(mdwc->core_clk);
- clk_prepare_enable(mdwc->ref_clk);
- clk_prepare_enable(mdwc->iface_clk);
+ if (!atomic_read(&mdwc->in_lpm)) {
+ clk_prepare_enable(mdwc->core_clk);
+ clk_prepare_enable(mdwc->ref_clk);
+ clk_prepare_enable(mdwc->iface_clk);
+ }
if (ret)
dev_err(mdwc->dev, "dwc3 core_clk deassert failed\n");
}