Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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).

+37 -25
+18 -8
sound/soc/intel/catpt/device.c
··· 28 28 #define CREATE_TRACE_POINTS 29 29 #include "trace.h" 30 30 31 - static int catpt_suspend(struct device *dev) 31 + static int catpt_do_suspend(struct device *dev) 32 32 { 33 33 struct catpt_dev *cdev = dev_get_drvdata(dev); 34 34 struct dma_chan *chan; ··· 70 70 if (ret) 71 71 return ret; 72 72 return catpt_dsp_power_down(cdev); 73 + } 74 + 75 + /* Do not block the system from suspending, recover on resume() if needed. */ 76 + static int catpt_suspend(struct device *dev) 77 + { 78 + catpt_do_suspend(dev); 79 + return 0; 73 80 } 74 81 75 82 static int catpt_resume(struct device *dev) ··· 121 114 } 122 115 module_put(dev->driver->owner); 123 116 124 - return catpt_suspend(dev); 117 + return catpt_do_suspend(dev); 125 118 } 126 119 127 120 static int catpt_runtime_resume(struct device *dev) ··· 191 184 goto err_boot_fw; 192 185 } 193 186 194 - ret = catpt_register_board(cdev); 195 - if (ret) { 196 - dev_err(cdev->dev, "register board failed: %d\n", ret); 197 - goto err_reg_board; 198 - } 199 - 200 187 /* reflect actual ADSP state in pm_runtime */ 201 188 pm_runtime_set_active(cdev->dev); 202 189 203 190 pm_runtime_set_autosuspend_delay(cdev->dev, 2000); 204 191 pm_runtime_use_autosuspend(cdev->dev); 205 192 pm_runtime_mark_last_busy(cdev->dev); 193 + /* Enable PM before spawning child device. See catpt_dai_pcm_new(). */ 206 194 pm_runtime_enable(cdev->dev); 195 + 196 + ret = catpt_register_board(cdev); 197 + if (ret) { 198 + dev_err(cdev->dev, "register board failed: %d\n", ret); 199 + goto err_reg_board; 200 + } 201 + 207 202 return 0; 208 203 209 204 err_reg_board: 205 + pm_runtime_disable(cdev->dev); 210 206 snd_soc_unregister_component(cdev->dev); 211 207 err_boot_fw: 212 208 catpt_dmac_remove(cdev);
+9 -9
sound/soc/intel/catpt/loader.c
··· 208 208 209 209 for (i = 0; i < cdev->dx_ctx.num_meminfo; i++) { 210 210 struct catpt_save_meminfo *info; 211 + struct resource r = {}; 211 212 u32 off; 212 213 int ret; 213 214 ··· 217 216 continue; 218 217 219 218 off = catpt_to_host_offset(info->offset); 220 - if (off < cdev->dram.start || off > cdev->dram.end) 219 + resource_set_range(&r, off, info->size); 220 + if (!resource_contains(&cdev->dram, &r)) 221 221 continue; 222 222 223 223 dev_dbg(cdev->dev, "restoring memdump: off 0x%08x size %d\n", ··· 241 239 struct dma_chan *chan, dma_addr_t paddr, 242 240 struct catpt_fw_block_hdr *blk) 243 241 { 244 - struct resource r1, r2, common; 242 + struct resource r1 = {}; 245 243 int i; 246 244 247 245 print_hex_dump_debug(__func__, DUMP_PREFIX_OFFSET, 8, 4, 248 246 blk, sizeof(*blk), false); 249 247 250 - r1.start = cdev->dram.start + blk->ram_offset; 251 - r1.end = r1.start + blk->size - 1; 248 + resource_set_range(&r1, cdev->dram.start + blk->ram_offset, blk->size); 252 249 /* advance to data area */ 253 250 paddr += sizeof(*blk); 254 251 255 252 for (i = 0; i < cdev->dx_ctx.num_meminfo; i++) { 256 253 struct catpt_save_meminfo *info; 254 + struct resource common = {}; 255 + struct resource r2 = {}; 257 256 u32 off; 258 257 int ret; 259 258 260 259 info = &cdev->dx_ctx.meminfo[i]; 261 - 262 260 if (info->source != CATPT_DX_TYPE_FW_IMAGE) 263 261 continue; 264 262 265 263 off = catpt_to_host_offset(info->offset); 266 - if (off < cdev->dram.start || off > cdev->dram.end) 264 + resource_set_range(&r2, off, info->size); 265 + if (!resource_contains(&cdev->dram, &r2)) 267 266 continue; 268 - 269 - r2.start = off; 270 - r2.end = r2.start + info->size - 1; 271 267 272 268 if (!resource_intersection(&r2, &r1, &common)) 273 269 continue;
+9 -7
sound/soc/intel/catpt/pcm.c
··· 417 417 return CATPT_IPC_ERROR(ret); 418 418 419 419 ret = catpt_dai_apply_usettings(dai, stream); 420 - if (ret) 420 + if (ret) { 421 + catpt_ipc_free_stream(cdev, stream->info.stream_hw_id); 421 422 return ret; 423 + } 422 424 423 425 stream->allocated = true; 424 426 return 0; ··· 671 669 return 0; 672 670 673 671 ret = pm_runtime_resume_and_get(cdev->dev); 674 - if (ret < 0 && ret != -EACCES) 672 + if (ret) 675 673 return ret; 676 674 677 675 ret = catpt_ipc_set_device_format(cdev, &devfmt); ··· 874 872 int i; 875 873 876 874 ret = pm_runtime_resume_and_get(cdev->dev); 877 - if (ret < 0 && ret != -EACCES) 875 + if (ret) 878 876 return ret; 879 877 880 878 for (i = 0; i < CATPT_CHANNELS_MAX; i++) { ··· 895 893 int ret; 896 894 897 895 ret = pm_runtime_resume_and_get(cdev->dev); 898 - if (ret < 0 && ret != -EACCES) 896 + if (ret) 899 897 return ret; 900 898 901 899 ret = catpt_set_dspvol(cdev, cdev->mixer.mixer_hw_id, ··· 926 924 } 927 925 928 926 ret = pm_runtime_resume_and_get(cdev->dev); 929 - if (ret < 0 && ret != -EACCES) 927 + if (ret) 930 928 return ret; 931 929 932 930 for (i = 0; i < CATPT_CHANNELS_MAX; i++) { ··· 957 955 } 958 956 959 957 ret = pm_runtime_resume_and_get(cdev->dev); 960 - if (ret < 0 && ret != -EACCES) 958 + if (ret) 961 959 return ret; 962 960 963 961 ret = catpt_set_dspvol(cdev, stream->info.stream_hw_id, ··· 1033 1031 } 1034 1032 1035 1033 ret = pm_runtime_resume_and_get(cdev->dev); 1036 - if (ret < 0 && ret != -EACCES) 1034 + if (ret) 1037 1035 return ret; 1038 1036 1039 1037 ret = catpt_ipc_mute_loopback(cdev, stream->info.stream_hw_id, mute);
+1 -1
sound/soc/intel/catpt/sysfs.c
··· 16 16 int ret; 17 17 18 18 ret = pm_runtime_resume_and_get(cdev->dev); 19 - if (ret < 0 && ret != -EACCES) 19 + if (ret) 20 20 return ret; 21 21 22 22 ret = catpt_ipc_get_fw_version(cdev, &version);