On Wed, 20 Jan 2021 01:31:50 +0100, Dmitry Osipenko wrote: > > Reset hardware on RPM-resume in order to bring it into a predictable > state. > > Tested-by: Peter Geis <pgwipeout@xxxxxxxxx> # Ouya T30 audio works > Tested-by: Matt Merhar <mattmerhar@xxxxxxxxxxxxxx> # Ouya T30 boot-tested > Tested-by: Nicolas Chauvet <kwizart@xxxxxxxxx> # TK1 boot-tested > Signed-off-by: Dmitry Osipenko <digetx@xxxxxxxxx> Currently we have neither dependency nor reverse-selection of CONFIG_RESET_CONTROLLER. It wouldn't be a problem for builds, but you'll get a runtime error from devm_reset_control_array_get_exclusive() always when CONFIG_RESET_CONTROLLER=n. I guess it must be a corner case, but just to be sure. thanks, Takashi > --- > sound/pci/hda/hda_tegra.c | 20 ++++++++++++++++++++ > 1 file changed, 20 insertions(+) > > diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c > index a25bf7083c28..04dcd4cdfd9e 100644 > --- a/sound/pci/hda/hda_tegra.c > +++ b/sound/pci/hda/hda_tegra.c > @@ -17,6 +17,7 @@ > #include <linux/moduleparam.h> > #include <linux/mutex.h> > #include <linux/of_device.h> > +#include <linux/reset.h> > #include <linux/slab.h> > #include <linux/time.h> > #include <linux/string.h> > @@ -70,6 +71,7 @@ > struct hda_tegra { > struct azx chip; > struct device *dev; > + struct reset_control *reset; > struct clk_bulk_data clocks[3]; > unsigned int nclocks; > void __iomem *regs; > @@ -167,6 +169,12 @@ static int __maybe_unused hda_tegra_runtime_resume(struct device *dev) > struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip); > int rc; > > + if (!chip->running) { > + rc = reset_control_assert(hda->reset); > + if (rc) > + return rc; > + } > + > rc = clk_bulk_prepare_enable(hda->nclocks, hda->clocks); > if (rc != 0) > return rc; > @@ -176,6 +184,12 @@ static int __maybe_unused hda_tegra_runtime_resume(struct device *dev) > /* disable controller wake up event*/ > azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) & > ~STATESTS_INT_MASK); > + } else { > + usleep_range(10, 100); > + > + rc = reset_control_deassert(hda->reset); > + if (rc) > + return rc; > } > > return 0; > @@ -441,6 +455,12 @@ static int hda_tegra_probe(struct platform_device *pdev) > return err; > } > > + hda->reset = devm_reset_control_array_get_exclusive(&pdev->dev); > + if (IS_ERR(hda->reset)) { > + err = PTR_ERR(hda->reset); > + goto out_free; > + } > + > hda->clocks[hda->nclocks++].id = "hda"; > hda->clocks[hda->nclocks++].id = "hda2hdmi"; > hda->clocks[hda->nclocks++].id = "hda2codec_2x"; > -- > 2.29.2 >