PM regression with commit 5de85b9d57ab PM runtime re-init in v4.5-rc1
Rafael J. Wysocki
rafael at kernel.org
Mon Feb 1 14:17:54 PST 2016
On Mon, Feb 1, 2016 at 11:06 PM, Tony Lindgren <tony at atomide.com> wrote:
> * Tony Lindgren <tony at atomide.com> [160201 10:12]:
>> * Ulf Hansson <ulf.hansson at linaro.org> [160201 08:45]:
>> > On 28 January 2016 at 17:58, Tony Lindgren <tony at atomide.com> wrote:
>> > >
>> > > The MMC hardware will not get idled properly any longer blocking any
>> > > deeper idle states.
>> > >
>> > >> Did the driver not probe successfully the second try? If so, what happened.
>> > >
>> > > It probes fine after a -EPROBE_DEFER on the vmmc i2c regulator.
>> > > But the PM runtime usecounts are wrong.
>> >
>> > Okay. How did you verify this?
>>
>> Well that was just based on what I see in the dmesg:
>>
>> omap_device: omap_device_enable() called from invalid state 1
>
> So we're now missing the idling of hardare after -EPROBE_DEFER..
> Does the following patch work for you guys?
>
> Regards,
>
> Tony
>
> 8< -----------------------------
> From: Tony Lindgren <tony at atomide.com>
> Date: Mon, 1 Feb 2016 13:40:46 -0800
> Subject: [PATCH] PM / runtime: Fix PM runtime reinit
>
> Commit 5de85b9d57ab ("PM / runtime: Re-init runtime PM states at probe
> error and driver unbind") added calls to reinit the PM runtime. This
> however broke things for idling the hardware at least if the driver
> probing has pm_runtime_set_autosuspend_delay() and -EPROBE_DEFER
> happens.
>
> Fix the problem by adding a check for configured autosuspend if
> RPM_ACTIVE is set. Then reset the autosuspend, and suspend the
> device to make sure the hardware gets idled.
>
> Let's also cut down one level of nestedness and remove a negative
> test by returning early if pm_runtime_enabled(dev) as there is
> currently nothing for us to do in that case.
>
> Fixes: 5de85b9d57ab ("PM / runtime: Re-init runtime PM states at
> probe error and driver unbind")
> Signed-off-by: Tony Lindgren <tony at atomide.com>
>
> --- a/drivers/base/power/runtime.c
> +++ b/drivers/base/power/runtime.c
> @@ -1419,17 +1419,25 @@ void pm_runtime_init(struct device *dev)
> */
> void pm_runtime_reinit(struct device *dev)
> {
> - if (!pm_runtime_enabled(dev)) {
> - if (dev->power.runtime_status == RPM_ACTIVE)
> + if (pm_runtime_enabled(dev))
> + return;
> +
> + if (dev->power.runtime_status == RPM_ACTIVE) {
> + if (dev->power.use_autosuspend) {
> + __pm_runtime_use_autosuspend(dev, false);
> + pm_runtime_suspend(dev);
This won't work, because runtime PM is disabled at this point.
What about doing this instead:
if (dev->power.use_autosuspend)
__pm_runtime_use_autosuspend(dev, false);
pm_runtime_set_suspended(dev);
> + } else {
> pm_runtime_set_suspended(dev);
> - if (dev->power.irq_safe) {
> - spin_lock_irq(&dev->power.lock);
> - dev->power.irq_safe = 0;
> - spin_unlock_irq(&dev->power.lock);
> - if (dev->parent)
> - pm_runtime_put(dev->parent);
> }
> }
> +
> + if (dev->power.irq_safe) {
> + spin_lock_irq(&dev->power.lock);
> + dev->power.irq_safe = 0;
> + spin_unlock_irq(&dev->power.lock);
> + if (dev->parent)
> + pm_runtime_put(dev->parent);
> + }
> }
>
> /**
More information about the linux-arm-kernel
mailing list