in of.c [455:516]
int dev_pm_opp_of_find_icc_paths(struct device *dev,
struct opp_table *opp_table)
{
struct device_node *np;
int ret, i, count, num_paths;
struct icc_path **paths;
ret = _bandwidth_supported(dev, opp_table);
if (ret == -EINVAL)
return 0; /* Empty OPP table is a valid corner-case, let's not fail */
else if (ret <= 0)
return ret;
ret = 0;
np = of_node_get(dev->of_node);
if (!np)
return 0;
count = of_count_phandle_with_args(np, "interconnects",
"#interconnect-cells");
of_node_put(np);
if (count < 0)
return 0;
/* two phandles when #interconnect-cells = <1> */
if (count % 2) {
dev_err(dev, "%s: Invalid interconnects values\n", __func__);
return -EINVAL;
}
num_paths = count / 2;
paths = kcalloc(num_paths, sizeof(*paths), GFP_KERNEL);
if (!paths)
return -ENOMEM;
for (i = 0; i < num_paths; i++) {
paths[i] = of_icc_get_by_index(dev, i);
if (IS_ERR(paths[i])) {
ret = PTR_ERR(paths[i]);
if (ret != -EPROBE_DEFER) {
dev_err(dev, "%s: Unable to get path%d: %d\n",
__func__, i, ret);
}
goto err;
}
}
if (opp_table) {
opp_table->paths = paths;
opp_table->path_count = num_paths;
return 0;
}
err:
while (i--)
icc_put(paths[i]);
kfree(paths);
return ret;
}