Skip to content

Commit 84cb7ff

Browse files
committed
OPP: pstate is only valid for genpd OPP tables
It is not very clear right now that the `pstate` field is only valid for genpd OPP tables and not consumer tables. And there is no checking for the same at various places. Add checks in place to verify that and make it clear to the reader. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org> Reviewed-by: Bjorn Andersson <quic_bjorande@quicinc.com> Tested-by: Bjorn Andersson <quic_bjorande@quicinc.com>
1 parent 04bd2ea commit 84cb7ff

3 files changed

Lines changed: 25 additions & 3 deletions

File tree

drivers/opp/core.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,16 +227,24 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_level);
227227
unsigned int dev_pm_opp_get_required_pstate(struct dev_pm_opp *opp,
228228
unsigned int index)
229229
{
230+
struct opp_table *opp_table = opp->opp_table;
231+
230232
if (IS_ERR_OR_NULL(opp) || !opp->available ||
231-
index >= opp->opp_table->required_opp_count) {
233+
index >= opp_table->required_opp_count) {
232234
pr_err("%s: Invalid parameters\n", __func__);
233235
return 0;
234236
}
235237

236238
/* required-opps not fully initialized yet */
237-
if (lazy_linking_pending(opp->opp_table))
239+
if (lazy_linking_pending(opp_table))
238240
return 0;
239241

242+
/* The required OPP table must belong to a genpd */
243+
if (unlikely(!opp_table->required_opp_tables[index]->is_genpd)) {
244+
pr_err("%s: Performance state is only valid for genpds.\n", __func__);
245+
return 0;
246+
}
247+
240248
return opp->required_opps[index]->pstate;
241249
}
242250
EXPORT_SYMBOL_GPL(dev_pm_opp_get_required_pstate);
@@ -2696,6 +2704,12 @@ int dev_pm_opp_xlate_performance_state(struct opp_table *src_table,
26962704
if (!src_table || !src_table->required_opp_count)
26972705
return pstate;
26982706

2707+
/* Both OPP tables must belong to genpds */
2708+
if (unlikely(!src_table->is_genpd || !dst_table->is_genpd)) {
2709+
pr_err("%s: Performance state is only valid for genpds.\n", __func__);
2710+
return -EINVAL;
2711+
}
2712+
26992713
/* required-opps not fully initialized yet */
27002714
if (lazy_linking_pending(src_table))
27012715
return -EBUSY;

drivers/opp/debugfs.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,13 @@ void opp_debug_create_one(struct dev_pm_opp *opp, struct opp_table *opp_table)
152152
debugfs_create_bool("dynamic", S_IRUGO, d, &opp->dynamic);
153153
debugfs_create_bool("turbo", S_IRUGO, d, &opp->turbo);
154154
debugfs_create_bool("suspend", S_IRUGO, d, &opp->suspend);
155-
debugfs_create_u32("performance_state", S_IRUGO, d, &opp->pstate);
156155
debugfs_create_u32("level", S_IRUGO, d, &opp->level);
157156
debugfs_create_ulong("clock_latency_ns", S_IRUGO, d,
158157
&opp->clock_latency_ns);
159158

159+
if (opp_table->is_genpd)
160+
debugfs_create_u32("performance_state", S_IRUGO, d, &opp->pstate);
161+
160162
opp->of_name = of_node_full_name(opp->np);
161163
debugfs_create_str("of_name", S_IRUGO, d, (char **)&opp->of_name);
162164

drivers/opp/of.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1392,6 +1392,12 @@ int of_get_required_opp_performance_state(struct device_node *np, int index)
13921392
goto put_required_np;
13931393
}
13941394

1395+
/* The OPP tables must belong to a genpd */
1396+
if (unlikely(!opp_table->is_genpd)) {
1397+
pr_err("%s: Performance state is only valid for genpds.\n", __func__);
1398+
goto put_required_np;
1399+
}
1400+
13951401
opp = _find_opp_of_np(opp_table, required_np);
13961402
if (opp) {
13971403
pstate = opp->pstate;

0 commit comments

Comments
 (0)