Re: [PATCH v2 2/2] pinctrl: Allow indicating loss of pin states during low-power
From: Linus Walleij <hidden>
Date: 2017-12-02 12:48:18
Also in:
linux-gpio, lkml
On Wed, Nov 29, 2017 at 6:37 PM, Florian Fainelli [off-list ref] wrote:
On 11/29/2017 09:02 AM, Tony Lindgren wrote:
quoted
Hmm well typically a device driver that loses it's context just does save and restore of the registers in runtime PM suspend/resume as needed. In this case it would mean duplicating the state for potentially for hundreds of registers.. So using the existing state in the pinctrl subsystem totally makes sense for the pins. Florian do you have other reasons why this should be done in the pinctrl framework instead of the driver? Might be worth describing the reasoning in the patch descriptions :)The pinctrl provider driver that I am using is pinctrl-single, which has proper suspend/resume callbacks but those are not causing any HW programming to happen because of the (p->state == state) check, hence this patch series.
So we are talking about these callbacks, correct?
#ifdef CONFIG_PM
static int pinctrl_single_suspend(struct platform_device *pdev,
pm_message_t state)
{
struct pcs_device *pcs;
pcs = platform_get_drvdata(pdev);
if (!pcs)
return -EINVAL;
return pinctrl_force_sleep(pcs->pctl);
}
static int pinctrl_single_resume(struct platform_device *pdev)
{
struct pcs_device *pcs;
pcs = platform_get_drvdata(pdev);
if (!pcs)
return -EINVAL;
return pinctrl_force_default(pcs->pctl);
}
#endif
Which falls through to this:
/**
* pinctrl_force_sleep() - turn a given controller device into sleep state
* @pctldev: pin controller device
*/
int pinctrl_force_sleep(struct pinctrl_dev *pctldev)
{
if (!IS_ERR(pctldev->p) && !IS_ERR(pctldev->hog_sleep))
return pinctrl_select_state(pctldev->p, pctldev->hog_sleep);
return 0;
}
EXPORT_SYMBOL_GPL(pinctrl_force_sleep);
/**
* pinctrl_force_default() - turn a given controller device into default state
* @pctldev: pin controller device
*/
int pinctrl_force_default(struct pinctrl_dev *pctldev)
{
if (!IS_ERR(pctldev->p) && !IS_ERR(pctldev->hog_default))
return pinctrl_select_state(pctldev->p, pctldev->hog_default);
return 0;
}
EXPORT_SYMBOL_GPL(pinctrl_force_default);
So am I right in assuming it is actually the hogs that is your biggest
problem, and those are the states that get lost over suspend/resume
that are especially problematic?
I.e. you don't have any problem with any non-hogged pinctrl
handles, those are handled just fine in the suspend/resume
paths of the client drivers?
If this is the case, it changes the problem scope slightly.
It is fair that functions named *force* should actually enforce
programming a state.
So then I would suggest somethin else: break pinctrl_select_state()
into two:
pinctrl_select_state() that works just like before, checking if
(p->state == state) but which calls a static function
pinctrl_select_state_commit() that commits the change unconditonally.
Then alter pinctrl_force_sleep() and pinctrl_force_sleep() to call
that function.
This should solve your problem without having to alter the semantics
of pinctrl_select_state() for everyone.
If you want I can cook a patch to illustrate what I mean so you can
try it.
Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html