Commit 4f876bfd authored by Takashi Iwai's avatar Takashi Iwai

Merge tag 'asoc-fix-v6.2-rc5' of...

Merge tag 'asoc-fix-v6.2-rc5' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus

ASoC: Fixes for v6.2

An unfortunately large batch of fixes here, the numbers amplified
by several repeated fixes for patterns of bugs in multiple
drivers.  Most of this is in the x86 drivers which are very
actively developed, the implementation of PCI shutdown is a fix
for issues with spamming warnings into the logs with a leaked
reference to the i915 driver.
parents 53466ebd e18c6da6
......@@ -193,6 +193,7 @@ static int snd_dw_hdmi_probe(struct platform_device *pdev)
struct hdmi_codec_pdata pdata;
struct platform_device *platform;
memset(&pdata, 0, sizeof(pdata));
pdata.ops = &dw_hdmi_i2s_ops;
pdata.i2s = 1;
pdata.max_i2s_channels = 8;
......
......@@ -198,9 +198,11 @@ static int st_es8336_late_probe(struct snd_soc_card *card)
int ret;
adev = acpi_dev_get_first_match_dev("ESSX8336", NULL, -1);
if (adev)
put_device(&adev->dev);
if (!adev)
return -ENODEV;
codec_dev = acpi_get_first_physical_node(adev);
acpi_dev_put(adev);
if (!codec_dev)
dev_err(card->dev, "can not find codec dev\n");
......
......@@ -227,6 +227,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Redmi Book Pro 14 2022"),
}
},
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "TIMI"),
DMI_MATCH(DMI_PRODUCT_NAME, "Redmi Book Pro 15 2022"),
}
},
{
.driver_data = &acp6x_card,
.matches = {
......@@ -234,6 +241,20 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Blade 14 (2022) - RZ09-0427"),
}
},
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "RB"),
DMI_MATCH(DMI_PRODUCT_NAME, "Swift SFA16-41"),
}
},
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "IRBIS"),
DMI_MATCH(DMI_PRODUCT_NAME, "15NBC1011"),
}
},
{}
};
......
......@@ -1191,18 +1191,12 @@ static int cs42l56_i2c_probe(struct i2c_client *i2c_client)
if (pdata) {
cs42l56->pdata = *pdata;
} else {
pdata = devm_kzalloc(&i2c_client->dev, sizeof(*pdata),
GFP_KERNEL);
if (!pdata)
return -ENOMEM;
if (i2c_client->dev.of_node) {
ret = cs42l56_handle_of_data(i2c_client,
&cs42l56->pdata);
if (ret != 0)
return ret;
}
cs42l56->pdata = *pdata;
}
if (cs42l56->pdata.gpio_nreset) {
......
......@@ -1359,8 +1359,8 @@ static struct snd_soc_dai_driver wsa883x_dais[] = {
.stream_name = "SPKR Playback",
.rates = WSA883X_RATES | WSA883X_FRAC_RATES,
.formats = WSA883X_FORMATS,
.rate_max = 8000,
.rate_min = 352800,
.rate_min = 8000,
.rate_max = 352800,
.channels_min = 1,
.channels_max = 1,
},
......
......@@ -481,6 +481,29 @@ static int avs_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
return ret;
}
static void avs_pci_shutdown(struct pci_dev *pci)
{
struct hdac_bus *bus = pci_get_drvdata(pci);
struct avs_dev *adev = hdac_to_avs(bus);
cancel_work_sync(&adev->probe_work);
avs_ipc_block(adev->ipc);
snd_hdac_stop_streams(bus);
avs_dsp_op(adev, int_control, false);
snd_hdac_ext_bus_ppcap_int_enable(bus, false);
snd_hdac_ext_bus_link_power_down_all(bus);
snd_hdac_bus_stop_chip(bus);
snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, false);
if (avs_platattr_test(adev, CLDMA))
pci_free_irq(pci, 0, &code_loader);
pci_free_irq(pci, 0, adev);
pci_free_irq(pci, 0, bus);
pci_free_irq_vectors(pci);
}
static void avs_pci_remove(struct pci_dev *pci)
{
struct hdac_device *hdev, *save;
......@@ -739,6 +762,7 @@ static struct pci_driver avs_pci_driver = {
.id_table = avs_ids,
.probe = avs_pci_probe,
.remove = avs_pci_remove,
.shutdown = avs_pci_shutdown,
.driver = {
.pm = &avs_dev_pm,
},
......
......@@ -497,21 +497,28 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
if (adev) {
snprintf(codec_name, sizeof(codec_name),
"i2c-%s", acpi_dev_name(adev));
put_device(&adev->dev);
byt_cht_es8316_dais[dai_index].codecs->name = codec_name;
} else {
dev_err(dev, "Error cannot find '%s' dev\n", mach->id);
return -ENXIO;
}
codec_dev = acpi_get_first_physical_node(adev);
acpi_dev_put(adev);
if (!codec_dev)
return -EPROBE_DEFER;
priv->codec_dev = get_device(codec_dev);
/* override platform name, if required */
byt_cht_es8316_card.dev = dev;
platform_name = mach->mach_params.platform;
ret = snd_soc_fixup_dai_links_platform_name(&byt_cht_es8316_card,
platform_name);
if (ret)
if (ret) {
put_device(codec_dev);
return ret;
}
/* Check for BYTCR or other platform and setup quirks */
dmi_id = dmi_first_match(byt_cht_es8316_quirk_table);
......@@ -539,13 +546,10 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
/* get the clock */
priv->mclk = devm_clk_get(dev, "pmc_plt_clk_3");
if (IS_ERR(priv->mclk))
if (IS_ERR(priv->mclk)) {
put_device(codec_dev);
return dev_err_probe(dev, PTR_ERR(priv->mclk), "clk_get pmc_plt_clk_3 failed\n");
codec_dev = acpi_get_first_physical_node(adev);
if (!codec_dev)
return -EPROBE_DEFER;
priv->codec_dev = get_device(codec_dev);
}
if (quirk & BYT_CHT_ES8316_JD_INVERTED)
props[cnt++] = PROPERTY_ENTRY_BOOL("everest,jack-detect-inverted");
......
......@@ -1636,13 +1636,18 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
if (adev) {
snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name),
"i2c-%s", acpi_dev_name(adev));
put_device(&adev->dev);
byt_rt5640_dais[dai_index].codecs->name = byt_rt5640_codec_name;
} else {
dev_err(dev, "Error cannot find '%s' dev\n", mach->id);
return -ENXIO;
}
codec_dev = acpi_get_first_physical_node(adev);
acpi_dev_put(adev);
if (!codec_dev)
return -EPROBE_DEFER;
priv->codec_dev = get_device(codec_dev);
/*
* swap SSP0 if bytcr is detected
* (will be overridden if DMI quirk is detected)
......@@ -1717,11 +1722,6 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
byt_rt5640_quirk = quirk_override;
}
codec_dev = acpi_get_first_physical_node(adev);
if (!codec_dev)
return -EPROBE_DEFER;
priv->codec_dev = get_device(codec_dev);
if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2) {
acpi_dev_add_driver_gpios(ACPI_COMPANION(priv->codec_dev),
byt_rt5640_hp_elitepad_1000g2_gpios);
......
......@@ -922,7 +922,6 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
if (adev) {
snprintf(byt_rt5651_codec_name, sizeof(byt_rt5651_codec_name),
"i2c-%s", acpi_dev_name(adev));
put_device(&adev->dev);
byt_rt5651_dais[dai_index].codecs->name = byt_rt5651_codec_name;
} else {
dev_err(dev, "Error cannot find '%s' dev\n", mach->id);
......@@ -930,6 +929,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
}
codec_dev = acpi_get_first_physical_node(adev);
acpi_dev_put(adev);
if (!codec_dev)
return -EPROBE_DEFER;
priv->codec_dev = get_device(codec_dev);
......
......@@ -411,9 +411,9 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev)
return -ENOENT;
}
snprintf(codec_name, sizeof(codec_name), "spi-%s", acpi_dev_name(adev));
put_device(&adev->dev);
codec_dev = bus_find_device_by_name(&spi_bus_type, NULL, codec_name);
acpi_dev_put(adev);
if (!codec_dev)
return -EPROBE_DEFER;
......
......@@ -336,6 +336,9 @@ static int create_spk_amp_dai_links(struct device *dev,
links[*id].platforms = platform_component;
links[*id].num_platforms = ARRAY_SIZE(platform_component);
links[*id].dpcm_playback = 1;
/* firmware-generated echo reference */
links[*id].dpcm_capture = 1;
links[*id].no_pcm = 1;
links[*id].cpus = &cpus[*id];
links[*id].num_cpus = 1;
......
......@@ -681,7 +681,6 @@ static int sof_es8336_probe(struct platform_device *pdev)
if (adev) {
snprintf(codec_name, sizeof(codec_name),
"i2c-%s", acpi_dev_name(adev));
put_device(&adev->dev);
dai_links[0].codecs->name = codec_name;
/* also fixup codec dai name if relevant */
......@@ -692,16 +691,19 @@ static int sof_es8336_probe(struct platform_device *pdev)
return -ENXIO;
}
ret = snd_soc_fixup_dai_links_platform_name(&sof_es8336_card,
mach->mach_params.platform);
if (ret)
return ret;
codec_dev = acpi_get_first_physical_node(adev);
acpi_dev_put(adev);
if (!codec_dev)
return -EPROBE_DEFER;
priv->codec_dev = get_device(codec_dev);
ret = snd_soc_fixup_dai_links_platform_name(&sof_es8336_card,
mach->mach_params.platform);
if (ret) {
put_device(codec_dev);
return ret;
}
if (quirk & SOF_ES8336_JD_INVERTED)
props[cnt++] = PROPERTY_ENTRY_BOOL("everest,jack-detect-inverted");
......
......@@ -487,8 +487,6 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
links[id].num_codecs = ARRAY_SIZE(max_98373_components);
links[id].init = max_98373_spk_codec_init;
links[id].ops = &max_98373_ops;
/* feedback stream */
links[id].dpcm_capture = 1;
} else if (sof_nau8825_quirk &
SOF_MAX98360A_SPEAKER_AMP_PRESENT) {
max_98360a_dai_link(&links[id]);
......@@ -506,6 +504,9 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
links[id].platforms = platform_component;
links[id].num_platforms = ARRAY_SIZE(platform_component);
links[id].dpcm_playback = 1;
/* feedback stream or firmware-generated echo reference */
links[id].dpcm_capture = 1;
links[id].no_pcm = 1;
links[id].cpus = &cpus[id];
links[id].num_cpus = 1;
......
......@@ -761,8 +761,6 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
links[id].num_codecs = ARRAY_SIZE(max_98373_components);
links[id].init = max_98373_spk_codec_init;
links[id].ops = &max_98373_ops;
/* feedback stream */
links[id].dpcm_capture = 1;
} else if (sof_rt5682_quirk &
SOF_MAX98360A_SPEAKER_AMP_PRESENT) {
max_98360a_dai_link(&links[id]);
......@@ -789,6 +787,9 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
links[id].platforms = platform_component;
links[id].num_platforms = ARRAY_SIZE(platform_component);
links[id].dpcm_playback = 1;
/* feedback stream or firmware-generated echo reference */
links[id].dpcm_capture = 1;
links[id].no_pcm = 1;
links[id].cpus = &cpus[id];
links[id].num_cpus = 1;
......
......@@ -258,13 +258,12 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
sof_rt1308_dai_link(&links[id]);
} else if (sof_ssp_amp_quirk & SOF_CS35L41_SPEAKER_AMP_PRESENT) {
cs35l41_set_dai_link(&links[id]);
/* feedback from amplifier */
links[id].dpcm_capture = 1;
}
links[id].platforms = platform_component;
links[id].num_platforms = ARRAY_SIZE(platform_component);
links[id].dpcm_playback = 1;
/* feedback from amplifier or firmware-generated echo reference */
links[id].dpcm_capture = 1;
links[id].no_pcm = 1;
links[id].cpus = &cpus[id];
links[id].num_cpus = 1;
......
......@@ -344,9 +344,10 @@ static ssize_t sof_ipc4_priority_mask_dfs_write(struct file *file,
size_t count, loff_t *ppos)
{
struct sof_mtrace_priv *priv = file->private_data;
int id, ret;
unsigned int id;
char *buf;
u32 mask;
int ret;
/*
* To update Nth mask entry, write:
......@@ -357,9 +358,9 @@ static ssize_t sof_ipc4_priority_mask_dfs_write(struct file *file,
if (IS_ERR(buf))
return PTR_ERR(buf);
ret = sscanf(buf, "%d,0x%x", &id, &mask);
ret = sscanf(buf, "%u,0x%x", &id, &mask);
if (ret != 2) {
ret = sscanf(buf, "%d,%x", &id, &mask);
ret = sscanf(buf, "%u,%x", &id, &mask);
if (ret != 2) {
ret = -EINVAL;
goto out;
......
......@@ -271,9 +271,9 @@ sof_unprepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widg
struct snd_sof_widget *swidget = widget->dobj.private;
struct snd_soc_dapm_path *p;
/* return if the widget is in use or if it is already unprepared */
if (!swidget->prepared || swidget->use_count > 1)
return;
/* skip if the widget is in use or if it is already unprepared */
if (!swidget || !swidget->prepared || swidget->use_count > 0)
goto sink_unprepare;
if (widget_ops[widget->id].ipc_unprepare)
/* unprepare the source widget */
......@@ -281,6 +281,7 @@ sof_unprepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widg
swidget->prepared = false;
sink_unprepare:
/* unprepare all widgets in the sink paths */
snd_soc_dapm_widget_for_each_sink_path(widget, p) {
if (!p->walking && p->sink->dobj.private) {
......@@ -303,7 +304,7 @@ sof_prepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget
struct snd_soc_dapm_path *p;
int ret;
if (!widget_ops[widget->id].ipc_prepare || swidget->prepared)
if (!swidget || !widget_ops[widget->id].ipc_prepare || swidget->prepared)
goto sink_prepare;
/* prepare the source widget */
......@@ -326,7 +327,8 @@ sof_prepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget
p->walking = false;
if (ret < 0) {
/* unprepare the source widget */
if (widget_ops[widget->id].ipc_unprepare && swidget->prepared) {
if (widget_ops[widget->id].ipc_unprepare &&
swidget && swidget->prepared) {
widget_ops[widget->id].ipc_unprepare(swidget);
swidget->prepared = false;
}
......@@ -429,11 +431,11 @@ sof_walk_widgets_in_order(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget_l
for_each_dapm_widgets(list, i, widget) {
/* starting widget for playback is AIF type */
if (dir == SNDRV_PCM_STREAM_PLAYBACK && !WIDGET_IS_AIF(widget->id))
if (dir == SNDRV_PCM_STREAM_PLAYBACK && widget->id != snd_soc_dapm_aif_in)
continue;
/* starting widget for capture is DAI type */
if (dir == SNDRV_PCM_STREAM_CAPTURE && !WIDGET_IS_DAI(widget->id))
if (dir == SNDRV_PCM_STREAM_CAPTURE && widget->id != snd_soc_dapm_dai_out)
continue;
switch (op) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment