mirror of https://github.com/torvalds/linux.git
ASoC: Intel: catpt: Round of fixes and PM changes
Merge series from Cezary Rojewski <cezary.rojewski@intel.com>: Set of changes addressing gaps in DRAM offset checks, error paths and PM. The first three patches are straight-forward, the last three relate to the power management. The standing out PM change is removal of the catpt-driver as a system-suspend (S3) blocker. This is a suggestion from Andy as indeed, audio is not a critical component that should prevent the system from going into S3. Whatever happens, the driver can recover on a follow up resume (S3 -> S0).
This commit is contained in:
commit
a76e1d951f
|
|
@ -28,7 +28,7 @@
|
|||
#define CREATE_TRACE_POINTS
|
||||
#include "trace.h"
|
||||
|
||||
static int catpt_suspend(struct device *dev)
|
||||
static int catpt_do_suspend(struct device *dev)
|
||||
{
|
||||
struct catpt_dev *cdev = dev_get_drvdata(dev);
|
||||
struct dma_chan *chan;
|
||||
|
|
@ -72,6 +72,13 @@ static int catpt_suspend(struct device *dev)
|
|||
return catpt_dsp_power_down(cdev);
|
||||
}
|
||||
|
||||
/* Do not block the system from suspending, recover on resume() if needed. */
|
||||
static int catpt_suspend(struct device *dev)
|
||||
{
|
||||
catpt_do_suspend(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int catpt_resume(struct device *dev)
|
||||
{
|
||||
struct catpt_dev *cdev = dev_get_drvdata(dev);
|
||||
|
|
@ -114,7 +121,7 @@ static int catpt_runtime_suspend(struct device *dev)
|
|||
}
|
||||
module_put(dev->driver->owner);
|
||||
|
||||
return catpt_suspend(dev);
|
||||
return catpt_do_suspend(dev);
|
||||
}
|
||||
|
||||
static int catpt_runtime_resume(struct device *dev)
|
||||
|
|
@ -184,22 +191,25 @@ static int catpt_probe_components(struct catpt_dev *cdev)
|
|||
goto err_boot_fw;
|
||||
}
|
||||
|
||||
ret = catpt_register_board(cdev);
|
||||
if (ret) {
|
||||
dev_err(cdev->dev, "register board failed: %d\n", ret);
|
||||
goto err_reg_board;
|
||||
}
|
||||
|
||||
/* reflect actual ADSP state in pm_runtime */
|
||||
pm_runtime_set_active(cdev->dev);
|
||||
|
||||
pm_runtime_set_autosuspend_delay(cdev->dev, 2000);
|
||||
pm_runtime_use_autosuspend(cdev->dev);
|
||||
pm_runtime_mark_last_busy(cdev->dev);
|
||||
/* Enable PM before spawning child device. See catpt_dai_pcm_new(). */
|
||||
pm_runtime_enable(cdev->dev);
|
||||
|
||||
ret = catpt_register_board(cdev);
|
||||
if (ret) {
|
||||
dev_err(cdev->dev, "register board failed: %d\n", ret);
|
||||
goto err_reg_board;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_reg_board:
|
||||
pm_runtime_disable(cdev->dev);
|
||||
snd_soc_unregister_component(cdev->dev);
|
||||
err_boot_fw:
|
||||
catpt_dmac_remove(cdev);
|
||||
|
|
|
|||
|
|
@ -208,6 +208,7 @@ static int catpt_restore_memdumps(struct catpt_dev *cdev, struct dma_chan *chan)
|
|||
|
||||
for (i = 0; i < cdev->dx_ctx.num_meminfo; i++) {
|
||||
struct catpt_save_meminfo *info;
|
||||
struct resource r = {};
|
||||
u32 off;
|
||||
int ret;
|
||||
|
||||
|
|
@ -216,7 +217,8 @@ static int catpt_restore_memdumps(struct catpt_dev *cdev, struct dma_chan *chan)
|
|||
continue;
|
||||
|
||||
off = catpt_to_host_offset(info->offset);
|
||||
if (off < cdev->dram.start || off > cdev->dram.end)
|
||||
resource_set_range(&r, off, info->size);
|
||||
if (!resource_contains(&cdev->dram, &r))
|
||||
continue;
|
||||
|
||||
dev_dbg(cdev->dev, "restoring memdump: off 0x%08x size %d\n",
|
||||
|
|
@ -239,34 +241,32 @@ static int catpt_restore_fwimage(struct catpt_dev *cdev,
|
|||
struct dma_chan *chan, dma_addr_t paddr,
|
||||
struct catpt_fw_block_hdr *blk)
|
||||
{
|
||||
struct resource r1, r2, common;
|
||||
struct resource r1 = {};
|
||||
int i;
|
||||
|
||||
print_hex_dump_debug(__func__, DUMP_PREFIX_OFFSET, 8, 4,
|
||||
blk, sizeof(*blk), false);
|
||||
|
||||
r1.start = cdev->dram.start + blk->ram_offset;
|
||||
r1.end = r1.start + blk->size - 1;
|
||||
resource_set_range(&r1, cdev->dram.start + blk->ram_offset, blk->size);
|
||||
/* advance to data area */
|
||||
paddr += sizeof(*blk);
|
||||
|
||||
for (i = 0; i < cdev->dx_ctx.num_meminfo; i++) {
|
||||
struct catpt_save_meminfo *info;
|
||||
struct resource common = {};
|
||||
struct resource r2 = {};
|
||||
u32 off;
|
||||
int ret;
|
||||
|
||||
info = &cdev->dx_ctx.meminfo[i];
|
||||
|
||||
if (info->source != CATPT_DX_TYPE_FW_IMAGE)
|
||||
continue;
|
||||
|
||||
off = catpt_to_host_offset(info->offset);
|
||||
if (off < cdev->dram.start || off > cdev->dram.end)
|
||||
resource_set_range(&r2, off, info->size);
|
||||
if (!resource_contains(&cdev->dram, &r2))
|
||||
continue;
|
||||
|
||||
r2.start = off;
|
||||
r2.end = r2.start + info->size - 1;
|
||||
|
||||
if (!resource_intersection(&r2, &r1, &common))
|
||||
continue;
|
||||
/* calculate start offset of common data area */
|
||||
|
|
|
|||
|
|
@ -417,8 +417,10 @@ static int catpt_dai_hw_params(struct snd_pcm_substream *substream,
|
|||
return CATPT_IPC_ERROR(ret);
|
||||
|
||||
ret = catpt_dai_apply_usettings(dai, stream);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
catpt_ipc_free_stream(cdev, stream->info.stream_hw_id);
|
||||
return ret;
|
||||
}
|
||||
|
||||
stream->allocated = true;
|
||||
return 0;
|
||||
|
|
@ -669,7 +671,7 @@ static int catpt_dai_pcm_new(struct snd_soc_pcm_runtime *rtm,
|
|||
return 0;
|
||||
|
||||
ret = pm_runtime_resume_and_get(cdev->dev);
|
||||
if (ret < 0 && ret != -EACCES)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = catpt_ipc_set_device_format(cdev, &devfmt);
|
||||
|
|
@ -872,7 +874,7 @@ static int catpt_mixer_volume_get(struct snd_kcontrol *kcontrol,
|
|||
int i;
|
||||
|
||||
ret = pm_runtime_resume_and_get(cdev->dev);
|
||||
if (ret < 0 && ret != -EACCES)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < CATPT_CHANNELS_MAX; i++) {
|
||||
|
|
@ -893,7 +895,7 @@ static int catpt_mixer_volume_put(struct snd_kcontrol *kcontrol,
|
|||
int ret;
|
||||
|
||||
ret = pm_runtime_resume_and_get(cdev->dev);
|
||||
if (ret < 0 && ret != -EACCES)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = catpt_set_dspvol(cdev, cdev->mixer.mixer_hw_id,
|
||||
|
|
@ -924,7 +926,7 @@ static int catpt_stream_volume_get(struct snd_kcontrol *kcontrol,
|
|||
}
|
||||
|
||||
ret = pm_runtime_resume_and_get(cdev->dev);
|
||||
if (ret < 0 && ret != -EACCES)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < CATPT_CHANNELS_MAX; i++) {
|
||||
|
|
@ -955,7 +957,7 @@ static int catpt_stream_volume_put(struct snd_kcontrol *kcontrol,
|
|||
}
|
||||
|
||||
ret = pm_runtime_resume_and_get(cdev->dev);
|
||||
if (ret < 0 && ret != -EACCES)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = catpt_set_dspvol(cdev, stream->info.stream_hw_id,
|
||||
|
|
@ -1031,7 +1033,7 @@ static int catpt_loopback_switch_put(struct snd_kcontrol *kcontrol,
|
|||
}
|
||||
|
||||
ret = pm_runtime_resume_and_get(cdev->dev);
|
||||
if (ret < 0 && ret != -EACCES)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = catpt_ipc_mute_loopback(cdev, stream->info.stream_hw_id, mute);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ static ssize_t fw_version_show(struct device *dev,
|
|||
int ret;
|
||||
|
||||
ret = pm_runtime_resume_and_get(cdev->dev);
|
||||
if (ret < 0 && ret != -EACCES)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = catpt_ipc_get_fw_version(cdev, &version);
|
||||
|
|
|
|||
Loading…
Reference in New Issue