diff options
| author | Viresh Kumar <viresh.kumar@linaro.org> | 2020-08-26 16:32:27 +0530 | 
|---|---|---|
| committer | Viresh Kumar <viresh.kumar@linaro.org> | 2020-09-16 14:02:33 +0530 | 
| commit | 0ff25c99042a56cd1580b381dd747a56286489cd (patch) | |
| tree | 0af62d34373136b8332f4db11dbe48a240a87d6b | |
| parent | 4461269572e6fc216b63e2254c83035d1bc21eb7 (diff) | |
opp: Allow opp-supported-hw to contain multiple versions
The bindings allow multiple versions to be passed to "opp-supported-hw"
property, either of which can result in enabling of the OPP.
Update code to allow that.
Tested-by: Stephan Gerhold <stephan@gerhold.net>
Tested-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
| -rw-r--r-- | drivers/opp/of.c | 47 | 
1 files changed, 33 insertions, 14 deletions
diff --git a/drivers/opp/of.c b/drivers/opp/of.c index 2f294c57ec06..aa829a569825 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -434,9 +434,9 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_of_find_icc_paths);  static bool _opp_is_supported(struct device *dev, struct opp_table *opp_table,  			      struct device_node *np)  { -	unsigned int count = opp_table->supported_hw_count; -	u32 version; -	int ret; +	unsigned int levels = opp_table->supported_hw_count; +	int count, versions, ret, i, j; +	u32 val;  	if (!opp_table->supported_hw) {  		/* @@ -451,21 +451,40 @@ static bool _opp_is_supported(struct device *dev, struct opp_table *opp_table,  			return true;  	} -	while (count--) { -		ret = of_property_read_u32_index(np, "opp-supported-hw", count, -						 &version); -		if (ret) { -			dev_warn(dev, "%s: failed to read opp-supported-hw property at index %d: %d\n", -				 __func__, count, ret); -			return false; +	count = of_property_count_u32_elems(np, "opp-supported-hw"); +	if (count <= 0 || count % levels) { +		dev_err(dev, "%s: Invalid opp-supported-hw property (%d)\n", +			__func__, count); +		return false; +	} + +	versions = count / levels; + +	/* All levels in at least one of the versions should match */ +	for (i = 0; i < versions; i++) { +		bool supported = true; + +		for (j = 0; j < levels; j++) { +			ret = of_property_read_u32_index(np, "opp-supported-hw", +							 i * levels + j, &val); +			if (ret) { +				dev_warn(dev, "%s: failed to read opp-supported-hw property at index %d: %d\n", +					 __func__, i * levels + j, ret); +				return false; +			} + +			/* Check if the level is supported */ +			if (!(val & opp_table->supported_hw[j])) { +				supported = false; +				break; +			}  		} -		/* Both of these are bitwise masks of the versions */ -		if (!(version & opp_table->supported_hw[count])) -			return false; +		if (supported) +			return true;  	} -	return true; +	return false;  }  static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev,  | 
