Skip to content

Commit 63ce228

Browse files
committed
Merge branch 'opp/linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm into pm-opp
Pull more OPP updates for v4.18 from Viresh Kumar. * 'opp/linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm: OPP: Allow same OPP table to be used for multiple genpd PM / OPP: Fix shared OPP table support in dev_pm_opp_register_set_opp_helper() PM / OPP: Fix shared OPP table support in dev_pm_opp_set_regulators() PM / OPP: Fix shared OPP table support in dev_pm_opp_set_prop_name() PM / OPP: Fix shared OPP table support in dev_pm_opp_set_supported_hw()
2 parents 9ad14c0 + 8a352fd commit 63ce228

File tree

2 files changed

+36
-74
lines changed

2 files changed

+36
-74
lines changed

drivers/opp/core.c

Lines changed: 21 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,7 +1157,6 @@ struct opp_table *dev_pm_opp_set_supported_hw(struct device *dev,
11571157
const u32 *versions, unsigned int count)
11581158
{
11591159
struct opp_table *opp_table;
1160-
int ret;
11611160

11621161
opp_table = dev_pm_opp_get_opp_table(dev);
11631162
if (!opp_table)
@@ -1166,29 +1165,20 @@ struct opp_table *dev_pm_opp_set_supported_hw(struct device *dev,
11661165
/* Make sure there are no concurrent readers while updating opp_table */
11671166
WARN_ON(!list_empty(&opp_table->opp_list));
11681167

1169-
/* Do we already have a version hierarchy associated with opp_table? */
1170-
if (opp_table->supported_hw) {
1171-
dev_err(dev, "%s: Already have supported hardware list\n",
1172-
__func__);
1173-
ret = -EBUSY;
1174-
goto err;
1175-
}
1168+
/* Another CPU that shares the OPP table has set the property ? */
1169+
if (opp_table->supported_hw)
1170+
return opp_table;
11761171

11771172
opp_table->supported_hw = kmemdup(versions, count * sizeof(*versions),
11781173
GFP_KERNEL);
11791174
if (!opp_table->supported_hw) {
1180-
ret = -ENOMEM;
1181-
goto err;
1175+
dev_pm_opp_put_opp_table(opp_table);
1176+
return ERR_PTR(-ENOMEM);
11821177
}
11831178

11841179
opp_table->supported_hw_count = count;
11851180

11861181
return opp_table;
1187-
1188-
err:
1189-
dev_pm_opp_put_opp_table(opp_table);
1190-
1191-
return ERR_PTR(ret);
11921182
}
11931183
EXPORT_SYMBOL_GPL(dev_pm_opp_set_supported_hw);
11941184

@@ -1205,12 +1195,6 @@ void dev_pm_opp_put_supported_hw(struct opp_table *opp_table)
12051195
/* Make sure there are no concurrent readers while updating opp_table */
12061196
WARN_ON(!list_empty(&opp_table->opp_list));
12071197

1208-
if (!opp_table->supported_hw) {
1209-
pr_err("%s: Doesn't have supported hardware list\n",
1210-
__func__);
1211-
return;
1212-
}
1213-
12141198
kfree(opp_table->supported_hw);
12151199
opp_table->supported_hw = NULL;
12161200
opp_table->supported_hw_count = 0;
@@ -1232,7 +1216,6 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_put_supported_hw);
12321216
struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, const char *name)
12331217
{
12341218
struct opp_table *opp_table;
1235-
int ret;
12361219

12371220
opp_table = dev_pm_opp_get_opp_table(dev);
12381221
if (!opp_table)
@@ -1241,26 +1224,17 @@ struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, const char *name)
12411224
/* Make sure there are no concurrent readers while updating opp_table */
12421225
WARN_ON(!list_empty(&opp_table->opp_list));
12431226

1244-
/* Do we already have a prop-name associated with opp_table? */
1245-
if (opp_table->prop_name) {
1246-
dev_err(dev, "%s: Already have prop-name %s\n", __func__,
1247-
opp_table->prop_name);
1248-
ret = -EBUSY;
1249-
goto err;
1250-
}
1227+
/* Another CPU that shares the OPP table has set the property ? */
1228+
if (opp_table->prop_name)
1229+
return opp_table;
12511230

12521231
opp_table->prop_name = kstrdup(name, GFP_KERNEL);
12531232
if (!opp_table->prop_name) {
1254-
ret = -ENOMEM;
1255-
goto err;
1233+
dev_pm_opp_put_opp_table(opp_table);
1234+
return ERR_PTR(-ENOMEM);
12561235
}
12571236

12581237
return opp_table;
1259-
1260-
err:
1261-
dev_pm_opp_put_opp_table(opp_table);
1262-
1263-
return ERR_PTR(ret);
12641238
}
12651239
EXPORT_SYMBOL_GPL(dev_pm_opp_set_prop_name);
12661240

@@ -1277,11 +1251,6 @@ void dev_pm_opp_put_prop_name(struct opp_table *opp_table)
12771251
/* Make sure there are no concurrent readers while updating opp_table */
12781252
WARN_ON(!list_empty(&opp_table->opp_list));
12791253

1280-
if (!opp_table->prop_name) {
1281-
pr_err("%s: Doesn't have a prop-name\n", __func__);
1282-
return;
1283-
}
1284-
12851254
kfree(opp_table->prop_name);
12861255
opp_table->prop_name = NULL;
12871256

@@ -1351,11 +1320,9 @@ struct opp_table *dev_pm_opp_set_regulators(struct device *dev,
13511320
goto err;
13521321
}
13531322

1354-
/* Already have regulators set */
1355-
if (opp_table->regulators) {
1356-
ret = -EBUSY;
1357-
goto err;
1358-
}
1323+
/* Another CPU that shares the OPP table has set the regulators ? */
1324+
if (opp_table->regulators)
1325+
return opp_table;
13591326

13601327
opp_table->regulators = kmalloc_array(count,
13611328
sizeof(*opp_table->regulators),
@@ -1409,10 +1376,8 @@ void dev_pm_opp_put_regulators(struct opp_table *opp_table)
14091376
{
14101377
int i;
14111378

1412-
if (!opp_table->regulators) {
1413-
pr_err("%s: Doesn't have regulators set\n", __func__);
1414-
return;
1415-
}
1379+
if (!opp_table->regulators)
1380+
goto put_opp_table;
14161381

14171382
/* Make sure there are no concurrent readers while updating opp_table */
14181383
WARN_ON(!list_empty(&opp_table->opp_list));
@@ -1426,6 +1391,7 @@ void dev_pm_opp_put_regulators(struct opp_table *opp_table)
14261391
opp_table->regulators = NULL;
14271392
opp_table->regulator_count = 0;
14281393

1394+
put_opp_table:
14291395
dev_pm_opp_put_opp_table(opp_table);
14301396
}
14311397
EXPORT_SYMBOL_GPL(dev_pm_opp_put_regulators);
@@ -1511,7 +1477,6 @@ struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev,
15111477
int (*set_opp)(struct dev_pm_set_opp_data *data))
15121478
{
15131479
struct opp_table *opp_table;
1514-
int ret;
15151480

15161481
if (!set_opp)
15171482
return ERR_PTR(-EINVAL);
@@ -1522,24 +1487,15 @@ struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev,
15221487

15231488
/* This should be called before OPPs are initialized */
15241489
if (WARN_ON(!list_empty(&opp_table->opp_list))) {
1525-
ret = -EBUSY;
1526-
goto err;
1490+
dev_pm_opp_put_opp_table(opp_table);
1491+
return ERR_PTR(-EBUSY);
15271492
}
15281493

1529-
/* Already have custom set_opp helper */
1530-
if (WARN_ON(opp_table->set_opp)) {
1531-
ret = -EBUSY;
1532-
goto err;
1533-
}
1534-
1535-
opp_table->set_opp = set_opp;
1494+
/* Another CPU that shares the OPP table has set the helper ? */
1495+
if (!opp_table->set_opp)
1496+
opp_table->set_opp = set_opp;
15361497

15371498
return opp_table;
1538-
1539-
err:
1540-
dev_pm_opp_put_opp_table(opp_table);
1541-
1542-
return ERR_PTR(ret);
15431499
}
15441500
EXPORT_SYMBOL_GPL(dev_pm_opp_register_set_opp_helper);
15451501

@@ -1552,17 +1508,10 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_register_set_opp_helper);
15521508
*/
15531509
void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table)
15541510
{
1555-
if (!opp_table->set_opp) {
1556-
pr_err("%s: Doesn't have custom set_opp helper set\n",
1557-
__func__);
1558-
return;
1559-
}
1560-
15611511
/* Make sure there are no concurrent readers while updating opp_table */
15621512
WARN_ON(!list_empty(&opp_table->opp_list));
15631513

15641514
opp_table->set_opp = NULL;
1565-
15661515
dev_pm_opp_put_opp_table(opp_table);
15671516
}
15681517
EXPORT_SYMBOL_GPL(dev_pm_opp_unregister_set_opp_helper);

drivers/opp/of.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -554,11 +554,24 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_of_add_table);
554554
int dev_pm_opp_of_add_table_indexed(struct device *dev, int index)
555555
{
556556
struct device_node *opp_np;
557-
int ret;
557+
int ret, count;
558558

559+
again:
559560
opp_np = _opp_of_get_opp_desc_node(dev->of_node, index);
560-
if (!opp_np)
561+
if (!opp_np) {
562+
/*
563+
* If only one phandle is present, then the same OPP table
564+
* applies for all index requests.
565+
*/
566+
count = of_count_phandle_with_args(dev->of_node,
567+
"operating-points-v2", NULL);
568+
if (count == 1 && index) {
569+
index = 0;
570+
goto again;
571+
}
572+
561573
return -ENODEV;
574+
}
562575

563576
ret = _of_add_opp_table_v2(dev, opp_np);
564577
of_node_put(opp_np);

0 commit comments

Comments
 (0)