Commit 3a557878 authored by Viresh Kumar's avatar Viresh Kumar

Merge branch 'opp/defer-probe' into HEAD

parents 8aaf6264 90d46d71
...@@ -2044,6 +2044,7 @@ int of_genpd_add_provider_simple(struct device_node *np, ...@@ -2044,6 +2044,7 @@ int of_genpd_add_provider_simple(struct device_node *np,
if (genpd->set_performance_state) { if (genpd->set_performance_state) {
ret = dev_pm_opp_of_add_table(&genpd->dev); ret = dev_pm_opp_of_add_table(&genpd->dev);
if (ret) { if (ret) {
if (ret != -EPROBE_DEFER)
dev_err(&genpd->dev, "Failed to add OPP table: %d\n", dev_err(&genpd->dev, "Failed to add OPP table: %d\n",
ret); ret);
goto unlock; goto unlock;
...@@ -2054,7 +2055,7 @@ int of_genpd_add_provider_simple(struct device_node *np, ...@@ -2054,7 +2055,7 @@ int of_genpd_add_provider_simple(struct device_node *np,
* state. * state.
*/ */
genpd->opp_table = dev_pm_opp_get_opp_table(&genpd->dev); genpd->opp_table = dev_pm_opp_get_opp_table(&genpd->dev);
WARN_ON(!genpd->opp_table); WARN_ON(IS_ERR(genpd->opp_table));
} }
ret = genpd_add_provider(np, genpd_xlate_simple, genpd); ret = genpd_add_provider(np, genpd_xlate_simple, genpd);
...@@ -2111,6 +2112,7 @@ int of_genpd_add_provider_onecell(struct device_node *np, ...@@ -2111,6 +2112,7 @@ int of_genpd_add_provider_onecell(struct device_node *np,
if (genpd->set_performance_state) { if (genpd->set_performance_state) {
ret = dev_pm_opp_of_add_table_indexed(&genpd->dev, i); ret = dev_pm_opp_of_add_table_indexed(&genpd->dev, i);
if (ret) { if (ret) {
if (ret != -EPROBE_DEFER)
dev_err(&genpd->dev, "Failed to add OPP table for index %d: %d\n", dev_err(&genpd->dev, "Failed to add OPP table for index %d: %d\n",
i, ret); i, ret);
goto error; goto error;
...@@ -2121,7 +2123,7 @@ int of_genpd_add_provider_onecell(struct device_node *np, ...@@ -2121,7 +2123,7 @@ int of_genpd_add_provider_onecell(struct device_node *np,
* performance state. * performance state.
*/ */
genpd->opp_table = dev_pm_opp_get_opp_table_indexed(&genpd->dev, i); genpd->opp_table = dev_pm_opp_get_opp_table_indexed(&genpd->dev, i);
WARN_ON(!genpd->opp_table); WARN_ON(IS_ERR(genpd->opp_table));
} }
genpd->provider = &np->fwnode; genpd->provider = &np->fwnode;
......
...@@ -1068,7 +1068,7 @@ static struct opp_table *_allocate_opp_table(struct device *dev, int index) ...@@ -1068,7 +1068,7 @@ static struct opp_table *_allocate_opp_table(struct device *dev, int index)
*/ */
opp_table = kzalloc(sizeof(*opp_table), GFP_KERNEL); opp_table = kzalloc(sizeof(*opp_table), GFP_KERNEL);
if (!opp_table) if (!opp_table)
return NULL; return ERR_PTR(-ENOMEM);
mutex_init(&opp_table->lock); mutex_init(&opp_table->lock);
mutex_init(&opp_table->genpd_virt_dev_lock); mutex_init(&opp_table->genpd_virt_dev_lock);
...@@ -1079,8 +1079,8 @@ static struct opp_table *_allocate_opp_table(struct device *dev, int index) ...@@ -1079,8 +1079,8 @@ static struct opp_table *_allocate_opp_table(struct device *dev, int index)
opp_dev = _add_opp_dev(dev, opp_table); opp_dev = _add_opp_dev(dev, opp_table);
if (!opp_dev) { if (!opp_dev) {
kfree(opp_table); ret = -ENOMEM;
return NULL; goto err;
} }
_of_init_opp_table(opp_table, dev, index); _of_init_opp_table(opp_table, dev, index);
...@@ -1089,16 +1089,21 @@ static struct opp_table *_allocate_opp_table(struct device *dev, int index) ...@@ -1089,16 +1089,21 @@ static struct opp_table *_allocate_opp_table(struct device *dev, int index)
opp_table->clk = clk_get(dev, NULL); opp_table->clk = clk_get(dev, NULL);
if (IS_ERR(opp_table->clk)) { if (IS_ERR(opp_table->clk)) {
ret = PTR_ERR(opp_table->clk); ret = PTR_ERR(opp_table->clk);
if (ret != -EPROBE_DEFER) if (ret == -EPROBE_DEFER)
dev_dbg(dev, "%s: Couldn't find clock: %d\n", __func__, goto err;
ret);
dev_dbg(dev, "%s: Couldn't find clock: %d\n", __func__, ret);
} }
/* Find interconnect path(s) for the device */ /* Find interconnect path(s) for the device */
ret = dev_pm_opp_of_find_icc_paths(dev, opp_table); ret = dev_pm_opp_of_find_icc_paths(dev, opp_table);
if (ret) if (ret) {
if (ret == -EPROBE_DEFER)
goto err;
dev_warn(dev, "%s: Error finding interconnect paths: %d\n", dev_warn(dev, "%s: Error finding interconnect paths: %d\n",
__func__, ret); __func__, ret);
}
BLOCKING_INIT_NOTIFIER_HEAD(&opp_table->head); BLOCKING_INIT_NOTIFIER_HEAD(&opp_table->head);
INIT_LIST_HEAD(&opp_table->opp_list); INIT_LIST_HEAD(&opp_table->opp_list);
...@@ -1107,6 +1112,10 @@ static struct opp_table *_allocate_opp_table(struct device *dev, int index) ...@@ -1107,6 +1112,10 @@ static struct opp_table *_allocate_opp_table(struct device *dev, int index)
/* Secure the device table modification */ /* Secure the device table modification */
list_add(&opp_table->node, &opp_tables); list_add(&opp_table->node, &opp_tables);
return opp_table; return opp_table;
err:
kfree(opp_table);
return ERR_PTR(ret);
} }
void _get_opp_table_kref(struct opp_table *opp_table) void _get_opp_table_kref(struct opp_table *opp_table)
...@@ -1129,7 +1138,7 @@ static struct opp_table *_opp_get_opp_table(struct device *dev, int index) ...@@ -1129,7 +1138,7 @@ static struct opp_table *_opp_get_opp_table(struct device *dev, int index)
if (opp_table) { if (opp_table) {
if (!_add_opp_dev_unlocked(dev, opp_table)) { if (!_add_opp_dev_unlocked(dev, opp_table)) {
dev_pm_opp_put_opp_table(opp_table); dev_pm_opp_put_opp_table(opp_table);
opp_table = NULL; opp_table = ERR_PTR(-ENOMEM);
} }
goto unlock; goto unlock;
} }
...@@ -1573,8 +1582,8 @@ struct opp_table *dev_pm_opp_set_supported_hw(struct device *dev, ...@@ -1573,8 +1582,8 @@ struct opp_table *dev_pm_opp_set_supported_hw(struct device *dev,
struct opp_table *opp_table; struct opp_table *opp_table;
opp_table = dev_pm_opp_get_opp_table(dev); opp_table = dev_pm_opp_get_opp_table(dev);
if (!opp_table) if (IS_ERR(opp_table))
return ERR_PTR(-ENOMEM); return opp_table;
/* Make sure there are no concurrent readers while updating opp_table */ /* Make sure there are no concurrent readers while updating opp_table */
WARN_ON(!list_empty(&opp_table->opp_list)); WARN_ON(!list_empty(&opp_table->opp_list));
...@@ -1632,8 +1641,8 @@ struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, const char *name) ...@@ -1632,8 +1641,8 @@ struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, const char *name)
struct opp_table *opp_table; struct opp_table *opp_table;
opp_table = dev_pm_opp_get_opp_table(dev); opp_table = dev_pm_opp_get_opp_table(dev);
if (!opp_table) if (IS_ERR(opp_table))
return ERR_PTR(-ENOMEM); return opp_table;
/* Make sure there are no concurrent readers while updating opp_table */ /* Make sure there are no concurrent readers while updating opp_table */
WARN_ON(!list_empty(&opp_table->opp_list)); WARN_ON(!list_empty(&opp_table->opp_list));
...@@ -1725,8 +1734,8 @@ struct opp_table *dev_pm_opp_set_regulators(struct device *dev, ...@@ -1725,8 +1734,8 @@ struct opp_table *dev_pm_opp_set_regulators(struct device *dev,
int ret, i; int ret, i;
opp_table = dev_pm_opp_get_opp_table(dev); opp_table = dev_pm_opp_get_opp_table(dev);
if (!opp_table) if (IS_ERR(opp_table))
return ERR_PTR(-ENOMEM); return opp_table;
/* This should be called before OPPs are initialized */ /* This should be called before OPPs are initialized */
if (WARN_ON(!list_empty(&opp_table->opp_list))) { if (WARN_ON(!list_empty(&opp_table->opp_list))) {
...@@ -1833,8 +1842,8 @@ struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char *name) ...@@ -1833,8 +1842,8 @@ struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char *name)
int ret; int ret;
opp_table = dev_pm_opp_get_opp_table(dev); opp_table = dev_pm_opp_get_opp_table(dev);
if (!opp_table) if (IS_ERR(opp_table))
return ERR_PTR(-ENOMEM); return opp_table;
/* This should be called before OPPs are initialized */ /* This should be called before OPPs are initialized */
if (WARN_ON(!list_empty(&opp_table->opp_list))) { if (WARN_ON(!list_empty(&opp_table->opp_list))) {
...@@ -1901,8 +1910,8 @@ struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev, ...@@ -1901,8 +1910,8 @@ struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev,
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
opp_table = dev_pm_opp_get_opp_table(dev); opp_table = dev_pm_opp_get_opp_table(dev);
if (!opp_table) if (!IS_ERR(opp_table))
return ERR_PTR(-ENOMEM); return opp_table;
/* This should be called before OPPs are initialized */ /* This should be called before OPPs are initialized */
if (WARN_ON(!list_empty(&opp_table->opp_list))) { if (WARN_ON(!list_empty(&opp_table->opp_list))) {
...@@ -1982,8 +1991,8 @@ struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, ...@@ -1982,8 +1991,8 @@ struct opp_table *dev_pm_opp_attach_genpd(struct device *dev,
const char **name = names; const char **name = names;
opp_table = dev_pm_opp_get_opp_table(dev); opp_table = dev_pm_opp_get_opp_table(dev);
if (!opp_table) if (IS_ERR(opp_table))
return ERR_PTR(-ENOMEM); return opp_table;
/* /*
* If the genpd's OPP table isn't already initialized, parsing of the * If the genpd's OPP table isn't already initialized, parsing of the
...@@ -2153,8 +2162,8 @@ int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt) ...@@ -2153,8 +2162,8 @@ int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
int ret; int ret;
opp_table = dev_pm_opp_get_opp_table(dev); opp_table = dev_pm_opp_get_opp_table(dev);
if (!opp_table) if (IS_ERR(opp_table))
return -ENOMEM; return PTR_ERR(opp_table);
/* Fix regulator count for dynamic OPPs */ /* Fix regulator count for dynamic OPPs */
opp_table->regulator_count = 1; opp_table->regulator_count = 1;
......
...@@ -886,11 +886,25 @@ static int _of_add_opp_table_v1(struct device *dev, struct opp_table *opp_table) ...@@ -886,11 +886,25 @@ static int _of_add_opp_table_v1(struct device *dev, struct opp_table *opp_table)
const __be32 *val; const __be32 *val;
int nr, ret = 0; int nr, ret = 0;
mutex_lock(&opp_table->lock);
if (opp_table->parsed_static_opps) {
opp_table->parsed_static_opps++;
mutex_unlock(&opp_table->lock);
return 0;
}
opp_table->parsed_static_opps = 1;
mutex_unlock(&opp_table->lock);
prop = of_find_property(dev->of_node, "operating-points", NULL); prop = of_find_property(dev->of_node, "operating-points", NULL);
if (!prop) if (!prop) {
return -ENODEV; ret = -ENODEV;
if (!prop->value) goto remove_static_opp;
return -ENODATA; }
if (!prop->value) {
ret = -ENODATA;
goto remove_static_opp;
}
/* /*
* Each OPP is a set of tuples consisting of frequency and * Each OPP is a set of tuples consisting of frequency and
...@@ -899,13 +913,10 @@ static int _of_add_opp_table_v1(struct device *dev, struct opp_table *opp_table) ...@@ -899,13 +913,10 @@ static int _of_add_opp_table_v1(struct device *dev, struct opp_table *opp_table)
nr = prop->length / sizeof(u32); nr = prop->length / sizeof(u32);
if (nr % 2) { if (nr % 2) {
dev_err(dev, "%s: Invalid OPP table\n", __func__); dev_err(dev, "%s: Invalid OPP table\n", __func__);
return -EINVAL; ret = -EINVAL;
goto remove_static_opp;
} }
mutex_lock(&opp_table->lock);
opp_table->parsed_static_opps = 1;
mutex_unlock(&opp_table->lock);
val = prop->value; val = prop->value;
while (nr) { while (nr) {
unsigned long freq = be32_to_cpup(val++) * 1000; unsigned long freq = be32_to_cpup(val++) * 1000;
...@@ -915,12 +926,14 @@ static int _of_add_opp_table_v1(struct device *dev, struct opp_table *opp_table) ...@@ -915,12 +926,14 @@ static int _of_add_opp_table_v1(struct device *dev, struct opp_table *opp_table)
if (ret) { if (ret) {
dev_err(dev, "%s: Failed to add OPP %ld (%d)\n", dev_err(dev, "%s: Failed to add OPP %ld (%d)\n",
__func__, freq, ret); __func__, freq, ret);
_opp_remove_all_static(opp_table); goto remove_static_opp;
return ret;
} }
nr -= 2; nr -= 2;
} }
remove_static_opp:
_opp_remove_all_static(opp_table);
return ret; return ret;
} }
...@@ -947,8 +960,8 @@ int dev_pm_opp_of_add_table(struct device *dev) ...@@ -947,8 +960,8 @@ int dev_pm_opp_of_add_table(struct device *dev)
int ret; int ret;
opp_table = dev_pm_opp_get_opp_table_indexed(dev, 0); opp_table = dev_pm_opp_get_opp_table_indexed(dev, 0);
if (!opp_table) if (IS_ERR(opp_table))
return -ENOMEM; return PTR_ERR(opp_table);
/* /*
* OPPs have two version of bindings now. Also try the old (v1) * OPPs have two version of bindings now. Also try the old (v1)
...@@ -1002,8 +1015,8 @@ int dev_pm_opp_of_add_table_indexed(struct device *dev, int index) ...@@ -1002,8 +1015,8 @@ int dev_pm_opp_of_add_table_indexed(struct device *dev, int index)
} }
opp_table = dev_pm_opp_get_opp_table_indexed(dev, index); opp_table = dev_pm_opp_get_opp_table_indexed(dev, index);
if (!opp_table) if (IS_ERR(opp_table))
return -ENOMEM; return PTR_ERR(opp_table);
ret = _of_add_opp_table_v2(dev, opp_table); ret = _of_add_opp_table_v2(dev, opp_table);
if (ret) if (ret)
......
...@@ -93,7 +93,7 @@ static int exynos_asv_update_opps(struct exynos_asv *asv) ...@@ -93,7 +93,7 @@ static int exynos_asv_update_opps(struct exynos_asv *asv)
continue; continue;
opp_table = dev_pm_opp_get_opp_table(cpu); opp_table = dev_pm_opp_get_opp_table(cpu);
if (IS_ERR_OR_NULL(opp_table)) if (IS_ERR(opp_table))
continue; continue;
if (!last_opp_table || opp_table != last_opp_table) { if (!last_opp_table || opp_table != last_opp_table) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment