From patchwork Wed Oct 4 14:17:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephan Gerhold X-Patchwork-Id: 13408813 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 754F4E7B61F for ; Wed, 4 Oct 2023 14:17:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242770AbjJDORd (ORCPT ); Wed, 4 Oct 2023 10:17:33 -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 ); 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 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 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 Cc: Liam Girdwood , Andy Gross , Bjorn Andersson , Konrad Dybcio , linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, Stephan Gerhold , Stephan Gerhold X-Mailer: b4 0.12.3 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org 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 --- 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(-) 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()) { From patchwork Wed Oct 4 14:17:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephan Gerhold X-Patchwork-Id: 13408814 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 885B6E75455 for ; Wed, 4 Oct 2023 14:17:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242883AbjJDORe (ORCPT ); Wed, 4 Oct 2023 10:17:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48736 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242880AbjJDORb (ORCPT ); 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 5421BBD; Wed, 4 Oct 2023 07:17:27 -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=uGFUKnshKK/Dlrx7eSaJi3UN15UGXc4Ye0y6BgFwE70=; b=mcndqaF/9YtRUFqpPsJk35hOjM ssdRCGiQRptp2Mz9hSJoC9ceNzNnFVX7rU3X2vCznKlRa20t5axk4+9w1KYS2AJnf5G+kV5Sp8w2m nsnBkhJLiNVv2U1cyj8wzbOpWopwDszXGdCxzxGRihGf80lMpvoXi7jlVEX3EPBqlQcIYbaiFWRDj qw3b8W3M/r7XSOkeQO6X6bWQgEp0r8pZW19fsVnHK6qOXiUpyF6g5A5WYbCFfZarXAIY61mBT88gS 33Fj7IaVRnTJRmJx6wPWoG263EUDVqgVKI/furH2T2IjWSehykKB2ykrNXMI2M1VBhmIfOkD77Jq8 JVKqIm2g==; 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 1qo2gl-0071hO-1J; Wed, 04 Oct 2023 16:17:23 +0200 From: Stephan Gerhold Date: Wed, 04 Oct 2023 16:17:18 +0200 Subject: [PATCH RFC 2/2] regulator: qcom_smd: Disable unused regulators MIME-Version: 1.0 Message-Id: <20231004-reg-smd-unused-v1-2-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 Cc: Liam Girdwood , Andy Gross , Bjorn Andersson , Konrad Dybcio , linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, Stephan Gerhold , Stephan Gerhold X-Mailer: b4 0.12.3 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org The RPM firmware on Qualcomm platforms does not provide a way to check if a regulator is on during boot using the SMD interface. If the regulators are already on during boot and Linux does not make use of them they will currently stay enabled forever. The regulator core does not know these regulators are on and cannot clean them up together with the other unused regulators. Fix this by setting the initial enable state to -EINVAL similar to qcom-rpmh-regulator.c. The regulator core will then also explicitly disable all unused regulators with unknown status. Signed-off-by: Stephan Gerhold --- NOTE: This has a slight potential of breaking boards that rely on having unused regulators permanently enabled (without regulator-always-on). However, this is always a mistake in the device tree so it's probably better to risk some breakage now, add the missing regulators and avoid this problem for all future boards. --- drivers/regulator/qcom_smd-regulator.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c index f53ada076252..0bbfba2e17ff 100644 --- a/drivers/regulator/qcom_smd-regulator.c +++ b/drivers/regulator/qcom_smd-regulator.c @@ -53,14 +53,14 @@ static int rpm_reg_write_active(struct qcom_rpm_reg *vreg) reqlen++; } - if (vreg->uv_updated && vreg->is_enabled) { + if (vreg->uv_updated && vreg->is_enabled > 0) { req[reqlen].key = cpu_to_le32(RPM_KEY_UV); req[reqlen].nbytes = cpu_to_le32(sizeof(u32)); req[reqlen].value = cpu_to_le32(vreg->uV); reqlen++; } - if (vreg->load_updated && vreg->is_enabled) { + if (vreg->load_updated && vreg->is_enabled > 0) { req[reqlen].key = cpu_to_le32(RPM_KEY_MA); req[reqlen].nbytes = cpu_to_le32(sizeof(u32)); req[reqlen].value = cpu_to_le32(vreg->load / 1000); @@ -1377,6 +1377,7 @@ static int rpm_regulator_init_vreg(struct qcom_rpm_reg *vreg, struct device *dev vreg->rpm = rpm; vreg->type = rpm_data->type; vreg->id = rpm_data->id; + vreg->is_enabled = -EINVAL; memcpy(&vreg->desc, rpm_data->desc, sizeof(vreg->desc)); vreg->desc.name = rpm_data->name;