From nobody Mon Jun 8 18:57:49 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 492E228466C for ; Wed, 27 May 2026 09:23:27 +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=1779873811; cv=none; b=W33+zh6tWXKpVL5SP24rjaZY0oGy7Sr7op8yIQUaqlfEc3s2n2YBrRk38IwH218UyLoJiUVd7NwDqnghTg+ElUK+55R71NYl1kIQALU0BDVElysJNQCHrQzS+QH4U4a0WifLKtcK7QwOVV2ADcbHNiHloQV42GuIwj+WXxRXti0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779873811; c=relaxed/simple; bh=bZXXxGK8ZOTfj0Acs1hXgVfv7uykaSOJk7ng2/VKxlc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Lx/WZMYHyN9F5zTmEk2EeOaEsFcqVJBk5jhJgretXEH8+nUm932fo80v/cO5vHW6cWcio1uvO2D+qPYzMQ5qHDO56WREKKmsDMcYrKoZzRj+rin/DkGFE/t+KUcMq+USWyaDGH1cevysurzgAOXjTp3bh3DsXIzfKnwp9HxRXVI= 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=A5tAZpgs; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=VEFlOR8K; 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="A5tAZpgs"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="VEFlOR8K" 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 64R8mhnG1168558 for ; Wed, 27 May 2026 09:23:26 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= ObWm1baL1QFt6fMABPrl+AGn01z1W07BBOFckHaRfGA=; b=A5tAZpgs/iEspIed JAChTQKZYZqnLBb6nXqAc8CAoKCGUKH3LoW86TGVImwXzJ9dziAjrTqPsGVS2Gch oGT+TtJ8sejFQLWQLk+Uhlv54vY0iw5Nyo6aHU9Tf/3Rzj8/daRh7Vk9wfSJeQRW S78UQTpDejEulaQB5EYO02Qpho0Z9+Brfdrluj6pD7sSgqVx73EARkEbu6qqDwcb gBUbolKq5B+JM29bGymKO+LvoOX0H4EPTo0V+hLZmZ1YIqdpkGzCIcs9qeAgCB7Y PUWXptKmRObMUxi96Eua3nbiQsU1uvL3fURAiWtRaa5g4NkHHroyPWHIQc0/CmMt cg60Kg== 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 4edfqk30fh-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Wed, 27 May 2026 09:23:26 +0000 (GMT) Received: by mail-dy1-f197.google.com with SMTP id 5a478bee46e88-304bbf2423cso405850eec.0 for ; Wed, 27 May 2026 02:23:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1779873805; x=1780478605; 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=ObWm1baL1QFt6fMABPrl+AGn01z1W07BBOFckHaRfGA=; b=VEFlOR8KtcOP5dMtbTr7KDc2JSRxez8TR2QuIibNJvYWxxjK183L0xAbjC/ohDAzEh crKoD0UMmbAbFYbbcv2BNQbHnqMLGOVDuPOp7d8nc32MunQ0AbvrXu2hSirBLC5klb1I w0cFufxFoII7CU4LQhIuYnmlXI6v1tLwGnHjbAKYfy0J17tVmP2A8icfiAsV32BE8pmt pIROdeTxHcZCaT+kPSnTdO6Z6iW4DwlQ1C5z5y/rajqe1+RWfbT4buiYN0mZJ4OWMHST jV5or+kaNAjU6Mwb4rloAO9jaRN48AMfqr01NrM7kEw0nIfUw8dyuJSdUK8jiUA3A+gF JzJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779873805; x=1780478605; 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=ObWm1baL1QFt6fMABPrl+AGn01z1W07BBOFckHaRfGA=; b=jz6iYTpVylcyTTvWVOJM0C2aF8jTLWn2ZxO9fXjsVvMk0eWc+IQRgZnbXzIqdXoTbq j1Y6x+fHHUbFEmBvqAy1+zZXZXmznjKj6o1HvH31UYJ4/I4iMnfQMCatwyaz9dNH3EM7 zfRAqctC8E9r8vp6kkITBAwapROiUizDr5gCYiUvwQgnoUUFwgC2zfi2/GYVDQAPL3R1 SVUEXYm574GCDAdwoHuUkMQtKzLT1Q28EDT+5gCt3/mmxzxpevL+wUDhhLJH80z1sn4d MhlT8A0zcJsGU+OO/JWNmia3yD99ls9Fd8IgzpWFWvjxIRJ8d8qJnq634Xy5tjXN4edE Gu8Q== X-Forwarded-Encrypted: i=1; AFNElJ8bBtk6fydMOWU49ixIWUA9pVyDaNk7eGn6qHgW2mgJwXXElcPCPFkSs5R3UMAEFKywTtTL0G4VJJsiCDg=@vger.kernel.org X-Gm-Message-State: AOJu0Yy7M1FWt2ucpHJsflhs0DkUsh4ode3n7zQsGliscsYhf+IaIHmE vVVxGwDt4VUWhwVMtPxZND6KtJidr44375a9xNue2rR6rclx/Eyvb7cxE38HQYlGMm9plVzqyXh 1ygfH98H3pFW3Fog8YaB1dQ/WqQPpmY7ZmeOJ52KbZPk01adMr6//Cv5AMWhY9rJpDA8= X-Gm-Gg: Acq92OFzX5QKv+7RJjseQjdGhdTyWMYpEY7oUnS4iOsxUF+c+p1MsgGzcVoKNBkJJyL QKQDMnpiFyYaJ0ojkioywixdut+NLcjHJEk78zgBYcEtT60ZvdxALy3yzwir6+UDfuo+diz1/rZ QbENUP3IJD/A9jdKdyvzRl4d15xSTJsFcJUDad++6enYET5R5ozfhubkwWZGjtjEpfQemw0Mfhk GfKN6QPD6vCTFqc6RqgM1cS+bYPRlM756UXwAHEl8GuUbXtq2FrbNSp0XKYEkAMT9yLx4XF97cF HIqvQ6NKFb0vXfBEtq96dXJ+auK3qdb9nvQAjcnTqPfxdmGljLI5NwRL6n1alo2BD3J+UNLOYha +u9xBSv2vbedwqM24KczzjL8maPWNZ1tLa3qtdaJkVJeMQKwAnhQxDAley3Reh4gBuOhzF+MgF0 /x//v6XHPf X-Received: by 2002:a05:7300:80d6:b0:2da:1874:f3bb with SMTP id 5a478bee46e88-304491d0badmr10433526eec.23.1779873805183; Wed, 27 May 2026 02:23:25 -0700 (PDT) X-Received: by 2002:a05:7300:80d6:b0:2da:1874:f3bb with SMTP id 5a478bee46e88-304491d0badmr10433516eec.23.1779873804600; Wed, 27 May 2026 02:23:24 -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-30451ef4afdsm12598732eec.5.2026.05.27.02.23.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 27 May 2026 02:23:24 -0700 (PDT) From: Fenglin Wu Date: Wed, 27 May 2026 02:22:44 -0700 Subject: [PATCH 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: <20260527-pinctrl-level-shifter-v1-1-1965461d0a7c@oss.qualcomm.com> References: <20260527-pinctrl-level-shifter-v1-0-1965461d0a7c@oss.qualcomm.com> In-Reply-To: <20260527-pinctrl-level-shifter-v1-0-1965461d0a7c@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=1779873801; l=8940; i=fenglin.wu@oss.qualcomm.com; s=20260324; h=from:subject:message-id; bh=bZXXxGK8ZOTfj0Acs1hXgVfv7uykaSOJk7ng2/VKxlc=; b=JIIMAMWdD6M8aF1L8hWlPDL5MrWpnon6g7Uw0IeR0mHCVMMF+KEth55s7+BsmN7Pjx+YylSCe gC9KvgyYxw8C0JCIMXphBDXwDC5HXKLg+EiZYDzsllo8bRNG2YvimJa X-Developer-Key: i=fenglin.wu@oss.qualcomm.com; a=ed25519; pk=hJdt3E7o54lql+miD2GaxwF74cDyhgNwMbmFOZ46bRU= X-Authority-Analysis: v=2.4 cv=fqPsol4f c=1 sm=1 tr=0 ts=6a16b80e 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=DJpcGTmdVt4CTyJn9g5Z:22 a=EUspDBNiAAAA:8 a=3W70XLUb-i4rQMzVbXEA:9 a=QEXdDO2ut3YA:10 a=PxkB5W3o20Ba91AHUih5:22 X-Proofpoint-ORIG-GUID: C9Sfu6ZnmwDksGdLVeTyPOwyNzCO1IT1 X-Proofpoint-GUID: C9Sfu6ZnmwDksGdLVeTyPOwyNzCO1IT1 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI3MDA5MCBTYWx0ZWRfXxQ99lPTIR7MJ U4BIamHEEsWin0bapz8un6Sef4Znzjk/K6Ao/ho+uv+KUZ0iaV3Odzw1fTz86C8WpgHkSqviAnP 285O3/uMTCn1DAZZoU/lz45cHaUwSZoW9+gDjHj8hxx0A5W0L4DvGLoTyO2UCNNTL96A4QtWAiB 6hMrf4+g48WwWSa5Siu5dDezywoAK45/knSm3V0ASpjw8Nhu+Y5x+KshURivx+fZOJc1O7i/YTj Ju98U1iixhOeeoo6ygp7GIfQY5tQrsLvE3tZsOjab8oVgHhk1ND6vTNSsJdKWjmvfCBO7sWJkqz v/VcSz4etxbMWXZqOg/uKx87v3mt7r01BWXWU2HKjkoShhrqzaAt6EJh7DHcLb5lH5qwQTFIDL4 pYTCjjH1a3RyvSt7AQ75J6L/zOlEa018wp+J4TZMjJMe1vEiqEFhu8+BB64Zx6V9fUKHjbRbeJI TesKQomD36Qt0dWW8WQ== 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-27_01,2026-05-26_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 malwarescore=0 lowpriorityscore=0 suspectscore=0 priorityscore=1501 phishscore=0 spamscore=0 adultscore=0 impostorscore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605130000 definitions=main-2605270090 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 | 161 +++++++++++++++++++++++++++++++++++++++++++-= ---- include/soc/qcom/rpmh.h | 21 +++++++ 2 files changed, 167 insertions(+), 15 deletions(-) diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c index ca37da3dc2b1..9c7844434e9a 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,114 @@ int rpmh_write(const struct device *dev, enum rpmh_st= ate state, } EXPORT_SYMBOL_GPL(rpmh_write); =20 +/** + * 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; + 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); + + ret =3D devm_add_action_or_reset(dev, (void (*)(void *))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 18:57:49 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 ABCF03E9F9A for ; Wed, 27 May 2026 09:23:28 +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=1779873813; cv=none; b=R8Ec6XrgsUJfq3KDVRd+Zderuq4c8OPDhDdAIMtMpF/bRF7q3yfSe7hHanVWjdvRsRgXiHgUN3gWwt0ADusfzdUoAjugl4kpF8gb4yg5aSH+rjyWGkopFYu8YsLw3t85dNbmHdM6Us/mKccak/2kUCThATQh5/O229D6Cs6YxpE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779873813; c=relaxed/simple; bh=zzUV0jy6gFznLS/8IxgTuw9hcE+Kof+0IvFnyhhZ+74=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=YHBkRpZfC3x13Zl+usXfOcAamPyWmvBIW8YTw7IyDOUBPwQ3dOfLEzA1qV6Tuedp24zS7JqnFrjtuvqtyqi1HgZhu/p631U8Et+/3ZQsKDWrWX9qqdvFHp4+Q6CV+7+CWF69MZZsLUeb9jOqsbQGLy3jlLuuEf4wdvW8Y0HDq2U= 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=D/Ezx8zy; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=jm9nNa+u; 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="D/Ezx8zy"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="jm9nNa+u" Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64R8mfow051629 for ; Wed, 27 May 2026 09:23:27 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= yH718uLubEk87H++cFbixr/BktM2LwHrJfhtUjmE6/Y=; b=D/Ezx8zyQksA+gAz V8Ghh6KCdjVozZVAN8nR4wKjP7ynwuEAUWRCw8lTrWhCA++qdRZCzxPGyOrNzyPW H2GwoTasnHFGkVInV1MUJTUOAwpGKuaD3ayVXVWLXFgz7yxM6CiU2KOmKaaId4yQ zlqEhr9mRvDkVzq+UwRDxX87aEhebzW/1KNLbMWJ4by+4Zu0Yaj8Do0odgq4g3AR EQqv+k1LkQWgtCMBN9I5QeyCRT3GEzL1LF2JmAe328EIdsoBp4Fif3eBvyhCh6C0 rgv58GlpSrRpPAvnNedCugxZLdde9MXaehsWxVvXJYK8UQ0Can0w03T9GafbDI3F thumVw== Received: from mail-dy1-f200.google.com (mail-dy1-f200.google.com [74.125.82.200]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4edg5pauwu-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Wed, 27 May 2026 09:23:26 +0000 (GMT) Received: by mail-dy1-f200.google.com with SMTP id 5a478bee46e88-3048abb847eso1481209eec.0 for ; Wed, 27 May 2026 02:23:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1779873806; x=1780478606; 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=yH718uLubEk87H++cFbixr/BktM2LwHrJfhtUjmE6/Y=; b=jm9nNa+uoi09vnPfbB5njnsdwVzqraimNxpglIb4fCWqDM+Jx9hG/yogvFD4mU+n8r 5nxYv4bPlAHU6Q93JxcBeN3wSuSQHuP4DYNzaXxBF3m+VewhGbMX2tFvC1Eyt5WLKeIg 4rzzH2/PoKb5uHyZON8v6NYAX6tHxJOERGhw900a1moHsBzfDVgMBtobAcbsKhA0FUVv qDMAHedMY2U6NwPRLU/2jF4MoOUPrGcd7+qlXu4ZJi0NgzAVb+cU1Uh5kXBxXHwbsopX 2iAH1V7ecbMjtTgeEA+OlHWESPCksfP7Ivp5N4DKjoeiqXMTigEWi3ItQHW2596fF4km W2hw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779873806; x=1780478606; 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=yH718uLubEk87H++cFbixr/BktM2LwHrJfhtUjmE6/Y=; b=ckEx0s/x5Ga3U5L8e1dDwqAlav5N6UayW1fo0WAZW5ZlYFiz7R0lJ8f+UFteSFuCxs ZzwgXWqJUSMSZsjadkhGNlxXVDmq1GtVPYyIxspdC5WPw2az3+rIWtaaVhCZ3YQdyByr w8ib20xHvqnDZrFTC+4v0KItjK8CIiBhV0zHZLPTSytSXD/ASB7uw0PMyXFW3VtfiNl4 wM6LIdSAT5SLirep/vc0RWJVWoXPpS6PnN7qvsW0ja8zZGOiSyivPvgFLt4gSSJOJksn tUVgc2ebNT4IA4LUqtqqQiGUPw25BCiNIrOIZSw6BdyfRe2jBs80Ys/Sfs8zhhLJWO/x KNbg== X-Forwarded-Encrypted: i=1; AFNElJ8PQo7YF6g21GdiB3NQi9hVfefneEJpeMHrJc+0PvSHGbbO/q8WQ75BcKUm61Xv6PZ6QWPdyTfxqeewgL4=@vger.kernel.org X-Gm-Message-State: AOJu0Yy6xkte7wpYetgpDB5+7yj8f+CvGCzlkzNdp2MO4eGaGooA7H+Y dVu1PK+Sqy09BPZGxAQTcifFD+E+Ha94gBsj1ScmIeScspbA5BYXDrhHcOEAKuI4QT0h5tensu8 lmyJC/MAkxQTYCDn+IAiT1Qoi2hSv2ThDny49jWSTYJRzW8GNof5w5y7iqyDAKNwHz+c= X-Gm-Gg: Acq92OEIKqJ2JClGr6brbmxdMQ1I25dGxOB0sEBdfVT1yBDFxrxfYXtTmbk2DkeLuBn Zva+7aWQQmMqKRRzOYdEq93nCvmelcvxuoGKYtBNx8tnIyHiBCD1kTCCD9/W5crNUEZkWpWfMJ4 x3ide5TdfVr3zwpF5TJSNxTRH8kzZl1MAcJx0zidRa6TsJ6a8/ClPnrJ3GCKXQKlGRRo7LV8sIo uUCE1mrqnirmNd19QZYdYIvS4qFSGj308XMcTQn7r35FcAa+tfv+wx/88anEAQczWynGPOXeeOv WMbgSai0FJb0Z9vpgvxqTHXnwgnA5shMghZa7p2IjbI3eggUP9cR7Ub37MVKoAt+w80sJcovDyM J7JBHp2DPBqwXchAYCaN1uIOenaFpC6KAN6DleEKLYqsr0yReFEztvO3kgA/GnJ6L8ABPM0DBzY T6xG28RwKG X-Received: by 2002:a05:693c:3103:b0:2c1:67e1:61a9 with SMTP id 5a478bee46e88-3044a5ed1abmr8284040eec.13.1779873806032; Wed, 27 May 2026 02:23:26 -0700 (PDT) X-Received: by 2002:a05:693c:3103:b0:2c1:67e1:61a9 with SMTP id 5a478bee46e88-3044a5ed1abmr8284028eec.13.1779873805481; Wed, 27 May 2026 02:23:25 -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-30451ef4afdsm12598732eec.5.2026.05.27.02.23.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 27 May 2026 02:23:25 -0700 (PDT) From: Fenglin Wu Date: Wed, 27 May 2026 02:22:45 -0700 Subject: [PATCH 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: <20260527-pinctrl-level-shifter-v1-2-1965461d0a7c@oss.qualcomm.com> References: <20260527-pinctrl-level-shifter-v1-0-1965461d0a7c@oss.qualcomm.com> In-Reply-To: <20260527-pinctrl-level-shifter-v1-0-1965461d0a7c@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=1779873802; l=4717; i=fenglin.wu@oss.qualcomm.com; s=20260324; h=from:subject:message-id; bh=zzUV0jy6gFznLS/8IxgTuw9hcE+Kof+0IvFnyhhZ+74=; b=fm6Vm71vjQ/cT5mcOuidqAMfp7wRPDLJX12JtwvLLlUkIMDa+aqpgsCT6K1PffhADWwuRzWOq QOnugF/WWqJAPhXlAfXePWogIlHMVFVoluKtfYDyHJodt7otBTACn4E X-Developer-Key: i=fenglin.wu@oss.qualcomm.com; a=ed25519; pk=hJdt3E7o54lql+miD2GaxwF74cDyhgNwMbmFOZ46bRU= X-Proofpoint-ORIG-GUID: NeevHNfmkyYxKSM_jBPqAk-rGF5zHgY6 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI3MDA5MCBTYWx0ZWRfX8lnVHXoy4pWR Q4CFw0S9IBfLIeLBz1anC2/BbGTIPmqrvKMz37wbeoMf4sevnHUDm/NXQwTn9zcwHuKC0cYmq9W 62Ubdq/hmdwHbADwJnI+eVvFC3aOo7FF6MuoKTlZ8eAuhz2PeyZB0yRcu07o/21wOk+pSTOKqD+ Ko1NhQj1T55Guiv0bbKHz34tZSf9wiL06CvLSucO3prSFngXSWqeXgdUwZWzot5SPNcVul5Fnt1 TF0myGj1HuAip1iyAlcG6IYMc7/CnxCo0fLrJC9zZB+H481VKg4YD2+74T+/a55AQD2IKlHFLBi 273AXR69e7Oc655CJauEdRJiWlOBqBOJq/WXCsYU1V4TMb28DlvNqq3JuDE9ka/bS07uCBkiXew +ahi2P5hw1OGOtWAbgjpmU2TIJuYpm4BZX1LnzfgblyFdQG9dTGchhUc55o5YKvaVryXG87wjiP eKuNHNgq9RNWx+JkvEA== X-Authority-Analysis: v=2.4 cv=I95Vgtgg c=1 sm=1 tr=0 ts=6a16b80e cx=c_pps a=PfFC4Oe2JQzmKTvty2cRDw==:117 a=ouPCqIW2jiPt+lZRy3xVPw==:17 a=IkcTkHD0fZMA:10 a=NGcC8JguVDcA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=yOCtJkima9RkubShWh1s:22 a=EUspDBNiAAAA:8 a=oPYuZtxd-o3nixQqOr8A:9 a=QEXdDO2ut3YA:10 a=6Ab_bkdmUrQuMsNx7PHu:22 X-Proofpoint-GUID: NeevHNfmkyYxKSM_jBPqAk-rGF5zHgY6 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-27_01,2026-05-26_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 clxscore=1015 priorityscore=1501 bulkscore=0 suspectscore=0 malwarescore=0 phishscore=0 adultscore=0 lowpriorityscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605130000 definitions=main-2605270090 Add the "level-shifter" function and add the required DT properties to allow RPMh firmware to control the level-shifter. Introduce a custom 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 | 69 ++++++++++++++++++= +++- include/dt-bindings/pinctrl/qcom,pmic-gpio.h | 1 + 2 files changed, 67 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..016f4ad75033 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 that suppo= rt + bidirectional level shifters (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,25 @@ 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 + required: + - qcom,rpmh + - qcom,pmic-id + + - if: + properties: + compatible: + contains: + enum: - qcom,pmih0108-gpio then: properties: @@ -523,6 +557,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 +583,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 +640,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 18:57:49 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.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 281283E9C3F for ; Wed, 27 May 2026 09:23:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779873818; cv=none; b=blE7YE4w5Tp3cKt0q9memnon4wrV25MlAhRzWmHpr5HQJcgpwqR2s98bOD5DWhgdidHqB7GD8Uw5CJOBnyWHC93BPg3LYhEnU0PrT9NTN0QaKwMG36KFn7IC1oUBhiay6KTYIQRi1A7YkREKqtG/ytsDXGs8CnxGhTSNnxO8xXw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779873818; c=relaxed/simple; bh=gSdLgqSkpOoecfv/3VBJHW/YQFShiUNpAWkMPY6bhI4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=c7YV57ACCuw1uIxxwr0iMs2MHBFZWxQlJZ9kuYZez8S12Zs8aflekNigHzAIcpV8kG4ifSzZhTGr43aUFP5rPRPSdb+LgZFU9pATbhKWUFh+qsBMi06fmMs/NMKWyBg/gruExp9jcrBHUpPBb8vUz4scnOfD3RPCMSdkDNtbrFo= 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=ULqD3VQj; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=YR8K1ZTZ; arc=none smtp.client-ip=205.220.180.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="ULqD3VQj"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="YR8K1ZTZ" Received: from pps.filterd (m0279869.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64R8mYEr3831015 for ; Wed, 27 May 2026 09:23:29 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= Kf2yRmT+Apw2wjvS6hL1oN8FcR4BN6jTzUh686bjw/g=; b=ULqD3VQj2RF+s/j2 BDUiyWtrXt/lpzSDXxI/RBrhpdeJGCgSnKw2sSC8hAi/cr5JclyDEWAlV/pbAu9j mWXDF5tCQdM5/ob/FkwPfzN0oRh3KC/Rug9ANw/gg995V2fLS5EVzhWS5I+mtbOe t4V5VoTf3Kj02N/S31xUJWJNMoAYieRzeHRM+lYhzzjcai7UgLqh7lWHzMtO/iek oIyZwhv7PSSbW2R3kHjJOtPla56Xdw36UI3ltRHkKEi1b0XcOIUuKpCZFt26moVs 3ItjXxdAEOMCb/Duj/c9gnA2k1oQiDl8uynl0upv37nuKUN2m6AenJNNBlPSrSS0 91ScVg== 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 4edn17huts-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Wed, 27 May 2026 09:23:29 +0000 (GMT) Received: by mail-dy1-f198.google.com with SMTP id 5a478bee46e88-304c46babe7so856838eec.0 for ; Wed, 27 May 2026 02:23:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1779873808; x=1780478608; 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=Kf2yRmT+Apw2wjvS6hL1oN8FcR4BN6jTzUh686bjw/g=; b=YR8K1ZTZsK0TT6FoPLPX567zu45VGywj3nE/0FjCRiV16cF5hxtcwoAZSCkfbbLo1U nV+o1EF5Yuiuhls35qvRLNe42HOsslbT3H2WGdHFMxIHjj/FRQP85oT1gFc8ltFO7Swa RNhgX9mkoaHtcvOmFVcMTOXyRG86xzvsj2aVJcV7pC5QrH2AfoLuClrlpaWdhspuJgCS f+JcgyDg0u0hedxqETHx1l1+retPNteu3rTLGMILzpd11Ouafpo9e9JC8TxfIfp+5GoZ 8Vx7ZaNFsWpY8qmWNzn2ieCKbROk+anp2+JuM1VPosER9Avks6XDDV80qrABYKKmTHmL JjYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779873808; x=1780478608; 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=Kf2yRmT+Apw2wjvS6hL1oN8FcR4BN6jTzUh686bjw/g=; b=s0escw+n1mgWXf5SFEp9Juix33Cu/tzPxcykHiq545+ULSm9NPeag0BgYU3B5blDz5 so/A/mSBpmN0gpq0J0pupmM49tP3fe0tXgW7+3sMgxIzO5jddBRu74LTJ8NZs/NMDvs3 +zllUopZjNiPFKhmWH5AFKpODUw7CKWYkEFOmu0+DigN5dfQTS5QhX3j1dmyq/2b5th4 2LVrDpLo38m89WqNcT8uoBQANXDTMCsjKH1ZiqnyJrd0aWJMveuQenJ0UfloPIAqXT/Q q0lj5cOibZYLiphbcHex7gBsTcE1uQ/f7xScLZdwS2WUU31VWNF3iG4OlekBMWXa0jzr Y8eQ== X-Forwarded-Encrypted: i=1; AFNElJ+iRNsuhFeu3ptH3gvmxkj2DqjTzd8v/S4XU7RpidSQ4Q96np/5A2F4BFFwOaBtEbv9WOS05q0WO+xXQqA=@vger.kernel.org X-Gm-Message-State: AOJu0YxuBF51/R5z0Hb47M0ile5IVTEfgCIfglhOUXHkHyipRM+vRA5x 6pWpL82Rm7QMq40Lxggrxw3XmCVqfz/99PAyCdWWRv1Wi513yCRmU9KKdfEm1CTraZT1u2XtTHl Aa28z/T3573cCHuyHDllKUBsqFBohwBokpzr7mXwGMuXB+xM5DjC6ozX2yFcilOQUsY8= X-Gm-Gg: Acq92OFXLYWGmVz4h4KJNL5ZehG8g+ECZLx1R4pdTrwzpqe5yYtXbmA5A6YprZf7Es1 vw4MMVTMJARZYrW7dub6Zz736J2+HLK6Y3XfVnJvoSEtCMdyGkVX085g0tfM7WsoFx4vJBcE09Y wtw6xHkT8vBsVCCNB400cH0C3+KkazTlN3C4OAb+KHPnuwW6/3qKLOVr9T4suJCIp5Rh8FoypoX FNK0NsSk4Gwf83mnEYneHl7dleWE8Rbabt2EDdllthZydE/qj6gK1XPVkCeZIcyYLRpIlS+syY/ oYXYNoa9a3Gqk5gcMpQ9rQgnz4l3IkTJRkR9/edt0sSH1PFpgk5i0lf4u53laQEhlluAGoqm3wW +8CPq45EIXX1ociN5ntXVIomMLDrQtfe/jCvIrx+14CZumxgk1Xu7q6vByfOf7zOifRI9k0JA+A == X-Received: by 2002:a05:7300:b507:b0:2ed:e15:c927 with SMTP id 5a478bee46e88-304491471cemr11088578eec.35.1779873808201; Wed, 27 May 2026 02:23:28 -0700 (PDT) X-Received: by 2002:a05:7300:b507:b0:2ed:e15:c927 with SMTP id 5a478bee46e88-304491471cemr11088547eec.35.1779873807558; Wed, 27 May 2026 02:23:27 -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-30451ef4afdsm12598732eec.5.2026.05.27.02.23.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 27 May 2026 02:23:26 -0700 (PDT) From: Fenglin Wu Date: Wed, 27 May 2026 02:22:46 -0700 Subject: [PATCH 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: <20260527-pinctrl-level-shifter-v1-3-1965461d0a7c@oss.qualcomm.com> References: <20260527-pinctrl-level-shifter-v1-0-1965461d0a7c@oss.qualcomm.com> In-Reply-To: <20260527-pinctrl-level-shifter-v1-0-1965461d0a7c@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=1779873802; l=16625; i=fenglin.wu@oss.qualcomm.com; s=20260324; h=from:subject:message-id; bh=gSdLgqSkpOoecfv/3VBJHW/YQFShiUNpAWkMPY6bhI4=; b=7JOHHPfi6jMOMs8bMzQP2SOqUYy3lXw91cMQJbp1kIDJEnk84nUHPRl0CzgWKRUYbL1dMHFaH e68nn7RBCrCC2qg1cXcvEHx+QwDGgyIRunsdky0/Fr+zkuq+A1Fy4U5 X-Developer-Key: i=fenglin.wu@oss.qualcomm.com; a=ed25519; pk=hJdt3E7o54lql+miD2GaxwF74cDyhgNwMbmFOZ46bRU= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI3MDA5MCBTYWx0ZWRfX/QZrGZ1NGFfw w9EuW1yDK+oqHcwGuAbohfs3eHviU+VkJAeLx0MP/DCFhigx4Y2XEz7JVOQt2mLxJoyopgwR5Ao MUmqo8T9oiP6HvgCr1M4ItDxFt30tlF9PyrYyOXo0vZ0HQyIqyfA6W50ZJMoQCciqD0LqBd/DrP C4e9QqqDyh1fSNBC4gQUGjWTaOpDY1xLum+e142Qh7feadh8auXUZvQKOnxQCPkrTGlfQFcEdu3 xGXa6XXZmrq7ZNuN9Gc8Gg+ga8eZGubVo95sZ3XqDSDMfqeFHRm2X8WXqUZT3QIDftkVdKr1ImZ 0OB2dlXzjnuLOqH+hzxRhKomMNgdddksDQ9Mbc3sSekoHfvwCdOVnh6PEuQecOgDgkOHkT+qzx8 9bUT9LYigQNi5kJ29kCzlUJVdQZkNArlGzUcRVjcq4np4G+h216WMUXjeZF/cvx0MS+GQkHnlLX StvNB1E7AoSDjkCztvg== X-Authority-Analysis: v=2.4 cv=R6Uz39RX c=1 sm=1 tr=0 ts=6a16b811 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=_glEPmIy2e8OvE2BGh3C:22 a=EUspDBNiAAAA:8 a=OvJITaBzo-gp9VRKLXEA:9 a=QEXdDO2ut3YA:10 a=O8hF6Hzn-FEA:10 a=bBxd6f-gb0O0v-kibOvt:22 X-Proofpoint-GUID: aTYfCKqut6sBMvOENZs5iyCcy97JWphq X-Proofpoint-ORIG-GUID: aTYfCKqut6sBMvOENZs5iyCcy97JWphq 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-27_01,2026-05-26_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 phishscore=0 adultscore=0 impostorscore=0 clxscore=1015 suspectscore=0 spamscore=0 lowpriorityscore=0 malwarescore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605130000 definitions=main-2605270090 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/pinctrl-spmi-gpio.c | 367 +++++++++++++++++++++------= ---- 1 file changed, 249 insertions(+), 118 deletions(-) diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qco= m/pinctrl-spmi-gpio.c index cdd61dae74cf..f159c56784b4 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; +} + +/** + * 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; } =20 -static void pmic_gpio_config_dbg_show(struct pinctrl_dev *pctldev, - struct seq_file *s, unsigned pin) +/** + * 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 @@ -1154,6 +1261,30 @@ static int pmic_gpio_probe(struct platform_device *p= dev) if (IS_ERR(state->ctrl)) return PTR_ERR(state->ctrl); =20 + /* 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; + } + } + parent_node =3D of_irq_find_parent(state->dev->of_node); if (!parent_node) return -ENXIO; --=20 2.43.0 From nobody Mon Jun 8 18:57:49 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 060A33E5EF4 for ; Wed, 27 May 2026 09:23:32 +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=1779873818; cv=none; b=FziMYX8xjHQLvb/W95DiQ4GQ6Kn2w0DtI/vQYCzGAL8LC5y059IQZ/xvD47RneSHLZ4OxuZMA4i+sGDu7qtMvetqxkn0kc0hvj4S1/KG3E1plYvbxcxl2FexD06sVvmgsIUqP1sQdyQ7GHK6afbHqUiHRxPJSFpHF2a/huGwmLY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779873818; c=relaxed/simple; bh=ZdtgHup1CUiT58+uan9Y1EBaEiejMTxrDIuTQRNxeIQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=BGRUsm7gQZJKT9EuosC5/kWcHSF3VUI1hUZ+n6jNdRuOZNP6Ky4BANi59z1JrbZhkssLHIxukBDibWR4edsGRheXBjEAeRTMSVIdxIaJdnRGTK3islWx9R8pKTatrCAhp1bijWiDw9KuQ53aeAoThnThkDHHqVu9/ipKlXZ3hFk= 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=Iuc6UWJR; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=Xl6Z6tfC; 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="Iuc6UWJR"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="Xl6Z6tfC" Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64R8mbmo051300 for ; Wed, 27 May 2026 09:23:31 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= 9ZueFuGp2FKhjaGfq3McD2gtxTN4Aa6zWUr9wxcF8pI=; b=Iuc6UWJRqOJKJ1Ld JKyZ0qU8q/ypMqinJnIWaARCjiC4G7E/qG5DrpHnheyqa3Wu13khIdj3Tz4UqeQj M2sBUnyAUEYJP2LktJ5s4NKJQ7i7OrawJv93r1gDZXKOfMN0q0pVQHDMehKUMoH/ XPynrBNUQ/+1srqvUyTxqIFTxWAkeI0agqYcQZscwZOh6YH80xqTJ1v2Qj3JvqVk vmQctJLoaRtRfjVX4NXs/OOQXmkG/SixBe8XYUrmGwonyV8uVu7rUewo5muQhEJq jNBA2EOo1hHSwQXRcBxZI6RCcgUuv9xcNLMlrnooN+nCLE8OkemYG7L3RHKsO+iT f0rdfw== Received: from mail-dy1-f200.google.com (mail-dy1-f200.google.com [74.125.82.200]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4edg5paux4-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Wed, 27 May 2026 09:23:30 +0000 (GMT) Received: by mail-dy1-f200.google.com with SMTP id 5a478bee46e88-304b8d0ee63so889753eec.0 for ; Wed, 27 May 2026 02:23:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1779873810; x=1780478610; 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=9ZueFuGp2FKhjaGfq3McD2gtxTN4Aa6zWUr9wxcF8pI=; b=Xl6Z6tfCvlm/SkR46f1XslBGEGYRCnTJ1u9Kn+OCDugmUc6qJLJnzbSP+Ppo4GSenF s9HvVjnV0QdFlNXF7kDyY+V3xRMaCSjjP42Bo3wFX++xtKPFTxZElGiy/fAtZRQB6eqr z86BJ3TQol5cBeifgzM37D9BcnzkKH3AeuKHVGsWPcmdJJO0gh84eLgjQ74p4Wq3m2za H5rsFZAjvwJPZ0nO1fMW/1pOr3Hfpbf7HOMnqYKMcc9EzfC4hGxDhIABfZsTAjJ2qPkm NSRyXmLPczgQmDEYrMxwukN3aIa4j3CiHOiIard409ZCrOI7ZQy2jvhexpVcpVJpihhb 475A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779873810; x=1780478610; 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=9ZueFuGp2FKhjaGfq3McD2gtxTN4Aa6zWUr9wxcF8pI=; b=stBysy0FYrgHLOu+iGdbkhPihkPJ8lCqu97Axlc6/HPibh/PbvsGX3kvM4M3Hrhp7B 6F+heDV9wY9nwq7yuRJg+Wihvj7mMlVxfEmDTvmGsD8RQoj/MYX+Pe0w/GrG02MOPmPL bDa2LwGsykRHeTpMmY691nOc8GjMl20pLlJAARWUCcvONPFWqOQiE3b3oRJuXekfvt4w wfuvM/D76j/XglrAK7jnJH+TRrnTBTG+zSOU2HDuOpCxuhBEhj7zD/7rUVfXF1fxPqEZ eojLSo68F+oxaClGaIxnuyFLuR6HOUilqiq+khRNXcjVg/ztEiFKcAg19Ks7H5sDitA1 funQ== X-Forwarded-Encrypted: i=1; AFNElJ+R509gYNNsY50yxhUusH9C/fvercMOlRe+EgjCra9voJ7CnZw/MsE4LZAX6e/B5+Nyck5yKgbcninIDPs=@vger.kernel.org X-Gm-Message-State: AOJu0Yx8jw4AQ2FtJSQdgn90rnVQ8FzIr3HQCXnuG+ZCn9/aimYOoUCq B3cBCX8+T7Yr26RFf8wZ/rLgVCuIvLJuEqZscL5ngfsWfmq1X7PF1PdCyPXjWy2l/338V5uqtOL X0twuQFuiIr9q/dxdHYRY7kFoxwMqKALj2f5717+XXPh2LZs+wluBWY8kphx2bgYisHE= X-Gm-Gg: Acq92OGkex11yhF0T7N0Qs4F+10Rhh0tA6FBKu5ie5Qp0HRWZToeIpUt8U/jSXLFj+V qclvrQ/X9B9zfKYwBsSOw7MlAbV48vt2WZ2Dtg65syHvjxqyhu3buVYiWkWHO0Yk+iIlea93YaT NsdHspkUwn2ndCkM1Rqt6aP1CwS8PGFe6VJapEZMf/OtPeI10BiFfQvT6s38Xsd1cJ00gJHv1sz ehfFjlNXdYtPb+op2Rknzm7otObx4jF4Cgysz5QODrcjvi95EHfI/lk/YBKXkzSRRYQO82yZ2MS QTOeT1MsaMOl+9sMUCsY8N7mRUdgq20MTIio/LHKHmrtgzWJQrGtcboyhp8V0vy3aB1kiIB5lYc vNA0WfNmiYcOsnMlj3L1wMdLjfBBJX83F722iSgqOXo33XxyMGYrP5EpLDE/aj9XbpRhFEi+ULQ == X-Received: by 2002:a05:7300:ec11:b0:2e6:fe90:27ad with SMTP id 5a478bee46e88-30448fd59d4mr8680560eec.7.1779873809703; Wed, 27 May 2026 02:23:29 -0700 (PDT) X-Received: by 2002:a05:7300:ec11:b0:2e6:fe90:27ad with SMTP id 5a478bee46e88-30448fd59d4mr8680542eec.7.1779873808993; Wed, 27 May 2026 02:23:28 -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-30451ef4afdsm12598732eec.5.2026.05.27.02.23.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 27 May 2026 02:23:28 -0700 (PDT) From: Fenglin Wu Date: Wed, 27 May 2026 02:22:47 -0700 Subject: [PATCH 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: <20260527-pinctrl-level-shifter-v1-4-1965461d0a7c@oss.qualcomm.com> References: <20260527-pinctrl-level-shifter-v1-0-1965461d0a7c@oss.qualcomm.com> In-Reply-To: <20260527-pinctrl-level-shifter-v1-0-1965461d0a7c@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=1779873802; l=26417; i=fenglin.wu@oss.qualcomm.com; s=20260324; h=from:subject:message-id; bh=ZdtgHup1CUiT58+uan9Y1EBaEiejMTxrDIuTQRNxeIQ=; b=LMHt9Yo2Bdyl7dw0KyDYRWE5wfwgvr2Dz625+7q+Ht9CQJ6EBx64kV/HkQiKQzA7GmrK9kWUM HOu88nmn6uMBRMx4DFh+iyo7xfFoKEENyPcIWboS7MoJe6DoQdrqPqj X-Developer-Key: i=fenglin.wu@oss.qualcomm.com; a=ed25519; pk=hJdt3E7o54lql+miD2GaxwF74cDyhgNwMbmFOZ46bRU= X-Proofpoint-ORIG-GUID: Kxphm-lt3sym0xIBV0GA_vlx0HzKXVzU X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI3MDA5MCBTYWx0ZWRfX0cX3aR9Wzl9U 8WWMKomtso/C8S53OfStFVerTtN/uh25h8XOilimsGOwmtG22I76Oi3CigvEFd0UQbrRlgTi9iT 45JxeEKdjqHds9E1wF0gBJAqUqe3qA1Oz6N2Z8lfCjRmFBkzQxzOG597EmQpAS9dwNRFjhCEB2M ik5EGl1vLXh64ESOp9MKg2s62njQiq/mAVE9RV2hYLvc3ujafPnNAGHEiJebIh0+LffoSmO9ouj mqSntz1ghTsw/D49/eb+P9eoOUID3ekrpCm4QXpDp1Vdd0wIpKbJJn74DS8jwF00xxE/bA+Nnpc Jye3Kyx11/Q8TH3tw/juF0bhMF70NqtH6n8io2YNYwJuqgPdcSxb1oqhtVXyS0OiLjwgwSRp6UE dpl6JNLC+VJjYma+hz2I74NF3VVqShpnUMCS4rLPCHZg8czTMGmh6nviUTiPyHgSOfKVELSL53V Z/H//qWesHy8+qLm2CQ== X-Authority-Analysis: v=2.4 cv=I95Vgtgg c=1 sm=1 tr=0 ts=6a16b812 cx=c_pps a=PfFC4Oe2JQzmKTvty2cRDw==:117 a=ouPCqIW2jiPt+lZRy3xVPw==:17 a=IkcTkHD0fZMA:10 a=NGcC8JguVDcA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=yOCtJkima9RkubShWh1s:22 a=EUspDBNiAAAA:8 a=O479GCAEFUW8rv5zZysA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 a=O8hF6Hzn-FEA:10 a=6Ab_bkdmUrQuMsNx7PHu:22 X-Proofpoint-GUID: Kxphm-lt3sym0xIBV0GA_vlx0HzKXVzU 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-27_01,2026-05-26_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 clxscore=1015 priorityscore=1501 bulkscore=0 suspectscore=0 malwarescore=0 phishscore=0 adultscore=0 lowpriorityscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605130000 definitions=main-2605270090 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 | 410 +++++++++++++++++++++++++--= ---- 1 file changed, 335 insertions(+), 75 deletions(-) diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qco= m/pinctrl-spmi-gpio.c index f159c56784b4..d0144dbb7cfc 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 @@ -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]; @@ -597,6 +723,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 +819,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 +835,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 +942,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 +957,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 +1333,96 @@ 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) { + 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 +1434,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 +1444,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 +1538,13 @@ static int pmic_gpio_probe(struct platform_device *p= dev) } } =20 + /* Register level-shifter groups and function if supported */ + if (hw_data->ls_config && hw_data->num_ls) { + 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; @@ -1345,80 +1605,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