From nobody Sat Jul 25 02:13:06 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 238CD438020 for ; Mon, 20 Jul 2026 15:55:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784562936; cv=none; b=r0HpC6KyURb8N79/JnoE9yniAEYL7uSlYX2kgSuM8u9ARYOOugSs2NJmQ3VLCYUXh1IyRk9ORG/AELnifuRKTQU9moeklkMSCgqElz8BkT3xjVpBzdrrqBWijhPg8ebDWjI5l14XidHUAtixuznCmrOnoXa6hBaHh20y7/2s/nA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784562936; c=relaxed/simple; bh=m6xMcLjI6nvUcZXVvbyDTD43VyBY95P9mKHBgMsKUGk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:Cc; b=gCQvd6r5GsSmGISDOEB7kwF942Mie1KaRmqFNIuGqGidq7j3E/C+1ZK2SaH7pN3tbMxoHJF7lTvnuylAXM6dSNhFmKmBLg24uUdZRZMxveBtxqrdNCXQ5+i0fxptnWxxbB4es70etQjLnl9jdlY0yDmpL7lC7sMQaFSNtlCAwRc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=StHCopM0; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=bqamy1wH; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="StHCopM0"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="bqamy1wH" Received: from pps.filterd (m0279866.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66KFLhgd2711645 for ; Mon, 20 Jul 2026 15:55:34 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:message-id :mime-version:subject:to; s=qcppdkim1; bh=eA9IMFjzDD6suXXS9Abt26 pMqgKCB+L10AjirlL76MM=; b=StHCopM0gBsh6ldO4JXXKzXAsDfO4PW7K3HARX hSuM9ZuJ8yFrEnqprrd7IKaxu/MurhGtwTXy+Wdthgn+U3MfYPSCQdI0vpxep0Gh CXuj9VJvFFh18SwaacE6wh6A6AJbX4sAnRS8rAwWTJA39D5jxnMuZIG271tZGOS7 HmuXp+IxLHrt2CyR02UXCJa071TbnMi6haNntowqgqb0y8lmo0HlEN2N4Kpdmy5t cn2mBoynWDTaf+EBVEwovF1eJFTtgAccssAcmurRs14vVFNC9oReZgS4xyN+XprD XQzUgQekrmVZPYVZBssYGapgOf3ZCNaTT7sogLw6KRoBlIvQ== Received: from mail-pl1-f198.google.com (mail-pl1-f198.google.com [209.85.214.198]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4fhh5y1nxa-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 20 Jul 2026 15:55:34 +0000 (GMT) Received: by mail-pl1-f198.google.com with SMTP id d9443c01a7336-2cca5e0a0c9so201875825ad.1 for ; Mon, 20 Jul 2026 08:55:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1784562933; x=1785167733; darn=vger.kernel.org; h=cc:to:message-id:content-transfer-encoding:content-type :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to:content-type; bh=eA9IMFjzDD6suXXS9Abt26pMqgKCB+L10AjirlL76MM=; b=bqamy1wHrrc58KJgCDvOuNnDOZS8V8poI680dUD8UgH/YmOnX84fNXr7xvlA+mEqj8 jAjaRYk5kv1xJ0TcL6uXPq3w1Fjh+l5hmJNu5pY/N5FPHOC85gjwuywQGM3kYoB50e18 xVfIpnUcZDmcXIPoUgs8JZwlk9sDXB7h9zbiJzEq7o3crvg5UvO05tjeXbQWiNF4GOJM nx1QL07035ol9xlM0k4kP+56xN7IhMsVn01nOqPQIHzUucRJ+0AfcTjbJGhUV2hfgaH5 ETMjaK2ljoj4YTWQLno5PqrdFH0K4KXsCD3bqGLM/L86MDUixUvtGAOGg+xIGvVDLc26 K6Pg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784562933; x=1785167733; h=cc:to:message-id:content-transfer-encoding:content-type :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to:content-type; bh=eA9IMFjzDD6suXXS9Abt26pMqgKCB+L10AjirlL76MM=; b=crfTFwzucSlaa5qE0p62Z8IUEI613SaWKLudx6emj7SfAZTgb5jNILjEopucdKvAs0 vs7Ym4Q+bbjkmIvX2+lDhIiZt88bUjqdN9hBiVW4Djs3vOSedr/G9AOFE7FHZzXECE8o KepHL+w/Ho4vo/SQ7GLh+ND/ydtsOYZH1TUqPF1x2y8dRNO7MPRpOowC0nAyt980tAsV A0ANR7naukJLhYiFe+nQYrFS9OdRJpHMg+giudOAlIxrw43HT2FfX75aXUfEQOES8WrL 1hT1ahgcbzYTXRSHLtBEHKoCIkzrA5w9CDy8XFeFScLfWe/RSpjyAm2ctOjPDPs1FF6H uGyA== X-Gm-Message-State: AOJu0YxxX93dMV6V0IPnxyhgZdE26jA8iJdozm1Hz7ItaW46CTmEaD6m eVctsI5FMpd6WkjzTTHQ3LO351RFY5zNlMyXUmLcE8hJsDhDm/LghTEGyZ9/CYiJlSj1J7buyLC DngXxWy3iNQ/4+rN9RFdvsopB9pNARZcAuBQJcj8JXP8uMuwbT32yI1NxDwIGYeX3S8NyYM9PZp I= X-Gm-Gg: AfdE7ckIRyRQzFeafvdWlHz8Gwp3PHrLvdCZE7R06a//GOVnPseN3QIShu54vt7jifl 7mVOiQ0PKxmmrUAdXQJVPNQkulaPzeyJ2dvfoTsfJp2z5dP+8JWQWbXAQH3SNayJQBi0EvNraK+ iwai+njYZBOEpYRrJdJ2Hguv5KB83F/BwZCYj2PK+51yEf+vZ6o+VshuHHqQLxbcXVxF7MVYBVw tyxT39c2Zx35FiK6kgKnOnGR7aIoBTXKyMhYEcSlTjqaEM6zlpQH2RWedvHK35DTbkl7yoI8p6y +XeAWipnqdy6OCntnml4VFYz9Y1Q3TVSPer+3iM3q97D17ByK+cCoW08ocxjB6Qyv0WmBAsw74z odjNvTmzWsJ2QlGcIeKucDgG/T7gQFA== X-Received: by 2002:a05:6a20:4303:b0:3c3:92aa:4302 with SMTP id adf61e73a8af0-3c3adab4e3bmr15665098637.70.1784562933042; Mon, 20 Jul 2026 08:55:33 -0700 (PDT) X-Received: by 2002:a05:6a20:4303:b0:3c3:92aa:4302 with SMTP id adf61e73a8af0-3c3adab4e3bmr15665073637.70.1784562932554; Mon, 20 Jul 2026 08:55:32 -0700 (PDT) Received: from hu-kamalw-hyd.qualcomm.com ([202.46.22.19]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-3142a1bb8a4sm40914017eec.14.2026.07.20.08.55.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Jul 2026 08:55:31 -0700 (PDT) From: Kamal Wadhwa Date: Mon, 20 Jul 2026 21:25:17 +0530 Subject: [PATCH] regulator: core: clamp voltage constraints before applying apply_uV Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260720-b4-regulator-core-clamp-voltage-v1-1-8e5eec076a8e@oss.qualcomm.com> X-B4-Tracking: v=1; b=H4sIAOREXmoC/yXNQQ6CMBCF4auQWTtJqQjGqxgW02HEmkrJtBATw t2tuPySl/9tkES9JLhVG6isPvk4FdSnCvhJ0yjoh2KwxramswZdgyrjEihHRY4qyIHeM64xZCp zS5eG+XxtXd1BqcwqD/85Hu7932lxL+H8y8K+fwHekfvfgwAAAA== X-Change-ID: 20260720-b4-regulator-core-clamp-voltage-2a54cc386b17 To: Liam Girdwood , Mark Brown Cc: linux-kernel@vger.kernel.org, Kamal Wadhwa X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1784562930; l=7045; i=kamal.wadhwa@oss.qualcomm.com; s=20260406; h=from:subject:message-id; bh=m6xMcLjI6nvUcZXVvbyDTD43VyBY95P9mKHBgMsKUGk=; b=cI5KkOoSeJjAzbdYks4UYCo7e/jSsmDRSIQu0C5/TGEHRzcUvIr1gSVyts8dHT+etBgeex0Oy VQtlN+1rNjNCyvWK18t7H66a75IjHtXgzJ3bcLJ/afbiwH4o/hDhxFV X-Developer-Key: i=kamal.wadhwa@oss.qualcomm.com; a=ed25519; pk=ylH1NxUZkBpYsmww89g6zVxpS0q8qthtzcORkYxn/Ag= X-Proofpoint-Spam-Info: AW1haW4tMjYwNzIwMDE3NSBTYWx0ZWRfX6vzqSR7zVh0K cb4cnADrzZnueWJzwiJDQoLWfVmUJdVCo2D4FSwpBQ7m667h8fwFQPJO4Y0TCB3l6Nh0Qa6Iqko N5M9OqVgsfbzntyQNR0PcYBfg/1MVTg= X-Proofpoint-GUID: ORNesAtEjZXpRxnQ_iAWeOZOl5Iuuu1x X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzIwMDE3NSBTYWx0ZWRfXyzHtw1BRs03y jo9wuxWrOLeiCi3wiNXmKTfI73/s83lVfW+AgkQdhz6BQZW30pdYa8VYpWsqmrtYM1fQz2Ji8CC Ip9cXZsYhszMXW7A6A03Fu4nxCT4WnjXpWzycxK8FXZxFRokP1H5nwVM2H0xq6wPKg1lzFXewyF KXfZDbtKOS/JG0BpN0sIpRZTf9DqfAeX25zm7J9uw3+1ODw/dYkL+uo+YCvktGajk/Ma5qenGqM jzcI5J880HFh39RqM7qe9UHguwT1D/0k7fE8e+DjF2IVFbvmej97DlJR3zeY5Nw2rE4/4kCuRB0 n6IEEk5GvY7HF2tIORPY3exRULNbKOjF72nr3McAB90ZphpDTAgveBIGN8lIKoF98KtmioBgRwj b0FkjU+CuIaq+oNRhKqQFI1eJAms0l/61zOLDBcl7Sjrgff3yTyYdkNw3JQ0Rw04GYJlySFcbgr Q+3Hi0R+M5lhnX7UF/Q== X-Proofpoint-ORIG-GUID: ORNesAtEjZXpRxnQ_iAWeOZOl5Iuuu1x X-Authority-Analysis: v=2.4 cv=f/x4wuyM c=1 sm=1 tr=0 ts=6a5e44f6 cx=c_pps a=MTSHoo12Qbhz2p7MsH1ifg==:117 a=fChuTYTh2wq5r3m49p7fHw==:17 a=IkcTkHD0fZMA:10 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=YMgV9FUhrdKAYTUUvYB2:22 a=EUspDBNiAAAA:8 a=k_5AWMP--inaU2paVVcA:9 a=QEXdDO2ut3YA:10 a=GvdueXVYPmCkWapjIL-Q:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-20_03,2026-07-20_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 bulkscore=0 priorityscore=1501 clxscore=1015 adultscore=0 malwarescore=0 impostorscore=0 lowpriorityscore=0 spamscore=0 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607200175 machine_constraints_voltage() currently applies apply_uV against the machine-supplied [min_uV, max_uV] range, and only afterwards clamps that range down to what the regulator can actually supply (via ops->list_voltage()). If the machine-supplied range is wider than the regulator's actual range, apply_uV's rounding can pick a selector outside the (correct) clamped range, so the regulator ends up programmed outside its clamped min/max. At bring-up this shows up as a voltage read-back outside the clamped range. Fix this by moving the clamping block ahead of the apply_uV block, so apply_uV always targets an already-clamped range. Whether apply_uV should run is decided from the unclamped constraints beforehand and stored in a local bool, since clamping must not itself change whether apply_uV fires. No functional change to the clamping logic itself, only its position relative to apply_uV. Its early return 0 exits become fallthroughs since the apply_uV logic now follows it. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Kamal Wadhwa --- drivers/regulator/core.c | 163 ++++++++++++++++++++++++++-----------------= ---- 1 file changed, 90 insertions(+), 73 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index dc5d67767336..b181988c4abe 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1220,10 +1220,98 @@ static int machine_constraints_voltage(struct regul= ator_dev *rdev, { const struct regulator_ops *ops =3D rdev->desc->ops; int ret; + bool apply_uV; + + /* + * Decide up front, from the constraints as handed to us, whether + * apply_uV needs to run below. The clamping pass right after this + * may rewrite constraints->min_uV/max_uV (e.g. the fixed-voltage + * autoconfigure case), and we don't want that to change whether + * apply_uV fires. + */ + apply_uV =3D rdev->constraints->apply_uV && + rdev->constraints->min_uV && rdev->constraints->max_uV; + + /* + * Constrain machine-level voltage specs to fit the actual range + * supported by this regulator before apply_uV (below) tries to + * force hardware to a value from that range: otherwise apply_uV + * can target a constraint value that doesn't correspond to any + * real voltage selector and fail registration outright, even + * though the clamping pass would have narrowed it to a value + * the regulator can actually hit. + */ + if (ops->list_voltage && rdev->desc->n_voltages) { + int count =3D rdev->desc->n_voltages; + int i; + int min_uV =3D INT_MAX; + int max_uV =3D INT_MIN; + int cmin =3D constraints->min_uV; + int cmax =3D constraints->max_uV; + + /* it's safe to autoconfigure fixed-voltage supplies + * and the constraints are used by list_voltage. + */ + if (count =3D=3D 1 && !cmin) { + cmin =3D 1; + cmax =3D INT_MAX; + constraints->min_uV =3D cmin; + constraints->max_uV =3D cmax; + } + + /* voltage constraints are optional */ + if ((cmin =3D=3D 0) && (cmax =3D=3D 0)) { + /* nothing more to do */ + + /* else require explicit machine-level constraints */ + } else if (cmin <=3D 0 || cmax <=3D 0 || cmax < cmin) { + rdev_err(rdev, "invalid voltage constraints\n"); + return -EINVAL; + + /* no need to loop voltages if range is continuous */ + } else if (rdev->desc->continuous_voltage_range) { + /* nothing more to do */ + + } else { + /* initial: [cmin..cmax] valid, [min_uV..max_uV] not */ + for (i =3D 0; i < count; i++) { + int value; + + value =3D ops->list_voltage(rdev, i); + if (value <=3D 0) + continue; + + /* maybe adjust [min_uV..max_uV] */ + if (value >=3D cmin && value < min_uV) + min_uV =3D value; + if (value <=3D cmax && value > max_uV) + max_uV =3D value; + } + + /* final: [min_uV..max_uV] valid iff constraints valid */ + if (max_uV < min_uV) { + rdev_err(rdev, + "unsupportable voltage constraints %u-%uuV\n", + min_uV, max_uV); + return -EINVAL; + } + + /* use regulator's subset of machine constraints */ + if (constraints->min_uV < min_uV) { + rdev_dbg(rdev, "override min_uV, %d -> %d\n", + constraints->min_uV, min_uV); + constraints->min_uV =3D min_uV; + } + if (constraints->max_uV > max_uV) { + rdev_dbg(rdev, "override max_uV, %d -> %d\n", + constraints->max_uV, max_uV); + constraints->max_uV =3D max_uV; + } + } + } =20 /* do we need to apply the constraint voltage */ - if (rdev->constraints->apply_uV && - rdev->constraints->min_uV && rdev->constraints->max_uV) { + if (apply_uV) { int target_min, target_max; int current_uV =3D regulator_get_voltage_rdev(rdev); =20 @@ -1278,77 +1366,6 @@ static int machine_constraints_voltage(struct regula= tor_dev *rdev, } } =20 - /* constrain machine-level voltage specs to fit - * the actual range supported by this regulator. - */ - if (ops->list_voltage && rdev->desc->n_voltages) { - int count =3D rdev->desc->n_voltages; - int i; - int min_uV =3D INT_MAX; - int max_uV =3D INT_MIN; - int cmin =3D constraints->min_uV; - int cmax =3D constraints->max_uV; - - /* it's safe to autoconfigure fixed-voltage supplies - * and the constraints are used by list_voltage. - */ - if (count =3D=3D 1 && !cmin) { - cmin =3D 1; - cmax =3D INT_MAX; - constraints->min_uV =3D cmin; - constraints->max_uV =3D cmax; - } - - /* voltage constraints are optional */ - if ((cmin =3D=3D 0) && (cmax =3D=3D 0)) - return 0; - - /* else require explicit machine-level constraints */ - if (cmin <=3D 0 || cmax <=3D 0 || cmax < cmin) { - rdev_err(rdev, "invalid voltage constraints\n"); - return -EINVAL; - } - - /* no need to loop voltages if range is continuous */ - if (rdev->desc->continuous_voltage_range) - return 0; - - /* initial: [cmin..cmax] valid, [min_uV..max_uV] not */ - for (i =3D 0; i < count; i++) { - int value; - - value =3D ops->list_voltage(rdev, i); - if (value <=3D 0) - continue; - - /* maybe adjust [min_uV..max_uV] */ - if (value >=3D cmin && value < min_uV) - min_uV =3D value; - if (value <=3D cmax && value > max_uV) - max_uV =3D value; - } - - /* final: [min_uV..max_uV] valid iff constraints valid */ - if (max_uV < min_uV) { - rdev_err(rdev, - "unsupportable voltage constraints %u-%uuV\n", - min_uV, max_uV); - return -EINVAL; - } - - /* use regulator's subset of machine constraints */ - if (constraints->min_uV < min_uV) { - rdev_dbg(rdev, "override min_uV, %d -> %d\n", - constraints->min_uV, min_uV); - constraints->min_uV =3D min_uV; - } - if (constraints->max_uV > max_uV) { - rdev_dbg(rdev, "override max_uV, %d -> %d\n", - constraints->max_uV, max_uV); - constraints->max_uV =3D max_uV; - } - } - return 0; } =20 --- base-commit: 5c73cd9f0819c1c44e373e3dabb68318b1de1a12 change-id: 20260720-b4-regulator-core-clamp-voltage-2a54cc386b17 Best regards, -- =20 Kamal Wadhwa