From nobody Mon Jun 8 14:36:11 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 9704635200C for ; Fri, 29 May 2026 01:05:46 +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=1780016749; cv=none; b=S3Ct/TnYYUFjQP+FnkPkv54KsGewZ5N+MJcQMlBnz7DNCqM50te4+kaTpc5naO0zik8PnYfLHdjN1gguwFbHx9JOuKCUp6HiBQdXt69g4M7syv8uzRCJ/2habHLeWOkGVuuzUscFCGTfAEPwqhvqI/16/jBTCTbkVSNMscZ+iBk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780016749; c=relaxed/simple; bh=eHzmOULRV2votD+kyy3YF5bvH7sFd6INfw6oEHcYFRM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=A8DJOEmhVBqlBCEQZlwa2r3IFfU0+ooOo4tfgrs+zsXo2f6VtqtgVuYziCPaQPkH5tOIPkYNnxpzPU/l3Dfv+Pc1b+Suiyz3SmLBPDn8QBTkPMygabMfuVRDqveNSWAHQCbIEiEBK9P0NY5ZijdjAwvybGML6g8yJcQglWuBMKw= 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=WcDvB9AY; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=BYNiFvg1; 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="WcDvB9AY"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="BYNiFvg1" Received: from pps.filterd (m0279865.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64SKkZbf3252762 for ; Fri, 29 May 2026 01:05:46 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= pTcrsNh9ZEqsKUj8N8O+AtmSHFfVnpNdf6+Ukz07bSw=; b=WcDvB9AYL6bIzhxg JDXX66aa/8XIzWo9cm9tc0nbQjY+tGDpJogkK3OzZOMCtwuwFF2bC7tJc5nd0ZDa Fb2zKVzuXN0htYLFaEr3K3FNTWujlHKXsacSOjBseJ0x8w21QIT4fSioIMnqrkpw WMdMtawl9GglCjfTADofs/Ooy0VBu4ECNY9zfyfH08YhvpMhEfbGflN/IXPG0+Fe tzYf9/CFFrZMBpagZX3b7ynLArbKB9g0RWzC+bUzk7lWH3g9HqFg1igjT/3BL5qn J8BHemcTqZXAMabr3vySMvCUXTtm22vb540MiBR8bqh4J/bh2c/UKDVePltCcnR8 RQydtw== Received: from mail-dy1-f197.google.com (mail-dy1-f197.google.com [74.125.82.197]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4eespn1y39-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 29 May 2026 01:05:45 +0000 (GMT) Received: by mail-dy1-f197.google.com with SMTP id 5a478bee46e88-304d8613efbso1580279eec.1 for ; Thu, 28 May 2026 18:05:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1780016745; x=1780621545; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=pTcrsNh9ZEqsKUj8N8O+AtmSHFfVnpNdf6+Ukz07bSw=; b=BYNiFvg1YgVXx2eU0xaInz4LE1wCwQZ3O9L85v7RhSv7y8ZWXy/et09KDPxqwVbxbS 9Ococ6165wvtuRkIWvCl3M/CUDnhSjVoE+20sl7gq3symIKEXtG+hlaknlMsHl0rSB3u ITULUQpnk3S2aEkjSvPOEhN/GJ4SBbJixc0gzBYeY7EDzZnHCpy7qSSZGesP6yRQzU0F 4PQ8u3KgnNM4w7BzJfYWZ/gCjyz6noju5Q5syy5gdpIHgVP4z2LOWpZgAv9JlAShdEeC AoyB9Et7eVD0PhRucM/QstEsvBP5FMT1ue65i8v+IbWRly6/Ea+3pfRnRUmF+HKpOBoY 6ysw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780016745; x=1780621545; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=pTcrsNh9ZEqsKUj8N8O+AtmSHFfVnpNdf6+Ukz07bSw=; b=ZVOvpGYmdp7rQQdHyBVMM2ljd0/BLCOCf8HRzXFaxRXbJrwiV9y91ZgOKLqIAn76sw +pHirtUK5pEY+zlXdf32cPdLg2LJBjrRPtyPXEC12K3BzubSvh3c6eLrWDpi/gqot7SY e6t1A3txq/y1dkEG1W6b7gF78wEjDroZY84zGak0TqxsuseZHTqi8XcthkMMNAqZH15r eUMLDJx0236kL2NpILxeAeSQcoRDfDYQ0rvYNOtGwPRixrhLvS4zcDrUDVoTzs+NKLbY vqdqq0h6j6R1pApiR9cw1ZbJliEwQEq9o3cg3olmv8vOC75L3mANsApL9dv/7/ZB0SVP kFtg== X-Forwarded-Encrypted: i=1; AFNElJ/h3iHL3t+pW++DSDWMlog2l1nus0i01b6+VoOe9j20iZxf2jCPXv9fiK5XrpcatVUm+Y4O7SC7YQKAA6w=@vger.kernel.org X-Gm-Message-State: AOJu0YyluzAd9FNbePhlPohySpc7dXsM4pu8LUalMwUh3A+cFEgne5ob 1E+LLCjPBBVXU6Mr+IAWEQTqwniICuA4qZFIeiOvGLr4xOorPWWnjp5py5p/6DUrKMqKoPHHMmH lChWG27hIn7iKqR93wbTd44xjasBrdmoC2XTnSvmWdAT/bhUyV1kxtaND/f0AiDMC40A1CnN3SE lVUA== X-Gm-Gg: Acq92OEc1LRhzhpXYqJFPpg1B4TRHK+4xw56tNj4SlsSh/iWJINiQ4KAmXsjAh1m4rO dxH7feBlPn7JjonlK4+fMq2/W16z95jCOKpKIuZ6UEhurTeaySgb5ARoMumdd4mCM4lESbSnd2+ bFWdvkyVnk3xtOguJ4OmwfDw30FimLRgNUnhdQT2IcfPPeoLk4QMD5MSj+6SyInRIhsJoBHZW/L Ck73E4eZf4cfekNqCoVI404MdwcCRqBp46zDYhPeVnA2vU+v2lUmXETK0XRt9CDg3lqzcEBR+sd 7Y4vriOaFnP6vm81gkAnG9PmUGG98c1L82KOdVPb4OXVBZd6gf762USdSDTcPw6w6iJ/TZ84Qop HgAWBSwkN/vtAvI9XcwdjcxupA2rQfhFFiKpcQel/YduijgTJRiclGBS5SX3jZijMDniH4cVLe9 gpcn37n2MH X-Received: by 2002:a05:7300:a889:b0:304:caa4:3559 with SMTP id 5a478bee46e88-304eb1f5f4bmr393406eec.22.1780016745059; Thu, 28 May 2026 18:05:45 -0700 (PDT) X-Received: by 2002:a05:7300:a889:b0:304:caa4:3559 with SMTP id 5a478bee46e88-304eb1f5f4bmr393390eec.22.1780016744418; Thu, 28 May 2026 18:05:44 -0700 (PDT) Received: from hu-fenglinw-lv.qualcomm.com (Global_NAT1.qualcomm.com. [129.46.96.20]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-304ed2c3121sm179812eec.5.2026.05.28.18.05.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 May 2026 18:05:43 -0700 (PDT) From: Fenglin Wu Date: Thu, 28 May 2026 18:05:35 -0700 Subject: [PATCH v2 1/4] soc: qcom: rpmh: Allow non-child devices to issue write commands 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: <20260528-pinctrl-level-shifter-v2-1-3a6a025392bf@oss.qualcomm.com> References: <20260528-pinctrl-level-shifter-v2-0-3a6a025392bf@oss.qualcomm.com> In-Reply-To: <20260528-pinctrl-level-shifter-v2-0-3a6a025392bf@oss.qualcomm.com> To: linux-arm-msm@vger.kernel.org, Bjorn Andersson , Konrad Dybcio , Linus Walleij , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bartosz Golaszewski Cc: David Collins , Subbaraman Narayanamurthy , Kamal Wadhwa , Maulik Shah , kernel@oss.qualcomm.com, linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, Fenglin Wu X-Mailer: b4 0.16-dev-17187 X-Developer-Signature: v=1; a=ed25519-sha256; t=1780016741; l=9203; i=fenglin.wu@oss.qualcomm.com; s=20260324; h=from:subject:message-id; bh=eHzmOULRV2votD+kyy3YF5bvH7sFd6INfw6oEHcYFRM=; b=lT6vmnQU6ArieAWcqteXb8b5No5i/HP33DmEaIGVZ8HBhQuWiDnAIl592HVUxiFsPC52hqDgb z0kRkqqDYvLAOLiQJk5Kks7PDccC7vNB27ZVb4LojcG0LqE9v+rEvMP X-Developer-Key: i=fenglin.wu@oss.qualcomm.com; a=ed25519; pk=hJdt3E7o54lql+miD2GaxwF74cDyhgNwMbmFOZ46bRU= X-Proofpoint-GUID: YFbvOyUa9Rg7zq7zYRV8GrZiyp5FzI2W X-Proofpoint-ORIG-GUID: YFbvOyUa9Rg7zq7zYRV8GrZiyp5FzI2W X-Authority-Analysis: v=2.4 cv=auOCzyZV c=1 sm=1 tr=0 ts=6a18e669 cx=c_pps a=Uww141gWH0fZj/3QKPojxA==:117 a=ouPCqIW2jiPt+lZRy3xVPw==:17 a=IkcTkHD0fZMA:10 a=NGcC8JguVDcA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=Um2Pa8k9VHT-vaBCBUpS:22 a=EUspDBNiAAAA:8 a=3W70XLUb-i4rQMzVbXEA:9 a=QEXdDO2ut3YA:10 a=PxkB5W3o20Ba91AHUih5:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDAwNyBTYWx0ZWRfX0f+P4nhVFC5B ZfAfdn4xd/VWPSTjqW7k7lRpgODIQTD3PAIZWfzKBeJV9Mpa7MdLYOzPBcaPQj8ynn/1HYdD/eH DKT3I6xypY7TjauhihD51zme52nEl2LAImbDvvE+tJlmDfAE9IZVPggHtH5tFXx8fkmDjPrTtCr WWcpsnI/XLbAO/nyK72ek6FgRuQmfPq2Xpzyzevd1THsi+chmwPmcurbxplXdLWnYL9vASN4E4G 66MAyeVEbLl7DDVsVZPv1z5GekUNrevZNbdl9EIWZi10jFMBNMU6eZBe5vaaYsEA3oCz/NCpx4N wLT+9+xMaxdQG5HUoOGPxp0WEplTwZh8YHD4JQrCU++NAeeZTh6MeQ/+WrkUe1Z+ssja939rbhJ g8srgbOhucYa3RFUbdwSKABYTsqQ2XsAMEkLmqDQ18keDA/FIMxSPkmSOOQ8kzo6Se+ODi77UZx rfXG+dp3+U0AM+/2j7w== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-28_07,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 impostorscore=0 bulkscore=0 spamscore=0 lowpriorityscore=0 suspectscore=0 clxscore=1015 phishscore=0 adultscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290007 Currently, the RPMH driver only allows child devices of the RPMH controller to issue commands, as it assumes dev->parent points to the RSC device. There is a possibility that certain devices which are not children of the RPMH controller want to send commands for special control at the RPMH side. For example, in PMH0101 PMICs, there are bidirectional level shifter (LS) peripherals, and each LS works with a pair of PMIC GPIOs. The control of the LS, which is combined with the GPIO configuration, is handled by RPMH firmware for sharing the resource between different subsystems. From a hardware point of view, the LS functionality is tied to a pair of PMIC GPIOs, so its control is more suitable to be added in the pinctrl-spmi-gpio driver by adding the level-shifter function. However, the pinctrl-spmi-gpio device is a child device of the SPMI controller, not the RPMH controller. This patch extends the RPMH driver to support write commands from any device that has a pointer to the RPMH controller device: 1. Add rpmh_get_ctrlr_dev() to lookup controller via device tree phandle "qcom,rpmh" 2. Add new APIs: rpmh_write_async_ctrlr() and rpmh_write_ctrlr() that accept controller device pointer directly With this change, the pinctrl-spmi-gpio driver is able to issue write commands to the RPMH controller by using the controller device pointer, and vote for enabling the level-shifter function. Signed-off-by: Fenglin Wu --- drivers/soc/qcom/rpmh.c | 173 +++++++++++++++++++++++++++++++++++++++++++-= ---- include/soc/qcom/rpmh.h | 21 ++++++ 2 files changed, 179 insertions(+), 15 deletions(-) diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c index ca37da3dc2b1..9dbc42b775d9 100644 --- a/drivers/soc/qcom/rpmh.c +++ b/drivers/soc/qcom/rpmh.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -76,6 +77,21 @@ static struct rpmh_ctrlr *get_rpmh_ctrlr(const struct de= vice *dev) return &drv->client; } =20 +static struct rpmh_ctrlr *get_rpmh_ctrlr_from_dev(const struct device *ctr= l_dev) +{ + struct rsc_drv *drv; + + if (!ctrl_dev) + return ERR_PTR(-EINVAL); + + drv =3D dev_get_drvdata(ctrl_dev); + + if (!drv) + return ERR_PTR(-ENODEV); + + return &drv->client; +} + void rpmh_tx_done(const struct tcs_request *msg) { struct rpmh_request *rpm_msg =3D container_of(msg, struct rpmh_request, @@ -156,23 +172,11 @@ static struct cache_req *cache_rpm_request(struct rpm= h_ctrlr *ctrlr, return req; } =20 -/** - * __rpmh_write: Cache and send the RPMH request - * - * @dev: The device making the request - * @state: Active/Sleep request type - * @rpm_msg: The data that needs to be sent (cmds). - * - * Cache the RPMH request and send if the state is ACTIVE_ONLY. - * SLEEP/WAKE_ONLY requests are not sent to the controller at - * this time. Use rpmh_flush() to send them to the controller. - */ -static int __rpmh_write(const struct device *dev, enum rpmh_state state, - struct rpmh_request *rpm_msg) +static int __rpmh_write_direct(struct rpmh_ctrlr *ctrlr, enum rpmh_state s= tate, + struct rpmh_request *rpm_msg) { - struct rpmh_ctrlr *ctrlr =3D get_rpmh_ctrlr(dev); - int ret =3D -EINVAL; struct cache_req *req; + int ret =3D -EINVAL; int i; =20 /* Cache the request in our store and link the payload */ @@ -193,6 +197,25 @@ static int __rpmh_write(const struct device *dev, enum= rpmh_state state, return ret; } =20 +/** + * __rpmh_write: Cache and send the RPMH request + * + * @dev: The device making the request + * @state: Active/Sleep request type + * @rpm_msg: The data that needs to be sent (cmds). + * + * Cache the RPMH request and send if the state is ACTIVE_ONLY. + * SLEEP/WAKE_ONLY requests are not sent to the controller at + * this time. Use rpmh_flush() to send them to the controller. + */ +static int __rpmh_write(const struct device *dev, enum rpmh_state state, + struct rpmh_request *rpm_msg) +{ + struct rpmh_ctrlr *ctrlr =3D get_rpmh_ctrlr(dev); + + return __rpmh_write_direct(ctrlr, state, rpm_msg); +} + static int __fill_rpmh_msg(struct rpmh_request *req, enum rpmh_state state, const struct tcs_cmd *cmd, u32 n) { @@ -271,6 +294,126 @@ int rpmh_write(const struct device *dev, enum rpmh_st= ate state, } EXPORT_SYMBOL_GPL(rpmh_write); =20 +static void rpmh_put_device(void *data) +{ + put_device(data); +} + +/** + * rpmh_get_ctrlr_dev: Get RPMH controller device from device tree + * + * @dev: Device with "qcom,rpmh" phandle property + * + * Returns: Pointer to RPMH controller device, with a devm action register= ed + * on @dev to release the reference when @dev is unbound. + */ +struct device *rpmh_get_ctrlr_dev(struct device *dev) +{ + struct device_node *rpmh_np; + struct platform_device *pdev; + struct device_link *link; + int ret; + + rpmh_np =3D of_parse_phandle(dev->of_node, "qcom,rpmh", 0); + if (!rpmh_np) + return ERR_PTR(-ENODEV); + + pdev =3D of_find_device_by_node(rpmh_np); + of_node_put(rpmh_np); + + if (!pdev) + return ERR_PTR(-EPROBE_DEFER); + + link =3D device_link_add(dev, &pdev->dev, + DL_FLAG_AUTOREMOVE_CONSUMER | DL_FLAG_PM_RUNTIME); + if (!link) { + put_device(&pdev->dev); + return ERR_PTR(-EINVAL); + } + + ret =3D devm_add_action_or_reset(dev, rpmh_put_device, &pdev->dev); + if (ret) + return ERR_PTR(ret); + + return &pdev->dev; +} +EXPORT_SYMBOL_GPL(rpmh_get_ctrlr_dev); + +/** + * rpmh_write_async_ctrlr: Write RPMH commands with the controller device = pointer + * + * @ctrl_dev: The RPMH controller device + * @state: Active/sleep set + * @cmd: The payload data + * @n: The number of elements in payload + * + * Write a set of RPMH commands, the order of commands is maintained + * and will be sent as a single shot. + */ +int rpmh_write_async_ctrlr(const struct device *ctrl_dev, enum rpmh_state = state, + const struct tcs_cmd *cmd, u32 n) +{ + struct rpmh_request *rpm_msg; + struct rpmh_ctrlr *ctrlr; + int ret; + + ctrlr =3D get_rpmh_ctrlr_from_dev(ctrl_dev); + if (IS_ERR(ctrlr)) + return PTR_ERR(ctrlr); + + rpm_msg =3D kzalloc_obj(*rpm_msg, GFP_ATOMIC); + if (!rpm_msg) + return -ENOMEM; + rpm_msg->needs_free =3D true; + + ret =3D __fill_rpmh_msg(rpm_msg, state, cmd, n); + if (ret) { + kfree(rpm_msg); + return ret; + } + + return __rpmh_write_direct(ctrlr, state, rpm_msg); +} +EXPORT_SYMBOL_GPL(rpmh_write_async_ctrlr); + +/** + * rpmh_write_ctrlr: Write RPMH commands and block until response, + * with the controller device pointer + * + * @ctrlr_dev: The RPMH controller device + * @state: Active/sleep set + * @cmd: The payload data + * @n: The number of elements in @cmd + * + * May sleep. Do not call from atomic contexts. + */ +int rpmh_write_ctrlr(const struct device *ctrlr_dev, enum rpmh_state state, + const struct tcs_cmd *cmd, u32 n) +{ + DECLARE_COMPLETION_ONSTACK(compl); + /* dev is unused in the synchronous non-batch path; pass NULL */ + DEFINE_RPMH_MSG_ONSTACK(NULL, state, &compl, rpm_msg); + struct rpmh_ctrlr *ctrlr; + int ret; + + ctrlr =3D get_rpmh_ctrlr_from_dev(ctrlr_dev); + if (IS_ERR(ctrlr)) + return PTR_ERR(ctrlr); + + ret =3D __fill_rpmh_msg(&rpm_msg, state, cmd, n); + if (ret) + return ret; + + ret =3D __rpmh_write_direct(ctrlr, state, &rpm_msg); + if (ret) + return ret; + + ret =3D wait_for_completion_timeout(&compl, RPMH_TIMEOUT_MS); + WARN_ON(!ret); + return (ret > 0) ? 0 : -ETIMEDOUT; +} +EXPORT_SYMBOL_GPL(rpmh_write_ctrlr); + static void cache_batch(struct rpmh_ctrlr *ctrlr, struct batch_cache_req *= req) { unsigned long flags; diff --git a/include/soc/qcom/rpmh.h b/include/soc/qcom/rpmh.h index bdbee1a97d36..90ddcd7ca2fe 100644 --- a/include/soc/qcom/rpmh.h +++ b/include/soc/qcom/rpmh.h @@ -22,6 +22,14 @@ int rpmh_write_batch(const struct device *dev, enum rpmh= _state state, =20 void rpmh_invalidate(const struct device *dev); =20 +struct device *rpmh_get_ctrlr_dev(struct device *dev); + +int rpmh_write_async_ctrlr(const struct device *ctrl_dev, enum rpmh_state = state, + const struct tcs_cmd *cmd, u32 n); + +int rpmh_write_ctrlr(const struct device *ctrlr_dev, enum rpmh_state state, + const struct tcs_cmd *cmd, u32 n); + #else =20 static inline int rpmh_write(const struct device *dev, enum rpmh_state sta= te, @@ -42,6 +50,19 @@ static inline void rpmh_invalidate(const struct device *= dev) { } =20 +static inline struct device *rpmh_get_ctrlr_dev(struct device *dev) +{ return ERR_PTR(-ENODEV); } + +static inline int rpmh_write_async_ctrlr(const struct device *ctrl_dev, + enum rpmh_state state, + const struct tcs_cmd *cmd, u32 n) +{ return -ENODEV; } + +static inline int rpmh_write_ctrlr(const struct device *ctrlr_dev, + enum rpmh_state state, + const struct tcs_cmd *cmd, u32 n) +{ return -ENODEV; } + #endif /* CONFIG_QCOM_RPMH */ =20 #endif /* __SOC_QCOM_RPMH_H__ */ --=20 2.43.0 From nobody Mon Jun 8 14:36:11 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 88DBF3546D1 for ; Fri, 29 May 2026 01:05:47 +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=1780016750; cv=none; b=jJNF2owAUbBMznEjx/TKV0c815FoULlI7QYXas54ZxH4tfoFaj6yTtd64/FA/JC2ZqUlnKiqh78kFPJrtzV4O2Hz0HQy+F+ppV/eARJr1L2v2zg3LposvCMc2bGuhJHwT2qYu5lNN+TYNefmfLQgyaFjAskG6bm4JPPqj+XrhDM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780016750; c=relaxed/simple; bh=lXy4t/t9OCmAgFepSL86P9vwWEgmZ7kUmPb0JJyweV0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=aV7R6pOeYe0BhtMN4R2NZ+wq3ooZOzvdboFa4ZNwzHQX3VLPSe8dquDYGUr5y7YkSG6DQahkE3TJoSy63b3ZarjvYal5kiqoFFN23BdEogMvDOkY26d/fVR6K2bikNpkAO7194h8KplKXbwZzkKSFji8QPk18iPanZXf1o1d9Xs= 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=BY8/Sy7Y; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=i1j63/JO; 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="BY8/Sy7Y"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="i1j63/JO" 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 64T0A00O1495135 for ; Fri, 29 May 2026 01:05:47 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= u1PyjGjvKsU44wuqA0Tto9I3prCpdK/S5nLQhgommlI=; b=BY8/Sy7YEVtBa8O+ G1Qi7JpGGF9vxDTfK+oC+9hpCUJqtYV7rH9iKoIAO+HdXmyiPlwLUcGShpa+BbrN sx2BDujI++nRJDvyBorIp+1rayp1Jnnc7iztWLfkztSQwYD7ZoyuUP2SXoeO0nfK wv8qIcYOgwfD0/EVnUL9889TppeY5+Rhrc2sqK2kLkmYhfzQ5NlwpxgAhzaFzguy l9H2uoLN/dQ4l7PtB/f5FyTMq+wpz2pZCcCy4Kcfqgu5IC/n6KeEb1VGJBv4SoW5 S2ihaOSprCxpEVGy1+ZtfDKeGKMZUmFTlyGiEXLZIsY3XNhPyvUfP6YmyH7NBBLk kMN5vg== Received: from mail-dy1-f197.google.com (mail-dy1-f197.google.com [74.125.82.197]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4ef01585kj-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 29 May 2026 01:05:46 +0000 (GMT) Received: by mail-dy1-f197.google.com with SMTP id 5a478bee46e88-304df51ff3eso1035433eec.0 for ; Thu, 28 May 2026 18:05:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1780016746; x=1780621546; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=u1PyjGjvKsU44wuqA0Tto9I3prCpdK/S5nLQhgommlI=; b=i1j63/JOQTXMh+ENzMnCwfY/fFnvl/JY+3US9r4g6wXJBS+/gBwAKN1ZRWDKISKtLI drv/NzbhXVDFp6U/FFxSUhgEKCySV1aoB6KOP7F2xkDB97+0BMcq5XGppk9sogCWl31A XnX7RILAD5o5g7l37uTkzFDzsnBnNmedWByQpVZfkbxrAj/jm8sBxzQZp5sv/a4UUbDh jkiFzFFx8lXP9nXiLfTeA8CjzsrzEGVR0nxXZohMgNMK2mtqm8hTFuIBHJQPZW5PgicG vwd9xACvXZgsNyrKo0y9s4JxHyAnIhFlm2PUaoiuvy1hZUf9bR13M5Jcirb/f+lcQME7 ylIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780016746; x=1780621546; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=u1PyjGjvKsU44wuqA0Tto9I3prCpdK/S5nLQhgommlI=; b=KPSssicNAwj0W1WDlUSEjmKadhLacNw3EiSR8FfQlgMPJGqMMNWx3o1L3gZv0KB5oT sd9pVSiNsfdEsB980HBSfHhm53YxzdSa0aHLVqecYpdqD7C7U/xXUhwDa0Tvqx40yj3I 35q4+HX4p0K/fiUJrdRdhSKDsZdj0ZX9f5OvZLytaVcvC3IiqAT2SZvp74IvD+LzYSWY zRPEF669hASpS6/S3VAIwRxTKy4EKa0qdh4hZuILsnUQtGOL1yWp6T1gmGuzBLgH7NSe jqbP5leRugxa/IjrSe/g3NGSxe5KJjZ/xYC2VR5wXVQ7k0FbXYjv41X5iwFtuvCODQD6 E2Bg== X-Forwarded-Encrypted: i=1; AFNElJ9/V1fb3dXo/X+MkApEv7x03nCKwPglVgniG2uRNAJKaOhrHN6tWuxP1kzmqdKXbHx1ag2ldkitITZqS8w=@vger.kernel.org X-Gm-Message-State: AOJu0YxDb24QL9rwZzqOgX/ho2zqwxoJyL+CzO88yF0s3xq9oeq5YZNf Jl5LxTu32cymfmiBfm8Rqp3tNmHQDgdaTBr8QFlB/WUCKeIUSMqbyLKpnfueSvoNgtetFhNOsx7 uSXtEfP9jQxbQq1nHo8oCwTcrzjvvT8IKJBPtZ2xCN5aPIeVIIrhEeBSc7jrWRDRlTtT1vFk1WL GaWA== X-Gm-Gg: Acq92OE4qW8o885GpR8Xx0BWSDCoAcTcONK5QNKnOJ5+iaaL+kRaCJsypJF3fHG7UVT TR2TPPMPKl/H1lvhtOXHeM9zd7afOjWYU1qd0yIo60ReTC3axEeJRic1YsEx9UHVzfkNO0tm9W8 Vt8HEVvvLKWp64dhTwW3wnBAZLLGSKzw9Ilcmon/KGvnga/uqnQrJusRQ8X3fnJOGnP72Omy45o keUvcXFIbUghKjwiROYRli/brXoEtGTa3MmdE59g9jZHVyYmAsRStfzphLdGNDfm0KMuEGj+xkO 5D0aD88xB+RR2z3SB2aIccjvkULAEeZXydcW956+J5XS34DliKZt9OtfDZqGwUYHFPJQf9GhOQ0 L+mrycrpOPIaPpEI1XHfXkmJLAmlaNc1y+eILP19pE+gyp0jO30IX3+GiSgg6LT092FqQ63/Pun rfkFuLcmET X-Received: by 2002:a05:7300:a484:b0:2d0:239a:23cb with SMTP id 5a478bee46e88-304eb0d866dmr475133eec.16.1780016746071; Thu, 28 May 2026 18:05:46 -0700 (PDT) X-Received: by 2002:a05:7300:a484:b0:2d0:239a:23cb with SMTP id 5a478bee46e88-304eb0d866dmr475101eec.16.1780016745528; Thu, 28 May 2026 18:05:45 -0700 (PDT) Received: from hu-fenglinw-lv.qualcomm.com (Global_NAT1.qualcomm.com. [129.46.96.20]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-304ed2c3121sm179812eec.5.2026.05.28.18.05.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 May 2026 18:05:44 -0700 (PDT) From: Fenglin Wu Date: Thu, 28 May 2026 18:05:36 -0700 Subject: [PATCH v2 2/4] dt-bindings: pinctrl: qcom,pmic-gpio: Add level-shifter function 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: <20260528-pinctrl-level-shifter-v2-2-3a6a025392bf@oss.qualcomm.com> References: <20260528-pinctrl-level-shifter-v2-0-3a6a025392bf@oss.qualcomm.com> In-Reply-To: <20260528-pinctrl-level-shifter-v2-0-3a6a025392bf@oss.qualcomm.com> To: linux-arm-msm@vger.kernel.org, Bjorn Andersson , Konrad Dybcio , Linus Walleij , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bartosz Golaszewski Cc: David Collins , Subbaraman Narayanamurthy , Kamal Wadhwa , Maulik Shah , kernel@oss.qualcomm.com, linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, Fenglin Wu X-Mailer: b4 0.16-dev-17187 X-Developer-Signature: v=1; a=ed25519-sha256; t=1780016741; l=4665; i=fenglin.wu@oss.qualcomm.com; s=20260324; h=from:subject:message-id; bh=lXy4t/t9OCmAgFepSL86P9vwWEgmZ7kUmPb0JJyweV0=; b=VmA/SAjy7f4I991yfIMjzvCQdrqCb0zwssphblgXNFImVZft9fr4KM4C4Bbnw1S2jJoli3KNF T0DrFWOqOKVBJ/uIBeGaYuTzgbuN0oW3YihDJQP7kPejTVAD2TDoV4m X-Developer-Key: i=fenglin.wu@oss.qualcomm.com; a=ed25519; pk=hJdt3E7o54lql+miD2GaxwF74cDyhgNwMbmFOZ46bRU= X-Proofpoint-ORIG-GUID: yEIBp2YknKq8H6412WzbyablItGofbo2 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDAwNyBTYWx0ZWRfX3EwhoqhhXIxm 6zEI4B+xs6puu6pTHusyaHFSTn7NNEoXPNkLGpPAVncyUq0gM2p6YgPJKkCEzlQNRQPcpY02qs0 iQ9peyjwcQisqFJLfs3xM1IrqPyX5I5A4GEEtR+jRgJfpOqvQhpgRrJirKWRiuvXWuESOhkWp44 ke9Zmib35x+NjK3rBUsZ4e9RmROiWe9LMcrBX388pRDTxPS/5T1hNd25L2faKuxlsgQM4drANq+ mQYqQIMnjvm/QXJDsaXcYB1nA8mOt6onnqxscDu9sIhlBPRW7QF5w7Kx0+xMVFWVmtFg9jRcRIC gICNwpetgsMRq3J5ojileNN1kFMPfcqhz4rRVzkr+f8GN28P0+4uxqA58p4tQaOtdxW5I7P8Jiv iv6gC5viVFl6Il6xxYl/B/KpudNdZ97n3wYFC00Dzd4oUMHIL8sOPsGn28Todt22Q1bbC6Q38bn i1eZ3xvO8S+0EGFQ++g== X-Authority-Analysis: v=2.4 cv=DIG/JSNb c=1 sm=1 tr=0 ts=6a18e66a cx=c_pps a=Uww141gWH0fZj/3QKPojxA==:117 a=ouPCqIW2jiPt+lZRy3xVPw==:17 a=IkcTkHD0fZMA:10 a=NGcC8JguVDcA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=YMgV9FUhrdKAYTUUvYB2:22 a=EUspDBNiAAAA:8 a=oPYuZtxd-o3nixQqOr8A:9 a=QEXdDO2ut3YA:10 a=PxkB5W3o20Ba91AHUih5:22 X-Proofpoint-GUID: yEIBp2YknKq8H6412WzbyablItGofbo2 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-28_07,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 phishscore=0 lowpriorityscore=0 bulkscore=0 priorityscore=1501 spamscore=0 impostorscore=0 adultscore=0 clxscore=1015 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290007 Add the "level-shifter" function and add the required DT properties to allow RPMh firmware to control the level-shifter. Introduce a custom pinconf parameter "qcom,1p2v-1p8v-ls-en" for enabling or disabling the level-shifter function. Additionally, add the "groups" property with the allowed group names that can be used to control the level-shifter function on pmh0101. Signed-off-by: Fenglin Wu --- .../bindings/pinctrl/qcom,pmic-gpio.yaml | 66 ++++++++++++++++++= +++- include/dt-bindings/pinctrl/qcom,pmic-gpio.h | 1 + 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml = b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml index b8109e6c2a10..19dc61ddff2d 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml @@ -119,6 +119,21 @@ properties: The first cell will be used to define gpio number and the second denotes the flags for this gpio =20 + qcom,rpmh: + description: + Phandle to the RPMh controller device. Required for PMICs when the + bidirectional level shifters is used (e.g., pmh0101), to enable + communication with RPMh firmware for level shifter control. + $ref: /schemas/types.yaml#/definitions/phandle + + qcom,pmic-id: + description: + The ID of the PMIC which supports bidirectional level shifter functi= on. + It is used as the RPMh resource name suffix to request control of the + level shifter to the RPMh firmware. + $ref: /schemas/types.yaml#/definitions/string + pattern: "^[A-N]_E[0-3]+$" + additionalProperties: false =20 required: @@ -330,6 +345,22 @@ allOf: contains: enum: - qcom,pmh0101-gpio + then: + properties: + gpio-line-names: + minItems: 18 + maxItems: 18 + gpio-reserved-ranges: + minItems: 1 + maxItems: 9 + qcom,rpmh: true + qcom,pmic-id: true + + - if: + properties: + compatible: + contains: + enum: - qcom,pmih0108-gpio then: properties: @@ -523,6 +554,19 @@ $defs: items: pattern: '^gpio([0-9]+)$' =20 + groups: + $ref: /schemas/types.yaml#/definitions/string-array + description: + List of GPIO groups to apply properties to. Only valid for + function "level-shifter" on pmh0101. Valid groups are + gpio11, gpio12; gpio13, gpio14; gpio15, gpio16; gpio17, gpio18. + items: + enum: + - gpio11, gpio12 + - gpio13, gpio14 + - gpio15, gpio16 + - gpio17, gpio18 + function: items: - enum: @@ -536,6 +580,7 @@ $defs: - dtest4 - func3 # supported by LV/MV GPIO subtypes - func4 # supported by LV/MV GPIO subtypes + - level-shifter # supported only by pmh0101 =20 bias-disable: true bias-pull-down: true @@ -592,9 +637,24 @@ $defs: configured as digital input. enum: [1, 2, 3, 4] =20 - required: - - pins - - function + qcom,1p2v-1p8v-ls-en: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Enable or disable the bidirectional 1.2V/1.8V level shifter + associated with the specified GPIO group. When set to 1, an RPMh + vote is sent to AOP to enable the level shifter. When set to 0, + the vote is withdrawn. Only valid when function is "level-shifte= r" + and groups is a level-shifter GPIO pair (e.g., "gpio11, gpio12" + on pmh0101). + enum: [0, 1] + + oneOf: + - required: + - pins + - function + - required: + - groups + - function =20 additionalProperties: false =20 diff --git a/include/dt-bindings/pinctrl/qcom,pmic-gpio.h b/include/dt-bind= ings/pinctrl/qcom,pmic-gpio.h index e5df5ce45a0f..b0824d5eb056 100644 --- a/include/dt-bindings/pinctrl/qcom,pmic-gpio.h +++ b/include/dt-bindings/pinctrl/qcom,pmic-gpio.h @@ -105,6 +105,7 @@ #define PMIC_GPIO_FUNC_DTEST2 "dtest2" #define PMIC_GPIO_FUNC_DTEST3 "dtest3" #define PMIC_GPIO_FUNC_DTEST4 "dtest4" +#define PMIC_GPIO_FUNC_LEVEL_SHIFTER "level-shifter" =20 #define PM8038_GPIO1_2_LPG_DRV PMIC_GPIO_FUNC_FUNC1 #define PM8038_GPIO3_5V_BOOST_EN PMIC_GPIO_FUNC_FUNC1 --=20 2.43.0 From nobody Mon Jun 8 14:36:11 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 2EECB330B3F for ; Fri, 29 May 2026 01:05:49 +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=1780016751; cv=none; b=jm9w2XOJOTfKuKO2Q5ecOXOwa8PB29+s3rj5Ms8fSyE0gZqV52rHMpY7XU9smFEjkO+sIJftXL8spdn5GfkWK/oSbNjHfluw+ybAHG8iu83pL86HX7FgGALYZuyuoa6y9Lw9NJPbl1LGlWVSr/mnCYfop20/EWMCsacaUKOkkMg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780016751; c=relaxed/simple; bh=1GINJ3OEwlxTTsPFRbXTnX9AzKanNu1y4Rg+fpmT0Kc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=LOGPTTsPGNdCt354juYTuh7OdJBWq7k2dhnzGV8AMOvhzpkBXe+aRcsZ6liGzBJMockJysloMXfzQUX6wWXR7wLCdyL25qBbwZ1mtQzXFetwc4o3J/oYQ63XO2Ad/X2kRszB0Vfc4eeLZTYHo/EtsXI3U8qQnA+g3mI6C1cYWd4= 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=RBX5vd1U; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=d4j9COQw; 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="RBX5vd1U"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="d4j9COQw" Received: from pps.filterd (m0279864.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64SKkfEo2117732 for ; Fri, 29 May 2026 01:05:48 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= PH0D6T67dxOTo6uuG0mNujRuALZ8gx+l/+S2uJNVaR4=; b=RBX5vd1U2Ub34qf0 L/SWEYc6ZwQLstPGF5aygKfvd7k5jWUV8Fi0KpFEy0LXrcbPW/BD+q9AzmLvEg8v FgNbw8d5P5cy4G5U46fyNuzatCJTvKHoEBhd0Gp2SBNJDjNMJYANZt5DS5ezfVYB ++CgZfEluAsfoPfckoCUxBaoJYG30E72i3knSahqO3VxlrEo/lUuVoNUG9hsZoix wimsuMWiE2cn6UUB0YHBfT5IXwuQLQXvgyIcJLugdQAHYL+bga+/slwnqyWBc5Uk 6uHZqIDWigmewMaV07+JvHIbEw38vIIICAi12yr1MyJysejvTy38Z0jt0PAWAWvz 6gmHUA== Received: from mail-dy1-f199.google.com (mail-dy1-f199.google.com [74.125.82.199]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4eeuy597hw-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 29 May 2026 01:05:48 +0000 (GMT) Received: by mail-dy1-f199.google.com with SMTP id 5a478bee46e88-304ea1eea05so815466eec.0 for ; Thu, 28 May 2026 18:05:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1780016748; x=1780621548; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=PH0D6T67dxOTo6uuG0mNujRuALZ8gx+l/+S2uJNVaR4=; b=d4j9COQwIvXvzNA1e4ek7aCNFaTWCW0UVed9OiM47ybr/gi/jLjx4xFpRftR53ajOL Ml5N7tzg5COYxr14uq2webqVfYZFydKthPIggJJRO6GWfkWQsr9tpK2+I+jVks4NJ+Xd PU/E9ZnGc5sVXfrEWNDwwX5pnSsXE+nhtWiZTCg5by9Qp3xrtHCVYbi9HNVeoE9NWpEX 41A+oPbZ7tPEzq/UFThHWJPWk9pnF4QDw3S5X4n4dX8OqtYqhwWBCHBxQc5JB22u/TK0 2kf1Yv64PfCjJR8ReaLMoOLVJD9zioW2kWClZgQRblFnhkMv2tWGA1xItn8VAgEvpT0P ZJfw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780016748; x=1780621548; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=PH0D6T67dxOTo6uuG0mNujRuALZ8gx+l/+S2uJNVaR4=; b=DdUcsXMoi5lv7O8wJgreyf3a697wz//s9FCa9YWLpF7/UsxmHyky4zHFA1ziG5yUMQ GgUey8zw8gTK9ocaFurBSjW9ic6PzVuVyKhTjk1ZkPhX9oTw0998uCdhpC8qZbBBqmz/ hAzqFnKgULGl0PDnZSK6922Fx3NchrSVTuRi2NhDQ0aJdhVkGaHVpc6WggqKu7q628we ikV/qd6noUn624EZnsaeWDemAQuZuHi67B9ij53JQYLR749vOVTAOCNpP+SrMQYJN+uU xXJtKKCV7bHRdc0KvOHZ9WiiJ03uEAcC5ir/wEty2jXHF2tGRV3u0ynWoroLGo0q5zmV +9Ew== X-Forwarded-Encrypted: i=1; AFNElJ9YvJaJHi5bXRnesdHW+56oZKYvNKxgGv500OG/l1AbcdEi73tsBKZ0/7Y3qW6BUhRSJNobSz4Oh/nZx+k=@vger.kernel.org X-Gm-Message-State: AOJu0YwUImYZVRy13KZbxe3jR2lzkM7e7j3jhpIFaDJJC/IGBD3y1F6G RVoyERGNukyKAFYQ/EbqVBKBYd4c9CiTJHP7+dTNiw303wyoXfuybjkkH3SfND3GgZvN2ZY5xm0 fvdDJrDTq9Cit8tMqZgrwzymsyml0IP5kFRv3EKs8CWsNmHjUDY/NEylCZQrQt+8rj2txFS/1uF PdFA== X-Gm-Gg: Acq92OHodTviHAG2gsvvdYYZz82tYWL8AMgEMmbqhSMsNjGVM960ei3yXUvywK52l9f 20rw5z4EvtOmF1gpAHgHKU3SwrwJ9mItJDFdEYaL4ZPZrYCNiC+r5/aAg49TiZ63gxEaqZD5+jA Xy33J+AIFatsjidSMG8RE9LS2dcaGop7GEEHzil3WZvktxo6y81h8OhqvwWLBkm0vMlvKQjEQ4S camxxmCaZ1fhhFMurNvgcIUsgxr8GhC2E5mH6UzkNxpa4jOTZ5tZjJrmcWBybECE3f1IABapBue HJJWodnUEXU32AcR6sVkQshiYI0Oq/22yXQqmc3IVKiG08esFUkdZgRurN4zHXNaLPw6wP12PSx kGh8098Jbuozq1b55TmFe2X7n3ZlQxyA7EPLckQt63WuIv/W9YiI13KBVH54NOyQ8MkICO4jWps OrmREoFj9M X-Received: by 2002:a05:7300:d706:b0:304:e865:f7d1 with SMTP id 5a478bee46e88-304eb22b5f8mr394229eec.25.1780016747410; Thu, 28 May 2026 18:05:47 -0700 (PDT) X-Received: by 2002:a05:7300:d706:b0:304:e865:f7d1 with SMTP id 5a478bee46e88-304eb22b5f8mr394202eec.25.1780016746763; Thu, 28 May 2026 18:05:46 -0700 (PDT) Received: from hu-fenglinw-lv.qualcomm.com (Global_NAT1.qualcomm.com. [129.46.96.20]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-304ed2c3121sm179812eec.5.2026.05.28.18.05.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 May 2026 18:05:46 -0700 (PDT) From: Fenglin Wu Date: Thu, 28 May 2026 18:05:37 -0700 Subject: [PATCH v2 3/4] pinctrl: qcom: spmi-gpio: Rearchitect for flexible group support 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: <20260528-pinctrl-level-shifter-v2-3-3a6a025392bf@oss.qualcomm.com> References: <20260528-pinctrl-level-shifter-v2-0-3a6a025392bf@oss.qualcomm.com> In-Reply-To: <20260528-pinctrl-level-shifter-v2-0-3a6a025392bf@oss.qualcomm.com> To: linux-arm-msm@vger.kernel.org, Bjorn Andersson , Konrad Dybcio , Linus Walleij , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bartosz Golaszewski Cc: David Collins , Subbaraman Narayanamurthy , Kamal Wadhwa , Maulik Shah , kernel@oss.qualcomm.com, linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, Fenglin Wu X-Mailer: b4 0.16-dev-17187 X-Developer-Signature: v=1; a=ed25519-sha256; t=1780016741; l=17738; i=fenglin.wu@oss.qualcomm.com; s=20260324; h=from:subject:message-id; bh=1GINJ3OEwlxTTsPFRbXTnX9AzKanNu1y4Rg+fpmT0Kc=; b=Gbw1f1wpUarPhI1wuKQX1z5axyiORSGQhrSH95ztfCHMGyNGgvjOCoOmynyzFnHC1TcQ7UbWd gk8SqgO+Gp9CzJ0uP6BCUiW02Tz9NLL3/BX1LvlwaD9gkTdXFS9o3lD X-Developer-Key: i=fenglin.wu@oss.qualcomm.com; a=ed25519; pk=hJdt3E7o54lql+miD2GaxwF74cDyhgNwMbmFOZ46bRU= X-Authority-Analysis: v=2.4 cv=SPtykuvH c=1 sm=1 tr=0 ts=6a18e66c cx=c_pps a=cFYjgdjTJScbgFmBucgdfQ==:117 a=ouPCqIW2jiPt+lZRy3xVPw==:17 a=IkcTkHD0fZMA:10 a=NGcC8JguVDcA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=DJpcGTmdVt4CTyJn9g5Z:22 a=EUspDBNiAAAA:8 a=AQbMkjDxTMOx3Hcn-oMA:9 a=QEXdDO2ut3YA:10 a=O8hF6Hzn-FEA:10 a=scEy_gLbYbu1JhEsrz4S:22 X-Proofpoint-GUID: eoHZNv_a54vKphdZkeJ3iJUUrtU_7wwx X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDAwNyBTYWx0ZWRfXxcGzByjdRd5w b57EpZMuT5ZGc4VW3k0ojSnFpqaUjFdEMJNmETZTRpr5Q+CCKwlWALUDG/C8xKUA7d8/ifKq/fm jUUllElwOMH0U5W5GPYP+6X6TlrbwSC/Fh3tw8OR9j4GHwuLTlyoz3JEEQtKLOrRfl7srq0ND58 6M5JTRmUWlG2OW/kkGTmRGOgrp8LVadoFVAMYJAzuVfCccgd/JYx5TK4oKOBVG/1ezCN1drV5Ox 4flEjZ70I7aX6/QXSSte5SEDTQyoE2triIQ9fUULsi0zETZOf4hy1AggIcf1r6nUAHvWiyravMR u2S1bxIbEUg4dbTyW3ti6zKrHn1ei8qrQttKbVjD+RZ9RD5f7cLr6qqK2z7A3C5viGDvJt4DF/t s76i9j8Ttc3kqQF3a99N8/x5pbGsvTSUSGckbzgeNumLkUwffMJn0mvblbl5dulfPWJwR0NwdP7 I8DPx/bVNp/3Ba4garw== X-Proofpoint-ORIG-GUID: eoHZNv_a54vKphdZkeJ3iJUUrtU_7wwx X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-28_07,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 lowpriorityscore=0 priorityscore=1501 impostorscore=0 suspectscore=0 malwarescore=0 clxscore=1015 phishscore=0 bulkscore=0 adultscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290007 Currently, the driver treats each pin as a group, and every pin or group can function correctly in all existing functions. However, this approach is no longer valid since some PMIC pins only operate together in specific functions, which are limited to certain GPIO groups. For example, in pmh0101, the level-shifter function is supported only between GPIO pairs like GPIO11/12, GPIO13/14, GPIO15/16, and GPIO17/18. To better accommodate these new functions and restrict GPIOs to those that support them, rearchitect the driver to enable flexible pinctrl group configurations by utilizing the generic pinctrl group and function APIs. Signed-off-by: Fenglin Wu --- drivers/pinctrl/qcom/Kconfig | 2 + drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 377 +++++++++++++++++++++------= ---- 2 files changed, 258 insertions(+), 121 deletions(-) diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig index a09e840a01c6..80bcec33b9b8 100644 --- a/drivers/pinctrl/qcom/Kconfig +++ b/drivers/pinctrl/qcom/Kconfig @@ -25,6 +25,8 @@ config PINCTRL_QCOM_SPMI_PMIC select PINMUX select PINCONF select GENERIC_PINCONF + select GENERIC_PINCTRL_GROUPS + select GENERIC_PINMUX_FUNCTIONS select GPIOLIB select GPIOLIB_IRQCHIP select IRQ_DOMAIN_HIERARCHY diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qco= m/pinctrl-spmi-gpio.c index cdd61dae74cf..268cfae706a8 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c @@ -24,6 +24,7 @@ #include =20 #include "../core.h" +#include "../pinmux.h" #include "../pinctrl-utils.h" =20 #define PMIC_GPIO_ADDRESS_RANGE 0x100 @@ -253,139 +254,124 @@ static int pmic_gpio_write(struct pmic_gpio_state *= state, return ret; } =20 -static int pmic_gpio_get_groups_count(struct pinctrl_dev *pctldev) -{ - /* Every PIN is a group */ - return pctldev->desc->npins; -} - -static const char *pmic_gpio_get_group_name(struct pinctrl_dev *pctldev, - unsigned pin) -{ - return pctldev->desc->pins[pin].name; -} - -static int pmic_gpio_get_group_pins(struct pinctrl_dev *pctldev, unsigned = pin, - const unsigned **pins, unsigned *num_pins) -{ - *pins =3D &pctldev->desc->pins[pin].number; - *num_pins =3D 1; - return 0; -} - static const struct pinctrl_ops pmic_gpio_pinctrl_ops =3D { - .get_groups_count =3D pmic_gpio_get_groups_count, - .get_group_name =3D pmic_gpio_get_group_name, - .get_group_pins =3D pmic_gpio_get_group_pins, + .get_groups_count =3D pinctrl_generic_get_group_count, + .get_group_name =3D pinctrl_generic_get_group_name, + .get_group_pins =3D pinctrl_generic_get_group_pins, .dt_node_to_map =3D pinconf_generic_dt_node_to_map_group, .dt_free_map =3D pinctrl_utils_free_map, }; =20 -static int pmic_gpio_get_functions_count(struct pinctrl_dev *pctldev) -{ - return ARRAY_SIZE(pmic_gpio_functions); -} - -static const char *pmic_gpio_get_function_name(struct pinctrl_dev *pctldev, - unsigned function) -{ - return pmic_gpio_functions[function]; -} - -static int pmic_gpio_get_function_groups(struct pinctrl_dev *pctldev, - unsigned function, - const char *const **groups, - unsigned *const num_qgroups) -{ - *groups =3D pmic_gpio_groups; - *num_qgroups =3D pctldev->desc->npins; - return 0; -} - -static int pmic_gpio_set_mux(struct pinctrl_dev *pctldev, unsigned functio= n, - unsigned pin) +static int pmic_gpio_set_mux(struct pinctrl_dev *pctldev, unsigned int fun= ction, + unsigned int selector) { struct pmic_gpio_state *state =3D pinctrl_dev_get_drvdata(pctldev); struct pmic_gpio_pad *pad; - unsigned int val; - int ret; + struct group_desc *group; + unsigned int val, pin, func; + int ret, i; =20 if (function > PMIC_GPIO_FUNC_INDEX_DTEST4) { pr_err("function: %d is not defined\n", function); return -EINVAL; } =20 - pad =3D pctldev->desc->pins[pin].drv_data; - /* - * Non-LV/MV subtypes only support 2 special functions, - * offsetting the dtestx function values by 2 - */ - if (!pad->lv_mv_type) { - if (function =3D=3D PMIC_GPIO_FUNC_INDEX_FUNC3 || - function =3D=3D PMIC_GPIO_FUNC_INDEX_FUNC4) { - pr_err("LV/MV subtype doesn't have func3/func4\n"); - return -EINVAL; + group =3D pinctrl_generic_get_group(pctldev, selector); + if (!group) + return -EINVAL; + + /* For standard functions, iterate over all pins in the group */ + for (i =3D 0; i < group->grp.npins; i++) { + pin =3D group->grp.pins[i]; + pad =3D pctldev->desc->pins[pin].drv_data; + + func =3D function; + /* + * Non-LV/MV subtypes only support 2 special functions, + * offsetting the dtestx function values by 2 + */ + if (!pad->lv_mv_type) { + if (func =3D=3D PMIC_GPIO_FUNC_INDEX_FUNC3 || + func =3D=3D PMIC_GPIO_FUNC_INDEX_FUNC4) { + dev_err(state->dev, + "pin%d: LV/MV subtype doesn't have func3/func4\n", + pin); + return -EINVAL; + } + if (func >=3D PMIC_GPIO_FUNC_INDEX_DTEST1) + func -=3D (PMIC_GPIO_FUNC_INDEX_DTEST1 - + PMIC_GPIO_FUNC_INDEX_FUNC3); } - if (function >=3D PMIC_GPIO_FUNC_INDEX_DTEST1) - function -=3D (PMIC_GPIO_FUNC_INDEX_DTEST1 - - PMIC_GPIO_FUNC_INDEX_FUNC3); - } =20 - pad->function =3D function; + pad->function =3D func; =20 - if (pad->analog_pass) - val =3D PMIC_GPIO_MODE_ANALOG_PASS_THRU; - else if (pad->output_enabled && pad->input_enabled) - val =3D PMIC_GPIO_MODE_DIGITAL_INPUT_OUTPUT; - else if (pad->output_enabled) - val =3D PMIC_GPIO_MODE_DIGITAL_OUTPUT; - else - val =3D PMIC_GPIO_MODE_DIGITAL_INPUT; + if (pad->analog_pass) + val =3D PMIC_GPIO_MODE_ANALOG_PASS_THRU; + else if (pad->output_enabled && pad->input_enabled) + val =3D PMIC_GPIO_MODE_DIGITAL_INPUT_OUTPUT; + else if (pad->output_enabled) + val =3D PMIC_GPIO_MODE_DIGITAL_OUTPUT; + else + val =3D PMIC_GPIO_MODE_DIGITAL_INPUT; =20 - if (pad->lv_mv_type) { - ret =3D pmic_gpio_write(state, pad, - PMIC_GPIO_REG_MODE_CTL, val); - if (ret < 0) - return ret; + if (pad->lv_mv_type) { + ret =3D pmic_gpio_write(state, pad, + PMIC_GPIO_REG_MODE_CTL, val); + if (ret < 0) + return ret; =20 - val =3D pad->atest - 1; - ret =3D pmic_gpio_write(state, pad, - PMIC_GPIO_REG_LV_MV_ANA_PASS_THRU_SEL, val); - if (ret < 0) - return ret; + val =3D pad->atest - 1; + ret =3D pmic_gpio_write(state, pad, + PMIC_GPIO_REG_LV_MV_ANA_PASS_THRU_SEL, val); + if (ret < 0) + return ret; + + val =3D pad->out_value + << PMIC_GPIO_LV_MV_OUTPUT_INVERT_SHIFT; + val |=3D pad->function + & PMIC_GPIO_LV_MV_OUTPUT_SOURCE_SEL_MASK; + ret =3D pmic_gpio_write(state, pad, + PMIC_GPIO_REG_LV_MV_DIG_OUT_SOURCE_CTL, val); + if (ret < 0) + return ret; + } else { + val =3D val << PMIC_GPIO_REG_MODE_DIR_SHIFT; + val |=3D pad->function << PMIC_GPIO_REG_MODE_FUNCTION_SHIFT; + val |=3D pad->out_value & PMIC_GPIO_REG_MODE_VALUE_SHIFT; =20 - val =3D pad->out_value - << PMIC_GPIO_LV_MV_OUTPUT_INVERT_SHIFT; - val |=3D pad->function - & PMIC_GPIO_LV_MV_OUTPUT_SOURCE_SEL_MASK; - ret =3D pmic_gpio_write(state, pad, - PMIC_GPIO_REG_LV_MV_DIG_OUT_SOURCE_CTL, val); - if (ret < 0) - return ret; - } else { - val =3D val << PMIC_GPIO_REG_MODE_DIR_SHIFT; - val |=3D pad->function << PMIC_GPIO_REG_MODE_FUNCTION_SHIFT; - val |=3D pad->out_value & PMIC_GPIO_REG_MODE_VALUE_SHIFT; + ret =3D pmic_gpio_write(state, pad, PMIC_GPIO_REG_MODE_CTL, val); + if (ret < 0) + return ret; + } =20 - ret =3D pmic_gpio_write(state, pad, PMIC_GPIO_REG_MODE_CTL, val); + val =3D pad->is_enabled << PMIC_GPIO_REG_MASTER_EN_SHIFT; + + ret =3D pmic_gpio_write(state, pad, PMIC_GPIO_REG_EN_CTL, val); if (ret < 0) return ret; } =20 - val =3D pad->is_enabled << PMIC_GPIO_REG_MASTER_EN_SHIFT; - - return pmic_gpio_write(state, pad, PMIC_GPIO_REG_EN_CTL, val); + return 0; } =20 static const struct pinmux_ops pmic_gpio_pinmux_ops =3D { - .get_functions_count =3D pmic_gpio_get_functions_count, - .get_function_name =3D pmic_gpio_get_function_name, - .get_function_groups =3D pmic_gpio_get_function_groups, + .get_functions_count =3D pinmux_generic_get_function_count, + .get_function_name =3D pinmux_generic_get_function_name, + .get_function_groups =3D pinmux_generic_get_function_groups, .set_mux =3D pmic_gpio_set_mux, }; =20 -static int pmic_gpio_config_get(struct pinctrl_dev *pctldev, - unsigned int pin, unsigned long *config) +/** + * pmic_gpio_pinconf_pin_get() - Get configuration for a single pin + * @pctldev: pinctrl device + * @pin: Pin number + * @config: Configuration parameter to get + * + * Core function to read a single pin's configuration. + * Used by both per-pin and per-group config get operations. + */ +static int pmic_gpio_pinconf_pin_get(struct pinctrl_dev *pctldev, + unsigned int pin, unsigned long *config) { unsigned param =3D pinconf_to_config_param(*config); struct pmic_gpio_pad *pad; @@ -476,8 +462,48 @@ static int pmic_gpio_config_get(struct pinctrl_dev *pc= tldev, return 0; } =20 -static int pmic_gpio_config_set(struct pinctrl_dev *pctldev, unsigned int = pin, - unsigned long *configs, unsigned nconfs) +/** + * pmic_gpio_pinconf_group_get() - Get configuration for a pin group + * @pctldev: pinctrl device + * @selector: Group selector + * @config: Configuration parameter to get + * + * For multi-pin groups, we assume all pins have the same configuration, + * so we read the configuration from the first pin in the group. + */ +static int pmic_gpio_pinconf_group_get(struct pinctrl_dev *pctldev, + unsigned int selector, + unsigned long *config) +{ + const struct group_desc *group; + unsigned int pin; + + group =3D pinctrl_generic_get_group(pctldev, selector); + if (!group) + return -EINVAL; + + /* + * For multi-pin groups, we assume all pins have the same configuration, + * so we read the configuration from the first pin in the group. + */ + pin =3D group->grp.pins[0]; + + return pmic_gpio_pinconf_pin_get(pctldev, pin, config); +} + +/** + * pmic_gpio_pinconf_pin_set() - Set configuration for a single pin + * @pctldev: pinctrl device + * @pin: Pin number + * @configs: Array of configuration parameters + * @nconfs: Number of configurations + * + * Core function to configure a single pin. + * Used by both per-pin and per-group config set operations. + */ +static int pmic_gpio_pinconf_pin_set(struct pinctrl_dev *pctldev, + unsigned int pin, + unsigned long *configs, unsigned int nconfs) { struct pmic_gpio_state *state =3D pinctrl_dev_get_drvdata(pctldev); struct pmic_gpio_pad *pad; @@ -651,12 +677,58 @@ static int pmic_gpio_config_set(struct pinctrl_dev *p= ctldev, unsigned int pin, val =3D pad->is_enabled << PMIC_GPIO_REG_MASTER_EN_SHIFT; =20 ret =3D pmic_gpio_write(state, pad, PMIC_GPIO_REG_EN_CTL, val); + if (ret < 0) + return ret; =20 - return ret; + return 0; } =20 -static void pmic_gpio_config_dbg_show(struct pinctrl_dev *pctldev, - struct seq_file *s, unsigned pin) +/** + * pmic_gpio_pinconf_group_set() - Set configuration for a pin group + * @pctldev: pinctrl device + * @selector: Group selector + * @configs: Array of configuration parameters + * @nconfs: Number of configurations + * + * Iterates over all pins in the group and applies config to each. + */ +static int pmic_gpio_pinconf_group_set(struct pinctrl_dev *pctldev, + unsigned int selector, + unsigned long *configs, + unsigned int nconfs) +{ + const struct group_desc *group; + unsigned int pin; + int i, ret; + + group =3D pinctrl_generic_get_group(pctldev, selector); + if (!group) + return -EINVAL; + + /* Iterate over all pins in the group and apply config to each */ + for (i =3D 0; i < group->grp.npins; i++) { + pin =3D group->grp.pins[i]; + + ret =3D pmic_gpio_pinconf_pin_set(pctldev, pin, configs, nconfs); + if (ret < 0) + return ret; + } + + return 0; +} + +/** + * pmic_gpio_pinconf_pin_dbg_show() - Show configuration for a single pin + * @pctldev: pinctrl device + * @s: seq_file for output + * @pin: Pin number + * + * Core function that dumps the configuration of a single GPIO pin. + * Used by pinconf-pins debugfs, pinconf-groups debugfs, and gpio debugfs. + */ +static void pmic_gpio_pinconf_pin_dbg_show(struct pinctrl_dev *pctldev, + struct seq_file *s, + unsigned int pin) { struct pmic_gpio_state *state =3D pinctrl_dev_get_drvdata(pctldev); struct pmic_gpio_pad *pad; @@ -716,11 +788,46 @@ static void pmic_gpio_config_dbg_show(struct pinctrl_= dev *pctldev, } } =20 +/** + * pmic_gpio_pinconf_group_dbg_show() - Show configuration for a pin group + * @pctldev: pinctrl device + * @s: seq_file for output + * @selector: Group selector + * + * Shows the configuration for all pins in a group. + * Used by the pinconf-groups debugfs interface. + */ +static void pmic_gpio_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, + struct seq_file *s, + unsigned int selector) +{ + const struct group_desc *group; + unsigned int pin; + int i; + + group =3D pinctrl_generic_get_group(pctldev, selector); + if (!group) + return; + + /* Iterate over all pins in the group and show status for each */ + for (i =3D 0; i < group->grp.npins; i++) { + pin =3D group->grp.pins[i]; + + if (i > 0) + seq_puts(s, "\n "); + + pmic_gpio_pinconf_pin_dbg_show(pctldev, s, pin); + } +} + static const struct pinconf_ops pmic_gpio_pinconf_ops =3D { .is_generic =3D true, - .pin_config_group_get =3D pmic_gpio_config_get, - .pin_config_group_set =3D pmic_gpio_config_set, - .pin_config_group_dbg_show =3D pmic_gpio_config_dbg_show, + .pin_config_get =3D pmic_gpio_pinconf_pin_get, + .pin_config_set =3D pmic_gpio_pinconf_pin_set, + .pin_config_dbg_show =3D pmic_gpio_pinconf_pin_dbg_show, + .pin_config_group_get =3D pmic_gpio_pinconf_group_get, + .pin_config_group_set =3D pmic_gpio_pinconf_group_set, + .pin_config_group_dbg_show =3D pmic_gpio_pinconf_group_dbg_show, }; =20 static int pmic_gpio_get_direction(struct gpio_chip *chip, unsigned pin) @@ -745,7 +852,7 @@ static int pmic_gpio_direction_input(struct gpio_chip *= chip, unsigned pin) =20 config =3D pinconf_to_config_packed(PIN_CONFIG_INPUT_ENABLE, 1); =20 - return pmic_gpio_config_set(state->ctrl, pin, &config, 1); + return pmic_gpio_pinconf_pin_set(state->ctrl, pin, &config, 1); } =20 static int pmic_gpio_direction_output(struct gpio_chip *chip, @@ -756,7 +863,7 @@ static int pmic_gpio_direction_output(struct gpio_chip = *chip, =20 config =3D pinconf_to_config_packed(PIN_CONFIG_LEVEL, val); =20 - return pmic_gpio_config_set(state->ctrl, pin, &config, 1); + return pmic_gpio_pinconf_pin_set(state->ctrl, pin, &config, 1); } =20 static int pmic_gpio_get(struct gpio_chip *chip, unsigned pin) @@ -788,7 +895,7 @@ static int pmic_gpio_set(struct gpio_chip *chip, unsign= ed int pin, int value) =20 config =3D pinconf_to_config_packed(PIN_CONFIG_LEVEL, value); =20 - return pmic_gpio_config_set(state->ctrl, pin, &config, 1); + return pmic_gpio_pinconf_pin_set(state->ctrl, pin, &config, 1); } =20 static int pmic_gpio_of_xlate(struct gpio_chip *chip, @@ -810,7 +917,7 @@ static void pmic_gpio_dbg_show(struct seq_file *s, stru= ct gpio_chip *chip) unsigned i; =20 for (i =3D 0; i < chip->ngpio; i++) { - pmic_gpio_config_dbg_show(state->ctrl, s, i); + pmic_gpio_pinconf_pin_dbg_show(state->ctrl, s, i); seq_puts(s, "\n"); } } @@ -1129,11 +1236,11 @@ static int pmic_gpio_probe(struct platform_device *= pdev) pctrldesc->custom_conf_items =3D pmic_conf_items; #endif =20 - for (i =3D 0; i < npins; i++, pindesc++) { + for (i =3D 0; i < npins; i++) { pad =3D &pads[i]; - pindesc->drv_data =3D pad; - pindesc->number =3D i; - pindesc->name =3D pmic_gpio_groups[i]; + pindesc[i].drv_data =3D pad; + pindesc[i].number =3D i; + pindesc[i].name =3D pmic_gpio_groups[i]; =20 pad->base =3D reg + i * PMIC_GPIO_ADDRESS_RANGE; =20 @@ -1150,9 +1257,33 @@ static int pmic_gpio_probe(struct platform_device *p= dev) state->chip.of_gpio_n_cells =3D 2; state->chip.can_sleep =3D false; =20 - state->ctrl =3D devm_pinctrl_register(dev, pctrldesc, state); - if (IS_ERR(state->ctrl)) - return PTR_ERR(state->ctrl); + ret =3D devm_pinctrl_register_and_init(dev, pctrldesc, state, &state->ctr= l); + if (ret) + return ret; + + /* Register pin groups - each GPIO is a group for standard functions */ + for (i =3D 0; i < npins; i++) { + ret =3D pinctrl_generic_add_group(state->ctrl, + pmic_gpio_groups[i], + &pindesc[i].number, 1, NULL); + if (ret < 0) { + dev_err(dev, "failed to register group %s\n", + pmic_gpio_groups[i]); + return ret; + } + } + + /* Register standard functions - all GPIOs support these */ + for (i =3D 0; i < ARRAY_SIZE(pmic_gpio_functions); i++) { + ret =3D pinmux_generic_add_function(state->ctrl, + pmic_gpio_functions[i], + pmic_gpio_groups, npins, NULL); + if (ret < 0) { + dev_err(dev, "failed to register function %s\n", + pmic_gpio_functions[i]); + return ret; + } + } =20 parent_node =3D of_irq_find_parent(state->dev->of_node); if (!parent_node) @@ -1174,6 +1305,10 @@ static int pmic_gpio_probe(struct platform_device *p= dev) girq->child_offset_to_irq =3D pmic_gpio_child_offset_to_irq; girq->child_irq_domain_ops.translate =3D pmic_gpio_domain_translate; =20 + ret =3D pinctrl_enable(state->ctrl); + if (ret) + return ret; + ret =3D gpiochip_add_data(&state->chip, state); if (ret) { dev_err(state->dev, "can't add gpio chip\n"); --=20 2.43.0 From nobody Mon Jun 8 14:36:11 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 8A0411DDC37 for ; Fri, 29 May 2026 01:05:50 +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=1780016753; cv=none; b=SRgHNNbuCP+UbKkszDzGaxjF0oXrFPBD5UnDIg23nfiNLyajW6veQnGKfTJNrs/cwmYW9gtnlB+l9zpm3/tyUmdQ9Bg98nLUQv4ONYcBlweCkuw6o/gWdnpef8ngfSLM0jPKzQjznclPT+aGt38Vz/k/F1DaBq+oWytqseAGUt8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780016753; c=relaxed/simple; bh=DVLsbFOisNLoLaDWw4A6fEx1CNtZSZlLpDSYN1MW3rg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=kG7fTkFZNxqjHYs6vpd5OsIkVgLkR6Ya/5wvKge+RiLzYIBM1eVe7XlswZ8S2ijNHYyoBrgUhlFF1gx3dxFmWpYEtYcoBytM/kTl9It3SLTHS05HLa/nYcLzPPycLtSyNlLGimc/0QiFgpFbpy+dhPJTToaYSSO8UPu5VMe7988= 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=RHRylA7a; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=Vcovl9rP; 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="RHRylA7a"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="Vcovl9rP" Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64SKkXkF1931874 for ; Fri, 29 May 2026 01:05:50 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= rs9BvaYIs/fEy4SVMRxksGtecpbU8Xw+OBbEDdNoklw=; b=RHRylA7aQyxqUTag /R7yPoOt4/q/SjBMopi3lpKdALUOd+lF7D/rcsWUaNQYmUD4NeyrBLb9FIqEJFjX uc93BDWBRnETP0XjUQ0BBebVBZL3Sc1PAKhHsXVlms+lQ4YI/NLpdUL11NNTjY2v 3m96ihSMtDey0MI3ijg8wZKWdin96ZxsRxIzTkTZlauO6hnt+4onblXRgFwceRT7 K6olUK2k08UE9ZdfWTWhRG2DYO71BUjDLauTxf3qFi5Q7b7740BYqf2rnUnMNjo5 /MxcHUsL0hwPqTmap+GKRK0QB6XDl1F2M7ITcKhY8JyVrrNaoyH+h4jEXz9fRURa SeJSOw== Received: from mail-dy1-f198.google.com (mail-dy1-f198.google.com [74.125.82.198]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4eesxa9w80-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 29 May 2026 01:05:49 +0000 (GMT) Received: by mail-dy1-f198.google.com with SMTP id 5a478bee46e88-304d0d0b28eso989475eec.0 for ; Thu, 28 May 2026 18:05:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1780016749; x=1780621549; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=rs9BvaYIs/fEy4SVMRxksGtecpbU8Xw+OBbEDdNoklw=; b=Vcovl9rPz85zEo+x7tnnlct5EZ0w0BOO8VGq4PowUcyxdjtEcftgZkIF33jO4ni97f F8ybRlhUX6WbAmr4n9EIeHexvGcljgmN+XurtUS2lnKQ8dKSjVYSSSmsxpgbvt4xnu0Q wtn6bAU7EFMpwDd6rPA3i4vlur9XKqKky7JQs9sOq933Nneeh44MwOtJp8VbtViP0zrO TEyMBIxO4NE1FE8O8i2Dt/vl/oMLbr6/jF7yKNjgjTnele7x+Z9Sh5ED7v9+4i6/XzUG bQlSXpIkGBI+pIJT7VDtmxAeUFlj/doABMIZeEkA3JWRTGbT3uKQg838Vrykj2zuJ6xR 5XxQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780016749; x=1780621549; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=rs9BvaYIs/fEy4SVMRxksGtecpbU8Xw+OBbEDdNoklw=; b=nUZrLGmJPrVf5Cadv1akq0xHevwcB8q4RVmISwTrUER/TJZsVT3n6ziB5UB7yE8V2W CTaPTcBUr1VMlJmAg8tpgILcP9xSdpShVFg06oxOBbxs3uncm8KVGe/iqFYbCoK2q2ie zGz6dMn2+D0ebL8SO7lVlphw1hlFaYUJSk8SMRZX/iWgmsbaAb7fUsEfAonjO7UYy/UO vBp3Ogwi1WnjATRYAGkXCBQiYuoHP8OLsQ5YhokXalD7+PB61nSet/n+rIleMqk60TAi xVHWGcObQX8mDXLsuFvKzsk6HP1rZSVwGod2+wRw7ARhaFMBfYfOomlVbCPq+0tpHCGy nhqA== X-Forwarded-Encrypted: i=1; AFNElJ+gg2VezeQbL1M6F06ZLsQ8UgR3we+2i2iLvofraoa3ZAiOLp7Mznl3nCkEY4ZCcYFy59AbFHjqBOjewq8=@vger.kernel.org X-Gm-Message-State: AOJu0YzlN75GT0uXqDtcM89rR07S140HEQro3KpQJ3UIdmBmMR73PL1N pQYRNfCtnwNGKgcTc2ynqN81/1t4Ow8UGu3YeSdoQrUNJ5XcTkDFX42qlZ4FfSgUq0oPbIP7VQw SD/+UFEyU8tBaqQ0krMANNAh/goRc2krcN5UusAOihumAiJkLVtvo4Pm24Pa65z763IZqOxh/kD Ch4Q== X-Gm-Gg: Acq92OEm04px59c9JqMT19Dva+bMVUnZO03iFE87zH/vYHaZ77FYvrdiF8J7SFNrwHX 2BGnsfafw6YBE7f+npQdr+6RnpKd68vyyQW5k0NvspVN4t5xfHlCPxnULsQLnxrLMTCPRz4nB99 nbiNovGeDxowEz7KZzGGpFgH61z2bszjccOoQ3UDsnulnFZ7r0VVmviZhP3hAowWao7uYeCJQs2 8QDqj1Lk/GrGB4JlOQRfVYf9QwrAUiCnoQSAt6eE6ezBhCP2/CMfUuqq8UQNtRnQZDKGJrhp9U0 GbykfiLUAQbOcAlCXsC14mRy1LyZNaHeVL6Gx2i1kMEZ4pTJSPIRLZGbr0FqiHI13STJ43eX19w laHEBUMd2mUJINDjkbogSn6Fm6a2TxI0bStsziRd6iRBvoz2LRN7J5T0LyleJ/QmBZ1j+ZLvZKk ZACNUgd1Sb X-Received: by 2002:a05:7301:4196:b0:2de:cc07:e99 with SMTP id 5a478bee46e88-304ead9b7fbmr451480eec.7.1780016748877; Thu, 28 May 2026 18:05:48 -0700 (PDT) X-Received: by 2002:a05:7301:4196:b0:2de:cc07:e99 with SMTP id 5a478bee46e88-304ead9b7fbmr451451eec.7.1780016748015; Thu, 28 May 2026 18:05:48 -0700 (PDT) Received: from hu-fenglinw-lv.qualcomm.com (Global_NAT1.qualcomm.com. [129.46.96.20]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-304ed2c3121sm179812eec.5.2026.05.28.18.05.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 May 2026 18:05:47 -0700 (PDT) From: Fenglin Wu Date: Thu, 28 May 2026 18:05:38 -0700 Subject: [PATCH v2 4/4] pinctrl: qcom: spmi-gpio: Add level-shifter function support 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: <20260528-pinctrl-level-shifter-v2-4-3a6a025392bf@oss.qualcomm.com> References: <20260528-pinctrl-level-shifter-v2-0-3a6a025392bf@oss.qualcomm.com> In-Reply-To: <20260528-pinctrl-level-shifter-v2-0-3a6a025392bf@oss.qualcomm.com> To: linux-arm-msm@vger.kernel.org, Bjorn Andersson , Konrad Dybcio , Linus Walleij , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bartosz Golaszewski Cc: David Collins , Subbaraman Narayanamurthy , Kamal Wadhwa , Maulik Shah , kernel@oss.qualcomm.com, linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, Fenglin Wu X-Mailer: b4 0.16-dev-17187 X-Developer-Signature: v=1; a=ed25519-sha256; t=1780016741; l=28441; i=fenglin.wu@oss.qualcomm.com; s=20260324; h=from:subject:message-id; bh=DVLsbFOisNLoLaDWw4A6fEx1CNtZSZlLpDSYN1MW3rg=; b=HRWbQ5D6VCo8TdNDYHrTsOeK2bQuDhaqBVNRhJh7ydFbgmBVRlARuAMpZMB8EO5zEb9xiYuvR k7Rc/au1RY9De7LunY4a+ta7WqmCT9e1hHTcs+bpIdQzXbg9JGnbLQm X-Developer-Key: i=fenglin.wu@oss.qualcomm.com; a=ed25519; pk=hJdt3E7o54lql+miD2GaxwF74cDyhgNwMbmFOZ46bRU= X-Proofpoint-GUID: 8cMyWzQFqVlStiUmtjDwiCQVTtr6pch8 X-Proofpoint-ORIG-GUID: 8cMyWzQFqVlStiUmtjDwiCQVTtr6pch8 X-Authority-Analysis: v=2.4 cv=ZdIt8MVA c=1 sm=1 tr=0 ts=6a18e66d cx=c_pps a=wEP8DlPgTf/vqF+yE6f9lg==:117 a=ouPCqIW2jiPt+lZRy3xVPw==:17 a=IkcTkHD0fZMA:10 a=NGcC8JguVDcA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=eoimf2acIAo5FJnRuUoq:22 a=EUspDBNiAAAA:8 a=jzRtHXlnCnXYBdHFFXcA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 a=O8hF6Hzn-FEA:10 a=bBxd6f-gb0O0v-kibOvt:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDAwNyBTYWx0ZWRfXzSa8qtzvoCl0 g1g16/SiFIItpSqK10PI8FPUICZy7zWHXJOqwFzx2ZTqEexYtOAXFPonmTOizATZzWcCmveBZwo scLfymSfODRjyyaWVo8m3RxzIWduWRN4E89xpqbDKCq+2D0+PTeUZDMUaudzwROVTewBxxLiJCj pJUT6tg7yZhFkiQpBssjO4fOU12o4OOy5b+i0rpMdLzY9kbA7tjWAs57/xvNB7I5nTjT072oMA2 Xs7t3qeadPG1OmCrkEeA3HM8WMdIFBZyQJq3EngT9d5wyo5nqQeXygnCVPrAO6/s1pvwrm4u6E5 X42rntv/eiJ5aZgJuVkQJ6ZPMmz3idQVEftdpQ0Ie0OdYhcFdemgZFMi6FSbDMHDKUzFNjHvXJY 5OGi/rfR7Pru7SJB2qH0BgCUGNwleYhnEeseOLWMuQ4wvDuqbyPBs16kftTwhF4T5p7kNRdPdQy KiVdMDFk2xTlLOuN9mA== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-28_07,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 phishscore=0 impostorscore=0 bulkscore=0 clxscore=1015 priorityscore=1501 suspectscore=0 lowpriorityscore=0 adultscore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290007 PMH0101 introduces bidirectional level shifter (BIDIR_LVL_SHIFTER) modules that provide voltage translation between 1.2 V and 1.8 V power domains for open-drain signals, such as connecting a camera sensor with 1.8 V I2C IO to a SoC I2C bus operating at 1.2 V IO. Each BIDIR_LVL_SHIFTER shares its two physical pins with a corresponding pair of GPIO modules. When used, the associated GPIOs need to keep disabled, with no GPIO function or configuration enabled. The BIDIR_LVL_SHIFTER then operates as a bidirectional open-drain voltage translator, using fixed 1.2 V and 1.8 V reference voltages on each side and relying on external board-level pull-up resistors for open-drain drive control. From a system perspective, a BIDIR_LVL_SHIFTER may be used on a serial bus shared by multiple clients managed by different subsystems. As a result, its enable control is shared and centrally managed by AOP, with each subsystem voting for the enable state via an RPMh =E2=80=9CXOB=E2= =80=9D resource. Add a new "level-shifter" function to the SPMI GPIO driver to support BIDIR_LVL_SHIFTER operation considering that BIDIR_LVL_SHIFTER shares physical pins with GPIOs, it must be mutually exclusive with all existing functions and configurations. Additionally, limit the "level-shifter" function to specific GPIO pairs that share physical pins with the BIDIR_LVL_SHIFTER module by creating pingroups and linking them to the "level-shifter" function. With this change, the BIDIR_LVL_SHIFTER could be controlled with following dtsi nodes: pmh0101-ls1-en { groups =3D "gpio11, gpio12"; function =3D "level-shifter"; qcom,1p2v-1p8v-ls-en =3D <1>; }; pmh0101-ls1-dis { groups =3D "gpio11, gpio12"; function =3D "level-shifter"; qcom,1p2v-1p8v-ls-en =3D <0>; }; Signed-off-by: Fenglin Wu --- drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 441 +++++++++++++++++++++++++--= ---- 1 file changed, 355 insertions(+), 86 deletions(-) diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qco= m/pinctrl-spmi-gpio.c index 268cfae706a8..741795ae261e 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c @@ -23,6 +23,9 @@ =20 #include =20 +#include +#include + #include "../core.h" #include "../pinmux.h" #include "../pinctrl-utils.h" @@ -118,12 +121,16 @@ /* PMIC_GPIO_REG_LV_MV_ANA_PASS_THRU_SEL */ #define PMIC_GPIO_LV_MV_ANA_MUX_SEL_MASK 0x3 =20 +/* Level shifter register offset */ +#define REG_LS_ENABLE_OFFSET 4 + /* Qualcomm specific pin configurations */ #define PMIC_GPIO_CONF_PULL_UP (PIN_CONFIG_END + 1) #define PMIC_GPIO_CONF_STRENGTH (PIN_CONFIG_END + 2) #define PMIC_GPIO_CONF_ATEST (PIN_CONFIG_END + 3) #define PMIC_GPIO_CONF_ANALOG_PASS (PIN_CONFIG_END + 4) #define PMIC_GPIO_CONF_DTEST_BUFFER (PIN_CONFIG_END + 5) +#define PMIC_GPIO_CONF_LS_ENABLE (PIN_CONFIG_END + 6) =20 /* The index of each function in pmic_gpio_functions[] array */ enum pmic_gpio_func_index { @@ -137,6 +144,7 @@ enum pmic_gpio_func_index { PMIC_GPIO_FUNC_INDEX_DTEST2, PMIC_GPIO_FUNC_INDEX_DTEST3, PMIC_GPIO_FUNC_INDEX_DTEST4, + PMIC_GPIO_FUNC_INDEX_LEVEL_SHIFTER, }; =20 /** @@ -183,25 +191,86 @@ struct pmic_gpio_state { struct regmap *map; struct pinctrl_dev *ctrl; struct gpio_chip chip; + struct device *rpmh_dev; + const char *pmic_id; u8 usid; u8 pid_base; }; =20 +/** + * struct ls_config - Level shifter configuration + * @name: Pinctrl group name (e.g., "gpio11, gpio12") + * @rpmh_prefix: RPMh resource name prefix (e.g., "LS1") + * @pins: Array of pin numbers for this level shifter pair + */ +struct ls_config { + const char *name; + const char *rpmh_prefix; + const unsigned int *pins; +}; + +/** + * struct ls_pingroup_data - Level shifter pin group data + * @config: Pointer to level shifter configuration + * @level_shifter_addr: RPMh address for level shifter control + * @ls_enabled: Shadowed enable state, updated on each successful RPMh wri= te + */ +struct ls_pingroup_data { + struct ls_config *config; + u32 level_shifter_addr; + bool ls_enabled; +}; + +/** + * struct pmic_gpio_hw_data - Hardware-specific data + * @npins: Number of GPIO pins + * @ls_config: Array of level shifter configurations + * @num_ls: Number of level shifters + */ +struct pmic_gpio_hw_data { + u32 npins; + struct ls_config *ls_config; + u32 num_ls; +}; + +/* Macro to create hardware data inline */ +#define PMIC_GPIO_HW_DATA(n, ls, num) \ + (&(const struct pmic_gpio_hw_data) { \ + .npins =3D n, \ + .ls_config =3D ls, \ + .num_ls =3D num, \ + }) + +/* Level shifter pin groups for PMH0101 */ +static const unsigned int ls1_pins[] =3D { 10, 11 }; /* GPIO11, GPIO12 */ +static const unsigned int ls2_pins[] =3D { 12, 13 }; /* GPIO13, GPIO14 */ +static const unsigned int ls3_pins[] =3D { 14, 15 }; /* GPIO15, GPIO16 */ +static const unsigned int ls4_pins[] =3D { 16, 17 }; /* GPIO17, GPIO18 */ + +static struct ls_config pmh0101_ls_configs[] =3D { + { "gpio11, gpio12", "LS1", ls1_pins }, + { "gpio13, gpio14", "LS2", ls2_pins }, + { "gpio15, gpio16", "LS3", ls3_pins }, + { "gpio17, gpio18", "LS4", ls4_pins }, +}; + static const struct pinconf_generic_params pmic_gpio_bindings[] =3D { {"qcom,pull-up-strength", PMIC_GPIO_CONF_PULL_UP, 0}, {"qcom,drive-strength", PMIC_GPIO_CONF_STRENGTH, 0}, {"qcom,atest", PMIC_GPIO_CONF_ATEST, 0}, {"qcom,analog-pass", PMIC_GPIO_CONF_ANALOG_PASS, 0}, - {"qcom,dtest-buffer", PMIC_GPIO_CONF_DTEST_BUFFER, 0}, + {"qcom,dtest-buffer", PMIC_GPIO_CONF_DTEST_BUFFER, 0}, + {"qcom,1p2v-1p8v-ls-en", PMIC_GPIO_CONF_LS_ENABLE, 0}, }; =20 #ifdef CONFIG_DEBUG_FS static const struct pin_config_item pmic_conf_items[ARRAY_SIZE(pmic_gpio_b= indings)] =3D { - PCONFDUMP(PMIC_GPIO_CONF_PULL_UP, "pull up strength", NULL, true), - PCONFDUMP(PMIC_GPIO_CONF_STRENGTH, "drive-strength", NULL, true), - PCONFDUMP(PMIC_GPIO_CONF_ATEST, "atest", NULL, true), - PCONFDUMP(PMIC_GPIO_CONF_ANALOG_PASS, "analog-pass", NULL, true), - PCONFDUMP(PMIC_GPIO_CONF_DTEST_BUFFER, "dtest-buffer", NULL, true), + PCONFDUMP(PMIC_GPIO_CONF_PULL_UP, "pull up strength", NULL, true), + PCONFDUMP(PMIC_GPIO_CONF_STRENGTH, "drive-strength", NULL, true), + PCONFDUMP(PMIC_GPIO_CONF_ATEST, "atest", NULL, true), + PCONFDUMP(PMIC_GPIO_CONF_ANALOG_PASS, "analog-pass", NULL, true), + PCONFDUMP(PMIC_GPIO_CONF_DTEST_BUFFER, "dtest-buffer", NULL, true), + PCONFDUMP(PMIC_GPIO_CONF_LS_ENABLE, "ls-enable", NULL, true), }; #endif =20 @@ -214,16 +283,16 @@ static const char *const pmic_gpio_groups[] =3D { }; =20 static const char *const pmic_gpio_functions[] =3D { - [PMIC_GPIO_FUNC_INDEX_NORMAL] =3D PMIC_GPIO_FUNC_NORMAL, - [PMIC_GPIO_FUNC_INDEX_PAIRED] =3D PMIC_GPIO_FUNC_PAIRED, - [PMIC_GPIO_FUNC_INDEX_FUNC1] =3D PMIC_GPIO_FUNC_FUNC1, - [PMIC_GPIO_FUNC_INDEX_FUNC2] =3D PMIC_GPIO_FUNC_FUNC2, - [PMIC_GPIO_FUNC_INDEX_FUNC3] =3D PMIC_GPIO_FUNC_FUNC3, - [PMIC_GPIO_FUNC_INDEX_FUNC4] =3D PMIC_GPIO_FUNC_FUNC4, - [PMIC_GPIO_FUNC_INDEX_DTEST1] =3D PMIC_GPIO_FUNC_DTEST1, - [PMIC_GPIO_FUNC_INDEX_DTEST2] =3D PMIC_GPIO_FUNC_DTEST2, - [PMIC_GPIO_FUNC_INDEX_DTEST3] =3D PMIC_GPIO_FUNC_DTEST3, - [PMIC_GPIO_FUNC_INDEX_DTEST4] =3D PMIC_GPIO_FUNC_DTEST4, + [PMIC_GPIO_FUNC_INDEX_NORMAL] =3D PMIC_GPIO_FUNC_NORMAL, + [PMIC_GPIO_FUNC_INDEX_PAIRED] =3D PMIC_GPIO_FUNC_PAIRED, + [PMIC_GPIO_FUNC_INDEX_FUNC1] =3D PMIC_GPIO_FUNC_FUNC1, + [PMIC_GPIO_FUNC_INDEX_FUNC2] =3D PMIC_GPIO_FUNC_FUNC2, + [PMIC_GPIO_FUNC_INDEX_FUNC3] =3D PMIC_GPIO_FUNC_FUNC3, + [PMIC_GPIO_FUNC_INDEX_FUNC4] =3D PMIC_GPIO_FUNC_FUNC4, + [PMIC_GPIO_FUNC_INDEX_DTEST1] =3D PMIC_GPIO_FUNC_DTEST1, + [PMIC_GPIO_FUNC_INDEX_DTEST2] =3D PMIC_GPIO_FUNC_DTEST2, + [PMIC_GPIO_FUNC_INDEX_DTEST3] =3D PMIC_GPIO_FUNC_DTEST3, + [PMIC_GPIO_FUNC_INDEX_DTEST4] =3D PMIC_GPIO_FUNC_DTEST4, }; =20 static int pmic_gpio_read(struct pmic_gpio_state *state, @@ -262,6 +331,41 @@ static const struct pinctrl_ops pmic_gpio_pinctrl_ops = =3D { .dt_free_map =3D pinctrl_utils_free_map, }; =20 +/** + * pmic_gpio_set_ls_rpmh() - Send RPMh XOB vote for a level shifter + * @state: PMIC GPIO state + * @ls_data: Level shifter pin group data + * @enable: true to enable, false to disable + * + * Return: 0 on success, negative error code on failure + */ +static int pmic_gpio_set_ls_rpmh(struct pmic_gpio_state *state, + struct ls_pingroup_data *ls_data, + bool enable) +{ + struct tcs_cmd cmd =3D { }; + int ret; + + if (!ls_data->level_shifter_addr) { + dev_err(state->dev, "Level shifter address not configured\n"); + return -EINVAL; + } + + if (!state->rpmh_dev) { + dev_err(state->dev, "RPMh device not available\n"); + return -ENODEV; + } + + cmd.addr =3D ls_data->level_shifter_addr + REG_LS_ENABLE_OFFSET; + cmd.data =3D enable ? 1 : 0; + + ret =3D rpmh_write_ctrlr(state->rpmh_dev, RPMH_ACTIVE_ONLY_STATE, &cmd, 1= ); + if (!ret) + ls_data->ls_enabled =3D enable; + + return ret; +} + static int pmic_gpio_set_mux(struct pinctrl_dev *pctldev, unsigned int fun= ction, unsigned int selector) { @@ -271,7 +375,7 @@ static int pmic_gpio_set_mux(struct pinctrl_dev *pctlde= v, unsigned int function, unsigned int val, pin, func; int ret, i; =20 - if (function > PMIC_GPIO_FUNC_INDEX_DTEST4) { + if (function > PMIC_GPIO_FUNC_INDEX_LEVEL_SHIFTER) { pr_err("function: %d is not defined\n", function); return -EINVAL; } @@ -280,6 +384,28 @@ static int pmic_gpio_set_mux(struct pinctrl_dev *pctld= ev, unsigned int function, if (!group) return -EINVAL; =20 + if (function =3D=3D PMIC_GPIO_FUNC_INDEX_LEVEL_SHIFTER) { + if (!group->data) + return -EINVAL; + + /* + * Disable both GPIO pads in the pair. The RPMh XOB vote is + * sent separately via the qcom,1p2v-1p8v-ls-en pinconf parameter. + */ + for (i =3D 0; i < group->grp.npins; i++) { + pin =3D group->grp.pins[i]; + pad =3D pctldev->desc->pins[pin].drv_data; + + ret =3D pmic_gpio_write(state, pad, PMIC_GPIO_REG_EN_CTL, 0); + if (ret < 0) + return ret; + + pad->is_enabled =3D false; + pad->function =3D PMIC_GPIO_FUNC_INDEX_LEVEL_SHIFTER; + } + return 0; + } + /* For standard functions, iterate over all pins in the group */ for (i =3D 0; i < group->grp.npins; i++) { pin =3D group->grp.pins[i]; @@ -513,7 +639,8 @@ static int pmic_gpio_pinconf_pin_set(struct pinctrl_dev= *pctldev, =20 pad =3D pctldev->desc->pins[pin].drv_data; =20 - pad->is_enabled =3D true; + if (pad->function !=3D PMIC_GPIO_FUNC_INDEX_LEVEL_SHIFTER) + pad->is_enabled =3D true; for (i =3D 0; i < nconfs; i++) { param =3D pinconf_to_config_param(configs[i]); arg =3D pinconf_to_config_argument(configs[i]); @@ -597,6 +724,9 @@ static int pmic_gpio_pinconf_pin_set(struct pinctrl_dev= *pctldev, return -EINVAL; pad->dtest_buffer =3D arg; break; + case PMIC_GPIO_CONF_LS_ENABLE: + /* Group-level only; handled in pmic_gpio_pinconf_group_set */ + break; default: return -EINVAL; } @@ -690,13 +820,14 @@ static int pmic_gpio_pinconf_pin_set(struct pinctrl_d= ev *pctldev, * @configs: Array of configuration parameters * @nconfs: Number of configurations * - * Iterates over all pins in the group and applies config to each. + * Handles group-level parameters (e.g., LS enable) before iterating per-p= in. */ static int pmic_gpio_pinconf_group_set(struct pinctrl_dev *pctldev, unsigned int selector, unsigned long *configs, unsigned int nconfs) { + struct pmic_gpio_state *state =3D pinctrl_dev_get_drvdata(pctldev); const struct group_desc *group; unsigned int pin; int i, ret; @@ -705,7 +836,25 @@ static int pmic_gpio_pinconf_group_set(struct pinctrl_= dev *pctldev, if (!group) return -EINVAL; =20 - /* Iterate over all pins in the group and apply config to each */ + /* Handle group-level LS_ENABLE before iterating per-pin configs */ + for (i =3D 0; i < nconfs; i++) { + if (pinconf_to_config_param(configs[i]) !=3D PMIC_GPIO_CONF_LS_ENABLE) + continue; + + if (!group->data) { + dev_err(state->dev, + "qcom,1p2v-1p8v-ls-en is only valid for level-shifter groups\n"); + return -EINVAL; + } + + ret =3D pmic_gpio_set_ls_rpmh(state, + (struct ls_pingroup_data *)group->data, + !!pinconf_to_config_argument(configs[i])); + if (ret < 0) + return ret; + } + + /* Apply per-pin configs to each pin in the group */ for (i =3D 0; i < group->grp.npins; i++) { pin =3D group->grp.pins[i]; =20 @@ -794,8 +943,8 @@ static void pmic_gpio_pinconf_pin_dbg_show(struct pinct= rl_dev *pctldev, * @s: seq_file for output * @selector: Group selector * - * Shows the configuration for all pins in a group. - * Used by the pinconf-groups debugfs interface. + * Shows the configuration for all pins in a group. For level-shifter grou= ps, + * also prints the RPMh address as a preamble. */ static void pmic_gpio_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, @@ -809,6 +958,14 @@ static void pmic_gpio_pinconf_group_dbg_show(struct pi= nctrl_dev *pctldev, if (!group) return; =20 + /* For level-shifter groups, print the enable status as preamble */ + if (group->data) { + const struct ls_pingroup_data *ls_data =3D group->data; + + seq_printf(s, ", level-shifter (%s)\n ", + ls_data->ls_enabled ? "enabled" : "disabled"); + } + /* Iterate over all pins in the group and show status for each */ for (i =3D 0; i < group->grp.npins; i++) { pin =3D group->grp.pins[i]; @@ -1177,6 +1334,102 @@ static const struct irq_chip spmi_gpio_irq_chip =3D= { GPIOCHIP_IRQ_RESOURCE_HELPERS, }; =20 +/** + * pmic_gpio_register_level_shifters() - Register level-shifter groups and= function + * @state: PMIC GPIO state + * @hw_data: Hardware-specific data containing level-shifter configurations + * + * This function registers level-shifter support by: + * 1. Getting RPMh device reference and PMIC ID from device tree + * 2. Registering each level-shifter pair as a multi-pin group + * 3. Getting RPMh addresses from cmd_db for each level-shifter + * 4. Registering the level-shifter function once with all valid groups + * + * Return: 0 on success, negative error code on failure + */ +static int pmic_gpio_register_level_shifters(struct pmic_gpio_state *state, + const struct pmic_gpio_hw_data *hw_data) +{ + struct device *dev =3D state->dev; + const char **ls_group_names; + int ret, i; + + /* Get RPMh device reference for level shifter control */ + state->rpmh_dev =3D rpmh_get_ctrlr_dev(dev); + if (IS_ERR(state->rpmh_dev)) + return dev_err_probe(dev, PTR_ERR(state->rpmh_dev), + "Level shifter needs rpmh device\n"); + + /* Get PMIC ID from device tree for RPMh resource name composition */ + ret =3D of_property_read_string(dev->of_node, "qcom,pmic-id", + &state->pmic_id); + if (ret) + return dev_err_probe(dev, ret, + "get qcom,pmic-id failed for rpmh resource\n"); + + /* Allocate array to hold all level-shifter group names */ + ls_group_names =3D devm_kcalloc(dev, hw_data->num_ls, + sizeof(*ls_group_names), GFP_KERNEL); + if (!ls_group_names) + return -ENOMEM; + + /* Register each level-shifter pair as a multi-pin group */ + for (i =3D 0; i < hw_data->num_ls; i++) { + struct ls_config *ls =3D &hw_data->ls_config[i]; + struct ls_pingroup_data *ls_group_data; + char rpmh_resource_name[32]; + + /* Allocate ls_pingroup_data for this level shifter */ + ls_group_data =3D devm_kzalloc(dev, sizeof(*ls_group_data), + GFP_KERNEL); + if (!ls_group_data) + return -ENOMEM; + + ls_group_data->config =3D ls; + + /* Compose RPMh resource name and get address from cmd_db */ + if (state->pmic_id && ls->rpmh_prefix) { + int ret_ready =3D cmd_db_ready(); + + if (ret_ready) + return dev_err_probe(dev, ret_ready, + "Command DB not available\n"); + + snprintf(rpmh_resource_name, + sizeof(rpmh_resource_name), + "%s%s", ls->rpmh_prefix, state->pmic_id); + ls_group_data->level_shifter_addr =3D + cmd_db_read_addr(rpmh_resource_name); + if (!ls_group_data->level_shifter_addr) + return dev_err_probe(dev, -ENODEV, + "RPMh resource %s not found in cmd_db\n", + rpmh_resource_name); + } + + /* Store group name for function registration */ + ls_group_names[i] =3D ls->name; + + /* Register the multi-pin group using the level-shifter name */ + ret =3D pinctrl_generic_add_group(state->ctrl, ls->name, + ls->pins, 2, ls_group_data); + if (ret < 0) + return dev_err_probe(dev, ret, + "Failed to register level-shifter group %s\n", + ls->name); + } + + /* Register level-shifter function once with all valid groups */ + ret =3D pinmux_generic_add_function(state->ctrl, + PMIC_GPIO_FUNC_LEVEL_SHIFTER, + ls_group_names, hw_data->num_ls, + NULL); + if (ret < 0) + return dev_err_probe(dev, ret, + "Failed to register level-shifter function\n"); + + return 0; +} + static int pmic_gpio_probe(struct platform_device *pdev) { struct irq_domain *parent_domain; @@ -1188,6 +1441,7 @@ static int pmic_gpio_probe(struct platform_device *pd= ev) struct pmic_gpio_state *state; struct gpio_irq_chip *girq; const struct spmi_device *parent_spmi_dev; + const struct pmic_gpio_hw_data *hw_data; int ret, npins, i; u32 reg; =20 @@ -1197,7 +1451,13 @@ static int pmic_gpio_probe(struct platform_device *p= dev) return ret; } =20 - npins =3D (uintptr_t) device_get_match_data(&pdev->dev); + hw_data =3D device_get_match_data(&pdev->dev); + if (!hw_data) { + dev_err(dev, "no match data found\n"); + return -EINVAL; + } + + npins =3D hw_data->npins; =20 state =3D devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); if (!state) @@ -1285,6 +1545,15 @@ static int pmic_gpio_probe(struct platform_device *p= dev) } } =20 + /* Register level-shifter groups and function if hardware and DT both opt= in */ + if (hw_data->ls_config && hw_data->num_ls && + of_property_present(dev->of_node, "qcom,rpmh") && + of_property_present(dev->of_node, "qcom,pmic-id")) { + ret =3D pmic_gpio_register_level_shifters(state, hw_data); + if (ret < 0) + return ret; + } + parent_node =3D of_irq_find_parent(state->dev->of_node); if (!parent_node) return -ENXIO; @@ -1349,80 +1618,80 @@ static void pmic_gpio_remove(struct platform_device= *pdev) } =20 static const struct of_device_id pmic_gpio_of_match[] =3D { - { .compatible =3D "qcom,pm2250-gpio", .data =3D (void *) 10 }, + { .compatible =3D "qcom,pm2250-gpio", .data =3D PMIC_GPIO_HW_DATA(10, NUL= L, 0) }, /* pm660 has 13 GPIOs with holes on 1, 5, 6, 7, 8 and 10 */ - { .compatible =3D "qcom,pm660-gpio", .data =3D (void *) 13 }, + { .compatible =3D "qcom,pm660-gpio", .data =3D PMIC_GPIO_HW_DATA(13, NULL= , 0) }, /* pm660l has 12 GPIOs with holes on 1, 2, 10, 11 and 12 */ - { .compatible =3D "qcom,pm660l-gpio", .data =3D (void *) 12 }, - { .compatible =3D "qcom,pm6125-gpio", .data =3D (void *) 9 }, - { .compatible =3D "qcom,pm6150-gpio", .data =3D (void *) 10 }, - { .compatible =3D "qcom,pm6150l-gpio", .data =3D (void *) 12 }, - { .compatible =3D "qcom,pm6350-gpio", .data =3D (void *) 9 }, - { .compatible =3D "qcom,pm6450-gpio", .data =3D (void *) 9 }, - { .compatible =3D "qcom,pm7250b-gpio", .data =3D (void *) 12 }, - { .compatible =3D "qcom,pm7325-gpio", .data =3D (void *) 10 }, - { .compatible =3D "qcom,pm7550-gpio", .data =3D (void *) 12 }, - { .compatible =3D "qcom,pm7550ba-gpio", .data =3D (void *) 8}, - { .compatible =3D "qcom,pm8005-gpio", .data =3D (void *) 4 }, - { .compatible =3D "qcom,pm8010-gpio", .data =3D (void *) 2 }, - { .compatible =3D "qcom,pm8019-gpio", .data =3D (void *) 6 }, + { .compatible =3D "qcom,pm660l-gpio", .data =3D PMIC_GPIO_HW_DATA(12, NUL= L, 0) }, + { .compatible =3D "qcom,pm6125-gpio", .data =3D PMIC_GPIO_HW_DATA(9, NULL= , 0) }, + { .compatible =3D "qcom,pm6150-gpio", .data =3D PMIC_GPIO_HW_DATA(10, NUL= L, 0) }, + { .compatible =3D "qcom,pm6150l-gpio", .data =3D PMIC_GPIO_HW_DATA(12, NU= LL, 0) }, + { .compatible =3D "qcom,pm6350-gpio", .data =3D PMIC_GPIO_HW_DATA(9, NULL= , 0) }, + { .compatible =3D "qcom,pm6450-gpio", .data =3D PMIC_GPIO_HW_DATA(9, NULL= , 0) }, + { .compatible =3D "qcom,pm7250b-gpio", .data =3D PMIC_GPIO_HW_DATA(12, NU= LL, 0) }, + { .compatible =3D "qcom,pm7325-gpio", .data =3D PMIC_GPIO_HW_DATA(10, NUL= L, 0) }, + { .compatible =3D "qcom,pm7550-gpio", .data =3D PMIC_GPIO_HW_DATA(12, NUL= L, 0) }, + { .compatible =3D "qcom,pm7550ba-gpio", .data =3D PMIC_GPIO_HW_DATA(8, NU= LL, 0) }, + { .compatible =3D "qcom,pm8005-gpio", .data =3D PMIC_GPIO_HW_DATA(4, NULL= , 0) }, + { .compatible =3D "qcom,pm8010-gpio", .data =3D PMIC_GPIO_HW_DATA(2, NULL= , 0) }, + { .compatible =3D "qcom,pm8019-gpio", .data =3D PMIC_GPIO_HW_DATA(6, NULL= , 0) }, /* pm8150 has 10 GPIOs with holes on 2, 5, 7 and 8 */ - { .compatible =3D "qcom,pm8150-gpio", .data =3D (void *) 10 }, - { .compatible =3D "qcom,pmc8180-gpio", .data =3D (void *) 10 }, + { .compatible =3D "qcom,pm8150-gpio", .data =3D PMIC_GPIO_HW_DATA(10, NUL= L, 0) }, + { .compatible =3D "qcom,pmc8180-gpio", .data =3D PMIC_GPIO_HW_DATA(10, NU= LL, 0) }, /* pm8150b has 12 GPIOs with holes on 3, r and 7 */ - { .compatible =3D "qcom,pm8150b-gpio", .data =3D (void *) 12 }, + { .compatible =3D "qcom,pm8150b-gpio", .data =3D PMIC_GPIO_HW_DATA(12, NU= LL, 0) }, /* pm8150l has 12 GPIOs with holes on 7 */ - { .compatible =3D "qcom,pm8150l-gpio", .data =3D (void *) 12 }, - { .compatible =3D "qcom,pmc8180c-gpio", .data =3D (void *) 12 }, - { .compatible =3D "qcom,pm8226-gpio", .data =3D (void *) 8 }, - { .compatible =3D "qcom,pm8350-gpio", .data =3D (void *) 10 }, - { .compatible =3D "qcom,pm8350b-gpio", .data =3D (void *) 8 }, - { .compatible =3D "qcom,pm8350c-gpio", .data =3D (void *) 9 }, - { .compatible =3D "qcom,pm8450-gpio", .data =3D (void *) 4 }, - { .compatible =3D "qcom,pm8550-gpio", .data =3D (void *) 12 }, - { .compatible =3D "qcom,pm8550b-gpio", .data =3D (void *) 12 }, - { .compatible =3D "qcom,pm8550ve-gpio", .data =3D (void *) 8 }, - { .compatible =3D "qcom,pm8550vs-gpio", .data =3D (void *) 6 }, - { .compatible =3D "qcom,pm8916-gpio", .data =3D (void *) 4 }, + { .compatible =3D "qcom,pm8150l-gpio", .data =3D PMIC_GPIO_HW_DATA(12, NU= LL, 0) }, + { .compatible =3D "qcom,pmc8180c-gpio", .data =3D PMIC_GPIO_HW_DATA(12, N= ULL, 0) }, + { .compatible =3D "qcom,pm8226-gpio", .data =3D PMIC_GPIO_HW_DATA(8, NULL= , 0) }, + { .compatible =3D "qcom,pm8350-gpio", .data =3D PMIC_GPIO_HW_DATA(10, NUL= L, 0) }, + { .compatible =3D "qcom,pm8350b-gpio", .data =3D PMIC_GPIO_HW_DATA(8, NUL= L, 0) }, + { .compatible =3D "qcom,pm8350c-gpio", .data =3D PMIC_GPIO_HW_DATA(9, NUL= L, 0) }, + { .compatible =3D "qcom,pm8450-gpio", .data =3D PMIC_GPIO_HW_DATA(4, NULL= , 0) }, + { .compatible =3D "qcom,pm8550-gpio", .data =3D PMIC_GPIO_HW_DATA(12, NUL= L, 0) }, + { .compatible =3D "qcom,pm8550b-gpio", .data =3D PMIC_GPIO_HW_DATA(12, NU= LL, 0) }, + { .compatible =3D "qcom,pm8550ve-gpio", .data =3D PMIC_GPIO_HW_DATA(8, NU= LL, 0) }, + { .compatible =3D "qcom,pm8550vs-gpio", .data =3D PMIC_GPIO_HW_DATA(6, NU= LL, 0) }, + { .compatible =3D "qcom,pm8916-gpio", .data =3D PMIC_GPIO_HW_DATA(4, NULL= , 0) }, /* pm8937 has 8 GPIOs with holes on 3, 4 and 6 */ - { .compatible =3D "qcom,pm8937-gpio", .data =3D (void *) 8 }, - { .compatible =3D "qcom,pm8941-gpio", .data =3D (void *) 36 }, + { .compatible =3D "qcom,pm8937-gpio", .data =3D PMIC_GPIO_HW_DATA(8, NULL= , 0) }, + { .compatible =3D "qcom,pm8941-gpio", .data =3D PMIC_GPIO_HW_DATA(36, NUL= L, 0) }, /* pm8950 has 8 GPIOs with holes on 3 */ - { .compatible =3D "qcom,pm8950-gpio", .data =3D (void *) 8 }, + { .compatible =3D "qcom,pm8950-gpio", .data =3D PMIC_GPIO_HW_DATA(8, NULL= , 0) }, /* pm8953 has 8 GPIOs with holes on 3 and 6 */ - { .compatible =3D "qcom,pm8953-gpio", .data =3D (void *) 8 }, - { .compatible =3D "qcom,pm8994-gpio", .data =3D (void *) 22 }, - { .compatible =3D "qcom,pm8998-gpio", .data =3D (void *) 26 }, - { .compatible =3D "qcom,pma8084-gpio", .data =3D (void *) 22 }, - { .compatible =3D "qcom,pmc8380-gpio", .data =3D (void *) 10 }, - { .compatible =3D "qcom,pmcx0102-gpio", .data =3D (void *)14 }, - { .compatible =3D "qcom,pmd8028-gpio", .data =3D (void *) 4 }, - { .compatible =3D "qcom,pmh0101-gpio", .data =3D (void *)18 }, - { .compatible =3D "qcom,pmh0104-gpio", .data =3D (void *)8 }, - { .compatible =3D "qcom,pmh0110-gpio", .data =3D (void *)14 }, - { .compatible =3D "qcom,pmi632-gpio", .data =3D (void *) 8 }, - { .compatible =3D "qcom,pmi8950-gpio", .data =3D (void *) 2 }, - { .compatible =3D "qcom,pmi8994-gpio", .data =3D (void *) 10 }, - { .compatible =3D "qcom,pmi8998-gpio", .data =3D (void *) 14 }, - { .compatible =3D "qcom,pmih0108-gpio", .data =3D (void *) 18 }, - { .compatible =3D "qcom,pmiv0104-gpio", .data =3D (void *) 10 }, - { .compatible =3D "qcom,pmk8350-gpio", .data =3D (void *) 4 }, - { .compatible =3D "qcom,pmk8550-gpio", .data =3D (void *) 6 }, - { .compatible =3D "qcom,pmk8850-gpio", .data =3D (void *)8 }, - { .compatible =3D "qcom,pmm8155au-gpio", .data =3D (void *) 10 }, - { .compatible =3D "qcom,pmm8654au-gpio", .data =3D (void *) 12 }, + { .compatible =3D "qcom,pm8953-gpio", .data =3D PMIC_GPIO_HW_DATA(8, NULL= , 0) }, + { .compatible =3D "qcom,pm8994-gpio", .data =3D PMIC_GPIO_HW_DATA(22, NUL= L, 0) }, + { .compatible =3D "qcom,pm8998-gpio", .data =3D PMIC_GPIO_HW_DATA(26, NUL= L, 0) }, + { .compatible =3D "qcom,pma8084-gpio", .data =3D PMIC_GPIO_HW_DATA(22, NU= LL, 0) }, + { .compatible =3D "qcom,pmc8380-gpio", .data =3D PMIC_GPIO_HW_DATA(10, NU= LL, 0) }, + { .compatible =3D "qcom,pmcx0102-gpio", .data =3D PMIC_GPIO_HW_DATA(14, N= ULL, 0) }, + { .compatible =3D "qcom,pmd8028-gpio", .data =3D PMIC_GPIO_HW_DATA(4, NUL= L, 0) }, + { .compatible =3D "qcom,pmh0101-gpio", .data =3D PMIC_GPIO_HW_DATA(18, pm= h0101_ls_configs, 4) }, + { .compatible =3D "qcom,pmh0104-gpio", .data =3D PMIC_GPIO_HW_DATA(8, NUL= L, 0) }, + { .compatible =3D "qcom,pmh0110-gpio", .data =3D PMIC_GPIO_HW_DATA(14, NU= LL, 0) }, + { .compatible =3D "qcom,pmi632-gpio", .data =3D PMIC_GPIO_HW_DATA(8, NULL= , 0) }, + { .compatible =3D "qcom,pmi8950-gpio", .data =3D PMIC_GPIO_HW_DATA(2, NUL= L, 0) }, + { .compatible =3D "qcom,pmi8994-gpio", .data =3D PMIC_GPIO_HW_DATA(10, NU= LL, 0) }, + { .compatible =3D "qcom,pmi8998-gpio", .data =3D PMIC_GPIO_HW_DATA(14, NU= LL, 0) }, + { .compatible =3D "qcom,pmih0108-gpio", .data =3D PMIC_GPIO_HW_DATA(18, N= ULL, 0) }, + { .compatible =3D "qcom,pmiv0104-gpio", .data =3D PMIC_GPIO_HW_DATA(10, N= ULL, 0) }, + { .compatible =3D "qcom,pmk8350-gpio", .data =3D PMIC_GPIO_HW_DATA(4, NUL= L, 0) }, + { .compatible =3D "qcom,pmk8550-gpio", .data =3D PMIC_GPIO_HW_DATA(6, NUL= L, 0) }, + { .compatible =3D "qcom,pmk8850-gpio", .data =3D PMIC_GPIO_HW_DATA(8, NUL= L, 0) }, + { .compatible =3D "qcom,pmm8155au-gpio", .data =3D PMIC_GPIO_HW_DATA(10, = NULL, 0) }, + { .compatible =3D "qcom,pmm8654au-gpio", .data =3D PMIC_GPIO_HW_DATA(12, = NULL, 0) }, /* pmp8074 has 12 GPIOs with holes on 1 and 12 */ - { .compatible =3D "qcom,pmp8074-gpio", .data =3D (void *) 12 }, - { .compatible =3D "qcom,pmr735a-gpio", .data =3D (void *) 4 }, - { .compatible =3D "qcom,pmr735b-gpio", .data =3D (void *) 4 }, - { .compatible =3D "qcom,pmr735d-gpio", .data =3D (void *) 2 }, + { .compatible =3D "qcom,pmp8074-gpio", .data =3D PMIC_GPIO_HW_DATA(12, NU= LL, 0) }, + { .compatible =3D "qcom,pmr735a-gpio", .data =3D PMIC_GPIO_HW_DATA(4, NUL= L, 0) }, + { .compatible =3D "qcom,pmr735b-gpio", .data =3D PMIC_GPIO_HW_DATA(4, NUL= L, 0) }, + { .compatible =3D "qcom,pmr735d-gpio", .data =3D PMIC_GPIO_HW_DATA(2, NUL= L, 0) }, /* pms405 has 12 GPIOs with holes on 1, 9, and 10 */ - { .compatible =3D "qcom,pms405-gpio", .data =3D (void *) 12 }, + { .compatible =3D "qcom,pms405-gpio", .data =3D PMIC_GPIO_HW_DATA(12, NUL= L, 0) }, /* pmx55 has 11 GPIOs with holes on 3, 7, 10, 11 */ - { .compatible =3D "qcom,pmx55-gpio", .data =3D (void *) 11 }, - { .compatible =3D "qcom,pmx65-gpio", .data =3D (void *) 16 }, - { .compatible =3D "qcom,pmx75-gpio", .data =3D (void *) 16 }, - { .compatible =3D "qcom,pmxr2230-gpio", .data =3D (void *) 12 }, + { .compatible =3D "qcom,pmx55-gpio", .data =3D PMIC_GPIO_HW_DATA(11, NULL= , 0) }, + { .compatible =3D "qcom,pmx65-gpio", .data =3D PMIC_GPIO_HW_DATA(16, NULL= , 0) }, + { .compatible =3D "qcom,pmx75-gpio", .data =3D PMIC_GPIO_HW_DATA(16, NULL= , 0) }, + { .compatible =3D "qcom,pmxr2230-gpio", .data =3D PMIC_GPIO_HW_DATA(12, N= ULL, 0) }, { }, }; =20 --=20 2.43.0