diff options
author | Viresh Kumar <viresh.kumar@linaro.org> | 2015-09-04 04:17:22 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-09-14 20:03:15 -0400 |
commit | 1840995c52d44bec8c20d6c07a706dc1499da9da (patch) | |
tree | 7272d7d285eadaa307a25d8c8069fa852817e64f | |
parent | 6ff33f3902c3b1c5d0db6b1e2c70b6d76fba357f (diff) |
PM / OPP: reuse of_parse_phandle()
We already have a better API to get the opp descriptor block's node from
cpu-node. Lets reuse that instead of creating our own routines for the
same stuff. That cleans the code a lot.
This also kills a check we had earlier (as we are using the generic API
now). Earlier we used to check if the operating-points-v2 property
contained multiple phandles instead of a single phandle.
Killing this check isn't an issue because, we only parse the first entry
with of_parse_phandle(). So, if a user passes multiple phandles, its
really his problem :)
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | drivers/base/power/opp.c | 71 |
1 files changed, 17 insertions, 54 deletions
diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c index 28cd75c535b0..c3a738652d13 100644 --- a/drivers/base/power/opp.c +++ b/drivers/base/power/opp.c | |||
@@ -1281,69 +1281,33 @@ void of_cpumask_free_opp_table(cpumask_var_t cpumask) | |||
1281 | } | 1281 | } |
1282 | EXPORT_SYMBOL_GPL(of_cpumask_free_opp_table); | 1282 | EXPORT_SYMBOL_GPL(of_cpumask_free_opp_table); |
1283 | 1283 | ||
1284 | /* Returns opp descriptor node from its phandle. Caller must do of_node_put() */ | 1284 | /* Returns opp descriptor node for a device, caller must do of_node_put() */ |
1285 | static struct device_node * | ||
1286 | _of_get_opp_desc_node_from_prop(struct device *dev, const struct property *prop) | ||
1287 | { | ||
1288 | struct device_node *opp_np; | ||
1289 | |||
1290 | opp_np = of_find_node_by_phandle(be32_to_cpup(prop->value)); | ||
1291 | if (!opp_np) { | ||
1292 | dev_err(dev, "%s: Prop: %s contains invalid opp desc phandle\n", | ||
1293 | __func__, prop->name); | ||
1294 | return ERR_PTR(-EINVAL); | ||
1295 | } | ||
1296 | |||
1297 | return opp_np; | ||
1298 | } | ||
1299 | |||
1300 | /* Returns opp descriptor node for a device. Caller must do of_node_put() */ | ||
1301 | static struct device_node *_of_get_opp_desc_node(struct device *dev) | 1285 | static struct device_node *_of_get_opp_desc_node(struct device *dev) |
1302 | { | 1286 | { |
1303 | const struct property *prop; | ||
1304 | |||
1305 | prop = of_find_property(dev->of_node, "operating-points-v2", NULL); | ||
1306 | if (!prop) | ||
1307 | return ERR_PTR(-ENODEV); | ||
1308 | if (!prop->value) | ||
1309 | return ERR_PTR(-ENODATA); | ||
1310 | |||
1311 | /* | 1287 | /* |
1312 | * TODO: Support for multiple OPP tables. | 1288 | * TODO: Support for multiple OPP tables. |
1313 | * | 1289 | * |
1314 | * There should be only ONE phandle present in "operating-points-v2" | 1290 | * There should be only ONE phandle present in "operating-points-v2" |
1315 | * property. | 1291 | * property. |
1316 | */ | 1292 | */ |
1317 | if (prop->length != sizeof(__be32)) { | ||
1318 | dev_err(dev, "%s: Invalid opp desc phandle\n", __func__); | ||
1319 | return ERR_PTR(-EINVAL); | ||
1320 | } | ||
1321 | 1293 | ||
1322 | return _of_get_opp_desc_node_from_prop(dev, prop); | 1294 | return of_parse_phandle(dev->of_node, "operating-points-v2", 0); |
1323 | } | 1295 | } |
1324 | 1296 | ||
1325 | /* Initializes OPP tables based on new bindings */ | 1297 | /* Initializes OPP tables based on new bindings */ |
1326 | static int _of_init_opp_table_v2(struct device *dev, | 1298 | static int _of_init_opp_table_v2(struct device *dev, |
1327 | const struct property *prop) | 1299 | struct device_node *opp_np) |
1328 | { | 1300 | { |
1329 | struct device_node *opp_np, *np; | 1301 | struct device_node *np; |
1330 | struct device_opp *dev_opp; | 1302 | struct device_opp *dev_opp; |
1331 | int ret = 0, count = 0; | 1303 | int ret = 0, count = 0; |
1332 | 1304 | ||
1333 | if (!prop->value) | ||
1334 | return -ENODATA; | ||
1335 | |||
1336 | /* Get opp node */ | ||
1337 | opp_np = _of_get_opp_desc_node_from_prop(dev, prop); | ||
1338 | if (IS_ERR(opp_np)) | ||
1339 | return PTR_ERR(opp_np); | ||
1340 | |||
1341 | dev_opp = _managed_opp(opp_np); | 1305 | dev_opp = _managed_opp(opp_np); |
1342 | if (dev_opp) { | 1306 | if (dev_opp) { |
1343 | /* OPPs are already managed */ | 1307 | /* OPPs are already managed */ |
1344 | if (!_add_list_dev(dev, dev_opp)) | 1308 | if (!_add_list_dev(dev, dev_opp)) |
1345 | ret = -ENOMEM; | 1309 | ret = -ENOMEM; |
1346 | goto put_opp_np; | 1310 | return ret; |
1347 | } | 1311 | } |
1348 | 1312 | ||
1349 | /* We have opp-list node now, iterate over it and add OPPs */ | 1313 | /* We have opp-list node now, iterate over it and add OPPs */ |
@@ -1359,10 +1323,8 @@ static int _of_init_opp_table_v2(struct device *dev, | |||
1359 | } | 1323 | } |
1360 | 1324 | ||
1361 | /* There should be one of more OPP defined */ | 1325 | /* There should be one of more OPP defined */ |
1362 | if (WARN_ON(!count)) { | 1326 | if (WARN_ON(!count)) |
1363 | ret = -ENOENT; | 1327 | return -ENOENT; |
1364 | goto put_opp_np; | ||
1365 | } | ||
1366 | 1328 | ||
1367 | dev_opp = _find_device_opp(dev); | 1329 | dev_opp = _find_device_opp(dev); |
1368 | if (WARN_ON(IS_ERR(dev_opp))) { | 1330 | if (WARN_ON(IS_ERR(dev_opp))) { |
@@ -1373,13 +1335,10 @@ static int _of_init_opp_table_v2(struct device *dev, | |||
1373 | dev_opp->np = opp_np; | 1335 | dev_opp->np = opp_np; |
1374 | dev_opp->shared_opp = of_property_read_bool(opp_np, "opp-shared"); | 1336 | dev_opp->shared_opp = of_property_read_bool(opp_np, "opp-shared"); |
1375 | 1337 | ||
1376 | of_node_put(opp_np); | ||
1377 | return 0; | 1338 | return 0; |
1378 | 1339 | ||
1379 | free_table: | 1340 | free_table: |
1380 | of_free_opp_table(dev); | 1341 | of_free_opp_table(dev); |
1381 | put_opp_np: | ||
1382 | of_node_put(opp_np); | ||
1383 | 1342 | ||
1384 | return ret; | 1343 | return ret; |
1385 | } | 1344 | } |
@@ -1446,14 +1405,15 @@ static int _of_init_opp_table_v1(struct device *dev) | |||
1446 | */ | 1405 | */ |
1447 | int of_init_opp_table(struct device *dev) | 1406 | int of_init_opp_table(struct device *dev) |
1448 | { | 1407 | { |
1449 | const struct property *prop; | 1408 | struct device_node *opp_np; |
1409 | int ret; | ||
1450 | 1410 | ||
1451 | /* | 1411 | /* |
1452 | * OPPs have two version of bindings now. The older one is deprecated, | 1412 | * OPPs have two version of bindings now. The older one is deprecated, |
1453 | * try for the new binding first. | 1413 | * try for the new binding first. |
1454 | */ | 1414 | */ |
1455 | prop = of_find_property(dev->of_node, "operating-points-v2", NULL); | 1415 | opp_np = _of_get_opp_desc_node(dev); |
1456 | if (!prop) { | 1416 | if (!opp_np) { |
1457 | /* | 1417 | /* |
1458 | * Try old-deprecated bindings for backward compatibility with | 1418 | * Try old-deprecated bindings for backward compatibility with |
1459 | * older dtbs. | 1419 | * older dtbs. |
@@ -1461,7 +1421,10 @@ int of_init_opp_table(struct device *dev) | |||
1461 | return _of_init_opp_table_v1(dev); | 1421 | return _of_init_opp_table_v1(dev); |
1462 | } | 1422 | } |
1463 | 1423 | ||
1464 | return _of_init_opp_table_v2(dev, prop); | 1424 | ret = _of_init_opp_table_v2(dev, opp_np); |
1425 | of_node_put(opp_np); | ||
1426 | |||
1427 | return ret; | ||
1465 | } | 1428 | } |
1466 | EXPORT_SYMBOL_GPL(of_init_opp_table); | 1429 | EXPORT_SYMBOL_GPL(of_init_opp_table); |
1467 | 1430 | ||
@@ -1550,7 +1513,7 @@ int of_get_cpus_sharing_opps(struct device *cpu_dev, cpumask_var_t cpumask) | |||
1550 | 1513 | ||
1551 | /* Get OPP descriptor node */ | 1514 | /* Get OPP descriptor node */ |
1552 | np = _of_get_opp_desc_node(cpu_dev); | 1515 | np = _of_get_opp_desc_node(cpu_dev); |
1553 | if (IS_ERR(np)) { | 1516 | if (!np) { |
1554 | dev_dbg(cpu_dev, "%s: Couldn't find opp node: %ld\n", __func__, | 1517 | dev_dbg(cpu_dev, "%s: Couldn't find opp node: %ld\n", __func__, |
1555 | PTR_ERR(np)); | 1518 | PTR_ERR(np)); |
1556 | return -ENOENT; | 1519 | return -ENOENT; |
@@ -1574,7 +1537,7 @@ int of_get_cpus_sharing_opps(struct device *cpu_dev, cpumask_var_t cpumask) | |||
1574 | 1537 | ||
1575 | /* Get OPP descriptor node */ | 1538 | /* Get OPP descriptor node */ |
1576 | tmp_np = _of_get_opp_desc_node(tcpu_dev); | 1539 | tmp_np = _of_get_opp_desc_node(tcpu_dev); |
1577 | if (IS_ERR(tmp_np)) { | 1540 | if (!tmp_np) { |
1578 | dev_err(tcpu_dev, "%s: Couldn't find opp node: %ld\n", | 1541 | dev_err(tcpu_dev, "%s: Couldn't find opp node: %ld\n", |
1579 | __func__, PTR_ERR(tmp_np)); | 1542 | __func__, PTR_ERR(tmp_np)); |
1580 | ret = PTR_ERR(tmp_np); | 1543 | ret = PTR_ERR(tmp_np); |