Skip to content

Commit

Permalink
soundwire: intel: refine runtime pm for SDW_INTEL_CLK_STOP_BUS_RESET
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
RanderWang committed Dec 12, 2019
1 parent 6fa65e2 commit 747a342
Showing 1 changed file with 16 additions and 3 deletions.
19 changes: 16 additions & 3 deletions drivers/soundwire/intel.c
Original file line number Diff line number Diff line change
Expand Up @@ -1696,6 +1696,8 @@ static int intel_resume_runtime(struct device *dev)
struct sdw_cdns *cdns = dev_get_drvdata(dev);
struct sdw_intel *sdw = cdns_to_intel(cdns);
u32 clock_stop_quirks;
bool clock_stop0;
int status;
int ret;

if (cdns->bus.prop.hw_disabled) {
Expand Down Expand Up @@ -1740,20 +1742,31 @@ 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(&sdw->cdns.bus,
SDW_UNATTACH_REQUEST_MASTER_RESET);
if (!clock_stop0) {
status = SDW_UNATTACH_REQUEST_MASTER_RESET;
sdw_clear_slave_status(&sdw->cdns.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_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;
Expand Down

0 comments on commit 747a342

Please sign in to comment.