ASoC: Fixes for v7.2

A fairly standard set of driver specific fixes and quirks that have come
in since the merge window, plus a MAINTAINERS update.  The tas675x
READ_ONCE change is probably not actually fixing issues properly but we
need a whole new approach to concurrency there and it came along with
some good fixes.
This commit is contained in:
Takashi Iwai
2026-07-03 09:30:30 +02:00
9 changed files with 86 additions and 19 deletions

View File

@@ -281,7 +281,7 @@ Global Temperature
:Description: Global die temperature sense register.
:Type: Integer (read-only)
:Range: 0 to 255
:Conversion: (value × 0.5 °C) 50 °C
:Conversion: value × 2.19 K; subtract 273.15 for °C
:Register: 0x75
CHx Temperature Range
@@ -289,10 +289,11 @@ CHx Temperature Range
:Description: Per-channel coarse temperature range indicator (x = 1, 2, 3, 4).
:Type: Integer (read-only)
:Range: 0 to 3
:Mapping: 0 = <80 °C, 1 = 80100 °C, 2 = 100120 °C, 3 = >120 °C
:Register: 0xBB bits [7:6] (CH1), bits [5:4] (CH2),
0xBC bits [3:2] (CH3), bits [1:0] (CH4)
:Range: 0 to 7
:Mapping: 0 = <95 °C, 1 = 95110 °C, 2 = 110125 °C, 3 = 125135 °C,
4 = 135145 °C, 5 = 145155 °C, 6 = 155165 °C, 7 = >165 °C
:Register: 0xBB bits [2:0] (CH1), bits [5:3] (CH2),
0xBC bits [2:0] (CH3), bits [5:3] (CH4)
Load Diagnostics
================

View File

@@ -25377,6 +25377,7 @@ M: Bard Liao <yung-chuan.liao@linux.intel.com>
M: Daniel Baluta <daniel.baluta@nxp.com>
R: Kai Vehmanen <kai.vehmanen@linux.intel.com>
R: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
R: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
L: sound-open-firmware@alsa-project.org (moderated for non-subscribers)
S: Supported
W: https://github.com/thesofproject/linux/

View File

@@ -528,6 +528,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Raider A18 HX A9WJG"),
}
},
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Alienware"),
DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m15 R7 AMD"),
}
},
{
.driver_data = &acp6x_card,
.matches = {

View File

@@ -244,6 +244,11 @@ static const struct va_macro_data sm8250_va_data = {
.version = LPASS_CODEC_VERSION_1_0,
};
static const struct va_macro_data sc7280_va_data = {
.has_swr_master = false,
.has_npl_clk = false,
};
static const struct va_macro_data sm8450_va_data = {
.has_swr_master = true,
.has_npl_clk = true,
@@ -1755,7 +1760,7 @@ static const struct dev_pm_ops va_macro_pm_ops = {
};
static const struct of_device_id va_macro_dt_match[] = {
{ .compatible = "qcom,sc7280-lpass-va-macro", .data = &sm8250_va_data },
{ .compatible = "qcom,sc7280-lpass-va-macro", .data = &sc7280_va_data },
{ .compatible = "qcom,sm6115-lpass-va-macro", .data = &sm8450_va_data },
{ .compatible = "qcom,sm8250-lpass-va-macro", .data = &sm8250_va_data },
{ .compatible = "qcom,sm8450-lpass-va-macro", .data = &sm8450_va_data },

View File

@@ -954,10 +954,10 @@ static const struct snd_kcontrol_new tas675x_snd_controls[] = {
/* Temperature and Voltage Monitoring */
SOC_SINGLE_RO("PVDD Sense", TAS675X_PVDD_SENSE_REG, 0, 0xFF),
SOC_SINGLE_RO("Global Temperature", TAS675X_TEMP_GLOBAL_REG, 0, 0xFF),
SOC_SINGLE_RO("CH1 Temperature Range", TAS675X_TEMP_CH1_CH2_REG, 6, 3),
SOC_SINGLE_RO("CH2 Temperature Range", TAS675X_TEMP_CH1_CH2_REG, 4, 3),
SOC_SINGLE_RO("CH3 Temperature Range", TAS675X_TEMP_CH3_CH4_REG, 2, 3),
SOC_SINGLE_RO("CH4 Temperature Range", TAS675X_TEMP_CH3_CH4_REG, 0, 3),
SOC_SINGLE_RO("CH1 Temperature Range", TAS675X_TEMP_CH1_CH2_REG, 0, 7),
SOC_SINGLE_RO("CH2 Temperature Range", TAS675X_TEMP_CH1_CH2_REG, 3, 7),
SOC_SINGLE_RO("CH3 Temperature Range", TAS675X_TEMP_CH3_CH4_REG, 0, 7),
SOC_SINGLE_RO("CH4 Temperature Range", TAS675X_TEMP_CH3_CH4_REG, 3, 7),
/* Speaker Protection & Detection */
SOC_SINGLE("Tweeter Detection Switch", TAS675X_TWEETER_DETECT_CTRL_REG, 0, 1, 1),
@@ -1133,7 +1133,7 @@ static int tas675x_hw_params(struct snd_pcm_substream *substream,
* Single clock domain: SDIN and SDOUT share one SCLK/FSYNC pair,
* so all active DAIs must use the same sample rate.
*/
if ((tas->active_playback_dais || tas->active_capture_dais) &&
if ((READ_ONCE(tas->active_playback_dais) || READ_ONCE(tas->active_capture_dais)) &&
tas->rate && tas->rate != rate) {
dev_err(component->dev,
"Rate %u conflicts with active rate %u\n",
@@ -1397,14 +1397,14 @@ static int tas675x_mute_stream(struct snd_soc_dai *dai, int mute, int direction)
set_bit(dai->id, &tas->active_playback_dais);
/* Last playback stream */
if (mute && !tas->active_playback_dais) {
if (mute && !READ_ONCE(tas->active_playback_dais)) {
ret = tas675x_set_state_all(tas, TAS675X_STATE_SLEEP_BOTH);
regmap_read(tas->regmap, TAS675X_CLK_FAULT_LATCHED_REG, &discard);
return ret;
}
return tas675x_set_state_all(tas,
tas->active_playback_dais ?
READ_ONCE(tas->active_playback_dais) ?
TAS675X_STATE_PLAY_BOTH :
TAS675X_STATE_SLEEP_BOTH);
}

View File

@@ -45,6 +45,7 @@ struct rsnd_adg {
struct rsnd_mod mod;
int clkin_rate[CLKINMAX];
bool ssi_clk_prepared;
bool clk_enabled;
int clkin_size;
int clkout_size;
u32 ckr;
@@ -463,6 +464,22 @@ int rsnd_adg_clk_control(struct rsnd_priv *priv, int enable)
struct clk *clk;
int ret = 0, i;
/*
* rsnd_adg_clk_enable() and rsnd_adg_clk_disable() can be called
* redundantly, for example when system suspend follows a resume
* whose enable failed. Make this function idempotent so that the
* "adg" clock, which has no clkin_rate[] style guard, is never
* disabled twice.
*/
if (enable) {
if (adg->clk_enabled)
return 0;
} else {
if (!adg->clk_enabled)
return 0;
adg->clk_enabled = false;
}
if (enable) {
ret = clk_prepare_enable(adg->adg);
if (ret < 0)
@@ -520,12 +537,22 @@ int rsnd_adg_clk_control(struct rsnd_priv *priv, int enable)
* rsnd_adg_clk_enable() might return error (_disable() will not).
* We need to rollback in such case
*/
if (ret < 0)
if (ret < 0) {
/*
* Mark as enabled so that the rollback below is not
* short-circuited by the idempotency guard. It clears
* the flag again on its way through.
*/
adg->clk_enabled = true;
rsnd_adg_clk_disable(priv);
return ret;
}
/* disable adg */
if (!enable)
clk_disable_unprepare(adg->adg);
else
adg->clk_enabled = true;
return ret;
}

View File

@@ -850,6 +850,7 @@ void rsnd_src_suspend(struct rsnd_priv *priv)
clk_disable_unprepare(src_ctrl->scu_x2);
clk_disable_unprepare(src_ctrl->scu);
clk_disable_unprepare(src_ctrl->scu_supply);
}
void rsnd_src_resume(struct rsnd_priv *priv)
@@ -861,6 +862,7 @@ void rsnd_src_resume(struct rsnd_priv *priv)
if (!src_ctrl)
return;
clk_prepare_enable(src_ctrl->scu_supply);
clk_prepare_enable(src_ctrl->scu);
clk_prepare_enable(src_ctrl->scu_x2);

View File

@@ -107,7 +107,7 @@ static int ipc3_probes_info(struct sof_client_dev *cdev, unsigned int cmd,
struct device *dev = &cdev->auxdev.dev;
struct sof_ipc_probe_info_params msg = {{{0}}};
struct sof_ipc_probe_info_params *reply;
size_t bytes;
size_t bytes, elem_size, payload_size;
int ret;
*params = NULL;
@@ -128,14 +128,29 @@ static int ipc3_probes_info(struct sof_client_dev *cdev, unsigned int cmd,
if (ret < 0 || reply->rhdr.error < 0)
goto exit;
payload_size = reply->rhdr.hdr.size;
if (payload_size < offsetof(struct sof_ipc_probe_info_params, dma)) {
ret = -EINVAL;
goto exit;
}
if (!reply->num_elems)
goto exit;
if (cmd == SOF_IPC_PROBE_DMA_INFO)
bytes = sizeof(reply->dma[0]);
elem_size = sizeof(reply->dma[0]);
else
bytes = sizeof(reply->desc[0]);
bytes *= reply->num_elems;
elem_size = sizeof(reply->desc[0]);
payload_size -= offsetof(struct sof_ipc_probe_info_params, dma);
if (reply->num_elems > payload_size / elem_size) {
dev_err(dev, "%s: invalid probe info element count %u\n",
__func__, reply->num_elems);
ret = -EINVAL;
goto exit;
}
bytes = reply->num_elems * elem_size;
*params = kmemdup(&reply->dma[0], bytes, GFP_KERNEL);
if (!*params) {
ret = -ENOMEM;

View File

@@ -248,10 +248,19 @@ static int ipc4_probes_points_info(struct sof_client_dev *cdev,
return ret;
}
info = msg.data_ptr;
if (msg.data_size < sizeof(*info) ||
info->num_elems > (msg.data_size - sizeof(*info)) /
sizeof(info->points[0])) {
dev_err(dev, "%s: invalid probe info element count %u\n",
__func__, info->num_elems);
kfree(msg.data_ptr);
return -EINVAL;
}
*num_desc = info->num_elems;
dev_dbg(dev, "%s: got %zu probe points", __func__, *num_desc);
*desc = kzalloc(*num_desc * sizeof(**desc), GFP_KERNEL);
*desc = kcalloc(*num_desc, sizeof(**desc), GFP_KERNEL);
if (!*desc) {
kfree(msg.data_ptr);
return -ENOMEM;