diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/opp/core.c | 23 | ||||
-rw-r--r-- | drivers/opp/of.c | 26 | ||||
-rw-r--r-- | drivers/opp/opp.h | 6 | ||||
-rw-r--r-- | drivers/opp/ti-opp-supply.c | 6 |
4 files changed, 42 insertions, 19 deletions
diff --git a/drivers/opp/core.c b/drivers/opp/core.c index eec1b60d7781..e5507add8f04 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -196,12 +196,12 @@ unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev) if (IS_ERR(opp_table)) return 0; - count = opp_table->regulator_count; - /* Regulator may not be required for the device */ - if (!count) + if (!opp_table->regulators) goto put_opp_table; + count = opp_table->regulator_count; + uV = kmalloc_array(count, sizeof(*uV), GFP_KERNEL); if (!uV) goto put_opp_table; @@ -843,6 +843,9 @@ static struct opp_table *_allocate_opp_table(struct device *dev, int index) mutex_init(&opp_table->genpd_virt_dev_lock); INIT_LIST_HEAD(&opp_table->dev_list); + /* Mark regulator count uninitialized */ + opp_table->regulator_count = -1; + opp_dev = _add_opp_dev(dev, opp_table); if (!opp_dev) { kfree(opp_table); @@ -1063,7 +1066,7 @@ struct dev_pm_opp *_opp_allocate(struct opp_table *table) int count, supply_size; /* Allocate space for at least one supply */ - count = table->regulator_count ? table->regulator_count : 1; + count = table->regulator_count > 0 ? table->regulator_count : 1; supply_size = sizeof(*opp->supplies) * count; /* allocate new OPP node and supplies structures */ @@ -1084,6 +1087,9 @@ static bool _opp_supported_by_regulators(struct dev_pm_opp *opp, struct regulator *reg; int i; + if (!opp_table->regulators) + return true; + for (i = 0; i < opp_table->regulator_count; i++) { reg = opp_table->regulators[i]; @@ -1368,7 +1374,7 @@ static int _allocate_set_opp_data(struct opp_table *opp_table) struct dev_pm_set_opp_data *data; int len, count = opp_table->regulator_count; - if (WARN_ON(!count)) + if (WARN_ON(!opp_table->regulators)) return -EINVAL; /* space for set_opp_data */ @@ -1465,7 +1471,7 @@ free_regulators: kfree(opp_table->regulators); opp_table->regulators = NULL; - opp_table->regulator_count = 0; + opp_table->regulator_count = -1; err: dev_pm_opp_put_opp_table(opp_table); @@ -1494,7 +1500,7 @@ void dev_pm_opp_put_regulators(struct opp_table *opp_table) kfree(opp_table->regulators); opp_table->regulators = NULL; - opp_table->regulator_count = 0; + opp_table->regulator_count = -1; put_opp_table: dev_pm_opp_put_opp_table(opp_table); @@ -1796,6 +1802,9 @@ int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt) if (!opp_table) return -ENOMEM; + /* Fix regulator count for dynamic OPPs */ + opp_table->regulator_count = 1; + ret = _opp_add_v1(opp_table, dev, freq, u_volt, true); if (ret) dev_pm_opp_put_opp_table(opp_table); diff --git a/drivers/opp/of.c b/drivers/opp/of.c index fde324dd8c46..06f0f632ec47 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -391,12 +391,10 @@ static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev, struct opp_table *opp_table) { u32 *microvolt, *microamp = NULL; - int supplies, vcount, icount, ret, i, j; + int supplies = opp_table->regulator_count, vcount, icount, ret, i, j; struct property *prop = NULL; char name[NAME_MAX]; - supplies = opp_table->regulator_count ? opp_table->regulator_count : 1; - /* Search for "opp-microvolt-<name>" */ if (opp_table->prop_name) { snprintf(name, sizeof(name), "opp-microvolt-%s", @@ -411,7 +409,13 @@ static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev, /* Missing property isn't a problem, but an invalid entry is */ if (!prop) { - if (!opp_table->regulator_count) + if (unlikely(supplies == -1)) { + /* Initialize regulator_count */ + opp_table->regulator_count = 0; + return 0; + } + + if (!supplies) return 0; dev_err(dev, "%s: opp-microvolt missing although OPP managing regulators\n", @@ -420,6 +424,14 @@ static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev, } } + if (unlikely(supplies == -1)) { + /* Initialize regulator_count */ + supplies = opp_table->regulator_count = 1; + } else if (unlikely(!supplies)) { + dev_err(dev, "%s: opp-microvolt wasn't expected\n", __func__); + return -EINVAL; + } + vcount = of_property_count_u32_elems(opp->np, name); if (vcount < 0) { dev_err(dev, "%s: Invalid %s property (%d)\n", @@ -826,10 +838,8 @@ int dev_pm_opp_of_add_table_indexed(struct device *dev, int index) */ count = of_count_phandle_with_args(dev->of_node, "operating-points-v2", NULL); - if (count != 1) - return -ENODEV; - - index = 0; + if (count == 1) + index = 0; } opp_table = dev_pm_opp_get_opp_table_indexed(dev, index); diff --git a/drivers/opp/opp.h b/drivers/opp/opp.h index 8aec38792cae..e24d81497375 100644 --- a/drivers/opp/opp.h +++ b/drivers/opp/opp.h @@ -145,7 +145,9 @@ enum opp_table_access { * @prop_name: A name to postfix to many DT properties, while parsing them. * @clk: Device's clock handle * @regulators: Supply regulators - * @regulator_count: Number of power supply regulators + * @regulator_count: Number of power supply regulators. Its value can be -1 + * (uninitialized), 0 (no opp-microvolt property) or > 0 (has opp-microvolt + * property). * @genpd_performance_state: Device's power domain support performance state. * @is_genpd: Marks if the OPP table belongs to a genpd. * @set_opp: Platform specific set_opp callback @@ -189,7 +191,7 @@ struct opp_table { const char *prop_name; struct clk *clk; struct regulator **regulators; - unsigned int regulator_count; + int regulator_count; bool genpd_performance_state; bool is_genpd; diff --git a/drivers/opp/ti-opp-supply.c b/drivers/opp/ti-opp-supply.c index 9e5a9a3112c9..1c69c404df11 100644 --- a/drivers/opp/ti-opp-supply.c +++ b/drivers/opp/ti-opp-supply.c @@ -288,7 +288,10 @@ static int ti_opp_supply_set_opp(struct dev_pm_set_opp_data *data) int ret; vdd_uv = _get_optimal_vdd_voltage(dev, &opp_data, - new_supply_vbb->u_volt); + new_supply_vdd->u_volt); + + if (new_supply_vdd->u_volt_min < vdd_uv) + new_supply_vdd->u_volt_min = vdd_uv; /* Scaling up? Scale voltage before frequency */ if (freq > old_freq) { @@ -414,7 +417,6 @@ static struct platform_driver ti_opp_supply_driver = { .probe = ti_opp_supply_probe, .driver = { .name = "ti_opp_supply", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(ti_opp_supply_of_match), }, }; |