From: Pierre-Louis Bossart <pierre-louis.boss...@linux.intel.com>

Deal with the BUS_RESET case, which is the default. The only change is
to add support for the exit sequence using the syncArm/syncGo mode for
the exit reset sequence.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.boss...@linux.intel.com>
Signed-off-by: Bard Liao <yung-chuan.l...@linux.intel.com>
---
 drivers/soundwire/intel.c | 49 +++++++++++++++++++++++++++++++--------
 1 file changed, 39 insertions(+), 10 deletions(-)

diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
index 259e3da98e42..8634d33c388c 100644
--- a/drivers/soundwire/intel.c
+++ b/drivers/soundwire/intel.c
@@ -1868,11 +1868,6 @@ static int intel_resume_runtime(struct device *dev)
 
                if (!clock_stop0) {
 
-                       /*
-                        * Re-initialize the IP since it was powered-off
-                        */
-                       sdw_cdns_init(&sdw->cdns);
-
                        /*
                         * make sure all Slaves are tagged as UNATTACHED and
                         * provide reason for reinitialization
@@ -1880,13 +1875,31 @@ static int intel_resume_runtime(struct device *dev)
 
                        status = SDW_UNATTACH_REQUEST_MASTER_RESET;
                        sdw_clear_slave_status(bus, status);
-               }
 
+                       ret = sdw_cdns_enable_interrupt(cdns, true);
+                       if (ret < 0) {
+                               dev_err(dev, "cannot enable interrupts during 
resume\n");
+                               return ret;
+                       }
 
-               ret = sdw_cdns_enable_interrupt(cdns, true);
-               if (ret < 0) {
-                       dev_err(dev, "cannot enable interrupts during 
resume\n");
-                       return ret;
+                       /*
+                        * follow recommended programming flows to avoid
+                        * timeouts when gsync is enabled
+                        */
+                       if (multi_link)
+                               intel_shim_sync_arm(sdw);
+
+                       /*
+                        * Re-initialize the IP since it was powered-off
+                        */
+                       sdw_cdns_init(&sdw->cdns);
+
+               } else {
+                       ret = sdw_cdns_enable_interrupt(cdns, true);
+                       if (ret < 0) {
+                               dev_err(dev, "cannot enable interrupts during 
resume\n");
+                               return ret;
+                       }
                }
 
                ret = sdw_cdns_clock_restart(cdns, !clock_stop0);
@@ -1894,6 +1907,22 @@ static int intel_resume_runtime(struct device *dev)
                        dev_err(dev, "unable to restart clock during resume\n");
                        return ret;
                }
+
+               if (!clock_stop0) {
+                       ret = sdw_cdns_exit_reset(cdns);
+                       if (ret < 0) {
+                               dev_err(dev, "unable to exit bus reset sequence 
during resume\n");
+                               return ret;
+                       }
+
+                       if (multi_link) {
+                               ret = intel_shim_sync_go(sdw);
+                               if (ret < 0) {
+                                       dev_err(sdw->cdns.dev, "sync go failed 
during resume\n");
+                                       return ret;
+                               }
+                       }
+               }
        } else if (!clock_stop_quirks) {
                ret = intel_init(sdw);
                if (ret) {
-- 
2.17.1

Reply via email to