diff mbox series

[v1] regulator: Don't error out fixed regulator in regulator_sync_voltage()

Message ID 20211021110707.20416-1-digetx@gmail.com
State Changes Requested
Headers show
Series [v1] regulator: Don't error out fixed regulator in regulator_sync_voltage() | expand

Commit Message

Dmitry Osipenko Oct. 21, 2021, 11:07 a.m. UTC
Fixed regulator can't change voltage and regulator_sync_voltage() returns
-EINVAL in this case. Make regulator_sync_voltage() to succeed for a fixed
regulator.

On NVIDIA Tegra power management driver needs to sync voltage and we have
one device (Trimslice) that uses fixed regulator which is getting synced.
The syncing error isn't treated as fatal, but produces a noisy error
message. This patch silences that error.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/regulator/core.c | 3 +++
 1 file changed, 3 insertions(+)

Comments

Mark Brown Oct. 21, 2021, 1:12 p.m. UTC | #1
On Thu, Oct 21, 2021 at 02:07:07PM +0300, Dmitry Osipenko wrote:

> Fixed regulator can't change voltage and regulator_sync_voltage() returns
> -EINVAL in this case. Make regulator_sync_voltage() to succeed for a fixed
> regulator.

> +++ b/drivers/regulator/core.c
> @@ -4249,6 +4249,9 @@ int regulator_sync_voltage(struct regulator *regulator)
>  	struct regulator_voltage *voltage = &regulator->voltage[PM_SUSPEND_ON];
>  	int ret, min_uV, max_uV;
>  
> +	if (rdev->desc->fixed_uV && rdev->desc->n_voltages == 1)
> +		return 0;
> +
>  	regulator_lock(rdev);

It's unclear why this is checking both fixed_uV and n_voltages.  TBH
this feels like a higher level issue - with normal voltage configuration
we would have noticed that our constraints prevent the voltage changing
and not go as far as trying to actually apply a new configuration.  I
would expect a similar thing to be happening here.
Dmitry Osipenko Oct. 21, 2021, 1:46 p.m. UTC | #2
21.10.2021 16:12, Mark Brown пишет:
> On Thu, Oct 21, 2021 at 02:07:07PM +0300, Dmitry Osipenko wrote:
> 
>> Fixed regulator can't change voltage and regulator_sync_voltage() returns
>> -EINVAL in this case. Make regulator_sync_voltage() to succeed for a fixed
>> regulator.
> 
>> +++ b/drivers/regulator/core.c
>> @@ -4249,6 +4249,9 @@ int regulator_sync_voltage(struct regulator *regulator)
>>  	struct regulator_voltage *voltage = &regulator->voltage[PM_SUSPEND_ON];
>>  	int ret, min_uV, max_uV;
>>  
>> +	if (rdev->desc->fixed_uV && rdev->desc->n_voltages == 1)
>> +		return 0;
>> +
>>  	regulator_lock(rdev);
> 
> It's unclear why this is checking both fixed_uV and n_voltages.

It's unclear to me either. I borrowed this variant from the  preexisting
code [1][2].

[1]
https://elixir.bootlin.com/linux/v5.15-rc6/source/drivers/regulator/core.c#L3075

[2]
https://elixir.bootlin.com/linux/v5.15-rc6/source/drivers/regulator/core.c#L4319

>  TBH
> this feels like a higher level issue - with normal voltage configuration
> we would have noticed that our constraints prevent the voltage changing
> and not go as far as trying to actually apply a new configuration.  I
> would expect a similar thing to be happening here.
> 

This works for a normal regulator_set_voltage() because it checks
whether current voltage equals to the requested and then succeeds [3].
The higher level code relies on this behaviour of the regulator core, in
particular OPP core won't work without it and that's why voltage changes
work for a fixed regulator.

[3]
https://elixir.bootlin.com/linux/v5.15-rc6/source/drivers/regulator/core.c#L3619

This doesn't work for the regulator_sync_voltage() because it uses a
different code path and the whole point is to re-apply the current
voltage. Hence the extra check is actually needed for the fixed
regulators in order to be consistent with the behaviour of
regulator_set_voltage().
Dmitry Osipenko Oct. 21, 2021, 1:55 p.m. UTC | #3
21.10.2021 16:46, Dmitry Osipenko пишет:
> 21.10.2021 16:12, Mark Brown пишет:
>> On Thu, Oct 21, 2021 at 02:07:07PM +0300, Dmitry Osipenko wrote:
>>
>>> Fixed regulator can't change voltage and regulator_sync_voltage() returns
>>> -EINVAL in this case. Make regulator_sync_voltage() to succeed for a fixed
>>> regulator.
>>
>>> +++ b/drivers/regulator/core.c
>>> @@ -4249,6 +4249,9 @@ int regulator_sync_voltage(struct regulator *regulator)
>>>  	struct regulator_voltage *voltage = &regulator->voltage[PM_SUSPEND_ON];
>>>  	int ret, min_uV, max_uV;
>>>  
>>> +	if (rdev->desc->fixed_uV && rdev->desc->n_voltages == 1)
>>> +		return 0;
>>> +
>>>  	regulator_lock(rdev);
>>
>> It's unclear why this is checking both fixed_uV and n_voltages.
> 
> It's unclear to me either. I borrowed this variant from the  preexisting
> code [1][2].
> 
> [1]
> https://elixir.bootlin.com/linux/v5.15-rc6/source/drivers/regulator/core.c#L3075
> 
> [2]
> https://elixir.bootlin.com/linux/v5.15-rc6/source/drivers/regulator/core.c#L4319

The alternative could be to check regulator's capabilities:

if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_VOLTAGE))
	return 0;

This looks like a better variant, actually.

>>  TBH
>> this feels like a higher level issue - with normal voltage configuration
>> we would have noticed that our constraints prevent the voltage changing
>> and not go as far as trying to actually apply a new configuration.  I
>> would expect a similar thing to be happening here.
>>
> 
> This works for a normal regulator_set_voltage() because it checks
> whether current voltage equals to the requested and then succeeds [3].
> The higher level code relies on this behaviour of the regulator core, in
> particular OPP core won't work without it and that's why voltage changes
> work for a fixed regulator.
> 
> [3]
> https://elixir.bootlin.com/linux/v5.15-rc6/source/drivers/regulator/core.c#L3619
> 
> This doesn't work for the regulator_sync_voltage() because it uses a
> different code path and the whole point is to re-apply the current
> voltage. Hence the extra check is actually needed for the fixed
> regulators in order to be consistent with the behaviour of
> regulator_set_voltage().
>
Mark Brown Oct. 21, 2021, 2:33 p.m. UTC | #4
On Thu, Oct 21, 2021 at 04:55:17PM +0300, Dmitry Osipenko wrote:

> The alternative could be to check regulator's capabilities:

> if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_VOLTAGE))
> 	return 0;

> This looks like a better variant, actually.

Yes, that should be more robust.
diff mbox series

Patch

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 26bee444fc70..e1324edb3f8d 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -4249,6 +4249,9 @@  int regulator_sync_voltage(struct regulator *regulator)
 	struct regulator_voltage *voltage = &regulator->voltage[PM_SUSPEND_ON];
 	int ret, min_uV, max_uV;
 
+	if (rdev->desc->fixed_uV && rdev->desc->n_voltages == 1)
+		return 0;
+
 	regulator_lock(rdev);
 
 	if (!rdev->desc->ops->set_voltage &&