[PATCH] regulator: bd718x7: Bypass bogus warnings

Vaittinen, Matti Matti.Vaittinen at fi.rohmeurope.com
Tue Jan 25 11:46:18 CET 2022


Hi dee Ho peeps!

On 1/25/22 04:46, Marek Vasut wrote:
> When regulator consumer attempts to set enabled DVS regulator voltage,
> the driver aborts with "Only DVS bucks can be changed when enabled".
> In case the regulator is already set to specified voltage, do nothing
> instead of failing outright.
> 
> When regulator consumer attempts to set enables regulator which cannot
> be controlled because it is already always enabled, the driver aborts
> with -EINVAL. Again, do nothing in such case and return 0, because the
> request is really fulfilled, the regulator is enabled.
>

I think this change makes sense. But at the same time there are risks.

I originally wrote this driver for executing some simple tests with the 
PMIC w/o loading an OS to control it. As a result, this driver uses 
static regulator configuration and assumes the run-states and things 
like whether to enable SW control for regulator ON/OFF.

What I am somewhat worried about is potential use together with full OS. 
For example at the current Linux driver for BD71837/BD71847 these 
assumptions are no longer enforced - whether to keep hardware-control 
for regulators or if the voltages are actually scaled by external 
feed-back connections can now be defined for OS via device-tree.

I am not sure what would be the best approach. We could add all the 
functionality and device-tree parsing that is done by the Linux driver - 
or we could remove all constraints/assumptions and leave sanity checks 
for users - which for sure can risk the SOC to not boot unless power to 
PMIC is cut (in practice this can mean removing/completely draining a 
battery).

To tell the truth - I have no idea where this driver is nowadays used - 
or if it is - so I can't really say what would be the sane thing to do :)


> Signed-off-by: Marek Vasut <marex at denx.de>
> Cc: Matti Vaittinen <matti.vaittinen at fi.rohmeurope.com>
> ---
>   drivers/power/regulator/bd71837.c | 69 ++++++++++++++++---------------
>   1 file changed, 36 insertions(+), 33 deletions(-)
> 
> diff --git a/drivers/power/regulator/bd71837.c b/drivers/power/regulator/bd71837.c
> index 74011d62985..d4f8da80ad7 100644
> --- a/drivers/power/regulator/bd71837.c
> +++ b/drivers/power/regulator/bd71837.c
> @@ -306,7 +306,7 @@ static int bd71837_set_enable(struct udevice *dev, bool enable)
>   	 * reseted to snvs state. Hence we can't set the state here.
>   	 */
>   	if (plat->enablemask == HW_STATE_CONTROL)

The HW_STATE_CONTROL flag is hard-coded based on assumed use-case for 
the power-rails and assumed reset-target. (Eg, it's not required to 
reset to SNVS state - in which case any of the power-rails can be under 
SW control. OTOH, it may be leaving power rail to the HW control is 
requested for any power rail regardless of the SNVS / boot-criticality 
in order to force certain output state at STBY. So simple hard-coding 
the HW_STATE_CONTROL may not work well with the OS configuration.

> -		return -EINVAL;
> +		return enable ? 0 : -EINVAL;
>   
>   	if (enable)
>   		val = plat->enablemask;
> @@ -315,6 +315,38 @@ static int bd71837_set_enable(struct udevice *dev, bool enable)
>   			       val);
>   }
>   
> +static int bd71837_get_value(struct udevice *dev)
> +{
> +	unsigned int reg, range;
> +	unsigned int tmp;
> +	struct bd71837_plat *plat = dev_get_plat(dev);
> +	int i;
> +
> +	reg = pmic_reg_read(dev->parent, plat->volt_reg);
> +	if (((int)reg) < 0)
> +		return reg;
> +
> +	range = reg & plat->rangemask;
> +
> +	reg &= plat->volt_mask;
> +	reg >>= ffs(plat->volt_mask) - 1;
> +
> +	for (i = 0; i < plat->numranges; i++) {
> +		struct bd71837_vrange *r = &plat->ranges[i];
> +
> +		if (plat->rangemask && ((plat->rangemask & range) !=
> +		    r->rangeval))
> +			continue;
> +
> +		if (!vrange_find_value(r, reg, &tmp))
> +			return tmp;
> +	}
> +
> +	pr_err("Unknown voltage value read from pmic\n");
> +
> +	return -EINVAL;
> +}
> +
>   static int bd71837_set_value(struct udevice *dev, int uvolt)
>   {
>   	unsigned int sel;
> @@ -330,6 +362,9 @@ static int bd71837_set_value(struct udevice *dev, int uvolt)
>   	 */
>   	if (!plat->dvs)
>   		if (bd71837_get_enable(dev)) {
> +			/* If the value is already set, skip the warning. */
> +			if (bd71837_get_value(dev) == uvolt)
> +				return 0;

I believe this fix is always correct - thanks Marek!

As a summary - no objections to the changes, just a word of warning for 
users of this driver that there might be more than this to do...

Best Regards
	-- Matti

-- 
The Linux Kernel guy at ROHM Semiconductors

Matti Vaittinen, Linux device drivers
ROHM Semiconductors, Finland SWDC
Kiviharjunlenkki 1E
90220 OULU
FINLAND

~~ this year is the year of a signature writers block ~~


More information about the U-Boot mailing list