Re: [PATCH 1/2] iio: adc: rzg2l_adc: Drop devm_pm_runtime_enable()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Jonathan,

On Mon, 27 Jan 2025 at 19:24, Jonathan Cameron
<Jonathan.Cameron@xxxxxxxxxx> wrote:
> On Mon, 27 Jan 2025 16:02:32 +0100
> Ulf Hansson <ulf.hansson@xxxxxxxxxx> wrote:
> > On Mon, 27 Jan 2025 at 13:32, Jonathan Cameron
> > <Jonathan.Cameron@xxxxxxxxxx> wrote:
> > > On Mon, 27 Jan 2025 11:47:44 +0100
> > > Ulf Hansson <ulf.hansson@xxxxxxxxxx> wrote:
> > > > > > > > > Do consider OK to change the order in pm_runtime_disable_action() to get
> > > > > > > > > rid of these issues, e.g.:
> > > > > > > > >
> > > > > > > > > diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
> > > > > > > > > index 2ee45841486b..f27d311d2619 100644
> > > > > > > > > --- a/drivers/base/power/runtime.c
> > > > > > > > > +++ b/drivers/base/power/runtime.c
> > > > > > > > > @@ -1547,8 +1547,8 @@ EXPORT_SYMBOL_GPL(pm_runtime_enable);
> > > > > > > > >
> > > > > > > > >  static void pm_runtime_disable_action(void *data)
> > > > > > > > >  {
> > > > > > > > > -       pm_runtime_dont_use_autosuspend(data);
> > > > > > > > >         pm_runtime_disable(data);
> > > > > > > > > +       pm_runtime_dont_use_autosuspend(data);
> > > > > > > > >  }
> > > > > > > > >
> > > > > > > > > though I see a rpm_resume() call is still possible though pm_runtime_disable().
> > > > > > > >
> > > > > > > > I am still worried about keeping the device runtime enabled during a
> > > > > > > > window when we have turned off all resources for the device. Typically
> > > > > > > > we want to leave the device in a low power state after unbind.
> > > > > > > >
> > > > > > > > That said, I would rather just drop the devm_pm_runtime_enable() API
> > > > > > > > altogether and convert all users of it into
> > > > > > > > pm_runtime_enable|disable(), similar to what your patch does.
> > > > > > >
> > > > > > > That is making a mess of a lot of automated cleanup for a strange
> > > > > > > runtime pm related path.  This is pain a driver should not have
> > > > > > > to deal with, though I'm not clear what the right solution is!
> > > > > > >
> > > > > > > Key is that drivers should not mix devm managed cleanup and not, so
> > > > > > > that means that anything that happens after runtime pm is enabled
> > > > > > > has to be torn down manually.  One solution to this might be to
> > > > > > > always enable it late assuming that is safe to do so there is
> > > > > > > never anything else done after it in the probe path of a driver.
> > > > > >
> > > > > > The problem is that runtime PM isn't really comparable to other
> > > > > > resources that we are managing through devm* functions.
> > > > > >
> > > > > > Enabling runtime PM for a device changes the behaviour for how
> > > > > > power-mgmt is handled for the device. Enabling/disabling of runtime PM
> > > > > > really needs to be explicitly controlled by the driver for the device.
> > > > >
> > > > > I'm sorry to say I'm not yet convinced.
> > > >
> > > > Okay, let me try one more time. :-)
> > >
> > > +CC Greg as the disagreement here is really a philosophy of what
> > > devm cleanup is relative to remove.  Perhaps Greg or Rafael can
> > > given some guidance on the intent there.
> > >
> > > Mind you I think I found another subsystem working around this
> > > and in a somewhat more elegant, general way (to my eyes anyway!)
> > >
> > > https://elixir.bootlin.com/linux/v6.12.6/source/drivers/i2c/i2c-core-base.c#L630
> > > https://lore.kernel.org/all/YFf1GFPephFxC0mC@xxxxxxxxxx/
> > >
> > > +CC Dmitry.
> > >
> > > I2C creates an extra devres group and releases it before devm_pm_domain_detach()
> > > As all devm calls from the driver end up in that group, they are released
> > > before dev_pm_domain_detach()
> >
> > How would that address the problem I pointed out with runtime PM
> > below? This problem isn't limited to attaching/detaching PM domains.
>
> It's associated with anything that happens after a driver remove is done.
> We just disagree on when that remove is finished. There is nothing special about
> the remove() callback, that is just part of remove process.
> No magic transition of state that allows new things to happen follows
> the device driver remove finishing. Sure you can get the remove
> handling ordering wrong whether devm is in use or not.  The trick is
> almost always to never mix devm and not.  Once you need a single bit of
> manual unwinding stop with the devm and do everything beyond that point
> by hand (in probe order, before that point in remove order)
>
> > > > > Devm callbacks are explicitly registered by the driver so that they
> > > > > are unwound in a specific order.  Many other parts of driver
> > > > > registration rely on this ordering.  This does not seem different
> > > > > for runtime PM than anything else.
> > > >
> > > > If you compare clocks, for example. It's the driver that is in full
> > > > control of the clock gating/ungating. When the ->remove() callback
> > > > runs, the driver typically makes sure that it leaves the clock gated.
> > > > Then it doesn't really matter when the clock resource gets released.
> > > > The point is, the driver is in full control of the resource.
> > >
> > > Not a good example. devm_clk_get_enabled() does not gate the clock until
> >
> > I was not referring to devm_clk_get_enable(), but rather just devm_clk_get().
> >
> > To me devm_clk_get_enable() is another interface that we should avoid.
> > For example, what if the clock is already gated when the ->remove()
> > callback runs? Then we need to ungate the clock just to make the
> > devres path happy so it doesn't gate an already gated clock. And this,
> > just to save one or two lines of code.
>
> If someone is using a clock that is gated by other calls in the driver
> that then indeed the use of devm_clk_get_enabled() is inappropriate
> or they turn they do need to enable the clock and turn it off again
> as you mention which is a mess but often needs doing anyway as we
> commonly need some clocks at least to put a device into a low power
> state.
>
> >
> > Don't get me wrong, I certainly like the devm* functions in general,
> > but it's not a good fit for everything.
>
> For anything that a driver otherwise calls in remove() they are
> a direct equivalent that is just called automatically. (though apparently
> not quite in platform drivers!) If you have a sequence that is
> sufficiently complex they may not be a good fit. I just don't think
> that the sequence in this driver (and many others) is complex.
> The driver code (with the above change from i2c ported to platform code
> to fix the specific problem) is a lot simpler before Claudia's v2 to
> change the handling. 32 lines added to work around this...
>
> >
> > > the devm cleanup. The assumption being that nothing that affects
> > > it runs between the remove() and devm cleanup.  So pretty much identical
> > > to the runtime pm case.  They being that you have to obey ordering so
> > > that if you need to run something after the clock is disabled then
> > > you register that callback before you call devm_clk_get_enabled()
> > >
> > > > If runtime PM would remain enabled beyond the call to the ->remove()
> > > > callback, it would mean that the driver's runtime PM callbacks could
> > > > be called too. For example, userspace via sysfs may at any point
> > > > decide to runtime resume the device. In other words, we may end up
> > > > calling the runtime PM callbacks in the driver, when they are not
> > > > intended to be called. In the worst case, I guess we could even end up
> > > > trying to control resources (like a clock) from the ->runtime
> > > > _resume() callback, when the references to these resources may already
> > > > have been released.
> > >
> > > This is all about what we consider remove. To me, with devm_ manged cleanup
> > > in place, both remove() and devm_ cleanup count as parts of that remove
> > > process.
> >
> > There is no straightforward process here, if you would keep runtime PM
> > enabled beyond ->remove(). Things can happen in parallel.
>
> How?  Nothing magic happens when a driver remove() ends.
> So there is no difference at all in a driver calling runtime pm disable
> in that code or in devres cleanup that happens immediately after that
> in the bus driver remove.
>
> > In that case, drivers would need to extend their runtime PM callbacks
> > to cope with more complicated conditions, as resources that those use
> > may have been released. Moreover, how can we make sure that the device
> > is put into a low power state after the ->remove() has been called?
>
> This is a fair question.  Also one commonly handled by drivers using devm
> though perhaps not for the reason you are thinking.  Key is that most
> drivers should not rely at all on runtime PM being built let alone
> enabled.

Drivers for components on SoCs that use PM Domains must use
Runtime PM, as that is the only available method to control the PM Domain.

> Solution is normally a devm_add_action_or_reset() call that
> registers a call to put the device into a low power state.
>
> Sequence is normally something like:
>
> 1) enable clks etc.

Can be done explicitly, or using pm_runtime_resume_and_get() in case
of a clock domain.

> 2) Turn the power on.

I assume you mean through a regulator, GPIO, or (deasserted) reset
signal?
In case of a PM Domain, that is done using pm_runtime_resume_and_get()
again.

> 3) device setup
> 4) enable runtime PM after setting the state to active. Let autosuspend
>    do it's work.
>
> On remove (all devm_ managed).
> 5) disable runtime PM.
> 6) Turn the power off (may involve a check on whether it is already
>    off though in many cases it's idempotent so we don't bother checking).
> 7) disable clocks.
>
> in this particular driver I'm assuming that the low power state is
> handled via the reset lines being put back into reset by the
> the unwind of the two
> devm_reset_control_get_exclusive_deasserted() calls.

No, power control is handled by the PM (Power and Clock!) Domain, which
controls both the power area (R9A08G045_PD_ADC) and the module clocks
(R9A08G045_ADC_ADCLK, R9A08G045_ADC_PCLK).

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@xxxxxxxxxxxxxx

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds




[Index of Archives]     [Linux Samsung SOC]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux