Re: [PATCH v2] ALSA: hda/tegra: enable clock during probe

From: Thierry Reding
Date: Thu Jan 31 2019 - 09:30:32 EST


On Thu, Jan 31, 2019 at 01:10:01PM +0100, Rafael J. Wysocki wrote:
> On Thu, Jan 31, 2019 at 12:59 PM Takashi Iwai <tiwai@xxxxxxx> wrote:
> >
> > On Thu, 31 Jan 2019 12:46:54 +0100,
> > Rafael J. Wysocki wrote:
> > >
> > > On Thu, Jan 31, 2019 at 12:21 PM Takashi Iwai <tiwai@xxxxxxx> wrote:
> > > >
> > > > On Thu, 31 Jan 2019 12:05:30 +0100,
> > > > Thierry Reding wrote:
> > > > >
> > > > > On Wed, Jan 30, 2019 at 05:40:42PM +0100, Takashi Iwai wrote:
> > >
> > > [cut]
> > >
> > > > > > If I understand correctly the code, the pm domain is already activated
> > > > > > at calling driver's probe callback.
> > > > >
> > > > > As far as I can tell, the domain will also be powered off again after
> > > > > probe finished, unless the device grabs a runtime PM reference. This is
> > > > > what happens via the dev->pm_domain->sync() call after successful probe
> > > > > of a driver.
> > > >
> > > > Ah, a good point. This can be a problem with a probe work like this
> > > > case.
> > > >
> > > > > It seems to me like it's not a very well defined case what to do when a
> > > > > device needs to be powered up but runtime PM is not enabled.
> > > > >
> > > > > Adding Rafael and linux-pm, maybe they can provide some guidance on what
> > > > > to do in these situations.
> > > > >
> > > > > To summarize, what we're debating here is how to handle powering up a
> > > > > device if the pm_runtime infrastructure doesn't take care of it. Jon's
> > > > > proposal here was, and we use this elsewhere, to do something like this:
> > > > >
> > > > > pm_runtime_enable(dev);
> > > > > if (!pm_runtime_enabled(dev)) {
> > > > > err = foo_runtime_resume(dev);
> > > > > if (err < 0)
> > > > > goto fail;
> > > > > }
> > > > >
> > > > > So basically when runtime PM is not available, we explicitly "resume"
> > > > > the device to power it up.
> > > > >
> > > > > It seems to me like that's a fairly common problem, so I'm wondering if
> > > > > there's something that the runtime PM core could do to help with this.
> > > > > Or perhaps there's already a way to achieve this that we're all
> > > > > overlooking?
> > > > >
> > > > > Rafael, any suggestions?
> > > >
> > > > If any, a common helper would be appreciated, indeed.
> > >
> > > I'm not sure that I understand the problem correctly, so let me
> > > restate it the way I understand it.
> > >
> > > What we're talking about is a driver ->probe() callback. Runtime PM
> > > is disabled initially and the device is off. It needs to be powered
> > > up, but the way to do that depends on some configuration of the board
> > > etc., so ideally
> > >
> > > pm_runtime_enable(dev);
> > > ret = pm_runtime_resume(dev);
> > >
> > > should just work, but the question is what to do if runtime PM doesn't
> > > work as expected. That is, CONFIG_PM_RUNTIME is unset? Or something
> > > else?
> >
> > Yes, the question is how to write the code for both with and without
> > CONFIG_PM (or CONFIG_PM_RUNTIME).
>
> This basically is about setup, because after that point all should
> just work in both cases.
>
> Personally, I would do
>
> if (IS_ENABLED(CONFIG_PM)) {
> do setup based on pm-runtime
> } else {
> do manual setup
> }
>
> > Right now, we have a code like below, pushing the initialization in an
> > async work and let the probe returning quickly.
> >
> > hda_tegra_probe() {
> > ....
>
> So why don't you do
>
> if (!IS_ENABLED(CONFIG_PM)) {
> do manual clock setup
> }
>
> here?

I think that's exactly what Jon and Sameer were proposing, although the
discussion started primarily because of the way it was done.

So basically the idea was to do:

pm_runtime_enable()
if (!pm_runtime_enabled()) /* basically !IS_ENABLED(CONFIG_PM) */
hda_runtime_resume()

So we're not calling pm_runtime_resume() but rather the driver's
implementation of it. This is to avoid duplicating the code, which under
some circumstances can be fairly long. Duplicating is also error prone
because both instances may not always be in sync.

My understanding is that Takashi had reservations about using this kind
of construct because, well, frankly, it looks a little weird. We'd also
likely want to have a similar construct again in the ->remove() callback
to make sure we properly power off the device when it is no longer
needed. I'm just wondering if perhaps there should be a mechanism in the
core to take care of this, because this is basically something that we'd
need to do for every single driver.

For example, if !CONFIG_PM couldn't the pm_runtime_enable() function be
modified to do the above? This would be somewhat tricky because drivers
usually use SET_RUNTIME_PM_OPS to populate the struct dev_pm_ops and
that would result in an empty structure if !CONFIG_PM, but we could
probably work around that by adding a __SET_RUNTIME_PM_OPS that would
never be compiled out for this kind of case. Or such drivers could even
manually set .runtime_suspend and .runtime_resume to make sure they're
always populated.

Another way out of this would be to make sure we never run into the case
where runtime PM is disabled. If we always "select PM" on Tegra, then PM
should always be available. But is it guaranteed that runtime PM for the
devices is functional in that case? From a cursory look at the code it
would seem that way.

Thierry

Attachment: signature.asc
Description: PGP signature