Message ID | 20210926224058.1252-17-digetx@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | NVIDIA Tegra power management patches for 5.16 | expand |
27.09.2021 01:40, Dmitry Osipenko пишет: > The Tegra USB controller belongs to the core power domain and we're going > to enable GENPD support for the core domain. Now USB controller must be > resumed using runtime PM API in order to initialize the USB power state. > We already support runtime PM for the CI device, but CI's PM is separated > from the RPM managed by tegra-usb driver. Add runtime PM and OPP support > to the driver. > > Signed-off-by: Dmitry Osipenko <digetx@gmail.com> > --- > drivers/usb/chipidea/ci_hdrc_tegra.c | 53 ++++++++++++++++++++++++---- > 1 file changed, 46 insertions(+), 7 deletions(-) Peter Chen, could you please ack this patch? Thanks in advance!
On 21-09-27 01:40:39, Dmitry Osipenko wrote: > The Tegra USB controller belongs to the core power domain and we're going > to enable GENPD support for the core domain. Now USB controller must be > resumed using runtime PM API in order to initialize the USB power state. > We already support runtime PM for the CI device, but CI's PM is separated > from the RPM managed by tegra-usb driver. Add runtime PM and OPP support > to the driver. > > Signed-off-by: Dmitry Osipenko <digetx@gmail.com> > --- > drivers/usb/chipidea/ci_hdrc_tegra.c | 53 ++++++++++++++++++++++++---- > 1 file changed, 46 insertions(+), 7 deletions(-) > > diff --git a/drivers/usb/chipidea/ci_hdrc_tegra.c b/drivers/usb/chipidea/ci_hdrc_tegra.c > index 60361141ac04..3142ef7ebe42 100644 > --- a/drivers/usb/chipidea/ci_hdrc_tegra.c > +++ b/drivers/usb/chipidea/ci_hdrc_tegra.c > @@ -7,6 +7,7 @@ > #include <linux/io.h> > #include <linux/module.h> > #include <linux/of_device.h> > +#include <linux/pm_runtime.h> > #include <linux/reset.h> > > #include <linux/usb.h> > @@ -15,6 +16,8 @@ > #include <linux/usb/of.h> > #include <linux/usb/phy.h> > > +#include <soc/tegra/common.h> > + > #include "../host/ehci.h" > > #include "ci.h" > @@ -278,6 +281,8 @@ static int tegra_usb_probe(struct platform_device *pdev) > if (!usb) > return -ENOMEM; > > + platform_set_drvdata(pdev, usb); > + > soc = of_device_get_match_data(&pdev->dev); > if (!soc) { > dev_err(&pdev->dev, "failed to match OF data\n"); > @@ -296,11 +301,17 @@ static int tegra_usb_probe(struct platform_device *pdev) > return err; > } > > - err = clk_prepare_enable(usb->clk); > - if (err < 0) { > - dev_err(&pdev->dev, "failed to enable clock: %d\n", err); > + err = devm_pm_runtime_enable(&pdev->dev); > + if (err) > + return err; > + > + err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev); > + if (err) > + return err; > + > + err = pm_runtime_resume_and_get(&pdev->dev); > + if (err) > return err; > - } > > if (device_property_present(&pdev->dev, "nvidia,needs-double-reset")) > usb->needs_double_reset = true; > @@ -320,8 +331,6 @@ static int tegra_usb_probe(struct platform_device *pdev) > if (err) > goto fail_power_off; > > - platform_set_drvdata(pdev, usb); > - > /* setup and register ChipIdea HDRC device */ > usb->soc = soc; > usb->data.name = "tegra-usb"; > @@ -350,7 +359,8 @@ static int tegra_usb_probe(struct platform_device *pdev) > phy_shutdown: > usb_phy_shutdown(usb->phy); > fail_power_off: > - clk_disable_unprepare(usb->clk); > + pm_runtime_put(&pdev->dev); > + > return err; > } > > @@ -360,15 +370,44 @@ static int tegra_usb_remove(struct platform_device *pdev) > > ci_hdrc_remove_device(usb->dev); > usb_phy_shutdown(usb->phy); > + pm_runtime_put(&pdev->dev); > + > + return 0; > +} > + > +static int __maybe_unused tegra_usb_runtime_resume(struct device *dev) > +{ > + struct tegra_usb *usb = dev_get_drvdata(dev); > + int err; > + > + err = clk_prepare_enable(usb->clk); > + if (err < 0) { > + dev_err(dev, "failed to enable clock: %d\n", err); > + return err; > + } > + > + return 0; > +} > + > +static int __maybe_unused tegra_usb_runtime_suspend(struct device *dev) > +{ > + struct tegra_usb *usb = dev_get_drvdata(dev); > + > clk_disable_unprepare(usb->clk); > > return 0; > } > > +static const struct dev_pm_ops tegra_usb_pm = { > + SET_RUNTIME_PM_OPS(tegra_usb_runtime_suspend, tegra_usb_runtime_resume, > + NULL) > +}; > + > static struct platform_driver tegra_usb_driver = { > .driver = { > .name = "tegra-usb", > .of_match_table = tegra_usb_of_match, > + .pm = &tegra_usb_pm, > }, > .probe = tegra_usb_probe, > .remove = tegra_usb_remove, > -- > 2.32.0 > I got below compile error if only compile this file, I think previous patches should include the definition, if that, feel free to add my ack to this patch. Acked-by: Peter Chen <peter.chen@kernel.org> drivers/usb/chipidea/ci_hdrc_tegra.c:308:8: error: implicit declaration of function ‘devm_tegra_core_dev_init_opp_table_common’; did you mean ‘devm_tegra_core_dev_init_opp_table’? [-Werror=implicit-function-declaration] 308 | err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | devm_tegra_core_dev_init_opp_table
30.09.2021 17:06, Peter Chen пишет: > On 21-09-27 01:40:39, Dmitry Osipenko wrote: >> The Tegra USB controller belongs to the core power domain and we're going >> to enable GENPD support for the core domain. Now USB controller must be >> resumed using runtime PM API in order to initialize the USB power state. >> We already support runtime PM for the CI device, but CI's PM is separated >> from the RPM managed by tegra-usb driver. Add runtime PM and OPP support >> to the driver. >> >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com> >> --- >> drivers/usb/chipidea/ci_hdrc_tegra.c | 53 ++++++++++++++++++++++++---- >> 1 file changed, 46 insertions(+), 7 deletions(-) ... > > I got below compile error if only compile this file, I think previous patches > should include the definition, if that, feel free to add my ack to this > patch. > > Acked-by: Peter Chen <peter.chen@kernel.org> > > drivers/usb/chipidea/ci_hdrc_tegra.c:308:8: error: implicit declaration of function ‘devm_tegra_core_dev_init_opp_table_common’; > did you mean ‘devm_tegra_core_dev_init_opp_table’? [-Werror=implicit-function-declaration] > 308 | err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev); > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > | devm_tegra_core_dev_init_opp_table That's correct, devm_tegra_core_dev_init_opp_table_common() is added by an earlier patch of this series. Thank you!
diff --git a/drivers/usb/chipidea/ci_hdrc_tegra.c b/drivers/usb/chipidea/ci_hdrc_tegra.c index 60361141ac04..3142ef7ebe42 100644 --- a/drivers/usb/chipidea/ci_hdrc_tegra.c +++ b/drivers/usb/chipidea/ci_hdrc_tegra.c @@ -7,6 +7,7 @@ #include <linux/io.h> #include <linux/module.h> #include <linux/of_device.h> +#include <linux/pm_runtime.h> #include <linux/reset.h> #include <linux/usb.h> @@ -15,6 +16,8 @@ #include <linux/usb/of.h> #include <linux/usb/phy.h> +#include <soc/tegra/common.h> + #include "../host/ehci.h" #include "ci.h" @@ -278,6 +281,8 @@ static int tegra_usb_probe(struct platform_device *pdev) if (!usb) return -ENOMEM; + platform_set_drvdata(pdev, usb); + soc = of_device_get_match_data(&pdev->dev); if (!soc) { dev_err(&pdev->dev, "failed to match OF data\n"); @@ -296,11 +301,17 @@ static int tegra_usb_probe(struct platform_device *pdev) return err; } - err = clk_prepare_enable(usb->clk); - if (err < 0) { - dev_err(&pdev->dev, "failed to enable clock: %d\n", err); + err = devm_pm_runtime_enable(&pdev->dev); + if (err) + return err; + + err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev); + if (err) + return err; + + err = pm_runtime_resume_and_get(&pdev->dev); + if (err) return err; - } if (device_property_present(&pdev->dev, "nvidia,needs-double-reset")) usb->needs_double_reset = true; @@ -320,8 +331,6 @@ static int tegra_usb_probe(struct platform_device *pdev) if (err) goto fail_power_off; - platform_set_drvdata(pdev, usb); - /* setup and register ChipIdea HDRC device */ usb->soc = soc; usb->data.name = "tegra-usb"; @@ -350,7 +359,8 @@ static int tegra_usb_probe(struct platform_device *pdev) phy_shutdown: usb_phy_shutdown(usb->phy); fail_power_off: - clk_disable_unprepare(usb->clk); + pm_runtime_put(&pdev->dev); + return err; } @@ -360,15 +370,44 @@ static int tegra_usb_remove(struct platform_device *pdev) ci_hdrc_remove_device(usb->dev); usb_phy_shutdown(usb->phy); + pm_runtime_put(&pdev->dev); + + return 0; +} + +static int __maybe_unused tegra_usb_runtime_resume(struct device *dev) +{ + struct tegra_usb *usb = dev_get_drvdata(dev); + int err; + + err = clk_prepare_enable(usb->clk); + if (err < 0) { + dev_err(dev, "failed to enable clock: %d\n", err); + return err; + } + + return 0; +} + +static int __maybe_unused tegra_usb_runtime_suspend(struct device *dev) +{ + struct tegra_usb *usb = dev_get_drvdata(dev); + clk_disable_unprepare(usb->clk); return 0; } +static const struct dev_pm_ops tegra_usb_pm = { + SET_RUNTIME_PM_OPS(tegra_usb_runtime_suspend, tegra_usb_runtime_resume, + NULL) +}; + static struct platform_driver tegra_usb_driver = { .driver = { .name = "tegra-usb", .of_match_table = tegra_usb_of_match, + .pm = &tegra_usb_pm, }, .probe = tegra_usb_probe, .remove = tegra_usb_remove,
The Tegra USB controller belongs to the core power domain and we're going to enable GENPD support for the core domain. Now USB controller must be resumed using runtime PM API in order to initialize the USB power state. We already support runtime PM for the CI device, but CI's PM is separated from the RPM managed by tegra-usb driver. Add runtime PM and OPP support to the driver. Signed-off-by: Dmitry Osipenko <digetx@gmail.com> --- drivers/usb/chipidea/ci_hdrc_tegra.c | 53 ++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 7 deletions(-)