"Varadarajan, Charulatha" <ch...@ti.com> writes:

[...]

>>> GPIO driver is modified to use dev_pm_ops instead of sysdev_class.
>>> With this approach, gpio_bank_suspend() & gpio_bank_resume()
>>> are not part of sys_dev_class.
>>>
>>> Usage of PM runtime get/put APIs in GPIO driver is as given below:
>>> pm_runtime_get_sync():
>>> * In the probe before accessing the GPIO registers
>>> * at the beginning of omap_gpio_request()
>>>       -only when one of the gpios is requested on a bank, in which,
>>>        no other gpio is being used (when mod_usage becomes non-zero).
>>
>> When using runtime PM, bank->mod_usage acutally becomes redundant with
>> usage counting already done at the runtime PM level.  IOW, checking
>> bank->mod_usage is he equivalent of checking pm_runtime_suspended(), so
>> I think you can totally get rid of bank->mod_usage.
>
> I wish to differ here. bank->mod_usage is filled for each GPIO pin in a bank.
> Hence during request/free if pm_runtime_get_sync() is called for each GPIO
> pin, then the count gets increased for each GPIO pin in a bank. But
> gpio_prepare_for_idle/suspend calls pm_runtime_put() only once for
> each bank. Hence there will be a count mismatch and hence this will lead
> to problems and never a bank will get suspended.
>
> IMO it is required to have bank->mod_usage checks. Please correct
> me if I am wrong.

You're right, I see what you're saying now.  Thanks for clarifying.

In that case, keeping bank->mod_usage should be OK for now.

That being said, as I'm looking at the idle prepare/resume hooks
something else came to mind.

Most of what the idle prepare/resume mehods do should actually be done
in the ->runtime_suspend() and ->runtime_resume() hooks (e.g. debounce
clock disable, edge-detect stuff, context save/restore).  IOW, that
stuff does not need to be done until the bank is actually
disabled/enabled.  For example, prepare_for_idle itself could be a
relatively simple check for bank->mod_usage and a call to
pm_runtime_put_sync().

What do you think?

[...]

>>> @@ -1058,22 +1079,7 @@ static int omap_gpio_request(struct gpio_chip *chip, 
>>> unsigned offset)
>>>               __raw_writel(__raw_readl(reg) | (1 << offset), reg);
>>>       }
>>>  #endif
>>> -     if (!cpu_class_is_omap1()) {
>>> -             if (!bank->mod_usage) {
>>> -                     void __iomem *reg = bank->base;
>>> -                     u32 ctrl;
>>> -
>>> -                     if (cpu_is_omap24xx() || cpu_is_omap34xx())
>>> -                             reg += OMAP24XX_GPIO_CTRL;
>>> -                     else if (cpu_is_omap44xx())
>>> -                             reg += OMAP4_GPIO_CTRL;
>>> -                     ctrl = __raw_readl(reg);
>>> -                     /* Module is enabled, clocks are not gated */
>>> -                     ctrl &= 0xFFFFFFFE;
>>> -                     __raw_writel(ctrl, reg);
>>> -             }
>>> -             bank->mod_usage |= 1 << offset;
>>> -     }
>>
>> Where did this code go?  I expected it to be moved, but not removed 
>> completely.
>
> It is only moved and not removed.
> bank->mod_usage |= 1 << offset; is done above and the rest is done below.

I found the set of bank->mod_usage, but I do not see the clock un-gating
in the resulting code.  Can you please share the line number in the
resulting code where this is done?   I just grep'd for 'Module is
enabled' and the 'ctrl &= 0xFFFFFFFE' line and could not find them.

Kevin
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to