ALSA: hda/tegra: Fix Tegra194 HDA reset failure
commitd278dc9151
upstream. HDA regression is recently reported on Tegra194 based platforms. This happens because "hda2codec_2x" reset does not really exist in Tegra194 and it causes probe failure. All the HDA based audio tests fail at the moment. This underlying issue is exposed by commitc045ceb5a1
("reset: tegra-bpmp: Handle errors in BPMP response") which now checks return code of BPMP command response. Fix this issue by skipping unavailable reset on Tegra194. Cc: stable@vger.kernel.org Signed-off-by: Sameer Pujar <spujar@nvidia.com> Reviewed-by: Dmitry Osipenko <digetx@gmail.com> Link: https://lore.kernel.org/r/1640260431-11613-2-git-send-email-spujar@nvidia.com Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
7c452ca7bc
commit
f76d5f9391
@ -68,14 +68,20 @@
|
|||||||
*/
|
*/
|
||||||
#define TEGRA194_NUM_SDO_LINES 4
|
#define TEGRA194_NUM_SDO_LINES 4
|
||||||
|
|
||||||
|
struct hda_tegra_soc {
|
||||||
|
bool has_hda2codec_2x_reset;
|
||||||
|
};
|
||||||
|
|
||||||
struct hda_tegra {
|
struct hda_tegra {
|
||||||
struct azx chip;
|
struct azx chip;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
struct reset_control *reset;
|
struct reset_control_bulk_data resets[3];
|
||||||
struct clk_bulk_data clocks[3];
|
struct clk_bulk_data clocks[3];
|
||||||
|
unsigned int nresets;
|
||||||
unsigned int nclocks;
|
unsigned int nclocks;
|
||||||
void __iomem *regs;
|
void __iomem *regs;
|
||||||
struct work_struct probe_work;
|
struct work_struct probe_work;
|
||||||
|
const struct hda_tegra_soc *soc;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
@ -170,7 +176,7 @@ static int __maybe_unused hda_tegra_runtime_resume(struct device *dev)
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (!chip->running) {
|
if (!chip->running) {
|
||||||
rc = reset_control_assert(hda->reset);
|
rc = reset_control_bulk_assert(hda->nresets, hda->resets);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -187,7 +193,7 @@ static int __maybe_unused hda_tegra_runtime_resume(struct device *dev)
|
|||||||
} else {
|
} else {
|
||||||
usleep_range(10, 100);
|
usleep_range(10, 100);
|
||||||
|
|
||||||
rc = reset_control_deassert(hda->reset);
|
rc = reset_control_bulk_deassert(hda->nresets, hda->resets);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -427,9 +433,17 @@ static int hda_tegra_create(struct snd_card *card,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct hda_tegra_soc tegra30_data = {
|
||||||
|
.has_hda2codec_2x_reset = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct hda_tegra_soc tegra194_data = {
|
||||||
|
.has_hda2codec_2x_reset = false,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct of_device_id hda_tegra_match[] = {
|
static const struct of_device_id hda_tegra_match[] = {
|
||||||
{ .compatible = "nvidia,tegra30-hda" },
|
{ .compatible = "nvidia,tegra30-hda", .data = &tegra30_data },
|
||||||
{ .compatible = "nvidia,tegra194-hda" },
|
{ .compatible = "nvidia,tegra194-hda", .data = &tegra194_data },
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, hda_tegra_match);
|
MODULE_DEVICE_TABLE(of, hda_tegra_match);
|
||||||
@ -449,6 +463,8 @@ static int hda_tegra_probe(struct platform_device *pdev)
|
|||||||
hda->dev = &pdev->dev;
|
hda->dev = &pdev->dev;
|
||||||
chip = &hda->chip;
|
chip = &hda->chip;
|
||||||
|
|
||||||
|
hda->soc = of_device_get_match_data(&pdev->dev);
|
||||||
|
|
||||||
err = snd_card_new(&pdev->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
|
err = snd_card_new(&pdev->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
|
||||||
THIS_MODULE, 0, &card);
|
THIS_MODULE, 0, &card);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
@ -456,11 +472,20 @@ static int hda_tegra_probe(struct platform_device *pdev)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
hda->reset = devm_reset_control_array_get_exclusive(&pdev->dev);
|
hda->resets[hda->nresets++].id = "hda";
|
||||||
if (IS_ERR(hda->reset)) {
|
hda->resets[hda->nresets++].id = "hda2hdmi";
|
||||||
err = PTR_ERR(hda->reset);
|
/*
|
||||||
|
* "hda2codec_2x" reset is not present on Tegra194. Though DT would
|
||||||
|
* be updated to reflect this, but to have backward compatibility
|
||||||
|
* below is necessary.
|
||||||
|
*/
|
||||||
|
if (hda->soc->has_hda2codec_2x_reset)
|
||||||
|
hda->resets[hda->nresets++].id = "hda2codec_2x";
|
||||||
|
|
||||||
|
err = devm_reset_control_bulk_get_exclusive(&pdev->dev, hda->nresets,
|
||||||
|
hda->resets);
|
||||||
|
if (err)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
|
||||||
|
|
||||||
hda->clocks[hda->nclocks++].id = "hda";
|
hda->clocks[hda->nclocks++].id = "hda";
|
||||||
hda->clocks[hda->nclocks++].id = "hda2hdmi";
|
hda->clocks[hda->nclocks++].id = "hda2hdmi";
|
||||||
|
Reference in New Issue
Block a user