Message ID | 20210827013415.24027-2-digetx@gmail.com (mailing list archive) |
---|---|
State | Not Applicable, archived |
Headers | show |
Series | NVIDIA Tegra power management patches for 5.16 | expand |
27.08.2021 04:34, Dmitry Osipenko пишет: > diff --git a/drivers/opp/core.c b/drivers/opp/core.c > index 04b4691a8aac..fae5267f5218 100644 > --- a/drivers/opp/core.c > +++ b/drivers/opp/core.c > @@ -939,7 +939,8 @@ static int _set_required_opps(struct device *dev, > return ret; > } > > -static void _find_current_opp(struct device *dev, struct opp_table *opp_table) > +static struct dev_pm_opp * > +_find_current_opp(struct device *dev, struct opp_table *opp_table) > { > struct dev_pm_opp *opp = ERR_PTR(-ENODEV); > unsigned long freq; > @@ -961,7 +962,7 @@ static void _find_current_opp(struct device *dev, struct opp_table *opp_table) > mutex_unlock(&opp_table->lock); > } > > - opp_table->current_opp = opp; > + return opp; > } > > static int _disable_opp_table(struct device *dev, struct opp_table *opp_table) > @@ -1003,7 +1004,7 @@ static int _set_opp(struct device *dev, struct opp_table *opp_table, > > /* Find the currently set OPP if we don't know already */ > if (unlikely(!opp_table->current_opp)) > - _find_current_opp(dev, opp_table); > + opp_table->current_opp = _find_current_opp(dev, opp_table); > > old_opp = opp_table->current_opp; > > @@ -2931,3 +2932,38 @@ int dev_pm_opp_sync_regulators(struct device *dev) > return ret; > } Please skip these lines. I missed to remove them during rebase and haven't noticed until now.
On 27-08-21, 04:34, Dmitry Osipenko wrote: > +/** > + * dev_pm_opp_from_clk_rate() - Get OPP from current clock rate > + * @dev: device for which we do this operation > + * > + * Get OPP which corresponds to the current clock rate of a device. > + * > + * Return: pointer to 'struct dev_pm_opp' on success and errorno otherwise. > + */ > +struct dev_pm_opp *dev_pm_opp_from_clk_rate(struct device *dev) I will rather call it dev_pm_opp_get_current(), and do the magic to find the current OPP here as well. No need to reinvent the wheel.
27.08.2021 06:00, Viresh Kumar пишет: > On 27-08-21, 04:34, Dmitry Osipenko wrote: >> +/** >> + * dev_pm_opp_from_clk_rate() - Get OPP from current clock rate >> + * @dev: device for which we do this operation >> + * >> + * Get OPP which corresponds to the current clock rate of a device. >> + * >> + * Return: pointer to 'struct dev_pm_opp' on success and errorno otherwise. >> + */ >> +struct dev_pm_opp *dev_pm_opp_from_clk_rate(struct device *dev) > > I will rather call it dev_pm_opp_get_current(), and do the magic to find the > current OPP here as well. No need to reinvent the wheel. > Okay, I'll change it.
diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 04b4691a8aac..fae5267f5218 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -939,7 +939,8 @@ static int _set_required_opps(struct device *dev, return ret; } -static void _find_current_opp(struct device *dev, struct opp_table *opp_table) +static struct dev_pm_opp * +_find_current_opp(struct device *dev, struct opp_table *opp_table) { struct dev_pm_opp *opp = ERR_PTR(-ENODEV); unsigned long freq; @@ -961,7 +962,7 @@ static void _find_current_opp(struct device *dev, struct opp_table *opp_table) mutex_unlock(&opp_table->lock); } - opp_table->current_opp = opp; + return opp; } static int _disable_opp_table(struct device *dev, struct opp_table *opp_table) @@ -1003,7 +1004,7 @@ static int _set_opp(struct device *dev, struct opp_table *opp_table, /* Find the currently set OPP if we don't know already */ if (unlikely(!opp_table->current_opp)) - _find_current_opp(dev, opp_table); + opp_table->current_opp = _find_current_opp(dev, opp_table); old_opp = opp_table->current_opp; @@ -2931,3 +2932,38 @@ int dev_pm_opp_sync_regulators(struct device *dev) return ret; } EXPORT_SYMBOL_GPL(dev_pm_opp_sync_regulators); + +/** + * dev_pm_opp_from_clk_rate() - Get OPP from current clock rate + * @dev: device for which we do this operation + * + * Get OPP which corresponds to the current clock rate of a device. + * + * Return: pointer to 'struct dev_pm_opp' on success and errorno otherwise. + */ +struct dev_pm_opp *dev_pm_opp_from_clk_rate(struct device *dev) +{ + struct dev_pm_opp *opp = ERR_PTR(-ENOENT); + struct opp_table *opp_table; + unsigned long freq; + + opp_table = _find_opp_table(dev); + if (IS_ERR(opp_table)) + return ERR_CAST(opp_table); + + if (IS_ERR(opp_table->clk)) { + opp = ERR_CAST(opp_table->clk); + goto put_table; + } + + if (opp_table->clk) { + freq = clk_get_rate(opp_table->clk); + opp = _find_freq_ceil(opp_table, &freq); + } +put_table: + /* Drop reference taken by _find_opp_table() */ + dev_pm_opp_put_opp_table(opp_table); + + return opp; +} +EXPORT_SYMBOL_GPL(dev_pm_opp_from_clk_rate); diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h index 84150a22fd7c..57e75144dd88 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h @@ -168,6 +168,7 @@ int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask) void dev_pm_opp_remove_table(struct device *dev); void dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask); int dev_pm_opp_sync_regulators(struct device *dev); +struct dev_pm_opp *dev_pm_opp_from_clk_rate(struct device *dev); #else static inline struct opp_table *dev_pm_opp_get_opp_table(struct device *dev) { @@ -434,6 +435,11 @@ static inline int dev_pm_opp_sync_regulators(struct device *dev) return -EOPNOTSUPP; } +static struct inline dev_pm_opp *dev_pm_opp_from_clk_rate(struct device *dev) +{ + return ERR_PTR(-EOPNOTSUPP); +} + #endif /* CONFIG_PM_OPP */ #if defined(CONFIG_PM_OPP) && defined(CONFIG_OF)
Add dev_pm_opp_from_clk_rate() helper that returns OPP corresponding to the current clock rate of a device. Signed-off-by: Dmitry Osipenko <digetx@gmail.com> --- drivers/opp/core.c | 42 +++++++++++++++++++++++++++++++++++++++--- include/linux/pm_opp.h | 6 ++++++ 2 files changed, 45 insertions(+), 3 deletions(-)