Re: [PATCH 1/4] regulator: core: If consumers don't call regulator_set_load() assume max

From: David Collins
Date: Tue Aug 14 2018 - 14:30:39 EST


Hello Doug,

On 08/14/2018 10:06 AM, Douglas Anderson wrote:
> Not all regulator consumers call regulator_set_load(). On some
> regulators (like on RPMh-regulator) this could be bad since the
> regulator framework will treat this as if consumer needs no load.
> It's much better to assume that a dumb client needs the maximum
> possible load so we get correctness first.
>
> Signed-off-by: Douglas Anderson <dianders@xxxxxxxxxxxx>
> ---

The behavior introduced by this patch seems like an undesirable hack to
me. It goes against the general philosophy within the regulator framework
of taking no action unless directed to do so by an explicit consumer
request (or special device tree property). We should assume that
consumers make requests to meet their needs instead of assuming that they
are missing important votes required by their hardware.


> drivers/regulator/core.c | 10 +++++++++-
> drivers/regulator/internal.h | 1 +
> 2 files changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
> index 6ed568b96c0e..a4da68775b49 100644
> --- a/drivers/regulator/core.c
> +++ b/drivers/regulator/core.c
> @@ -732,6 +732,7 @@ static int drms_uA_update(struct regulator_dev *rdev)
> struct regulator *sibling;
> int current_uA = 0, output_uV, input_uV, err;
> unsigned int mode;
> + bool any_unset = false;
>
> lockdep_assert_held_once(&rdev->mutex);
>
> @@ -751,11 +752,17 @@ static int drms_uA_update(struct regulator_dev *rdev)
> return -EINVAL;
>
> /* calc total requested load */
> - list_for_each_entry(sibling, &rdev->consumer_list, list)
> + list_for_each_entry(sibling, &rdev->consumer_list, list) {
> current_uA += sibling->uA_load;
> + if (!sibling->uA_load_set)
> + any_unset = true;
> + }
>
> current_uA += rdev->constraints->system_load;
>
> + if (any_unset)
> + current_uA = INT_MAX;
> +

This check will incorrectly result in a constant load request of INT_MAX
for all regulators that have at least one child regulator. This is the
case because such child regulators are present in rdev->consumer_list and
because regulator_set_load() requests are not propagated up to parent
regulators. Thus, the regulator structs for child regulators will always
have uA_load==0 and uA_load_set==false.

Take care,
David

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project