Unverified Commit b3f3ca04 authored by Mark Brown's avatar Mark Brown
Browse files

ASoC: Intel: avs: Set of functional fixes

Merge series from Cezary Rojewski <cezary.rojewski@intel.com>:

Medium range of fixes all avs-driver related. The most important fixes
lead the way:

1. For ASoC-hda codec driver, existing RPM manipulation in
hda_codec_probe_complete()'s error path is superfluous and leads to RPM
usage count underflow if the probe exists early e.g.: build-controls
operation fails.

2. Resolve deadlock when DSP-recovery is a consequence of SET_D0IX IPC.
The procedure handling IPC timeouts and EXCEPTION_CAUGHT notification
shall cancel any D0IX work before proceeding with DSP recovery. If
SET_D0IX called from delayed_work is the failing IPC the procedure will
deadlock.

3. LINK format (PPLCxFMT) calculation is incorrect.
HDAudio transfer types utilize SDxFMT for front-end (HOST) and PPLCxFMT
for back-end (LINK) side when setting up the stream. BE's
substream->runtime duplicates FE runtime so switch to using BE's
hw_params to address incorrect format values on the LINK side when FE
and BE formats differ.

Below three patches address problems found by Coverity static analyzer:
  ASoC: Intel: avs: Fix possible null-ptr-deref when initing hw
  ASoC: Intel: avs: Verify kcalloc() status when setting constraints
  ASoC: Intel: avs: Verify content returned by parse_int_array()

While unlikely in runtime, it's good to keep code resilient. The last
few patches are readability/cohesiveness improvements.
parents bae071aa 38b1befc
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -152,7 +152,7 @@ int hda_codec_probe_complete(struct hda_codec *codec)
	ret = snd_hda_codec_build_controls(codec);
	if (ret < 0) {
		dev_err(&hdev->dev, "unable to create controls %d\n", ret);
		goto out;
		return ret;
	}

	/* Bus suspended codecs as it does not manage their pm */
@@ -160,7 +160,7 @@ int hda_codec_probe_complete(struct hda_codec *codec)
	/* rpm was forbidden in snd_hda_codec_device_new() */
	snd_hda_codec_set_power_save(codec, 2000);
	snd_hda_codec_register(codec);
out:

	/* Complement pm_runtime_get_sync(bus) in probe */
	pm_runtime_mark_last_busy(bus->dev);
	pm_runtime_put_autosuspend(bus->dev);
+10 −10
Original line number Diff line number Diff line
@@ -945,14 +945,14 @@ MODULE_AUTHOR("Cezary Rojewski <cezary.rojewski@intel.com>");
MODULE_AUTHOR("Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>");
MODULE_DESCRIPTION("Intel cAVS sound driver");
MODULE_LICENSE("GPL");
MODULE_FIRMWARE("intel/skl/dsp_basefw.bin");
MODULE_FIRMWARE("intel/apl/dsp_basefw.bin");
MODULE_FIRMWARE("intel/cnl/dsp_basefw.bin");
MODULE_FIRMWARE("intel/icl/dsp_basefw.bin");
MODULE_FIRMWARE("intel/jsl/dsp_basefw.bin");
MODULE_FIRMWARE("intel/lkf/dsp_basefw.bin");
MODULE_FIRMWARE("intel/tgl/dsp_basefw.bin");
MODULE_FIRMWARE("intel/ehl/dsp_basefw.bin");
MODULE_FIRMWARE("intel/adl/dsp_basefw.bin");
MODULE_FIRMWARE("intel/adl_n/dsp_basefw.bin");
MODULE_FIRMWARE("intel/avs/skl/dsp_basefw.bin");
MODULE_FIRMWARE("intel/avs/apl/dsp_basefw.bin");
MODULE_FIRMWARE("intel/avs/cnl/dsp_basefw.bin");
MODULE_FIRMWARE("intel/avs/icl/dsp_basefw.bin");
MODULE_FIRMWARE("intel/avs/jsl/dsp_basefw.bin");
MODULE_FIRMWARE("intel/avs/lkf/dsp_basefw.bin");
MODULE_FIRMWARE("intel/avs/tgl/dsp_basefw.bin");
MODULE_FIRMWARE("intel/avs/ehl/dsp_basefw.bin");
MODULE_FIRMWARE("intel/avs/adl/dsp_basefw.bin");
MODULE_FIRMWARE("intel/avs/adl_n/dsp_basefw.bin");
MODULE_FIRMWARE("intel/fcl/dsp_basefw.bin");
+5 −1
Original line number Diff line number Diff line
@@ -373,7 +373,10 @@ static ssize_t trace_control_write(struct file *file, const char __user *from, s
		return ret;

	num_elems = *array;
	resource_mask = array[1];
	if (!num_elems) {
		ret = -EINVAL;
		goto free_array;
	}

	/*
	 * Disable if just resource mask is provided - no log priority flags.
@@ -381,6 +384,7 @@ static ssize_t trace_control_write(struct file *file, const char __user *from, s
	 * Enable input format:   mask, prio1, .., prioN
	 * Where 'N' equals number of bits set in the 'mask'.
	 */
	resource_mask = array[1];
	if (num_elems == 1) {
		ret = disable_logs(adev, resource_mask);
	} else {
+3 −1
Original line number Diff line number Diff line
@@ -169,6 +169,8 @@ static void avs_dsp_exception_caught(struct avs_dev *adev, union avs_notify_msg

	dev_crit(adev->dev, "communication severed, rebooting dsp..\n");

	/* Avoid deadlock as the exception may be the response to SET_D0IX. */
	if (current_work() != &ipc->d0ix_work.work)
		cancel_delayed_work_sync(&ipc->d0ix_work);
	ipc->in_d0ix = false;
	/* Re-enabled on recovery completion. */
+1 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#include <linux/firmware.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <sound/hdaudio.h>
#include <sound/hdaudio_ext.h>
#include "avs.h"
Loading