From: Rander Wang <rander.wang@xxxxxxxxx> When all the links are suspended, the HDaudio controller may suspend and the power rails to the SoundWire IP may be disabled, requiring a complete re-initialization/enumeration on resume. However, if one or more Masters remained active, the HDaudio controller will remain active and the power rails will remain enabled. As a result, during the link resume step we can check if the context was preserved by verifying if the clock was stopped, and avoid doing a complete bus reset and re-enumeration. Signed-off-by: Rander Wang <rander.wang@xxxxxxxxx> Signed-off-by: Bard Liao <yung-chuan.liao@xxxxxxxxxxxxxxx> --- drivers/soundwire/intel.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c index 22b3359855c5..da279b175848 100644 --- a/drivers/soundwire/intel.c +++ b/drivers/soundwire/intel.c @@ -1701,6 +1701,8 @@ static int intel_resume_runtime(struct device *dev) struct sdw_intel *sdw = cdns_to_intel(cdns); struct sdw_bus *bus = &cdns->bus; u32 clock_stop_quirks; + bool clock_stop0; + int status; int ret; if (bus->prop.hw_disabled) { @@ -1742,11 +1744,24 @@ static int intel_resume_runtime(struct device *dev) return ret; } + /* + * An exception condition occurs for the CLK_STOP_BUS_RESET + * case if one or more masters remain active. In this condition, + * all the masters are powered on for they are in the same power + * domain. Master can preserve its context for clock stop0, so + * there is no need to clear slave status and reset bus. + */ + clock_stop0 = sdw_cdns_is_clock_stop(&sdw->cdns); + /* * make sure all Slaves are tagged as UNATTACHED and * provide reason for reinitialization */ - sdw_clear_slave_status(bus, SDW_UNATTACH_REQUEST_MASTER_RESET); + if (!clock_stop0) { + status = SDW_UNATTACH_REQUEST_MASTER_RESET; + sdw_clear_slave_status(bus, status); + } + ret = sdw_cdns_enable_interrupt(cdns, true); if (ret < 0) { @@ -1754,7 +1769,7 @@ static int intel_resume_runtime(struct device *dev) return ret; } - ret = sdw_cdns_clock_restart(cdns, true); + ret = sdw_cdns_clock_restart(cdns, !clock_stop0); if (ret < 0) { dev_err(dev, "unable to restart clock during resume\n"); return ret; -- 2.17.1