Skip to content

Commit eed25eb

Browse files
committed
OPP: Make dev_pm_opp_set_regulators() accept NULL terminated list
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2122311 Conflicts: drivers/gpu/drm/panfrost/panfrost_drv.c - context differences in applying the NULL termination to the supplies arrays. commit 87686cc Author: Viresh Kumar <viresh.kumar@linaro.org> Date: Mon, 4 Jul 2022 16:10:39 +0530 Make dev_pm_opp_set_regulators() accept a NULL terminated list of names instead of making the callers keep the two parameters in sync, which creates an opportunity for bugs to get in. Suggested-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Reviewed-by: Steven Price <steven.price@arm.com> # panfrost Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Mark Langsdorf <mlangsdo@redhat.com>
1 parent e2a0883 commit eed25eb

File tree

9 files changed

+40
-33
lines changed

9 files changed

+40
-33
lines changed

drivers/cpufreq/cpufreq-dt.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ static int dt_cpufreq_early_init(struct device *dev, int cpu)
194194
struct private_data *priv;
195195
struct device *cpu_dev;
196196
bool fallback = false;
197-
const char *reg_name;
197+
const char *reg_name[] = { NULL, NULL };
198198
int ret;
199199

200200
/* Check if this CPU is already covered by some other policy */
@@ -219,10 +219,9 @@ static int dt_cpufreq_early_init(struct device *dev, int cpu)
219219
* OPP layer will be taking care of regulators now, but it needs to know
220220
* the name of the regulator first.
221221
*/
222-
reg_name = find_supply_name(cpu_dev);
223-
if (reg_name) {
224-
priv->opp_table = dev_pm_opp_set_regulators(cpu_dev, &reg_name,
225-
1);
222+
reg_name[0] = find_supply_name(cpu_dev);
223+
if (reg_name[0]) {
224+
priv->opp_table = dev_pm_opp_set_regulators(cpu_dev, reg_name);
226225
if (IS_ERR(priv->opp_table)) {
227226
ret = PTR_ERR(priv->opp_table);
228227
if (ret != -EPROBE_DEFER)

drivers/cpufreq/ti-cpufreq.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ static struct ti_cpufreq_soc_data omap34xx_soc_data = {
173173
* seems to always read as 0).
174174
*/
175175

176-
static const char * const omap3_reg_names[] = {"cpu0", "vbb"};
176+
static const char * const omap3_reg_names[] = {"cpu0", "vbb", NULL};
177177

178178
static struct ti_cpufreq_soc_data omap36xx_soc_data = {
179179
.reg_names = omap3_reg_names,
@@ -326,7 +326,7 @@ static int ti_cpufreq_probe(struct platform_device *pdev)
326326
const struct of_device_id *match;
327327
struct opp_table *ti_opp_table;
328328
struct ti_cpufreq_data *opp_data;
329-
const char * const default_reg_names[] = {"vdd", "vbb"};
329+
const char * const default_reg_names[] = {"vdd", "vbb", NULL};
330330
int ret;
331331

332332
match = dev_get_platdata(&pdev->dev);
@@ -387,8 +387,7 @@ static int ti_cpufreq_probe(struct platform_device *pdev)
387387
if (opp_data->soc_data->reg_names)
388388
reg_names = opp_data->soc_data->reg_names;
389389
ti_opp_table = dev_pm_opp_set_regulators(opp_data->cpu_dev,
390-
reg_names,
391-
ARRAY_SIZE(default_reg_names));
390+
reg_names);
392391
if (IS_ERR(ti_opp_table)) {
393392
dev_pm_opp_put_supported_hw(opp_data->opp_table);
394393
ret = PTR_ERR(ti_opp_table);

drivers/devfreq/exynos-bus.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,10 @@ static int exynos_bus_parent_parse_of(struct device_node *np,
180180
{
181181
struct device *dev = bus->dev;
182182
struct opp_table *opp_table;
183-
const char *vdd = "vdd";
183+
const char *supplies[] = { "vdd", NULL };
184184
int i, ret, count, size;
185185

186-
opp_table = dev_pm_opp_set_regulators(dev, &vdd, 1);
186+
opp_table = dev_pm_opp_set_regulators(dev, supplies);
187187
if (IS_ERR(opp_table)) {
188188
ret = PTR_ERR(opp_table);
189189
dev_err(dev, "failed to set regulators %d\n", ret);

drivers/gpu/drm/lima/lima_devfreq.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ int lima_devfreq_init(struct lima_device *ldev)
111111
struct dev_pm_opp *opp;
112112
unsigned long cur_freq;
113113
int ret;
114+
const char *regulator_names[] = { "mali", NULL };
114115

115116
if (!device_property_present(dev, "operating-points-v2"))
116117
/* Optional, continue without devfreq */
@@ -122,7 +123,7 @@ int lima_devfreq_init(struct lima_device *ldev)
122123
if (ret)
123124
return ret;
124125

125-
ret = devm_pm_opp_set_regulators(dev, (const char *[]){ "mali" }, 1);
126+
ret = devm_pm_opp_set_regulators(dev, regulator_names);
126127
if (ret) {
127128
/* Continue if the optional regulator is missing */
128129
if (ret != -ENODEV)

drivers/gpu/drm/panfrost/panfrost_devfreq.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,7 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
101101
return 0;
102102
}
103103

104-
ret = devm_pm_opp_set_regulators(dev, pfdev->comp->supply_names,
105-
pfdev->comp->num_supplies);
104+
ret = devm_pm_opp_set_regulators(dev, pfdev->comp->supply_names);
106105
if (ret) {
107106
/* Continue if the optional regulator is missing */
108107
if (ret != -ENODEV) {

drivers/gpu/drm/panfrost/panfrost_drv.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -652,24 +652,28 @@ static int panfrost_remove(struct platform_device *pdev)
652652
return 0;
653653
}
654654

655-
static const char * const default_supplies[] = { "mali" };
656-
static const struct panfrost_compatible default_data = {
657-
.num_supplies = ARRAY_SIZE(default_supplies),
655+
/*
656+
* The OPP core wants the supply names to be NULL terminated, but we need the
657+
* correct num_supplies value for regulator core. Hence, we NULL terminate here
658+
* and then initialize num_supplies with ARRAY_SIZE - 1.
659+
*/
660+
static const char * const default_supplies[] = { "mali", NULL };
661+
.num_supplies = ARRAY_SIZE(default_supplies) - 1,
658662
.supply_names = default_supplies,
659663
.num_pm_domains = 1, /* optional */
660664
.pm_domain_names = NULL,
661665
};
662666

663667
static const struct panfrost_compatible amlogic_data = {
664-
.num_supplies = ARRAY_SIZE(default_supplies),
668+
.num_supplies = ARRAY_SIZE(default_supplies) - 1,
665669
.supply_names = default_supplies,
666670
.vendor_quirk = panfrost_gpu_amlogic_quirk,
667671
};
668672

669-
const char * const mediatek_mt8183_supplies[] = { "mali", "sram" };
673+
const char * const mediatek_mt8183_supplies[] = { "mali", "sram", NULL };
670674
const char * const mediatek_mt8183_pm_domains[] = { "core0", "core1", "core2" };
671675
static const struct panfrost_compatible mediatek_mt8183_data = {
672-
.num_supplies = ARRAY_SIZE(mediatek_mt8183_supplies),
676+
.num_supplies = ARRAY_SIZE(mediatek_mt8183_supplies) - 1,
673677
.supply_names = mediatek_mt8183_supplies,
674678
.num_pm_domains = ARRAY_SIZE(mediatek_mt8183_pm_domains),
675679
.pm_domain_names = mediatek_mt8183_pm_domains,

drivers/opp/core.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1985,13 +1985,20 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_put_prop_name);
19851985
* This must be called before any OPPs are initialized for the device.
19861986
*/
19871987
struct opp_table *dev_pm_opp_set_regulators(struct device *dev,
1988-
const char * const names[],
1989-
unsigned int count)
1988+
const char * const names[])
19901989
{
19911990
struct dev_pm_opp_supply *supplies;
1991+
const char * const *temp = names;
19921992
struct opp_table *opp_table;
19931993
struct regulator *reg;
1994-
int ret, i;
1994+
int count = 0, ret, i;
1995+
1996+
/* Count number of regulators */
1997+
while (*temp++)
1998+
count++;
1999+
2000+
if (!count)
2001+
return ERR_PTR(-EINVAL);
19952002

19962003
opp_table = _add_opp_table(dev, false);
19972004
if (IS_ERR(opp_table))
@@ -2116,12 +2123,11 @@ static void devm_pm_opp_regulators_release(void *data)
21162123
* Return: 0 on success and errorno otherwise.
21172124
*/
21182125
int devm_pm_opp_set_regulators(struct device *dev,
2119-
const char * const names[],
2120-
unsigned int count)
2126+
const char * const names[])
21212127
{
21222128
struct opp_table *opp_table;
21232129

2124-
opp_table = dev_pm_opp_set_regulators(dev, names, count);
2130+
opp_table = dev_pm_opp_set_regulators(dev, names);
21252131
if (IS_ERR(opp_table))
21262132
return PTR_ERR(opp_table);
21272133

drivers/soc/tegra/pmc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1345,7 +1345,7 @@ tegra_pmc_core_pd_opp_to_performance_state(struct generic_pm_domain *genpd,
13451345
static int tegra_pmc_core_pd_add(struct tegra_pmc *pmc, struct device_node *np)
13461346
{
13471347
struct generic_pm_domain *genpd;
1348-
const char *rname = "core";
1348+
const char *rname[] = { "core", NULL};
13491349
int err;
13501350

13511351
genpd = devm_kzalloc(pmc->dev, sizeof(*genpd), GFP_KERNEL);
@@ -1356,7 +1356,7 @@ static int tegra_pmc_core_pd_add(struct tegra_pmc *pmc, struct device_node *np)
13561356
genpd->set_performance_state = tegra_pmc_core_pd_set_performance_state;
13571357
genpd->opp_to_performance_state = tegra_pmc_core_pd_opp_to_performance_state;
13581358

1359-
err = devm_pm_opp_set_regulators(pmc->dev, &rname, 1);
1359+
err = devm_pm_opp_set_regulators(pmc->dev, rname);
13601360
if (err)
13611361
return dev_err_probe(pmc->dev, err,
13621362
"failed to set core OPP regulator\n");

include/linux/pm_opp.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,9 @@ void dev_pm_opp_put_supported_hw(struct opp_table *opp_table);
152152
int devm_pm_opp_set_supported_hw(struct device *dev, const u32 *versions, unsigned int count);
153153
struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, const char *name);
154154
void dev_pm_opp_put_prop_name(struct opp_table *opp_table);
155-
struct opp_table *dev_pm_opp_set_regulators(struct device *dev, const char * const names[], unsigned int count);
155+
struct opp_table *dev_pm_opp_set_regulators(struct device *dev, const char * const names[]);
156156
void dev_pm_opp_put_regulators(struct opp_table *opp_table);
157-
int devm_pm_opp_set_regulators(struct device *dev, const char * const names[], unsigned int count);
157+
int devm_pm_opp_set_regulators(struct device *dev, const char * const names[]);
158158
struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char *name);
159159
void dev_pm_opp_put_clkname(struct opp_table *opp_table);
160160
int devm_pm_opp_set_clkname(struct device *dev, const char *name);
@@ -360,16 +360,15 @@ static inline struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, con
360360

361361
static inline void dev_pm_opp_put_prop_name(struct opp_table *opp_table) {}
362362

363-
static inline struct opp_table *dev_pm_opp_set_regulators(struct device *dev, const char * const names[], unsigned int count)
363+
static inline struct opp_table *dev_pm_opp_set_regulators(struct device *dev, const char * const names[])
364364
{
365365
return ERR_PTR(-EOPNOTSUPP);
366366
}
367367

368368
static inline void dev_pm_opp_put_regulators(struct opp_table *opp_table) {}
369369

370370
static inline int devm_pm_opp_set_regulators(struct device *dev,
371-
const char * const names[],
372-
unsigned int count)
371+
const char * const names[])
373372
{
374373
return -EOPNOTSUPP;
375374
}

0 commit comments

Comments
 (0)