Message ID | 20210120003154.26749-3-digetx@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Clock and reset improvements for Tegra ALSA drivers | expand |
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@gmail.com> # Ouya T30 audio works > Tested-by: Matt Merhar <mattmerhar@protonmail.com> # Ouya T30 boot-tested > Tested-by: Nicolas Chauvet <kwizart@gmail.com> # TK1 boot-tested > Signed-off-by: Dmitry Osipenko <digetx@gmail.com> 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 >
25.01.2021 18:18, Takashi Iwai пишет: > 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@gmail.com> # Ouya T30 audio works >> Tested-by: Matt Merhar <mattmerhar@protonmail.com> # Ouya T30 boot-tested >> Tested-by: Nicolas Chauvet <kwizart@gmail.com> # TK1 boot-tested >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com> > > 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. The CONFIG_RESET_CONTROLLER=y at least for ARM32 Tegra builds. https://elixir.bootlin.com/linux/v5.11-rc5/source/arch/arm/mach-tegra/Kconfig#L15 Not sure about ARM64.
On Mon, 25 Jan 2021 16:27:30 +0100, Dmitry Osipenko wrote: > > 25.01.2021 18:18, Takashi Iwai пишет: > > 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@gmail.com> # Ouya T30 audio works > >> Tested-by: Matt Merhar <mattmerhar@protonmail.com> # Ouya T30 boot-tested > >> Tested-by: Nicolas Chauvet <kwizart@gmail.com> # TK1 boot-tested > >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com> > > > > 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. > > The CONFIG_RESET_CONTROLLER=y at least for ARM32 Tegra builds. > > https://elixir.bootlin.com/linux/v5.11-rc5/source/arch/arm/mach-tegra/Kconfig#L15 > > Not sure about ARM64. OK, then it must be fine. I applied now. Thanks. Takashi
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";