Message ID | 20231004-reg-smd-unused-v1-1-5d682493d555@kernkonzept.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:254a:b0:403:3b70:6f57 with SMTP id hf10csp166794vqb; Wed, 4 Oct 2023 07:17:37 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEhoJAYSGuip2WPNsM/9h7ZdkXt1U7OupaunaCcRnSWPG0GxkhUrgAcjkk1I4YHIQdLIIg3 X-Received: by 2002:a05:6830:1354:b0:6bc:f6d0:87d2 with SMTP id r20-20020a056830135400b006bcf6d087d2mr2036350otq.38.1696429057223; Wed, 04 Oct 2023 07:17:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1696429057; cv=none; d=google.com; s=arc-20160816; b=z1Ds4jUj+qxUR+bdT4Q+Kn6oGXKVwrzt11S7Sc20PWvX0fRseBFRPw55mH6n4ilteQ nJD8lcMx9iyMgn2FX2iO5Vlkn7+6TVNGPvRwF7MZnDvs0jIv1QFhYS3kbQ2ZhYAKA5sF yu+PnHbPT3Dst0lFvYBGXvekOe8OmHDXBY26xD4688OuUIGkhET8BlHpY9J09L+55RSb AGsdSzQOPuumZB8V2ggXbEGv5wampnAUVX6ZxZN0H8W4X4Ae1x+VRsfGP3AmWcJ2EqO/ pzV53SHUcDcq5Rsk7BgWagnE79t9BJhL2pImWwRQBQ5Z6ysBO0XhliCq0Z5FONWwWbR4 4CDw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:in-reply-to:references:message-id :content-transfer-encoding:mime-version:subject:date:from :dkim-signature; bh=SkbWpdDlNPiVngrUfwn9Q3KUJG64A7lq4G4XSXJ8ny8=; fh=6ROhvpJrsh+iZGjEACun9ZXYVgb1LMu8Jj3+nzwGyNE=; b=XHLKPc7yjVergnp+UvvLngHbKECgiNb3//Qp/mk6RDmJh1kycnmtvCU3LL+NTbqsJf +kt1qj91v2c/bNXY9BWJFaXr9R3sKwKj2yjhSVnLj4jmzUXxlWv+RGGIdZuBwaQE4dI/ ZAMTX345mnogp7tj89lMJWGCk/IUmehOiIEIyRlYPW/nH6IVs7yyICIQYPQF0+4xMKD6 dxF8cCxTSCATIlFapx4RcLQ5uzQglkyVTftPNkK49FnIZWZeliB2PJzWUSD01yLwxS8S 4I75DsMvumk40oSb3JpUpraMxQjwTALe6SSynOI12uH3v9n8g7YQwkJfLzCFKCN7qI51 Qd3A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernkonzept.com header.s=mx1 header.b=Ey6XFdVJ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernkonzept.com Received: from snail.vger.email (snail.vger.email. [23.128.96.37]) by mx.google.com with ESMTPS id r20-20020a6560d4000000b005644a9be955si3733749pgv.179.2023.10.04.07.17.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Oct 2023 07:17:37 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) client-ip=23.128.96.37; Authentication-Results: mx.google.com; dkim=pass header.i=@kernkonzept.com header.s=mx1 header.b=Ey6XFdVJ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernkonzept.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id DFF4F821A147; Wed, 4 Oct 2023 07:17:35 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242877AbjJDORe (ORCPT <rfc822;pusanteemu@gmail.com> + 18 others); Wed, 4 Oct 2023 10:17:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48744 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242879AbjJDORb (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Wed, 4 Oct 2023 10:17:31 -0400 Received: from mx.kernkonzept.com (serv1.kernkonzept.com [IPv6:2a01:4f8:1c1c:b490::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 81B0EAD; Wed, 4 Oct 2023 07:17:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=kernkonzept.com; s=mx1; h=Cc:To:In-Reply-To:References:Message-Id: Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date:From: Reply-To:Content-ID:Content-Description; bh=SkbWpdDlNPiVngrUfwn9Q3KUJG64A7lq4G4XSXJ8ny8=; b=Ey6XFdVJPni7Vjj/dP2fzSll4K LnYLm7C3dDqJe9KaqyAl0gmltjHRWRt18tHoDEuCyhW8zSkW3g6rjcFUJBG98iSH9zAw2OXxtbTMh DV8QVszoYimRfe47hlguY7xk5ieDNBuXUz6dXRV2iB0+rCoIRDRtH0me/Qt0YSw5MtmBYMsbB0u+f s0yxshk2WgBQqCx7LCt0uV4TvX2ZYAjqc5DG5wL5nrelx3oX4n+3n01MINF5TwShj1gv9sEYsOTSk JSSDt36nQMsytbqhUnOHWg7t2B3wgvTLFoPsl5fR7KW7Y8T02llzbWCYxoG4ywuacKUQ2YMv++oSS J+Z5Cjqw==; Received: from [10.22.3.24] (helo=serv1.dd1.int.kernkonzept.com) by mx.kernkonzept.com with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.96) id 1qo2gk-0071hO-1E; Wed, 04 Oct 2023 16:17:22 +0200 From: Stephan Gerhold <stephan.gerhold@kernkonzept.com> Date: Wed, 04 Oct 2023 16:17:17 +0200 Subject: [PATCH RFC 1/2] regulator: core: Disable unused regulators with unknown status MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20231004-reg-smd-unused-v1-1-5d682493d555@kernkonzept.com> References: <20231004-reg-smd-unused-v1-0-5d682493d555@kernkonzept.com> In-Reply-To: <20231004-reg-smd-unused-v1-0-5d682493d555@kernkonzept.com> To: Mark Brown <broonie@kernel.org> Cc: Liam Girdwood <lgirdwood@gmail.com>, Andy Gross <agross@kernel.org>, Bjorn Andersson <andersson@kernel.org>, Konrad Dybcio <konrad.dybcio@linaro.org>, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, Stephan Gerhold <stephan@gerhold.net>, Stephan Gerhold <stephan.gerhold@kernkonzept.com> X-Mailer: b4 0.12.3 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Wed, 04 Oct 2023 07:17:35 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1778834795273084631 X-GMAIL-MSGID: 1778834795273084631 |
Series |
regulator: qcom_smd: Disable unused regulators
|
|
Commit Message
Stephan Gerhold
Oct. 4, 2023, 2:17 p.m. UTC
Some regulator drivers do not provide a way to check if the regulator is
currently enabled or not. That does not necessarily mean that the
regulator is always-on. For example, the regulators managed by the RPM
firmware on Qualcomm platforms can be either on or off during boot but
the initial state is not known. To sync the state the regulator should
get either explicitly enabled or explicitly disabled.
Enabling all regulators unconditionally is not safe, because we might
not know which voltages are safe. The devices supplied by those
regulators might also require a special power-up sequence where the
regulators are turned on in a certain order or with specific delay.
Disabling all unused regulators is safer. If the regulator is already
off it will just stay that way. If the regulator is on, disabling it
explicitly allows the firmware to turn it off for reduced power
consumption.
The regulator core already has functionality for disabling unused
regulators. However, at the moment it assumes that all regulators where
the .is_enabled() callback fails are actually off. There is no way to
return a special value for the "unknown" state to explicitly ask for
disabling those regulators.
Some drivers (e.g. qcom-rpmh-regulator.c) return -EINVAL for the case
where the initial status is unknown. Use that return code to assume the
initial status is unknown and try to explicitly disable the regulator
in that case.
Signed-off-by: Stephan Gerhold <stephan.gerhold@kernkonzept.com>
---
Instead of -EINVAL we could also use a different return code to indicate
the initial status is unknown. Or maybe there is some other option that
would be easier? This is working for me but I'm sending it as RFC to get
more feedback. :)
---
drivers/regulator/core.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
Comments
On 4.10.2023 16:17, Stephan Gerhold wrote: > Some regulator drivers do not provide a way to check if the regulator is > currently enabled or not. That does not necessarily mean that the > regulator is always-on. For example, the regulators managed by the RPM > firmware on Qualcomm platforms can be either on or off during boot but > the initial state is not known. To sync the state the regulator should > get either explicitly enabled or explicitly disabled. > > Enabling all regulators unconditionally is not safe, because we might > not know which voltages are safe. The devices supplied by those > regulators might also require a special power-up sequence where the > regulators are turned on in a certain order or with specific delay. > > Disabling all unused regulators is safer. If the regulator is already > off it will just stay that way. If the regulator is on, disabling it > explicitly allows the firmware to turn it off for reduced power > consumption. > > The regulator core already has functionality for disabling unused > regulators. However, at the moment it assumes that all regulators where > the .is_enabled() callback fails are actually off. There is no way to > return a special value for the "unknown" state to explicitly ask for > disabling those regulators. > > Some drivers (e.g. qcom-rpmh-regulator.c) return -EINVAL for the case > where the initial status is unknown. Use that return code to assume the > initial status is unknown and try to explicitly disable the regulator > in that case. > > Signed-off-by: Stephan Gerhold <stephan.gerhold@kernkonzept.com> > --- > Instead of -EINVAL we could also use a different return code to indicate > the initial status is unknown. Or maybe there is some other option that > would be easier? This is working for me but I'm sending it as RFC to get > more feedback. :) -EOPNOTSUPP for "doesn't support getting is_enabled state"? I think this looks really good.. And will definitely help finding power hogs! At the cost of breaking booting with broken DTs. But as the name by which I referred to them suggests, this was never really destined to work.. Konrad
On Fri, Oct 06, 2023 at 11:11:48PM +0200, Konrad Dybcio wrote: > On 4.10.2023 16:17, Stephan Gerhold wrote: > > Some regulator drivers do not provide a way to check if the regulator is > > currently enabled or not. That does not necessarily mean that the > > regulator is always-on. For example, the regulators managed by the RPM > > firmware on Qualcomm platforms can be either on or off during boot but > > the initial state is not known. To sync the state the regulator should > > get either explicitly enabled or explicitly disabled. > > > > Enabling all regulators unconditionally is not safe, because we might > > not know which voltages are safe. The devices supplied by those > > regulators might also require a special power-up sequence where the > > regulators are turned on in a certain order or with specific delay. > > > > Disabling all unused regulators is safer. If the regulator is already > > off it will just stay that way. If the regulator is on, disabling it > > explicitly allows the firmware to turn it off for reduced power > > consumption. > > > > The regulator core already has functionality for disabling unused > > regulators. However, at the moment it assumes that all regulators where > > the .is_enabled() callback fails are actually off. There is no way to > > return a special value for the "unknown" state to explicitly ask for > > disabling those regulators. > > > > Some drivers (e.g. qcom-rpmh-regulator.c) return -EINVAL for the case > > where the initial status is unknown. Use that return code to assume the > > initial status is unknown and try to explicitly disable the regulator > > in that case. > > > > Signed-off-by: Stephan Gerhold <stephan.gerhold@kernkonzept.com> > > --- > > Instead of -EINVAL we could also use a different return code to indicate > > the initial status is unknown. Or maybe there is some other option that > > would be easier? This is working for me but I'm sending it as RFC to get > > more feedback. :) > > -EOPNOTSUPP for "doesn't support getting is_enabled state"? > The way it is implemented right now the Qualcomm SMD RPM regulator does actually support getting the .is_enabled() state. It is only unable to determine the initial state during boot. Once the regulator has been enabled by some consumer for the first time the .is_enabled() callback starts returning the expected results. Typically -EOPNOTSUPP is used when the driver callback (or similar) is not implemented at all. I'm not sure if using -EOPNOTSUPP for the "temporarily unable to determine state" purpose would be misleading. Thanks, Stephan
On 10/9/23 22:21, Stephan Gerhold wrote: > On Fri, Oct 06, 2023 at 11:11:48PM +0200, Konrad Dybcio wrote: >> On 4.10.2023 16:17, Stephan Gerhold wrote: >>> Some regulator drivers do not provide a way to check if the regulator is >>> currently enabled or not. That does not necessarily mean that the >>> regulator is always-on. For example, the regulators managed by the RPM >>> firmware on Qualcomm platforms can be either on or off during boot but >>> the initial state is not known. To sync the state the regulator should >>> get either explicitly enabled or explicitly disabled. >>> >>> Enabling all regulators unconditionally is not safe, because we might >>> not know which voltages are safe. The devices supplied by those >>> regulators might also require a special power-up sequence where the >>> regulators are turned on in a certain order or with specific delay. >>> >>> Disabling all unused regulators is safer. If the regulator is already >>> off it will just stay that way. If the regulator is on, disabling it >>> explicitly allows the firmware to turn it off for reduced power >>> consumption. >>> >>> The regulator core already has functionality for disabling unused >>> regulators. However, at the moment it assumes that all regulators where >>> the .is_enabled() callback fails are actually off. There is no way to >>> return a special value for the "unknown" state to explicitly ask for >>> disabling those regulators. >>> >>> Some drivers (e.g. qcom-rpmh-regulator.c) return -EINVAL for the case >>> where the initial status is unknown. Use that return code to assume the >>> initial status is unknown and try to explicitly disable the regulator >>> in that case. >>> >>> Signed-off-by: Stephan Gerhold <stephan.gerhold@kernkonzept.com> >>> --- >>> Instead of -EINVAL we could also use a different return code to indicate >>> the initial status is unknown. Or maybe there is some other option that >>> would be easier? This is working for me but I'm sending it as RFC to get >>> more feedback. :) >> >> -EOPNOTSUPP for "doesn't support getting is_enabled state"? >> > > The way it is implemented right now the Qualcomm SMD RPM regulator does > actually support getting the .is_enabled() state. It is only unable to > determine the initial state during boot. Once the regulator has been > enabled by some consumer for the first time the .is_enabled() callback > starts returning the expected results. > > Typically -EOPNOTSUPP is used when the driver callback (or similar) is > not implemented at all. I'm not sure if using -EOPNOTSUPP for the > "temporarily unable to determine state" purpose would be misleading. I'd say EOPNOTSUPP is fair here because calling is_enabled in that context is not supported, but I guess it's up to Mark. Konrad
On Wed, Oct 04, 2023 at 04:17:17PM +0200, Stephan Gerhold wrote: > Instead of -EINVAL we could also use a different return code to indicate > the initial status is unknown. Or maybe there is some other option that > would be easier? This is working for me but I'm sending it as RFC to get > more feedback. :) The more normal thing here would be -EBUSY I think - -EINVAL kind of indicates that the operation will never work while in reality it could possibly work in future. Though for the RPMH it's not really the case that it ever supports readback, what it does is have it's own reference counting in the driver. Rather than doing this we should probably have logic in the core which sees that the driver has a write operation but no read operation and implements appropriate behaviour.
On Mon, Oct 23, 2023 at 01:09:11PM +0100, Mark Brown wrote: > On Wed, Oct 04, 2023 at 04:17:17PM +0200, Stephan Gerhold wrote: > > > Instead of -EINVAL we could also use a different return code to indicate > > the initial status is unknown. Or maybe there is some other option that > > would be easier? This is working for me but I'm sending it as RFC to get > > more feedback. :) > > The more normal thing here would be -EBUSY I think - -EINVAL kind of > indicates that the operation will never work while in reality it could > possibly work in future. Though for the RPMH it's not really the case > that it ever supports readback, what it does is have it's own reference > counting in the driver. Rather than doing this we should probably have > logic in the core which sees that the driver has a write operation but > no read operation and implements appropriate behaviour. I like the suggestion to not implement is_enabled, and handle that in the core instead, for all three generations of our rpm-based regulators. Regards, Bjorn
On Mon, Oct 23, 2023 at 01:09:11PM +0100, Mark Brown wrote: > On Wed, Oct 04, 2023 at 04:17:17PM +0200, Stephan Gerhold wrote: > > > Instead of -EINVAL we could also use a different return code to indicate > > the initial status is unknown. Or maybe there is some other option that > > would be easier? This is working for me but I'm sending it as RFC to get > > more feedback. :) > > The more normal thing here would be -EBUSY I think - -EINVAL kind of > indicates that the operation will never work while in reality it could > possibly work in future. Though for the RPMH it's not really the case > that it ever supports readback, what it does is have it's own reference > counting in the driver. Rather than doing this we should probably have > logic in the core which sees that the driver has a write operation but > no read operation and implements appropriate behaviour. Yep, I agree that it would be nicer to handle this case in the core, rather than duplicating the logic in all the RPM-related drivers. I think it does not change much for this patch, though. Even when implemented in the core we still need to represent this situation somehow for regulator_is_enabled(). Simply returning 0 (disabled) or 1 (enabled) would be wrong. Do you think returning -EBUSY would be appropriate for that? The second challenge I see on a quick look is that both qcom_smd-regulator.c and qcom-rpmh-regulator.c use their reference counter internally in other function (e.g. to decide if a voltage change should be sent, see "vreg->enabled" checks). I think we would also need to add some rdev_is_enabled() function that would expose the core reference counter to the driver? Tracking the enable state in the driver (the way it is right now) is not that much code, so I'm not entirely sure if we might actually end up with more code/complexity when moving this to the core. Thanks,
On Tue, Oct 24, 2023 at 10:57:38AM +0200, Stephan Gerhold wrote: > I think it does not change much for this patch, though. Even when > implemented in the core we still need to represent this situation > somehow for regulator_is_enabled(). Simply returning 0 (disabled) or > 1 (enabled) would be wrong. Do you think returning -EBUSY would be > appropriate for that? In these cases where we simply can't read the expectation is that we'll always be using the logical state - one way of thinking about it is that the operation is mostly a bootstrapping helper to figure out what the initial state is. A quick survey of users suggest they'll pretty much all be buggy if we start returning errors, and I frankly even if all the current users were fixed I'd expect that to continue to be a common error. I suppose that the effect of ignoring the possibility of error is like the current behaviour though. > The second challenge I see on a quick look is that both > qcom_smd-regulator.c and qcom-rpmh-regulator.c use their reference > counter internally in other function (e.g. to decide if a voltage change > should be sent, see "vreg->enabled" checks). I think we would also need > to add some rdev_is_enabled() function that would expose the core > reference counter to the driver? > Tracking the enable state in the driver (the way it is right now) is not > that much code, so I'm not entirely sure if we might actually end up > with more code/complexity when moving this to the core. We have to do the reference count in the core anyway since it's a reference count not just a simple on/off so it doesn't really cost us anything to make it available to drivers.
On Wed, Oct 25, 2023 at 06:49:47PM +0100, Mark Brown wrote: > On Tue, Oct 24, 2023 at 10:57:38AM +0200, Stephan Gerhold wrote: > > > I think it does not change much for this patch, though. Even when > > implemented in the core we still need to represent this situation > > somehow for regulator_is_enabled(). Simply returning 0 (disabled) or > > 1 (enabled) would be wrong. Do you think returning -EBUSY would be > > appropriate for that? > > In these cases where we simply can't read the expectation is that we'll > always be using the logical state - one way of thinking about it is that > the operation is mostly a bootstrapping helper to figure out what the > initial state is. A quick survey of users suggest they'll pretty much > all be buggy if we start returning errors, and I frankly even if all the > current users were fixed I'd expect that to continue to be a common > error. I suppose that the effect of ignoring the possibility of error > is like the current behaviour though. > regulator_is_enabled() already returns error codes in various cases, e.g. regulator_is_enabled_regmap() returns the original error code from the regmap_read() call if that fails. So if users ignore that and interpret the value as logical one they either don't care (which is probably fine in some cases?) or already use it wrong. Or am I missing something? > > qcom_smd-regulator.c and qcom-rpmh-regulator.c use their reference > > counter internally in other function (e.g. to decide if a voltage change > > should be sent, see "vreg->enabled" checks). I think we would also need > > to add some rdev_is_enabled() function that would expose the core > > reference counter to the driver? > > > Tracking the enable state in the driver (the way it is right now) is not > > that much code, so I'm not entirely sure if we might actually end up > > with more code/complexity when moving this to the core. > > We have to do the reference count in the core anyway since it's a > reference count not just a simple on/off so it doesn't really cost us > anything to make it available to drivers. I assume you're referring to "use_count" as the reference counter? On a closer look I think it cannot be used as-is for my purpose: 1. With "regulator-boot-on", set_machine_constraints() explicitly enables the regulator, but doesn't increase the use_count. In that case we should return true in ->is_enabled(). I'm not sure how we would know, just based on use_count = 0. 2. To cleanup unused regulators that may or may not be enabled we need to know if the regulator was ever explicitly enabled/disabled before. It's pointless to send a disable request for a regulator that we already disabled explicitly before (after a enable -> disable cycle). use_count just tells us if there is currently a user, but not if there was one before. I think I would literally need to move the existing "enabled" field from the RPM regulator drivers to the core and manage it similarly there based on ->enable() and ->disable() calls. Which would be a (slight) overhead for all regulators rather than being isolated for the few RPM regulator drivers. Thanks, Stephan
On Wed, Oct 25, 2023 at 09:51:51PM +0200, Stephan Gerhold wrote: > On Wed, Oct 25, 2023 at 06:49:47PM +0100, Mark Brown wrote: > > In these cases where we simply can't read the expectation is that we'll > > always be using the logical state - one way of thinking about it is that > > the operation is mostly a bootstrapping helper to figure out what the > > initial state is. A quick survey of users suggest they'll pretty much > > all be buggy if we start returning errors, and I frankly even if all the > > current users were fixed I'd expect that to continue to be a common > > error. I suppose that the effect of ignoring the possibility of error > > is like the current behaviour though. > regulator_is_enabled() already returns error codes in various cases, > e.g. regulator_is_enabled_regmap() returns the original error code from > the regmap_read() call if that fails. So if users ignore that and > interpret the value as logical one they either don't care (which is > probably fine in some cases?) or already use it wrong. Or am I missing > something? That's broadly what I just indicated. Expecting anybody to do anything useful with an error report is probably optimistic, but it's probably going to give the same behaviour as we have currently so it's probably fine. > > We have to do the reference count in the core anyway since it's a > > reference count not just a simple on/off so it doesn't really cost us > > anything to make it available to drivers. > I assume you're referring to "use_count" as the reference counter? Yes. > On a closer look I think it cannot be used as-is for my purpose: > 1. With "regulator-boot-on", set_machine_constraints() explicitly > enables the regulator, but doesn't increase the use_count. > In that case we should return true in ->is_enabled(). I'm not sure > how we would know, just based on use_count = 0. OK, so use_count plus other information we also already have to hand. Or OTOH it's not that much overhead to track the enable state explicitly for hardware without readback as you're suggesting below if it ends up being too much hassle. > 2. To cleanup unused regulators that may or may not be enabled we need > to know if the regulator was ever explicitly enabled/disabled before. > It's pointless to send a disable request for a regulator that we > already disabled explicitly before (after a enable -> disable cycle). > use_count just tells us if there is currently a user, but not if > there was one before. It's pointless, but equally well it's not huge overhead. > I think I would literally need to move the existing "enabled" field from > the RPM regulator drivers to the core and manage it similarly there > based on ->enable() and ->disable() calls. Which would be a (slight) > overhead for all regulators rather than being isolated for the few RPM > regulator drivers. These aren't the only regulators with this limitation, we've also got similar open coding for GPIO controlled regulators like the fixed regualtor for example.
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 3137e40fcd3e..182e3727651a 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -6207,8 +6207,13 @@ static int regulator_late_cleanup(struct device *dev, void *data) if (rdev->use_count) goto unlock; - /* If reading the status failed, assume that it's off. */ - if (_regulator_is_enabled(rdev) <= 0) + /* + * If reading the status failed, assume that it's off. + * If the current status is unknown (-EINVAL), assume that the + * regulator might be on and try to explicitly disable it. + */ + ret = _regulator_is_enabled(rdev); + if (ret <= 0 && ret != -EINVAL) goto unlock; if (have_full_constraints()) {