diff options
author | Rander Wang <rander.wang@intel.com> | 2020-08-17 23:29:23 +0800 |
---|---|---|
committer | Vinod Koul <vkoul@kernel.org> | 2020-08-18 12:01:05 +0530 |
commit | 08abad9f45f105e947d91822bdbc47650fbd7773 (patch) | |
tree | 1c8d29542f3a86830c430e63661f1449cbbe3bb6 /drivers/soundwire | |
parent | 61fb830bf9ca02f040fdfe65b714bea492a44986 (diff) |
soundwire: intel: refine runtime pm for SDW_INTEL_CLK_STOP_BUS_RESET
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@intel.com>
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Link: https://lore.kernel.org/r/20200817152923.3259-13-yung-chuan.liao@linux.intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Diffstat (limited to 'drivers/soundwire')
-rw-r--r-- | drivers/soundwire/intel.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c index 2899445e2649..dbcbe2708563 100644 --- a/drivers/soundwire/intel.c +++ b/drivers/soundwire/intel.c @@ -1698,6 +1698,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) { @@ -1740,10 +1742,23 @@ static int intel_resume_runtime(struct device *dev) } /* + * 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) { @@ -1751,7 +1766,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; |