diff mbox series

[v4,02/18] pinctrl: pinctrl-single: move suspend()/resume() callbacks to noirq

Message ID 20240102-j7200-pcie-s2r-v4-2-6f1f53390c85@bootlin.com
State New
Headers show
Series Add suspend to ram support for PCIe on J7200 | expand

Commit Message

Thomas Richard March 4, 2024, 3:35 p.m. UTC
The goal is to extend the active period of pinctrl.
Some devices may need active pinctrl after suspend() and/or before
resume().
So move suspend()/resume() to suspend_noirq()/resume_noirq() in order to
have active pinctrl until suspend_noirq() (included), and from
resume_noirq() (included).

The deprecated API has been removed to use the new one (dev_pm_ops struct).

No need to check the pointer returned by dev_get_drvdata(), as
platform_set_drvdata() is called during the probe.

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Thomas Richard <thomas.richard@bootlin.com>
---
 drivers/pinctrl/pinctrl-single.c | 28 +++++++++-------------------
 1 file changed, 9 insertions(+), 19 deletions(-)

Comments

Dhruva Gole March 20, 2024, 7:44 a.m. UTC | #1
Hi,

On Mar 04, 2024 at 16:35:45 +0100, Thomas Richard wrote:
> The goal is to extend the active period of pinctrl.
> Some devices may need active pinctrl after suspend() and/or before
> resume().
> So move suspend()/resume() to suspend_noirq()/resume_noirq() in order to
> have active pinctrl until suspend_noirq() (included), and from
> resume_noirq() (included).
> 
> The deprecated API has been removed to use the new one (dev_pm_ops struct).
> 
> No need to check the pointer returned by dev_get_drvdata(), as
> platform_set_drvdata() is called during the probe.
> 
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
> Signed-off-by: Thomas Richard <thomas.richard@bootlin.com>
> ---

I was planning to do this but didn't see particular benefit to it. Do
you see the benefit on your specific device? Can you help me understand
how? Not against the patch, just curious.

Reviewed-by: Dhruva Gole <d-gole@ti.com>
Thomas Richard March 20, 2024, 8:37 a.m. UTC | #2
On 3/20/24 08:44, Dhruva Gole wrote:
> Hi,
> 
> On Mar 04, 2024 at 16:35:45 +0100, Thomas Richard wrote:
>> The goal is to extend the active period of pinctrl.
>> Some devices may need active pinctrl after suspend() and/or before
>> resume().
>> So move suspend()/resume() to suspend_noirq()/resume_noirq() in order to
>> have active pinctrl until suspend_noirq() (included), and from
>> resume_noirq() (included).
>>
>> The deprecated API has been removed to use the new one (dev_pm_ops struct).
>>
>> No need to check the pointer returned by dev_get_drvdata(), as
>> platform_set_drvdata() is called during the probe.
>>
>> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
>> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
>> Signed-off-by: Thomas Richard <thomas.richard@bootlin.com>
>> ---
> 
> I was planning to do this but didn't see particular benefit to it. Do
> you see the benefit on your specific device? Can you help me understand
> how? Not against the patch, just curious.

Hello Dhruva,

We need this patch to support suspend to ram for the PCIe on J7200.
In root complex mode, a gpio is used to reset endpoints.
This gpio shall be managed during suspend_noirq and resume_noirq stages.
On J7200 this gpio is on a gpio expander.
So we need this patch to restore pinctrl to be able to do i2c accesses
in noirq stages.

Best Regards,
Linus Walleij March 28, 2024, 9:07 p.m. UTC | #3
On Mon, Mar 4, 2024 at 4:36 PM Thomas Richard
<thomas.richard@bootlin.com> wrote:


> The goal is to extend the active period of pinctrl.
> Some devices may need active pinctrl after suspend() and/or before
> resume().
> So move suspend()/resume() to suspend_noirq()/resume_noirq() in order to
> have active pinctrl until suspend_noirq() (included), and from
> resume_noirq() (included).
>
> The deprecated API has been removed to use the new one (dev_pm_ops struct).
>
> No need to check the pointer returned by dev_get_drvdata(), as
> platform_set_drvdata() is called during the probe.
>
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
> Signed-off-by: Thomas Richard <thomas.richard@bootlin.com>

Since this patch looks independent from the rest I ripped it out of the
patch series and applied it to the pinctrl tree for kernel v6.10.

Yours,
Linus Walleij
diff mbox series

Patch

diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index 19cc0db771a5..0dd4b0e11adf 100644
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -1625,7 +1625,6 @@  static int pcs_irq_init_chained_handler(struct pcs_device *pcs,
 	return 0;
 }
 
-#ifdef CONFIG_PM
 static int pcs_save_context(struct pcs_device *pcs)
 {
 	int i, mux_bytes;
@@ -1690,14 +1689,9 @@  static void pcs_restore_context(struct pcs_device *pcs)
 	}
 }
 
-static int pinctrl_single_suspend(struct platform_device *pdev,
-					pm_message_t state)
+static int pinctrl_single_suspend_noirq(struct device *dev)
 {
-	struct pcs_device *pcs;
-
-	pcs = platform_get_drvdata(pdev);
-	if (!pcs)
-		return -EINVAL;
+	struct pcs_device *pcs = dev_get_drvdata(dev);
 
 	if (pcs->flags & PCS_CONTEXT_LOSS_OFF) {
 		int ret;
@@ -1710,20 +1704,19 @@  static int pinctrl_single_suspend(struct platform_device *pdev,
 	return pinctrl_force_sleep(pcs->pctl);
 }
 
-static int pinctrl_single_resume(struct platform_device *pdev)
+static int pinctrl_single_resume_noirq(struct device *dev)
 {
-	struct pcs_device *pcs;
-
-	pcs = platform_get_drvdata(pdev);
-	if (!pcs)
-		return -EINVAL;
+	struct pcs_device *pcs = dev_get_drvdata(dev);
 
 	if (pcs->flags & PCS_CONTEXT_LOSS_OFF)
 		pcs_restore_context(pcs);
 
 	return pinctrl_force_default(pcs->pctl);
 }
-#endif
+
+static DEFINE_NOIRQ_DEV_PM_OPS(pinctrl_single_pm_ops,
+			       pinctrl_single_suspend_noirq,
+			       pinctrl_single_resume_noirq);
 
 /**
  * pcs_quirk_missing_pinctrl_cells - handle legacy binding
@@ -1986,11 +1979,8 @@  static struct platform_driver pcs_driver = {
 	.driver = {
 		.name		= DRIVER_NAME,
 		.of_match_table	= pcs_of_match,
+		.pm = pm_sleep_ptr(&pinctrl_single_pm_ops),
 	},
-#ifdef CONFIG_PM
-	.suspend = pinctrl_single_suspend,
-	.resume = pinctrl_single_resume,
-#endif
 };
 
 module_platform_driver(pcs_driver);