Skip to content

Commit

Permalink
OPP: pstate is only valid for genpd OPP tables
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
vireshk committed Jun 19, 2023
1 parent 04bd2ea commit 84cb7ff
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 3 deletions.
18 changes: 16 additions & 2 deletions drivers/opp/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,16 +227,24 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_level);
unsigned int dev_pm_opp_get_required_pstate(struct dev_pm_opp *opp,
unsigned int index)
{
struct opp_table *opp_table = opp->opp_table;

if (IS_ERR_OR_NULL(opp) || !opp->available ||
index >= opp->opp_table->required_opp_count) {
index >= opp_table->required_opp_count) {
pr_err("%s: Invalid parameters\n", __func__);
return 0;
}

/* required-opps not fully initialized yet */
if (lazy_linking_pending(opp->opp_table))
if (lazy_linking_pending(opp_table))
return 0;

/* The required OPP table must belong to a genpd */
if (unlikely(!opp_table->required_opp_tables[index]->is_genpd)) {
pr_err("%s: Performance state is only valid for genpds.\n", __func__);
return 0;
}

return opp->required_opps[index]->pstate;
}
EXPORT_SYMBOL_GPL(dev_pm_opp_get_required_pstate);
Expand Down Expand Up @@ -2696,6 +2704,12 @@ int dev_pm_opp_xlate_performance_state(struct opp_table *src_table,
if (!src_table || !src_table->required_opp_count)
return pstate;

/* Both OPP tables must belong to genpds */
if (unlikely(!src_table->is_genpd || !dst_table->is_genpd)) {
pr_err("%s: Performance state is only valid for genpds.\n", __func__);
return -EINVAL;
}

/* required-opps not fully initialized yet */
if (lazy_linking_pending(src_table))
return -EBUSY;
Expand Down
4 changes: 3 additions & 1 deletion drivers/opp/debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,11 +152,13 @@ void opp_debug_create_one(struct dev_pm_opp *opp, struct opp_table *opp_table)
debugfs_create_bool("dynamic", S_IRUGO, d, &opp->dynamic);
debugfs_create_bool("turbo", S_IRUGO, d, &opp->turbo);
debugfs_create_bool("suspend", S_IRUGO, d, &opp->suspend);
debugfs_create_u32("performance_state", S_IRUGO, d, &opp->pstate);
debugfs_create_u32("level", S_IRUGO, d, &opp->level);
debugfs_create_ulong("clock_latency_ns", S_IRUGO, d,
&opp->clock_latency_ns);

if (opp_table->is_genpd)
debugfs_create_u32("performance_state", S_IRUGO, d, &opp->pstate);

opp->of_name = of_node_full_name(opp->np);
debugfs_create_str("of_name", S_IRUGO, d, (char **)&opp->of_name);

Expand Down
6 changes: 6 additions & 0 deletions drivers/opp/of.c
Original file line number Diff line number Diff line change
Expand Up @@ -1392,6 +1392,12 @@ int of_get_required_opp_performance_state(struct device_node *np, int index)
goto put_required_np;
}

/* The OPP tables must belong to a genpd */
if (unlikely(!opp_table->is_genpd)) {
pr_err("%s: Performance state is only valid for genpds.\n", __func__);
goto put_required_np;
}

opp = _find_opp_of_np(opp_table, required_np);
if (opp) {
pstate = opp->pstate;
Expand Down

0 comments on commit 84cb7ff

Please sign in to comment.