Re: [PATCH 3/6] usb: cdns3-ti: add suspend/resume procedures for J7200
From: Roger Quadros <rogerq@kernel.org>
Date: 2023-11-15 11:38:01
Also in:
linux-arm-kernel, linux-usb, lkml
On 13/11/2023 16:26, Théo Lebrun wrote:
Hardware initialisation is only done at probe. The J7200 USB controller is reset at resume because of power-domains toggling off & on. We therefore (1) toggle PM runtime at suspend/resume & (2) reconfigure the hardware at resume.
at probe we are doing a pm_runtime_get() and never doing a put thus preventing any runtime PM.
quoted hunk ↗ jump to hunk
Reuse the newly extracted cdns_ti_init_hw() function that contains the register write sequence. We guard this behavior based on compatible to avoid modifying the current behavior on other platforms. If the controller does not reset we do not want to touch PM runtime & do not want to redo reg writes. Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com> --- drivers/usb/cdns3/cdns3-ti.c | 48 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-)diff --git a/drivers/usb/cdns3/cdns3-ti.c b/drivers/usb/cdns3/cdns3-ti.c index c331bcd2faeb..50b38c4b9c87 100644 --- a/drivers/usb/cdns3/cdns3-ti.c +++ b/drivers/usb/cdns3/cdns3-ti.c@@ -197,6 +197,50 @@ static int cdns_ti_probe(struct platform_device *pdev) return error; } +#ifdef CONFIG_PM + +static int cdns_ti_suspend(struct device *dev) +{ + struct cdns_ti *data = dev_get_drvdata(dev); + + if (!of_device_is_compatible(dev_of_node(dev), "ti,j7200-usb")) + return 0; + + pm_runtime_put_sync(data->dev); + + return 0;
You might want to check suspend/resume ops in cdns3-plat and do something similar here.
quoted hunk ↗ jump to hunk
+} + +static int cdns_ti_resume(struct device *dev) +{ + struct cdns_ti *data = dev_get_drvdata(dev); + int ret; + + if (!of_device_is_compatible(dev_of_node(dev), "ti,j7200-usb")) + return 0; + + ret = pm_runtime_get_sync(dev); + if (ret < 0) { + dev_err(dev, "pm_runtime_get_sync failed: %d\n", ret); + goto err; + } + + cdns_ti_init_hw(data); + + return 0; + +err: + pm_runtime_put_sync(data->dev); + pm_runtime_disable(data->dev); + return ret; +} + +static const struct dev_pm_ops cdns_ti_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(cdns_ti_suspend, cdns_ti_resume) +}; + +#endif /* CONFIG_PM */ + static int cdns_ti_remove_core(struct device *dev, void *c) { struct platform_device *pdev = to_platform_device(dev);@@ -218,6 +262,7 @@ static void cdns_ti_remove(struct platform_device *pdev) } static const struct of_device_id cdns_ti_of_match[] = { + { .compatible = "ti,j7200-usb", }, { .compatible = "ti,j721e-usb", }, { .compatible = "ti,am64-usb", }, {},@@ -228,8 +273,9 @@ static struct platform_driver cdns_ti_driver = { .probe = cdns_ti_probe, .remove_new = cdns_ti_remove, .driver = { - .name = "cdns3-ti", + .name = "cdns3-ti", .of_match_table = cdns_ti_of_match, + .pm = pm_ptr(&cdns_ti_pm_ops), }, };
-- cheers, -roger