Message ID | 20210926224058.1252-18-digetx@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | NVIDIA Tegra power management patches for 5.16 | expand |
On Mon, 27 Sept 2021 at 00:42, Dmitry Osipenko <digetx@gmail.com> wrote: > > The GMI bus on Tegra belongs to the core power domain and we're going to > enable GENPD support for the core domain. Now GMI must be resumed using > runtime PM API in order to initialize the GMI power state. Add runtime PM > and OPP support to the GMI driver. > > Signed-off-by: Dmitry Osipenko <digetx@gmail.com> > --- > drivers/bus/tegra-gmi.c | 52 ++++++++++++++++++++++++++++++++++++----- > 1 file changed, 46 insertions(+), 6 deletions(-) > > diff --git a/drivers/bus/tegra-gmi.c b/drivers/bus/tegra-gmi.c > index a6570789f7af..72ef8a8c236b 100644 > --- a/drivers/bus/tegra-gmi.c > +++ b/drivers/bus/tegra-gmi.c > @@ -13,8 +13,11 @@ > #include <linux/io.h> > #include <linux/module.h> > #include <linux/of_device.h> > +#include <linux/pm_runtime.h> > #include <linux/reset.h> > > +#include <soc/tegra/common.h> > + > #define TEGRA_GMI_CONFIG 0x00 > #define TEGRA_GMI_CONFIG_GO BIT(31) > #define TEGRA_GMI_BUS_WIDTH_32BIT BIT(30) > @@ -54,9 +57,9 @@ static int tegra_gmi_enable(struct tegra_gmi *gmi) > { > int err; > > - err = clk_prepare_enable(gmi->clk); > - if (err < 0) { > - dev_err(gmi->dev, "failed to enable clock: %d\n", err); > + err = pm_runtime_resume_and_get(gmi->dev); > + if (err) { > + pm_runtime_disable(gmi->dev); > return err; > } > > @@ -83,7 +86,8 @@ static void tegra_gmi_disable(struct tegra_gmi *gmi) > writel(config, gmi->base + TEGRA_GMI_CONFIG); > > reset_control_assert(gmi->rst); > - clk_disable_unprepare(gmi->clk); > + > + pm_runtime_put(gmi->dev); > } > > static int tegra_gmi_parse_dt(struct tegra_gmi *gmi) > @@ -213,6 +217,7 @@ static int tegra_gmi_probe(struct platform_device *pdev) > if (!gmi) > return -ENOMEM; > > + platform_set_drvdata(pdev, gmi); > gmi->dev = dev; > > res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > @@ -232,6 +237,14 @@ static int tegra_gmi_probe(struct platform_device *pdev) > return PTR_ERR(gmi->rst); > } > > + err = devm_pm_runtime_enable(gmi->dev); > + if (err) > + return err; > + > + err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev); > + if (err) > + return err; > + > err = tegra_gmi_parse_dt(gmi); > if (err) > return err; > @@ -247,8 +260,6 @@ static int tegra_gmi_probe(struct platform_device *pdev) > return err; > } > > - platform_set_drvdata(pdev, gmi); > - > return 0; > } > > @@ -262,6 +273,34 @@ static int tegra_gmi_remove(struct platform_device *pdev) Similar comment as for patch13, for the ->remove() callback. This problem, which sometimes also exists in the error path in ->probe() (according to my comments in patch13), seems to be a common issue in the series. I will therefore not continue to repeat my comment on this for the remaining patches in the series, I think I have made my point. :-) Kind regards Uffe
diff --git a/drivers/bus/tegra-gmi.c b/drivers/bus/tegra-gmi.c index a6570789f7af..72ef8a8c236b 100644 --- a/drivers/bus/tegra-gmi.c +++ b/drivers/bus/tegra-gmi.c @@ -13,8 +13,11 @@ #include <linux/io.h> #include <linux/module.h> #include <linux/of_device.h> +#include <linux/pm_runtime.h> #include <linux/reset.h> +#include <soc/tegra/common.h> + #define TEGRA_GMI_CONFIG 0x00 #define TEGRA_GMI_CONFIG_GO BIT(31) #define TEGRA_GMI_BUS_WIDTH_32BIT BIT(30) @@ -54,9 +57,9 @@ static int tegra_gmi_enable(struct tegra_gmi *gmi) { int err; - err = clk_prepare_enable(gmi->clk); - if (err < 0) { - dev_err(gmi->dev, "failed to enable clock: %d\n", err); + err = pm_runtime_resume_and_get(gmi->dev); + if (err) { + pm_runtime_disable(gmi->dev); return err; } @@ -83,7 +86,8 @@ static void tegra_gmi_disable(struct tegra_gmi *gmi) writel(config, gmi->base + TEGRA_GMI_CONFIG); reset_control_assert(gmi->rst); - clk_disable_unprepare(gmi->clk); + + pm_runtime_put(gmi->dev); } static int tegra_gmi_parse_dt(struct tegra_gmi *gmi) @@ -213,6 +217,7 @@ static int tegra_gmi_probe(struct platform_device *pdev) if (!gmi) return -ENOMEM; + platform_set_drvdata(pdev, gmi); gmi->dev = dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -232,6 +237,14 @@ static int tegra_gmi_probe(struct platform_device *pdev) return PTR_ERR(gmi->rst); } + err = devm_pm_runtime_enable(gmi->dev); + if (err) + return err; + + err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev); + if (err) + return err; + err = tegra_gmi_parse_dt(gmi); if (err) return err; @@ -247,8 +260,6 @@ static int tegra_gmi_probe(struct platform_device *pdev) return err; } - platform_set_drvdata(pdev, gmi); - return 0; } @@ -262,6 +273,34 @@ static int tegra_gmi_remove(struct platform_device *pdev) return 0; } +static int __maybe_unused tegra_gmi_runtime_resume(struct device *dev) +{ + struct tegra_gmi *gmi = dev_get_drvdata(dev); + int err; + + err = clk_prepare_enable(gmi->clk); + if (err < 0) { + dev_err(gmi->dev, "failed to enable clock: %d\n", err); + return err; + } + + return 0; +} + +static int __maybe_unused tegra_gmi_runtime_suspend(struct device *dev) +{ + struct tegra_gmi *gmi = dev_get_drvdata(dev); + + clk_disable_unprepare(gmi->clk); + + return 0; +} + +static const struct dev_pm_ops tegra_gmi_pm = { + SET_RUNTIME_PM_OPS(tegra_gmi_runtime_suspend, tegra_gmi_runtime_resume, + NULL) +}; + static const struct of_device_id tegra_gmi_id_table[] = { { .compatible = "nvidia,tegra20-gmi", }, { .compatible = "nvidia,tegra30-gmi", }, @@ -275,6 +314,7 @@ static struct platform_driver tegra_gmi_driver = { .driver = { .name = "tegra-gmi", .of_match_table = tegra_gmi_id_table, + .pm = &tegra_gmi_pm, }, }; module_platform_driver(tegra_gmi_driver);
The GMI bus on Tegra belongs to the core power domain and we're going to enable GENPD support for the core domain. Now GMI must be resumed using runtime PM API in order to initialize the GMI power state. Add runtime PM and OPP support to the GMI driver. Signed-off-by: Dmitry Osipenko <digetx@gmail.com> --- drivers/bus/tegra-gmi.c | 52 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 6 deletions(-)