mirror of https://gitee.com/openkylin/linux.git
soundwire: intel: add CLK_STOP_TEARDOWN for pm_runtime suspend
Now that we have options, add support for TEARDOWN mode (same functionality as existing code) All other modes will be added in follow-up patches. Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com> Link: https://lore.kernel.org/r/20200817152923.3259-8-yung-chuan.liao@linux.intel.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
parent
a2d9c161db
commit
a320f41eac
|
@ -1548,6 +1548,7 @@ static int intel_suspend_runtime(struct device *dev)
|
|||
struct sdw_cdns *cdns = dev_get_drvdata(dev);
|
||||
struct sdw_intel *sdw = cdns_to_intel(cdns);
|
||||
struct sdw_bus *bus = &cdns->bus;
|
||||
u32 clock_stop_quirks;
|
||||
int ret;
|
||||
|
||||
if (bus->prop.hw_disabled) {
|
||||
|
@ -1556,21 +1557,31 @@ static int intel_suspend_runtime(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
ret = sdw_cdns_enable_interrupt(cdns, false);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "cannot disable interrupts on suspend\n");
|
||||
return ret;
|
||||
clock_stop_quirks = sdw->link_res->clock_stop_quirks;
|
||||
|
||||
if (clock_stop_quirks & SDW_INTEL_CLK_STOP_TEARDOWN) {
|
||||
|
||||
ret = sdw_cdns_enable_interrupt(cdns, false);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "cannot disable interrupts on suspend\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = intel_link_power_down(sdw);
|
||||
if (ret) {
|
||||
dev_err(dev, "Link power down failed: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
intel_shim_wake(sdw, false);
|
||||
|
||||
} else {
|
||||
dev_err(dev, "%s clock_stop_quirks %x unsupported\n",
|
||||
__func__, clock_stop_quirks);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
ret = intel_link_power_down(sdw);
|
||||
if (ret) {
|
||||
dev_err(dev, "Link power down failed: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
intel_shim_wake(sdw, false);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int intel_resume(struct device *dev)
|
||||
|
@ -1645,6 +1656,7 @@ static int intel_resume_runtime(struct device *dev)
|
|||
struct sdw_cdns *cdns = dev_get_drvdata(dev);
|
||||
struct sdw_intel *sdw = cdns_to_intel(cdns);
|
||||
struct sdw_bus *bus = &cdns->bus;
|
||||
u32 clock_stop_quirks;
|
||||
int ret;
|
||||
|
||||
if (bus->prop.hw_disabled) {
|
||||
|
@ -1653,28 +1665,36 @@ static int intel_resume_runtime(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
ret = intel_init(sdw);
|
||||
if (ret) {
|
||||
dev_err(dev, "%s failed: %d", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
clock_stop_quirks = sdw->link_res->clock_stop_quirks;
|
||||
|
||||
/*
|
||||
* 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_stop_quirks & SDW_INTEL_CLK_STOP_TEARDOWN) {
|
||||
ret = intel_init(sdw);
|
||||
if (ret) {
|
||||
dev_err(dev, "%s failed: %d", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = sdw_cdns_enable_interrupt(cdns, true);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "cannot enable interrupts during resume\n");
|
||||
return ret;
|
||||
}
|
||||
/*
|
||||
* make sure all Slaves are tagged as UNATTACHED and provide
|
||||
* reason for reinitialization
|
||||
*/
|
||||
sdw_clear_slave_status(bus, SDW_UNATTACH_REQUEST_MASTER_RESET);
|
||||
|
||||
ret = sdw_cdns_exit_reset(cdns);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "unable to exit bus reset sequence 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;
|
||||
}
|
||||
|
||||
ret = sdw_cdns_exit_reset(cdns);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "unable to exit bus reset sequence during resume\n");
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
dev_err(dev, "%s clock_stop_quirks %x unsupported\n",
|
||||
__func__, clock_stop_quirks);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
* @dev: device implementing hw_params and free callbacks
|
||||
* @shim_lock: mutex to handle access to shared SHIM registers
|
||||
* @shim_mask: global pointer to check SHIM register initialization
|
||||
* @clock_stop_quirks: mask defining requested behavior on pm_suspend
|
||||
* @cdns: Cadence master descriptor
|
||||
* @list: used to walk-through all masters exposed by the same controller
|
||||
*/
|
||||
|
@ -31,6 +32,7 @@ struct sdw_intel_link_res {
|
|||
struct device *dev;
|
||||
struct mutex *shim_lock; /* protect shared registers */
|
||||
u32 *shim_mask;
|
||||
u32 clock_stop_quirks;
|
||||
struct sdw_cdns *cdns;
|
||||
struct list_head list;
|
||||
};
|
||||
|
|
|
@ -249,6 +249,7 @@ static struct sdw_intel_ctx
|
|||
link->ops = res->ops;
|
||||
link->dev = res->dev;
|
||||
|
||||
link->clock_stop_quirks = res->clock_stop_quirks;
|
||||
link->shim_lock = &ctx->shim_lock;
|
||||
link->shim_mask = &ctx->shim_mask;
|
||||
|
||||
|
|
Loading…
Reference in New Issue