From patchwork Thu Mar 14 13:35:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Peng Fan \(OSS\)" X-Patchwork-Id: 780408 Received: from EUR04-VI1-obe.outbound.protection.outlook.com (mail-vi1eur04on2042.outbound.protection.outlook.com [40.107.8.42]) (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 5EC625BAFC; Thu, 14 Mar 2024 13:27:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.8.42 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710422839; cv=fail; b=njd/fopPLHhZEUHfS1sItF8Uk8KcS5gNbGDRn9BLrfFhHn7afOCFUc/aIBJDJfo3RJytWuiTJTsN6BxN5+Rq75vSjofYIHHkcyjItG9KTMeP+dp1w9Az25KWRonfZy+AeJor5tzAozs/g7Nb6IdEj7Z1aPC2s03qeAdkASkREMo= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710422839; c=relaxed/simple; bh=t5HLy5gFexuRUd/gcXkLur0tNUBqrWNFLScENOV0ZWY=; h=From:Date:Subject:Content-Type:Message-Id:References:In-Reply-To: To:Cc:MIME-Version; b=qHQDi4hL+NQboxpjplNIQ3U3B3sBQ9SpWmuny07FusLSVEbzqf2CfsTLNaXccnB0Ieys9WwH+Lzp6GoAo8gq5RxBrnlKdrzpkfLSiTvhMyX4bD4S915ZndkEZ94r616leH0Of/LcZbIy2BTg/LlkQt9C5JXb+Z2t+wkGN3E40IM= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=oss.nxp.com; spf=pass smtp.mailfrom=oss.nxp.com; dkim=pass (1024-bit key) header.d=NXP1.onmicrosoft.com header.i=@NXP1.onmicrosoft.com header.b=BPpRTPWP; arc=fail smtp.client-ip=40.107.8.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=oss.nxp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.nxp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=NXP1.onmicrosoft.com header.i=@NXP1.onmicrosoft.com header.b="BPpRTPWP" ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=D/I18MYCOba+ITMNpKFXky5/qV1a/5cbB9O0Q1eJJhH2tXbJbFmaVu3/9XOCGjytr4v93cCfDFr9JLC8pFY+1DCnHSGpEFjDQIHyMUuuw9KrPgh0rigTB+jLfhvFf8gzGQBwmegHKIPnAyDsFZyZhfwKVUHiiW/705H+fvfQK0RWirsy0uMwPBy7cyY90pDRcEOE7apETlaiE+oLeLZUcvrB10jgF/MZwxCifZErxD8Nl+ycUX1cOm5GgnxF9CowpYXLcSAvMndRnbT7rkxhMYq3ePBL4f9DQNxfdOcY2+Jnr9QmisZ/MC2ithD+p8GkKnf+o42xaqJQw9S+zcISkw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=DkhFzy347CReKh8Y/3De5x5m9e7u839I/9k6SdaIf8U=; b=Wzi8I1PEgs6w++cy2ImwhcNzoOrUHl6fUrpaY4EVn1+hcZ0kK90EnxCrNBRPHcwsTmgN0IQXiMmkvLdfmMt8BKf0VYLewN9ndq5MO31skyxAlGZVSPld1t8dqbCgShMvuKU33BgJF17zc7L+jrQGaXoUzkG8l4TFoMCLcGPqNRAXYqZ7S9j9OPCJh/PE96/ydb2DT/pKSILwGPkOZHgJREEy84x3gNPy7VK41FCJQQjF9rlmEp4/uHcZNCzC0D+Hp2Evdvq+2bkq0oZaFEQ5QHTLvCU9fSy+gZshGFquJ0lIzBYAxE20FvsY0vSO41HR08FOLuwhDStIfJ2+TCChRw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oss.nxp.com; dmarc=pass action=none header.from=oss.nxp.com; dkim=pass header.d=oss.nxp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=NXP1.onmicrosoft.com; s=selector2-NXP1-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=DkhFzy347CReKh8Y/3De5x5m9e7u839I/9k6SdaIf8U=; b=BPpRTPWPL293Tza8Ny6nUgjHlAD7lk4LyGTqYuRvHDQ555lng1PrSibREfpS+TLQQjgy+NIRSEmNlchrLXyjPI+0s+TNOm+3FA1LH1V04niQCZXqhdo94G26SFqyK6PR6UBuQrUnup0Iy352JKGc4I6+Zr0Ab/lriU1zLLQ3RWk= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=oss.nxp.com; Received: from DU0PR04MB9417.eurprd04.prod.outlook.com (2603:10a6:10:358::11) by PAWPR04MB9861.eurprd04.prod.outlook.com (2603:10a6:102:381::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7362.36; Thu, 14 Mar 2024 13:27:14 +0000 Received: from DU0PR04MB9417.eurprd04.prod.outlook.com ([fe80::d30b:44e7:e78e:662d]) by DU0PR04MB9417.eurprd04.prod.outlook.com ([fe80::d30b:44e7:e78e:662d%4]) with mapi id 15.20.7386.017; Thu, 14 Mar 2024 13:27:14 +0000 From: "Peng Fan (OSS)" Date: Thu, 14 Mar 2024 21:35:18 +0800 Subject: [PATCH v5 1/4] firmware: arm_scmi: introduce helper get_max_msg_size Message-Id: <20240314-pinctrl-scmi-v5-1-b19576e557f2@nxp.com> References: <20240314-pinctrl-scmi-v5-0-b19576e557f2@nxp.com> In-Reply-To: <20240314-pinctrl-scmi-v5-0-b19576e557f2@nxp.com> To: Sudeep Holla , Cristian Marussi , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Oleksii Moisieiev , Linus Walleij , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam , NXP Linux Team Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-gpio@vger.kernel.org, AKASHI Takahiro , Peng Fan X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1710423327; l=2653; i=peng.fan@nxp.com; s=20230812; h=from:subject:message-id; bh=dKDsMHnM+cuvfvX6K6tAU3ADCasBJe+OHaz6qBQ1Tuc=; b=4xzM3YkXuTqYU0tEDo6x/HN4gsRKw3cpJZgM2pUwWmhzTcBuCmBTTPCH+IZBUrrpdGdNWuVQ8 6MyD12S/yYnCjWetyg8RKWlUcjin4Jf8siW5hQolqJ7mOHzFtszNtL0 X-Developer-Key: i=peng.fan@nxp.com; a=ed25519; pk=I4sJg7atIT1g63H7bb5lDRGR2gJW14RKDD0wFL8TT1g= X-ClientProxiedBy: SG2PR06CA0188.apcprd06.prod.outlook.com (2603:1096:4:1::20) To DU0PR04MB9417.eurprd04.prod.outlook.com (2603:10a6:10:358::11) Precedence: bulk X-Mailing-List: linux-gpio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DU0PR04MB9417:EE_|PAWPR04MB9861:EE_ X-MS-Office365-Filtering-Correlation-Id: 2640a9d6-c38f-404d-f731-08dc442a75fb X-MS-Exchange-SharedMailbox-RoutingAgent-Processed: True X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: N5VTujBtBoO/i+cA10llx2BsBHIOkUQ/kQV2Ev0E/7x4JXhCSmSux6L+r1sdil4gduW6DPMgs812ypiNg+on03kzFubcJfOEq5cvUOJSaiR6psLiTLZeZeoXy8HW7cpwoj8hZVjXUtBECCw068mWu4t542197KD/yP5G9knFCkb0wmbLya44B3wY649nFvnqSi2sGsjQ+e044BV4yjKYmOXQ43weY6xdY3TSQ3j3sD/thbBvLrLN/GqgejwKpwYrLivn0m8IWXzCSiM3dl99bLrVIze1t0cXkMuRifWGmU2UlV93QetIJZ0IYNHsTnmUHXiTDrLCx8sigOLWor0lk+hCm+W4FGo5IoPb0CJmD6bqMou17cRbjEvhGDeCUfKBGLbHGZXn5aJ3UD/R7lT6Wvm4DWjW3a5j8qYxFLxmCgvFykpfUfrk0PpD91hfYXQn0diTddVew5vVGuu4J7yYLrqH/oz6Xp18k3JzwG8w+2MyiKgjIKo9m7vdy0Sd4g97+lgDvwF77oJ27T+kFji1yc67flBXf9mw1ZD2heJdK9MdFSJg8y6CUnFgsGhsHvo/rh/YRHttVJpyl/c4HeL0UXTGz11NoyzjMNB0Qf9Pf0RoYlFJYvDKpPDuxS8kYvmf6TTBkw59l5pOj34CFtMinLPRDWjSyuuIpVQnSjwKS5p6VHrSMUoOVGmsD7MUelvEFjYwDkFv1TyTlo8umn7JuRETT5gans/ENyBxeFcjjW0= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:DU0PR04MB9417.eurprd04.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230031)(376005)(52116005)(7416005)(1800799015)(38350700005)(921011); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?wF+0KEwoOvQxpdHb/ZxCiXWHhpVr?= =?utf-8?q?eOpnOB0kYrSWW5dcEI9offwcTHufWITLX+EaZVCDvP8jcpGCQmW4QpobQJ9s5umYY?= =?utf-8?q?r7sYS34epA8wtwUFi9DKxItGAf4Na0UBI5aAW3rbMaIW97KV7hv/LuxaeV13/Dwuw?= =?utf-8?q?58GW88Hi3q6+0hIVdEFAhWqgtTJPUxm5vOFV4idrKlJAp7+QccoFbSkjjrV3C50I6?= =?utf-8?q?4vNk6OJ0vE9wl7idF3xfUUB8uszZIfTpb5CLbgBVIzIrHHPMu161IqltokKK0UdP2?= =?utf-8?q?b9EShJwu2LV2GbxyRGjz14VGdQb6cDdLbHTdkba83H3mRNeaXlpzNlvAfPjBnOBOc?= =?utf-8?q?cFPweNK4311d/BusH842gY9FmVfbHnO5kPLddhXCLN7deBALuLHCSNwRcgx1fRbPS?= =?utf-8?q?KRHqSHwDxwjO74ranbxr1yltyT5lk/4dbrVJ47kLAfuGnPgyYQUlsjP3xfFLEqooL?= =?utf-8?q?juoOoYcaKhXp2/Xlk4q9GtGwAjuui6aOLqweV7YUbjVXGuup/xW8OAIuy/aV4eY9A?= =?utf-8?q?KJ6MLyBGJg10NfX3xVlAe8+co/R0q9urnp9zodj4OdIajdOpsVMaoKaavKO+WozWD?= =?utf-8?q?nvQoHMOWyYPBba5YN+TKUqQjSmf3HPPLLTw5r5GmLDl1Wx82YQYk3wGlPG8vCuT3b?= =?utf-8?q?8F7gtUTdyc5DbXV+EfeOPeUEyV+B53DHy9ApTdsxbHjJ3nJapX9FOQuaKHtZ6hRy7?= =?utf-8?q?virvTm1mUSGg9AxLHgTCKoNhVicFViMfdIECMfWBrst4J9txKKLhxBvpyo1W8ouFT?= =?utf-8?q?Xc/lhRGWddZcYn/OImrB/9UJlTzj844ahGp4tptqDAJrkCjk6oEmAULfC7T3h8F3T?= =?utf-8?q?+MSkt1gveyiukHiGO0UeJgQg9KOOaNBQUXq+o0nhqPW3DZpm2im4/m9VKiQVk6DVZ?= =?utf-8?q?mSjLwAiqxIqzwmHS4W4TJ58WXpLTol68PYfead2FyRgrKznTuznDgsj8K8H52S3Fo?= =?utf-8?q?R09J9TAYlUh+OwltPoluQc0sQ/VEcDhrWByqkTWxhVYGyghzVKTwUmLC8iTyXhatO?= =?utf-8?q?FSPTiwb/Sw2nATC0RTz58xft+uQwYNvPD7J4hevHsYUvEgW9pTbrlS/DbSTop8Rdy?= =?utf-8?q?6CtRr5SJJ7/XZ0VNX39EfREUL3fdJczkmqQmTGd9bbRSyYnoRm0EHWy+uwnWS5wtj?= =?utf-8?q?FpChIM1bqE3Z8D4wXRK5GLk6jc5VdmOnABkiXMPLHpPm+G6GBuJBZVOWeXQatGCc2?= =?utf-8?q?ykfsWC5rRfHPAGnQTe4A1mRcmE5FRSULsyn/uV8Z+J7y8Hx40Qwd9dxStIaNhI/kQ?= =?utf-8?q?+VSE24k82+e8cJWYaymVCCfenICut9noeteHv8pZ8fE0MV4kX38f7SRP7PDTiOrIf?= =?utf-8?q?bfc5YsT6kf7pA01fXuJgd7/jEfC9OcVYu8pZ+WMkPCo/vgfkC7hdNCuTBjPTe2n+g?= =?utf-8?q?i7scBiz3Alf12YfxU9fWv73FidTVVikqPu2JG/8ODsu1JDz1/v9gHf2AKAlxxqQk1?= =?utf-8?q?wTTAmV757A10HIpTEYFBPQL+UjBiF+ap8zTO1whvyqTE+xc79oT6X822JF602bLCF?= =?utf-8?q?5vna69l4sLWb?= X-OriginatorOrg: oss.nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2640a9d6-c38f-404d-f731-08dc442a75fb X-MS-Exchange-CrossTenant-AuthSource: DU0PR04MB9417.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 14 Mar 2024 13:27:14.0136 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: YWnfXaZZPbqlvaphSEnMaLnzFdlKpr4wJg30PWA4kiHrjt1WPCVIZNpC1WJddCu8kfJnaPqMkakWrb7e3lZucQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAWPR04MB9861 From: Peng Fan When Agent sending data to SCMI server, the Agent driver could check the size to avoid protocol buffer overflow. So introduce the helper get_max_msg_size. Reviewed-by: Cristian Marussi Signed-off-by: Peng Fan --- drivers/firmware/arm_scmi/driver.c | 15 +++++++++++++++ drivers/firmware/arm_scmi/protocols.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 2709598f3008..415e6f510057 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -1488,6 +1488,20 @@ static int scmi_common_extended_name_get(const struct scmi_protocol_handle *ph, return ret; } +/** + * scmi_common_get_max_msg_size - Get maximum message size + * @ph: A protocol handle reference. + * + * Return: Maximum message size for the current protocol. + */ +static int scmi_common_get_max_msg_size(const struct scmi_protocol_handle *ph) +{ + const struct scmi_protocol_instance *pi = ph_to_pi(ph); + struct scmi_info *info = handle_to_scmi_info(pi->handle); + + return info->desc->max_msg_size; +} + /** * struct scmi_iterator - Iterator descriptor * @msg: A reference to the message TX buffer; filled by @prepare_message with @@ -1799,6 +1813,7 @@ static int scmi_protocol_msg_check(const struct scmi_protocol_handle *ph, static const struct scmi_proto_helpers_ops helpers_ops = { .extended_name_get = scmi_common_extended_name_get, + .get_max_msg_size = scmi_common_get_max_msg_size, .iter_response_init = scmi_iterator_init, .iter_response_run = scmi_iterator_run, .protocol_msg_check = scmi_protocol_msg_check, diff --git a/drivers/firmware/arm_scmi/protocols.h b/drivers/firmware/arm_scmi/protocols.h index 317d3fb32676..3e91536a77a3 100644 --- a/drivers/firmware/arm_scmi/protocols.h +++ b/drivers/firmware/arm_scmi/protocols.h @@ -258,6 +258,7 @@ struct scmi_fc_info { * @fastchannel_init: A common helper used to initialize FC descriptors by * gathering FC descriptions from the SCMI platform server. * @fastchannel_db_ring: A common helper to ring a FC doorbell. + * @get_max_msg_size: A common helper to get the maximum message size. */ struct scmi_proto_helpers_ops { int (*extended_name_get)(const struct scmi_protocol_handle *ph, @@ -277,6 +278,7 @@ struct scmi_proto_helpers_ops { struct scmi_fc_db_info **p_db, u32 *rate_limit); void (*fastchannel_db_ring)(struct scmi_fc_db_info *db); + int (*get_max_msg_size)(const struct scmi_protocol_handle *ph); }; /** From patchwork Thu Mar 14 13:35:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Peng Fan \(OSS\)" X-Patchwork-Id: 780643 Received: from EUR03-DBA-obe.outbound.protection.outlook.com (mail-dbaeur03on2074.outbound.protection.outlook.com [40.107.104.74]) (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 F037B6FE09; Thu, 14 Mar 2024 13:27:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.104.74 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710422844; cv=fail; b=KwWM2Hc4VM67DdZLzHK2IkM6SuLiSS1q3Vep67XMrTkY5/tytb1wMQbwA+gG6ukR0UHtzsjOr17X5b337iTlygk2NTAfYpTAuFcoKPwJNorKp+V46PAC7Wo6Nz06Ko6e1KgAmQQh376DcysxbRFvOPu1mN94107d3S1nN5UhGHc= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710422844; c=relaxed/simple; bh=Lp5urJcXxMhFvLEjMl/gU+u8bqJReXBFK776pK6/zCE=; h=From:Date:Subject:Content-Type:Message-Id:References:In-Reply-To: To:Cc:MIME-Version; b=ecybaI2Iq6fO0U5Wjj5WavpZx0jVav0dF2JGPCqQD481PCYeaapQW2xF+zomCMG3zTaVL18LnCGpufWsYHhbnkT+Uf/ptmi9cM+9fCtpYFBxSys2FM1h7fuo1dlyny97XW0p+zTgJ/GD4xgghcxMCUFb88UpwjmVNwKbiDvjtSw= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=oss.nxp.com; spf=pass smtp.mailfrom=oss.nxp.com; dkim=pass (1024-bit key) header.d=NXP1.onmicrosoft.com header.i=@NXP1.onmicrosoft.com header.b=hhBSmvM4; arc=fail smtp.client-ip=40.107.104.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=oss.nxp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.nxp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=NXP1.onmicrosoft.com header.i=@NXP1.onmicrosoft.com header.b="hhBSmvM4" ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=eAKD4grpspoj7J5gHC+MzGYTrNmDEzFzNNnkD2wHs62IB7N9+UVtSuNIz2y6CVzBgjnnMHr/SnRZC2Ldi3+GvjkioeSi23jBs09gK21qmZbZZ7ZztL86cjRTJoDoclqo2+ksj1IAs9q7bfqZJGvGo9f7ZHgjtYLa6g8cjj2o2i489c1ex6RTgZL8/XcyHHoJ3tl/AxfMzi5GyUm3m4KdCf+PJyvDp3rZ0ZqF3iNahp2bXZRmUhLzbjCmC9kwBX4YYtQofsrtz+eeViymQT6eJKPCzLQKOh8iwplF9VuQgC9nPZ4+s7JyfMlg6ulAyYaBb9P1a4PAyHzaz73KKxl2+w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=jQmOgq15KqTro5dgNBFbE6fRWivw0EMchUXspHRUUpw=; b=j7v+PwdeXN+tVZBfF9jlsi28Pk10CR0GRTZxos7pDOrPF+mFFDZq9F4qmvHnuZZj+WaL5JU0V16lWp/lhT9muG/HiROo/df1uksPWFSiRVQH4vLvDBc/0G4aFF7tB2wuy5U1Fl6S/+cGK8OoyvWy9MxKfRF6Lh0xjErHJVIL6ZE7ur+ncwrgutWUa7qOW0jTwfKGW7Fu6VOsjBlXXUqH4zLAMZmbt2bQyxbED8Plp75pEJ2MEN4T8BKzkAXmNCcB+wOYRVnd4F9U6b4CfteqLWmbpo+oSI+mt5ucBdFkaRcfRKN7dPJQcf7GDv97fvIE2BMgiUOrvSzRkAy9h12zrQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oss.nxp.com; dmarc=pass action=none header.from=oss.nxp.com; dkim=pass header.d=oss.nxp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=NXP1.onmicrosoft.com; s=selector2-NXP1-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=jQmOgq15KqTro5dgNBFbE6fRWivw0EMchUXspHRUUpw=; b=hhBSmvM4/tTRD9MBw+9EgNZhmqQ4+N1zAwMlZ/cKJcuuZW/y9j8bzTkC3cy9NcUkAOw2jyAg+OHMNqkjYGhSGG6ibRc4D6Ua0/B1m0Rh7AYl8+qMSN3Ff8zIy1NVkfOfq1BEJPbcaOYRWaq4E/Te91X2ph3i7tO4NeNlX3JHL5s= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=oss.nxp.com; Received: from DU0PR04MB9417.eurprd04.prod.outlook.com (2603:10a6:10:358::11) by PAWPR04MB9861.eurprd04.prod.outlook.com (2603:10a6:102:381::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7362.36; Thu, 14 Mar 2024 13:27:19 +0000 Received: from DU0PR04MB9417.eurprd04.prod.outlook.com ([fe80::d30b:44e7:e78e:662d]) by DU0PR04MB9417.eurprd04.prod.outlook.com ([fe80::d30b:44e7:e78e:662d%4]) with mapi id 15.20.7386.017; Thu, 14 Mar 2024 13:27:19 +0000 From: "Peng Fan (OSS)" Date: Thu, 14 Mar 2024 21:35:19 +0800 Subject: [PATCH v5 2/4] dt-bindings: firmware: arm,scmi: support pinctrl protocol Message-Id: <20240314-pinctrl-scmi-v5-2-b19576e557f2@nxp.com> References: <20240314-pinctrl-scmi-v5-0-b19576e557f2@nxp.com> In-Reply-To: <20240314-pinctrl-scmi-v5-0-b19576e557f2@nxp.com> To: Sudeep Holla , Cristian Marussi , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Oleksii Moisieiev , Linus Walleij , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam , NXP Linux Team Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-gpio@vger.kernel.org, AKASHI Takahiro , Peng Fan , Rob Herring X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1710423327; l=2375; i=peng.fan@nxp.com; s=20230812; h=from:subject:message-id; bh=xWNejZclzOUqKROUnFYHgVlFI6BqdpjzWE8+IpqHKp8=; b=317nGOwnn1TiMFVscUa4xs9xpYTG+IsZ3UdOHV3mWSBSPM0cAYedarba1fh/a23ZeoMIfBvx+ t3NSj+vfz8TAoHt98WX99DWTDHX/afcb4DAfgArQU8oUPkW+22RzR5L X-Developer-Key: i=peng.fan@nxp.com; a=ed25519; pk=I4sJg7atIT1g63H7bb5lDRGR2gJW14RKDD0wFL8TT1g= X-ClientProxiedBy: SG2PR06CA0188.apcprd06.prod.outlook.com (2603:1096:4:1::20) To DU0PR04MB9417.eurprd04.prod.outlook.com (2603:10a6:10:358::11) Precedence: bulk X-Mailing-List: linux-gpio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DU0PR04MB9417:EE_|PAWPR04MB9861:EE_ X-MS-Office365-Filtering-Correlation-Id: 45fcbd0a-12b1-4975-93f4-08dc442a797d X-MS-Exchange-SharedMailbox-RoutingAgent-Processed: True X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: U97MrxKMY5B+dHDlv/+GIeKn2ViEhvJQO3elMrFtD7ay7HKUClOQVaVhpBNFMOpeTj6VbB1ZVCutIS9h5OP4lDXR6yGJbqtxtqcB4wVBdiyn3GMAAJoDuI8o2NQMutWcB2d2Dk8mEE9qlWDYyr0y56sPHfRGkq/44yEkFRm8CHv+JmaW9PpKDewbgRcUEq4PQkJgV03atICWSm5zoSyQq/3n09jMuDmHYoJYnEkN9Vro/LjnWIZHjRcq66TIvuIzvBdnCTzE3G3XALo2WDyIbXYfAtIEZjGaVh5qYHoHUn0zpA0nYgPwP+QOXzTuikj2yGicFnf8JuP8x8UMQc6ZcGftPmM5jFHpkMvKvwBXJkNpLnwgXqBr4OG3f8Bed/JR6xlThisGgg5IhejqSEDZFBrbqRcY1vjDbU0HnIZff7dimWpykutq5E9HT0j4qlZzy+IfwK6d6nH4ictrq6ImTKWUXJHwNYr9gaiIMb2S+hnnmFNwxOnOiL1OeSV5TTjbej+bM5S4qRpzlPCZelENDZp3RLJANYlebx/7sXvoHmSpSvoP9CWXuAfRiIkHefc9g/Xfg3JNoCqv2LAx01KmWXIoTQ47amk6+xxVxKU3thxPP0hYsPtrkUuI3yOAEltn7uPNtYjl+I4C2FTGGoDSB0XWSqbfrb8fFfP/8wre8aPF3pqDrge2rcMvpp6DqZBJpujYanS2V+XOd/fkPrP+I6gREKo1bMfOkLxxEPTnzDg= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:DU0PR04MB9417.eurprd04.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230031)(376005)(52116005)(7416005)(1800799015)(38350700005)(921011); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?X5vTtbish4ZjEykFq8c3rL4Pvg7B?= =?utf-8?q?dyMIFR/bTDUAOgbkpTLY/UthzHckrzhevG4M4wRz6jOfi2cUZJNbyhOj422z9szee?= =?utf-8?q?boXI4rqbJNtyV06GirMa2YqYiplhFwFmvcJeF17YxkiJRySl379YGH66JzGwukXG7?= =?utf-8?q?DGQnNMRgM5MKXX9pEqD9GTk9dnh7OKiRNVgygU9EQNxQud6NJ7q9OcjPuWhduJMOi?= =?utf-8?q?wrmWAAWl4cRoRNdQo1x6IC3NByVpRg6VanDrJIzziZ4vooS4Wl52QQjgoJt+pPajS?= =?utf-8?q?40b9kRRq5hjzexyQc+of3vKAh/WIsNf6nGWUyUoLyrzrUf967Y3S31PMYOB99gvoj?= =?utf-8?q?iQrBMUj0k8WRwEAsXjetZw9foXVLULPPOJdGCMv6E8z3lyCLvxbQO7lvEBwitWVHC?= =?utf-8?q?53ksCkZHVe8/CzepM+n/zzWFac2PO5dyq1VfrpjlwKIuZ6rSbYpJaKz7GW1VDapHc?= =?utf-8?q?/yjQyf12oHfu8rwDGabjjrPne42eKJGEdEU/r5ZIFpqgcn8+MAcDOGS6j8BnnBlvD?= =?utf-8?q?8UOGBcvFvZgoCUt7/eQ7W62QgKqz2VTX9KvrfcVZcverFlBzTTS4KYsJ1r0l+hb3h?= =?utf-8?q?zdBcDGX77JNQbm3CJf81GQAjBFQNANQStkGYmoNY4hm6AJVKvyYLB1mqd8EZemJDr?= =?utf-8?q?V9CVFDV7swrmnXq03JDH/T2RwiGO1kINuqfsAy2m2MRsRx7Id/sM39CF2D58uwWo0?= =?utf-8?q?toDah/v8l5JLOVBZjpuB3XWR4LIPCS8fgI3RqdSA2ISNM8jL5TPmGVJUJ65KLvfc2?= =?utf-8?q?6xyg1on6w1NQbP99IPQmUvgPWG4qj4vWUJJgRBfR/ontA7b/9edtxhMT+fXts20H6?= =?utf-8?q?JRA56F8C9OPIQJvrqduKnf/drPkHUk9J5lASBgbC8SuIf9CBl8ftmbVzyyaAkc+Uv?= =?utf-8?q?zeqtgUqQFntm2F+nhCgcPjZPS5oeD3jcHdNBQPXHFcmyWxrx73H8ZzMWYBHIfj4P9?= =?utf-8?q?inuYnPv7j3zI7bdAjGnSYbNwtCb8CmmMR2n58NVcrfBMOgHJFul2LUzWMkqPdXtaQ?= =?utf-8?q?1mlfDUHuXd+3UZwg5Ikk+dFXdj/TVDBDEFfPZScCQ7dFhdrD6aMFLYeu7JA9defps?= =?utf-8?q?6EFfnI64rkVvFJo4avKuyXKhot0UWim1iJX1JRbQgW1pwd5g0ty3k71EIwlIC1mf/?= =?utf-8?q?Fiz2ecutAqsw2bBvdkz6rh6hwQtjs2M+OOM1YzGI7dxrrjQvGosdE4Nfe7GfAaiKP?= =?utf-8?q?qtQkxGg6gw4PtRoVxAy9PIhPCQRrRQxiNs0K5OVgKj70qfVggLTfuC207vabuqCjO?= =?utf-8?q?rkPA8mAlpUnQPgyjSEtkO+olo3hlyHokM36CmnL+J9tV3HY6brueyxUDpWZdDWcnn?= =?utf-8?q?JbMp3L4tdZEFJSMDNHVMDibNC+WR1JM1k1a/ykHIVPABMgMhTfefEjIrVCUi4litd?= =?utf-8?q?i1kHgmF1vmdjVD5Bt0X+SeSk8yxeuN6HGTwl/21fSydY5bQvfeDud+eK2ZPU86XPS?= =?utf-8?q?Dpi6V06kuuOMaQwBvi+Jw5heZT+/9tsMr7mC7deHtglrF3vSFEueXchIfu9+LNMMw?= =?utf-8?q?vmOxsg+2bOiE?= X-OriginatorOrg: oss.nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 45fcbd0a-12b1-4975-93f4-08dc442a797d X-MS-Exchange-CrossTenant-AuthSource: DU0PR04MB9417.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 14 Mar 2024 13:27:19.8345 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: wyNqA3iCfLowopmS4Mf/+GMrj9sNHR6lgaVUY/+8f615iKLSt3W46U/oKvIimN56ODQKyUdzkZdDycQYT+6zvg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAWPR04MB9861 From: Peng Fan Add SCMI v3.2 pinctrl protocol bindings and example. Reviewed-by: Rob Herring Reviewed-by: Linus Walleij Signed-off-by: Peng Fan --- .../devicetree/bindings/firmware/arm,scmi.yaml | 50 ++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml index 4591523b51a0..bba4a37de6b4 100644 --- a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml +++ b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml @@ -247,6 +247,37 @@ properties: reg: const: 0x18 + protocol@19: + type: object + allOf: + - $ref: '#/$defs/protocol-node' + - $ref: /schemas/pinctrl/pinctrl.yaml + + unevaluatedProperties: false + + properties: + reg: + const: 0x19 + + patternProperties: + '-pins$': + type: object + allOf: + - $ref: /schemas/pinctrl/pincfg-node.yaml# + - $ref: /schemas/pinctrl/pinmux-node.yaml# + unevaluatedProperties: false + + description: + A pin multiplexing sub-node describe how to configure a + set of pins is some desired function. + A single sub-node may define several pin configurations. + This sub-node is using default pinctrl bindings to configure + pin multiplexing and using SCMI protocol to apply specified + configuration using SCMI protocol. + + required: + - reg + additionalProperties: false $defs: @@ -401,6 +432,25 @@ examples: scmi_powercap: protocol@18 { reg = <0x18>; }; + + scmi_pinctrl: protocol@19 { + reg = <0x19>; + + i2c2-pins { + groups = "g_i2c2_a", "g_i2c2_b"; + function = "f_i2c2"; + }; + + mdio-pins { + groups = "g_avb_mdio"; + drive-strength = <24>; + }; + + keys_pins: keys-pins { + pins = "gpio_5_17", "gpio_5_20", "gpio_5_22", "gpio_2_1"; + bias-pull-up; + }; + }; }; }; From patchwork Thu Mar 14 13:35:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Peng Fan \(OSS\)" X-Patchwork-Id: 780407 Received: from EUR03-DBA-obe.outbound.protection.outlook.com (mail-dbaeur03on2074.outbound.protection.outlook.com [40.107.104.74]) (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 818FE6FE22; Thu, 14 Mar 2024 13:27:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.104.74 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710422851; cv=fail; b=sttfXOUgaAoTWeGmixt12hXPfEsUuuIbkcGV06uD2GGOGgoSAcY8SwKOjuGaFTHx0xTZ9C+zxFBYLCwML3mEVOo4MVB9uJsKX5x03MpztDM/rYekUjDcFBbMnoA5ZE9S/uVVUnoaQj/D1nRNH1Q+FYPcuQ2B/2R6SVVHmIhdVVU= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710422851; c=relaxed/simple; bh=tH0eC01P1SodZKI50kIXMHtNzY3s86HNL4/2f2223Bs=; h=From:Date:Subject:Content-Type:Message-Id:References:In-Reply-To: To:Cc:MIME-Version; b=hE/9nZiyQzabtON9jUn44qYAxyyTWVSJfykPakL+6aSsvuhA7DtuZ0anw1N7juzQAxFfVB8RsHzfWWNZaexJqMxyW1N4NqMEOmIoWb/YWjPhwtK4D0DEKbxFLGTfgstLYvBR0bNgIGP7AR3YfhT4ZaLgsL2HuRCi4m2PHIPAPKE= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=oss.nxp.com; spf=pass smtp.mailfrom=oss.nxp.com; dkim=pass (1024-bit key) header.d=NXP1.onmicrosoft.com header.i=@NXP1.onmicrosoft.com header.b=ZHhYhe2Y; arc=fail smtp.client-ip=40.107.104.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=oss.nxp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.nxp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=NXP1.onmicrosoft.com header.i=@NXP1.onmicrosoft.com header.b="ZHhYhe2Y" ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=hgYZpKBQR23OM0C5diJN7ncjNdRv1pPch7L3vuMYfsnwVQZRBtHCF/J2jlvmYXfj8jLUeRr0Q5Tn5H1P8oJ/xG1d8IIamEAJ4JeFtU9VBLR3L5bLMpJ2WBKciETQc/HGOXfd6/DrwMwHUWFx/tx24M2QiTDUQanLOdWzQc7p20dCF3ic+Oyj8JTVeqfcuXBh2Ro7H51gEToqxOeiCQZNin9c3kZuNSaw9te+Lg+qGAH10M+z3YwCyi5tFSK19jMSKFHEM13zrhgI0atL8OzItmpvG3civ1gKCCOPBe8z1+PuyIMjoj5RWYgDb+LVdi8j+eNvYHcaXU762Mvtk3HQ+g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=XS4cAFTg6rut/mYml6sCuuTOigzwfuxEsF8o4aFYzec=; b=DXsGgmpq0WSrLEJArwHscXVp+iTHUOypLBIs0eYfPjVa4Nta6PIpak2d7DjbvjtglAE3ZjkUkeDc+N7wHlfTTvAaMFCITskMUW6C350OhplfR7RDP/xxPMgwPFmQfmMozChjAj04qv51XG6qa8wktO9FoU2BEcY4+QRj4aSKCsW27rZVv6FgmR1Q8gv0p5Yte6m1t68fkTsw8hAatvBR7GPtIOcvaf63NKiFVAqINFhy5ga28uamQHZjMKfbUbWOmQl1TWzsxOM3nPfuP39oCcNdm8DhPH60RVxvxIoFP70l1bwdh0/sHNFK7ZqLKlEJ3l5Hd23qYOu6ZBFtYId84w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oss.nxp.com; dmarc=pass action=none header.from=oss.nxp.com; dkim=pass header.d=oss.nxp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=NXP1.onmicrosoft.com; s=selector2-NXP1-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=XS4cAFTg6rut/mYml6sCuuTOigzwfuxEsF8o4aFYzec=; b=ZHhYhe2YpzYVO81iEhAwm5rZq6jMHIMVOPdISeIuFWVt+gB3+WQ7HxzU/lqaY8wE7gK4ndp1BiMsQbJ7GabFG2f5GILzg79A6KBAjsVVqKgVj+sL1134wdttElvhMq8+I+mTifmmy2BJt+tjBDMC2yetd/ySZcmv2kwUYWwkuHs= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=oss.nxp.com; Received: from DU0PR04MB9417.eurprd04.prod.outlook.com (2603:10a6:10:358::11) by PAWPR04MB9861.eurprd04.prod.outlook.com (2603:10a6:102:381::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7362.36; Thu, 14 Mar 2024 13:27:25 +0000 Received: from DU0PR04MB9417.eurprd04.prod.outlook.com ([fe80::d30b:44e7:e78e:662d]) by DU0PR04MB9417.eurprd04.prod.outlook.com ([fe80::d30b:44e7:e78e:662d%4]) with mapi id 15.20.7386.017; Thu, 14 Mar 2024 13:27:25 +0000 From: "Peng Fan (OSS)" Date: Thu, 14 Mar 2024 21:35:20 +0800 Subject: [PATCH v5 3/4] firmware: arm_scmi: Add SCMI v3.2 pincontrol protocol basic support Message-Id: <20240314-pinctrl-scmi-v5-3-b19576e557f2@nxp.com> References: <20240314-pinctrl-scmi-v5-0-b19576e557f2@nxp.com> In-Reply-To: <20240314-pinctrl-scmi-v5-0-b19576e557f2@nxp.com> To: Sudeep Holla , Cristian Marussi , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Oleksii Moisieiev , Linus Walleij , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam , NXP Linux Team Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-gpio@vger.kernel.org, AKASHI Takahiro , Peng Fan X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1710423327; l=28800; i=peng.fan@nxp.com; s=20230812; h=from:subject:message-id; bh=XZwzoonOhaJxlQjlsC99F8HeyGsNpcCXiDYSm0qP2Ws=; b=DRJlM0aVKmUAkoQMvJbHjPiGQNcPmGrWEemX7HoN/RQWk1CjUM9eL9Nf+PGcb/ezgVJ0+nvAT /JbOQdISkZ1Af6wiIOfyZQIL25PNs0W2g7jTzCBqLfF4rrIm308j+45 X-Developer-Key: i=peng.fan@nxp.com; a=ed25519; pk=I4sJg7atIT1g63H7bb5lDRGR2gJW14RKDD0wFL8TT1g= X-ClientProxiedBy: SG2PR06CA0188.apcprd06.prod.outlook.com (2603:1096:4:1::20) To DU0PR04MB9417.eurprd04.prod.outlook.com (2603:10a6:10:358::11) Precedence: bulk X-Mailing-List: linux-gpio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DU0PR04MB9417:EE_|PAWPR04MB9861:EE_ X-MS-Office365-Filtering-Correlation-Id: 7e015a2b-42d8-4489-467f-08dc442a7c9d X-MS-Exchange-SharedMailbox-RoutingAgent-Processed: True X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: AkZMWNXXrS6qnwKX+suLVKc4t3qXoMu5QC3NGJwmxe+p+U46MFzzoit+nvv/bFrvai4IPIx1/D8HsxpANqhMuj5FSUVl9CTVRvJCfHnPeabjpkZNs6nA9ULLESG4ZYjPA53x+REYMjBXiCKpN4Ooaw8gi3kuBxBY2GGDrpkeatI5v3Xj3sDBqDWN/MnO1mMIF7GMinAarG+5luXxokdhMuSRiJM6T3sOKydnwh+UK/l+eMTJgYfR0xA4BUBaf2c6T5t9/5i4Hrbcuwv/lBPvjWPEkdf2W1Q0TAWj4YbSOAfU1PhR4f6UBmQS517zo6Y2NMQ8KnXdLn1J/sIDqO7imBAi5n/zgPbOCwRfATvnd5EalgqelXRiCDYkKzzHQ6P/qty5bNw3ss2eH7Y1kEPVbkSj1ML7XSMa7pqfiUeejUVbfBZwo6oD2ZKJ3RdKSoMu/1gH5a2xyurcHA5Bz8onglhAgvhlYMo3BGjOlIMbelWKq8clBOIpJnwqqe4P0O9/T8D27EQvjtzJZCj8l4UXky260yJA2k3iQtoKcKKyBOo4FsgzVzkMhY5sR/If8ndzwxQ6zLqJq41BtlZpv7UBTg5IbheVm/H6dRCYZQMIDi/z4H2iErvnINQhfpyznfNqum4t1t5F97+BgK7Tg2RYBrVZmNHoz9rZw3FPeS8z3eA/pZ8DdH/gQhuUynAVx0E4xA5aZ4WruP6PEX/eQSFfN3rEmmnHKLZTdzbXCDmcbtY= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:DU0PR04MB9417.eurprd04.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230031)(376005)(52116005)(7416005)(1800799015)(38350700005)(921011); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?Vmmee7r81thkBmrrzmnmJ+0kGTNE?= =?utf-8?q?IO7FIUu4AXAmGU25M/iTtw4WLhQhLFwnLNGiNGKugb2/5xUTwGvpd7Cjz24qyu81q?= =?utf-8?q?MsMYGNK7u+toPbGfl3ET4lA4WKsOjfzMzuIyKPDuDvOoFIlUfkvSdwaFVx4VXxPNp?= =?utf-8?q?2nIItB47EB8ej+W+CevwnAeZwlHE0H8/nG5ocKLunOQ9xVgjKJR1fCr+rqO+VRLlP?= =?utf-8?q?B4tGRQWUZzuv7iGJ1H7JIlrhz1gj4zN94M/PTkcm41L3NfM6+JQIyQ9jxgZ3aZlvG?= =?utf-8?q?UxK+ZaFfMwHIUAr6N+UuVJSYuRTBoKHyaM6ybCQKrMij2ohjeqfjyReMMX2kUldcF?= =?utf-8?q?pKngyB2nnOY7AnBD+J6Zm0L0QQRYTT90roSyOqqZWHUxg44rBAnF5QNm8+Y6k16T8?= =?utf-8?q?sYiuPeSMyyr4yseV8tfvrO8DSvBH8S5Bi4AdZj+sksvWASL5adxOFgD0QkbVJgVAz?= =?utf-8?q?I2N9y/ibiEyhRJwgFwxjeKOSLpFVgds3yzfX26A3HkLRBqegrBQP9r0MEDZpqhePB?= =?utf-8?q?4d9T4xbHlG2qiIpC/NDWQ/BKnf/Yln+V8InuBvb4ySaWduFLSMjx0YP8VNWQCNeYU?= =?utf-8?q?4RDAVf8zCN+maTfhmRlSLvHq0njAiSFLppMNp1OJVAC+pjQRF1+ooAh6gl9H1KMvn?= =?utf-8?q?eBAz5aN/m7aXvPARUfFLEXGQ1R4MSPAPuqV+pC7EzlHbW0M9IkqI+T9XYhRv1/nem?= =?utf-8?q?PM9yPU4mDWBP5/gIICULAv/vz7GWVtyB9iYcU7OrlFy40ATdZcVRPu5AxU/9u2wyb?= =?utf-8?q?QaJUcOfdjcCTqmQDRmR+fdAaIwpU38ym2/M7d9IKPSVZisR9SvXt9Cusfc45MFu/M?= =?utf-8?q?M7+7W/ppU44F7cZha+OrUaZG17OIdKgUQAJnmoSQlsoA4mN3qhcSG5lgDXTqMuGS+?= =?utf-8?q?3MoQEk+guNyl7n6VSesyM+yQA6llv5ygnqXhtnNOVsj/m+8Vu76bKDYghUGUoRJkA?= =?utf-8?q?zyBc5pIloqgwPe8ykwQwENnUCGvRWQ2267xoAlBvH69SbhmT/8N+j/NAH6EldXkFk?= =?utf-8?q?19MvrtO9+i/nOeD1lS0RnnSdCwSCzIzX4cjvi8La/De6CoN0SuBgKQoJdzNMSzvcH?= =?utf-8?q?awTPU3N4LOuBeBhUOWF0BI35YD3gaxMbBHOj3FoYqlxectakHRfHHFjNX4yV4XRi2?= =?utf-8?q?K4Xm/jPqd/2Y4SKaD1co+MZWV2kecXE/YMFa7vsk7g+ChJZKg5/FyxgvQVJIji5L8?= =?utf-8?q?ZwAHQF3Npq53ZS2kIv3dI8XUjDvC74v2RbgGtnYdC6jFqrhRVKM0XAWJqOoN8dmPi?= =?utf-8?q?JqtleGiR7UH9LvugbbuSNinOkY8nLsuVRhHaTyrS+YTl/B8eZBdpuVJ64uzJVeQCN?= =?utf-8?q?rYt+nM8zqMZ2kEgCIbhvbQdBxu65W7aeklUqJemCNUygIxlMoyPYwiFPVsaeaXI6t?= =?utf-8?q?3LWM+qabaQu1sqYhjqSWC9UN0izmSOinubZuzOu+J2AqpBsy1+EstdEFsubh06DGU?= =?utf-8?q?Z7VxHObX2OaBoqINtCg4Jd8yNgocUkHBEt8KBGmuzooRfcQ6Sh/1kjInU+ye8hr3p?= =?utf-8?q?0uGaheq7hGX9?= X-OriginatorOrg: oss.nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 7e015a2b-42d8-4489-467f-08dc442a7c9d X-MS-Exchange-CrossTenant-AuthSource: DU0PR04MB9417.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 14 Mar 2024 13:27:25.1137 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: ijK+bBsnVFiPFIUovS/ZBEQ5Sq6qdFUgL3aVajiZKbzARX7kvsMVUp9JZN1zvHK2zJPwTjVj5BZz/HUCiClhQQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAWPR04MB9861 From: Oleksii Moisieiev Add basic implementation of the SCMI v3.2 pincontrol protocol. Reviewed-by: Cristian Marussi Tested-by: Cristian Marussi Reviewed-by: Linus Walleij Signed-off-by: Oleksii Moisieiev Co-developed-by: Peng Fan Signed-off-by: Peng Fan --- drivers/firmware/arm_scmi/Makefile | 1 + drivers/firmware/arm_scmi/driver.c | 2 + drivers/firmware/arm_scmi/pinctrl.c | 908 ++++++++++++++++++++++++++++++++++ drivers/firmware/arm_scmi/protocols.h | 1 + include/linux/scmi_protocol.h | 75 +++ 5 files changed, 987 insertions(+) diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/arm_scmi/Makefile index a7bc4796519c..8e3874ff1544 100644 --- a/drivers/firmware/arm_scmi/Makefile +++ b/drivers/firmware/arm_scmi/Makefile @@ -11,6 +11,7 @@ scmi-transport-$(CONFIG_ARM_SCMI_HAVE_MSG) += msg.o scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO) += virtio.o scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) += optee.o scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o system.o voltage.o powercap.o +scmi-protocols-y += pinctrl.o scmi-module-objs := $(scmi-driver-y) $(scmi-protocols-y) $(scmi-transport-y) obj-$(CONFIG_ARM_SCMI_PROTOCOL) += scmi-core.o diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 415e6f510057..ac2d4b19727c 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -3142,6 +3142,7 @@ static int __init scmi_driver_init(void) scmi_voltage_register(); scmi_system_register(); scmi_powercap_register(); + scmi_pinctrl_register(); return platform_driver_register(&scmi_driver); } @@ -3159,6 +3160,7 @@ static void __exit scmi_driver_exit(void) scmi_voltage_unregister(); scmi_system_unregister(); scmi_powercap_unregister(); + scmi_pinctrl_unregister(); scmi_transports_exit(); diff --git a/drivers/firmware/arm_scmi/pinctrl.c b/drivers/firmware/arm_scmi/pinctrl.c new file mode 100644 index 000000000000..0fcfa4269473 --- /dev/null +++ b/drivers/firmware/arm_scmi/pinctrl.c @@ -0,0 +1,908 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * System Control and Management Interface (SCMI) Pinctrl Protocol + * + * Copyright (C) 2024 EPAM + * Copyright 2024 NXP + */ + +#include +#include +#include + +#include "common.h" +#include "protocols.h" + +/* Updated only after ALL the mandatory features for that version are merged */ +#define SCMI_PROTOCOL_SUPPORTED_VERSION 0x0 + +#define REG_TYPE_BITS GENMASK(9, 8) +#define REG_CONFIG GENMASK(7, 0) + +#define GET_GROUPS_NR(x) le32_get_bits((x), GENMASK(31, 16)) +#define GET_PINS_NR(x) le32_get_bits((x), GENMASK(15, 0)) +#define GET_FUNCTIONS_NR(x) le32_get_bits((x), GENMASK(15, 0)) + +#define EXT_NAME_FLAG(x) le32_get_bits((x), BIT(31)) +#define NUM_ELEMS(x) le32_get_bits((x), GENMASK(15, 0)) + +#define REMAINING(x) le32_get_bits((x), GENMASK(31, 16)) +#define RETURNED(x) le32_get_bits((x), GENMASK(11, 0)) + +enum scmi_pinctrl_protocol_cmd { + PINCTRL_ATTRIBUTES = 0x3, + PINCTRL_LIST_ASSOCIATIONS = 0x4, + PINCTRL_CONFIG_GET = 0x5, + PINCTRL_CONFIG_SET = 0x6, + PINCTRL_FUNCTION_SELECT = 0x7, + PINCTRL_REQUEST = 0x8, + PINCTRL_RELEASE = 0x9, + PINCTRL_NAME_GET = 0xa, + PINCTRL_SET_PERMISSIONS = 0xb +}; + +struct scmi_msg_conf_set { + __le32 identifier; + __le32 attributes; + __le32 configs[]; +}; + +struct scmi_msg_conf_get { + __le32 identifier; + __le32 attributes; +}; + +struct scmi_resp_conf_get { + __le32 num_configs; + __le32 configs[]; +}; + +struct scmi_msg_pinctrl_protocol_attributes { + __le32 attributes_low; + __le32 attributes_high; +}; + +struct scmi_msg_pinctrl_attributes { + __le32 identifier; + __le32 flags; +}; + +struct scmi_resp_pinctrl_attributes { + __le32 attributes; + u8 name[SCMI_SHORT_NAME_MAX_SIZE]; +}; + +struct scmi_msg_pinctrl_list_assoc { + __le32 identifier; + __le32 flags; + __le32 index; +}; + +struct scmi_resp_pinctrl_list_assoc { + __le32 flags; + __le16 array[]; +}; + +struct scmi_msg_func_set { + __le32 identifier; + __le32 function_id; + __le32 flags; +}; + +struct scmi_msg_request { + __le32 identifier; + __le32 flags; +}; + +struct scmi_group_info { + char name[SCMI_MAX_STR_SIZE]; + bool present; + unsigned int *group_pins; + unsigned int nr_pins; +}; + +struct scmi_function_info { + char name[SCMI_MAX_STR_SIZE]; + bool present; + unsigned int *groups; + unsigned int nr_groups; +}; + +struct scmi_pin_info { + char name[SCMI_MAX_STR_SIZE]; + bool present; +}; + +struct scmi_pinctrl_info { + u32 version; + int nr_groups; + int nr_functions; + int nr_pins; + struct scmi_group_info *groups; + struct scmi_function_info *functions; + struct scmi_pin_info *pins; +}; + +static int scmi_pinctrl_attributes_get(const struct scmi_protocol_handle *ph, + struct scmi_pinctrl_info *pi) +{ + int ret; + struct scmi_xfer *t; + struct scmi_msg_pinctrl_protocol_attributes *attr; + + ret = ph->xops->xfer_get_init(ph, PROTOCOL_ATTRIBUTES, 0, sizeof(*attr), + &t); + if (ret) + return ret; + + attr = t->rx.buf; + + ret = ph->xops->do_xfer(ph, t); + if (!ret) { + pi->nr_functions = GET_FUNCTIONS_NR(attr->attributes_high); + pi->nr_groups = GET_GROUPS_NR(attr->attributes_low); + pi->nr_pins = GET_PINS_NR(attr->attributes_low); + } + + ph->xops->xfer_put(ph, t); + return ret; +} + +static int scmi_pinctrl_count_get(const struct scmi_protocol_handle *ph, + enum scmi_pinctrl_selector_type type) +{ + struct scmi_pinctrl_info *pi = ph->get_priv(ph); + + switch (type) { + case PIN_TYPE: + return pi->nr_pins; + case GROUP_TYPE: + return pi->nr_groups; + case FUNCTION_TYPE: + return pi->nr_functions; + default: + return -EINVAL; + } +} + +static int scmi_pinctrl_validate_id(const struct scmi_protocol_handle *ph, + u32 identifier, + enum scmi_pinctrl_selector_type type) +{ + int value; + + value = scmi_pinctrl_count_get(ph, type); + if (value < 0) + return value; + + if (identifier >= value) + return -EINVAL; + + return 0; +} + +static int scmi_pinctrl_attributes(const struct scmi_protocol_handle *ph, + enum scmi_pinctrl_selector_type type, + u32 selector, char *name, + unsigned int *n_elems) +{ + int ret; + struct scmi_xfer *t; + struct scmi_msg_pinctrl_attributes *tx; + struct scmi_resp_pinctrl_attributes *rx; + + if (!name) + return -EINVAL; + + ret = scmi_pinctrl_validate_id(ph, selector, type); + if (ret) + return ret; + + ret = ph->xops->xfer_get_init(ph, PINCTRL_ATTRIBUTES, sizeof(*tx), + sizeof(*rx), &t); + if (ret) + return ret; + + tx = t->tx.buf; + rx = t->rx.buf; + tx->identifier = cpu_to_le32(selector); + tx->flags = cpu_to_le32(type); + + ret = ph->xops->do_xfer(ph, t); + if (!ret) { + if (n_elems) + *n_elems = NUM_ELEMS(rx->attributes); + + strscpy(name, rx->name, SCMI_SHORT_NAME_MAX_SIZE); + } + + ph->xops->xfer_put(ph, t); + + /* + * If supported overwrite short name with the extended one; + * on error just carry on and use already provided short name. + */ + if (!ret && EXT_NAME_FLAG(rx->attributes)) + ph->hops->extended_name_get(ph, PINCTRL_NAME_GET, selector, + (u32 *)&type, name, + SCMI_MAX_STR_SIZE); + return ret; +} + +struct scmi_pinctrl_ipriv { + u32 selector; + enum scmi_pinctrl_selector_type type; + unsigned int *array; +}; + +static void iter_pinctrl_assoc_prepare_message(void *message, + unsigned int desc_index, + const void *priv) +{ + struct scmi_msg_pinctrl_list_assoc *msg = message; + const struct scmi_pinctrl_ipriv *p = priv; + + msg->identifier = cpu_to_le32(p->selector); + msg->flags = cpu_to_le32(p->type); + /* Set the number of OPPs to be skipped/already read */ + msg->index = cpu_to_le32(desc_index); +} + +static int iter_pinctrl_assoc_update_state(struct scmi_iterator_state *st, + const void *response, void *priv) +{ + const struct scmi_resp_pinctrl_list_assoc *r = response; + + st->num_returned = RETURNED(r->flags); + st->num_remaining = REMAINING(r->flags); + + return 0; +} + +static int +iter_pinctrl_assoc_process_response(const struct scmi_protocol_handle *ph, + const void *response, + struct scmi_iterator_state *st, void *priv) +{ + const struct scmi_resp_pinctrl_list_assoc *r = response; + struct scmi_pinctrl_ipriv *p = priv; + + p->array[st->desc_index + st->loop_idx] = + le16_to_cpu(r->array[st->loop_idx]); + + return 0; +} + +static int scmi_pinctrl_list_associations(const struct scmi_protocol_handle *ph, + u32 selector, + enum scmi_pinctrl_selector_type type, + u16 size, unsigned int *array) +{ + int ret; + void *iter; + struct scmi_iterator_ops ops = { + .prepare_message = iter_pinctrl_assoc_prepare_message, + .update_state = iter_pinctrl_assoc_update_state, + .process_response = iter_pinctrl_assoc_process_response, + }; + struct scmi_pinctrl_ipriv ipriv = { + .selector = selector, + .type = type, + .array = array, + }; + + if (!array || !size || type == PIN_TYPE) + return -EINVAL; + + ret = scmi_pinctrl_validate_id(ph, selector, type); + if (ret) + return ret; + + iter = ph->hops->iter_response_init(ph, &ops, size, + PINCTRL_LIST_ASSOCIATIONS, + sizeof(struct scmi_msg_pinctrl_list_assoc), + &ipriv); + + if (IS_ERR(iter)) + return PTR_ERR(iter); + + return ph->hops->iter_response_run(iter); +} + +struct scmi_conf_get_ipriv { + u32 selector; + enum scmi_pinctrl_selector_type type; + u8 all; + enum scmi_pinctrl_conf_type *config_types; + u32 *config_values; +}; + +static void iter_pinctrl_conf_get_prepare_message(void *message, + unsigned int desc_index, + const void *priv) +{ + struct scmi_msg_conf_get *msg = message; + const struct scmi_conf_get_ipriv *p = priv; + u32 attributes; + + attributes = FIELD_PREP(BIT(18), p->all) | + FIELD_PREP(GENMASK(17, 16), p->type); + + if (p->all) + attributes |= FIELD_PREP(GENMASK(15, 8), desc_index); + else + attributes |= FIELD_PREP(GENMASK(7, 0), p->config_types[0]); + + msg->attributes = cpu_to_le32(attributes); + msg->identifier = cpu_to_le32(p->selector); +} + +static int iter_pinctrl_conf_get_update_state(struct scmi_iterator_state *st, + const void *response, void *priv) +{ + const struct scmi_resp_conf_get *r = response; + struct scmi_conf_get_ipriv *p = priv; + + if (!p->all) { + st->num_returned = 1; + st->num_remaining = 0; + } else { + st->num_returned = le32_get_bits(r->num_configs, GENMASK(7, 0)); + st->num_remaining = le32_get_bits(r->num_configs, + GENMASK(31, 24)); + } + + return 0; +} + +static int +iter_pinctrl_conf_get_process_response(const struct scmi_protocol_handle *ph, + const void *response, + struct scmi_iterator_state *st, + void *priv) +{ + const struct scmi_resp_conf_get *r = response; + struct scmi_conf_get_ipriv *p = priv; + + if (!p->all) { + if (p->config_types[0] != + le32_get_bits(r->configs[st->loop_idx * 2], GENMASK(7, 0))) + return -EINVAL; + } else { + p->config_types[st->desc_index + st->loop_idx] = + le32_get_bits(r->configs[st->loop_idx * 2], + GENMASK(7, 0)); + } + + p->config_values[st->desc_index + st->loop_idx] = + le32_to_cpu(r->configs[st->loop_idx * 2 + 1]); + + return 0; +} + +static int +scmi_pinctrl_config_get(const struct scmi_protocol_handle *ph, u32 selector, + enum scmi_pinctrl_selector_type type, + enum scmi_pinctrl_conf_type config_type, + u32 *config_value) +{ + int ret; + void *iter; + struct scmi_iterator_ops ops = { + .prepare_message = iter_pinctrl_conf_get_prepare_message, + .update_state = iter_pinctrl_conf_get_update_state, + .process_response = iter_pinctrl_conf_get_process_response, + }; + struct scmi_conf_get_ipriv ipriv = { + .selector = selector, + .type = type, + .all = 0, + .config_types = &config_type, + .config_values = config_value, + }; + + if (!config_value || type == FUNCTION_TYPE) + return -EINVAL; + + ret = scmi_pinctrl_validate_id(ph, selector, type); + if (ret) + return ret; + + iter = ph->hops->iter_response_init(ph, &ops, 1, PINCTRL_CONFIG_GET, + sizeof(struct scmi_msg_conf_get), + &ipriv); + + if (IS_ERR(iter)) + return PTR_ERR(iter); + + return ph->hops->iter_response_run(iter); +} + +static int +scmi_pinctrl_config_set(const struct scmi_protocol_handle *ph, u32 selector, + enum scmi_pinctrl_selector_type type, + unsigned int nr_configs, + enum scmi_pinctrl_conf_type *config_type, + u32 *config_value) +{ + struct scmi_xfer *t; + struct scmi_msg_conf_set *tx; + u32 attributes; + int ret, i; + unsigned int configs_in_chunk, conf_num = 0; + unsigned int chunk; + int max_msg_size = ph->hops->get_max_msg_size(ph); + + if (!config_type || !config_value || type == FUNCTION_TYPE) + return -EINVAL; + + ret = scmi_pinctrl_validate_id(ph, selector, type); + if (ret) + return ret; + + configs_in_chunk = (max_msg_size - sizeof(*tx)) / (sizeof(__le32) * 2); + while (conf_num < nr_configs) { + chunk = (nr_configs - conf_num > configs_in_chunk) ? + configs_in_chunk : nr_configs - conf_num; + + ret = ph->xops->xfer_get_init(ph, PINCTRL_CONFIG_SET, + sizeof(*tx) + + chunk * 2 * sizeof(__le32), + 0, &t); + if (ret) + return ret; + + tx = t->tx.buf; + tx->identifier = cpu_to_le32(selector); + attributes = FIELD_PREP(GENMASK(1, 0), type) | + FIELD_PREP(GENMASK(9, 2), chunk); + tx->attributes = cpu_to_le32(attributes); + + for (i = 0; i < chunk; i++) { + tx->configs[i * 2] = + cpu_to_le32(config_type[conf_num + i]); + tx->configs[i * 2 + 1] = + cpu_to_le32(config_value[conf_num + i]); + } + + ret = ph->xops->do_xfer(ph, t); + + ph->xops->xfer_put(ph, t); + + if (ret) + break; + + conf_num += chunk; + } + + return ret; +} + +static int scmi_pinctrl_function_select(const struct scmi_protocol_handle *ph, + u32 identifier, + enum scmi_pinctrl_selector_type type, + u32 function_id) +{ + int ret; + struct scmi_xfer *t; + struct scmi_msg_func_set *tx; + + if (type == FUNCTION_TYPE) + return -EINVAL; + + ret = scmi_pinctrl_validate_id(ph, identifier, type); + if (ret) + return ret; + + ret = ph->xops->xfer_get_init(ph, PINCTRL_FUNCTION_SELECT, sizeof(*tx), + 0, &t); + if (ret) + return ret; + + tx = t->tx.buf; + tx->identifier = cpu_to_le32(identifier); + tx->function_id = cpu_to_le32(function_id); + tx->flags = cpu_to_le32(type); + + ret = ph->xops->do_xfer(ph, t); + ph->xops->xfer_put(ph, t); + + return ret; +} + +static int scmi_pinctrl_request(const struct scmi_protocol_handle *ph, + u32 identifier, + enum scmi_pinctrl_selector_type type) +{ + int ret; + struct scmi_xfer *t; + struct scmi_msg_request *tx; + + if (type == FUNCTION_TYPE) + return -EINVAL; + + ret = scmi_pinctrl_validate_id(ph, identifier, type); + if (ret) + return ret; + + ret = ph->xops->xfer_get_init(ph, PINCTRL_REQUEST, sizeof(*tx), 0, &t); + + tx = t->tx.buf; + tx->identifier = cpu_to_le32(identifier); + tx->flags = cpu_to_le32(type); + + ret = ph->xops->do_xfer(ph, t); + ph->xops->xfer_put(ph, t); + + return ret; +} + +static int scmi_pinctrl_pin_request(const struct scmi_protocol_handle *ph, + u32 pin) +{ + return scmi_pinctrl_request(ph, pin, PIN_TYPE); +} + +static int scmi_pinctrl_free(const struct scmi_protocol_handle *ph, + u32 identifier, + enum scmi_pinctrl_selector_type type) +{ + int ret; + struct scmi_xfer *t; + struct scmi_msg_request *tx; + + if (type == FUNCTION_TYPE) + return -EINVAL; + + ret = scmi_pinctrl_validate_id(ph, identifier, type); + if (ret) + return ret; + + ret = ph->xops->xfer_get_init(ph, PINCTRL_RELEASE, sizeof(*tx), 0, &t); + + tx = t->tx.buf; + tx->identifier = cpu_to_le32(identifier); + tx->flags = cpu_to_le32(type); + + ret = ph->xops->do_xfer(ph, t); + ph->xops->xfer_put(ph, t); + + return ret; +} + +static int scmi_pinctrl_pin_free(const struct scmi_protocol_handle *ph, u32 pin) +{ + return scmi_pinctrl_free(ph, pin, PIN_TYPE); +} + +static int scmi_pinctrl_get_group_info(const struct scmi_protocol_handle *ph, + u32 selector, + struct scmi_group_info *group) +{ + int ret; + + if (!group) + return -EINVAL; + + ret = scmi_pinctrl_attributes(ph, GROUP_TYPE, selector, + group->name, + &group->nr_pins); + if (ret) + return ret; + + if (!group->nr_pins) { + dev_err(ph->dev, "Group %d has 0 elements", selector); + return -ENODATA; + } + + group->group_pins = kmalloc_array(group->nr_pins, + sizeof(*group->group_pins), + GFP_KERNEL); + if (!group->group_pins) + return -ENOMEM; + + ret = scmi_pinctrl_list_associations(ph, selector, GROUP_TYPE, + group->nr_pins, group->group_pins); + if (ret) { + kfree(group->group_pins); + return ret; + } + + group->present = true; + return 0; +} + +static int scmi_pinctrl_get_group_name(const struct scmi_protocol_handle *ph, + u32 selector, const char **name) +{ + struct scmi_pinctrl_info *pi = ph->get_priv(ph); + + if (!name) + return -EINVAL; + + if (selector >= pi->nr_groups) + return -EINVAL; + + if (!pi->groups[selector].present) { + int ret; + + ret = scmi_pinctrl_get_group_info(ph, selector, + &pi->groups[selector]); + if (ret) + return ret; + } + + *name = pi->groups[selector].name; + + return 0; +} + +static int scmi_pinctrl_group_pins_get(const struct scmi_protocol_handle *ph, + u32 selector, const unsigned int **pins, + unsigned int *nr_pins) +{ + struct scmi_pinctrl_info *pi = ph->get_priv(ph); + + if (!pins || !nr_pins) + return -EINVAL; + + if (selector >= pi->nr_groups) + return -EINVAL; + + if (!pi->groups[selector].present) { + int ret; + + ret = scmi_pinctrl_get_group_info(ph, selector, + &pi->groups[selector]); + if (ret) + return ret; + } + + *pins = pi->groups[selector].group_pins; + *nr_pins = pi->groups[selector].nr_pins; + + return 0; +} + +static int scmi_pinctrl_get_function_info(const struct scmi_protocol_handle *ph, + u32 selector, + struct scmi_function_info *func) +{ + int ret; + + if (!func) + return -EINVAL; + + ret = scmi_pinctrl_attributes(ph, FUNCTION_TYPE, selector, + func->name, + &func->nr_groups); + if (ret) + return ret; + + if (!func->nr_groups) { + dev_err(ph->dev, "Function %d has 0 elements", selector); + return -ENODATA; + } + + func->groups = kmalloc_array(func->nr_groups, sizeof(*func->groups), + GFP_KERNEL); + if (!func->groups) + return -ENOMEM; + + ret = scmi_pinctrl_list_associations(ph, selector, FUNCTION_TYPE, + func->nr_groups, func->groups); + if (ret) { + kfree(func->groups); + return ret; + } + + func->present = true; + return 0; +} + +static int scmi_pinctrl_get_function_name(const struct scmi_protocol_handle *ph, + u32 selector, const char **name) +{ + struct scmi_pinctrl_info *pi = ph->get_priv(ph); + + if (!name) + return -EINVAL; + + if (selector >= pi->nr_functions) + return -EINVAL; + + if (!pi->functions[selector].present) { + int ret; + + ret = scmi_pinctrl_get_function_info(ph, selector, + &pi->functions[selector]); + if (ret) + return ret; + } + + *name = pi->functions[selector].name; + return 0; +} + +static int +scmi_pinctrl_function_groups_get(const struct scmi_protocol_handle *ph, + u32 selector, unsigned int *nr_groups, + const unsigned int **groups) +{ + struct scmi_pinctrl_info *pi = ph->get_priv(ph); + + if (!groups || !nr_groups) + return -EINVAL; + + if (selector >= pi->nr_functions) + return -EINVAL; + + if (!pi->functions[selector].present) { + int ret; + + ret = scmi_pinctrl_get_function_info(ph, selector, + &pi->functions[selector]); + if (ret) + return ret; + } + + *groups = pi->functions[selector].groups; + *nr_groups = pi->functions[selector].nr_groups; + + return 0; +} + +static int scmi_pinctrl_mux_set(const struct scmi_protocol_handle *ph, + u32 selector, u32 group) +{ + return scmi_pinctrl_function_select(ph, group, GROUP_TYPE, + selector); +} + +static int scmi_pinctrl_get_pin_info(const struct scmi_protocol_handle *ph, + u32 selector, struct scmi_pin_info *pin) +{ + int ret; + + if (!pin) + return -EINVAL; + + ret = scmi_pinctrl_attributes(ph, PIN_TYPE, selector, + pin->name, NULL); + if (ret) + return ret; + + pin->present = true; + return 0; +} + +static int scmi_pinctrl_get_pin_name(const struct scmi_protocol_handle *ph, + u32 selector, const char **name) +{ + struct scmi_pinctrl_info *pi = ph->get_priv(ph); + + if (!name) + return -EINVAL; + + if (selector >= pi->nr_pins) + return -EINVAL; + + if (!pi->pins[selector].present) { + int ret; + + ret = scmi_pinctrl_get_pin_info(ph, selector, + &pi->pins[selector]); + if (ret) + return ret; + } + + *name = pi->pins[selector].name; + + return 0; +} + +static int scmi_pinctrl_name_get(const struct scmi_protocol_handle *ph, + u32 selector, + enum scmi_pinctrl_selector_type type, + const char **name) +{ + switch (type) { + case PIN_TYPE: + return scmi_pinctrl_get_pin_name(ph, selector, name); + case GROUP_TYPE: + return scmi_pinctrl_get_group_name(ph, selector, name); + case FUNCTION_TYPE: + return scmi_pinctrl_get_function_name(ph, selector, name); + default: + return -EINVAL; + } +} + +static const struct scmi_pinctrl_proto_ops pinctrl_proto_ops = { + .count_get = scmi_pinctrl_count_get, + .name_get = scmi_pinctrl_name_get, + .group_pins_get = scmi_pinctrl_group_pins_get, + .function_groups_get = scmi_pinctrl_function_groups_get, + .mux_set = scmi_pinctrl_mux_set, + .config_get = scmi_pinctrl_config_get, + .config_set = scmi_pinctrl_config_set, + .pin_request = scmi_pinctrl_pin_request, + .pin_free = scmi_pinctrl_pin_free, +}; + +static int scmi_pinctrl_protocol_init(const struct scmi_protocol_handle *ph) +{ + int ret; + u32 version; + struct scmi_pinctrl_info *pinfo; + + ret = ph->xops->version_get(ph, &version); + if (ret) + return ret; + + dev_dbg(ph->dev, "Pinctrl Version %d.%d\n", + PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version)); + + pinfo = devm_kzalloc(ph->dev, sizeof(*pinfo), GFP_KERNEL); + if (!pinfo) + return -ENOMEM; + + ret = scmi_pinctrl_attributes_get(ph, pinfo); + if (ret) + return ret; + + pinfo->pins = devm_kcalloc(ph->dev, pinfo->nr_pins, + sizeof(*pinfo->pins), + GFP_KERNEL); + if (!pinfo->pins) + return -ENOMEM; + + pinfo->groups = devm_kcalloc(ph->dev, pinfo->nr_groups, + sizeof(*pinfo->groups), + GFP_KERNEL); + if (!pinfo->groups) + return -ENOMEM; + + pinfo->functions = devm_kcalloc(ph->dev, pinfo->nr_functions, + sizeof(*pinfo->functions), + GFP_KERNEL); + if (!pinfo->functions) + return -ENOMEM; + + pinfo->version = version; + + return ph->set_priv(ph, pinfo, version); +} + +static int scmi_pinctrl_protocol_deinit(const struct scmi_protocol_handle *ph) +{ + int i; + struct scmi_pinctrl_info *pi = ph->get_priv(ph); + + for (i = 0; i < pi->nr_groups; i++) { + if (pi->groups[i].present) { + kfree(pi->groups[i].group_pins); + pi->groups[i].present = false; + } + } + + for (i = 0; i < pi->nr_functions; i++) { + if (pi->functions[i].present) { + kfree(pi->functions[i].groups); + pi->functions[i].present = false; + } + } + + return 0; +} + +static const struct scmi_protocol scmi_pinctrl = { + .id = SCMI_PROTOCOL_PINCTRL, + .owner = THIS_MODULE, + .instance_init = &scmi_pinctrl_protocol_init, + .instance_deinit = &scmi_pinctrl_protocol_deinit, + .ops = &pinctrl_proto_ops, + .supported_version = SCMI_PROTOCOL_SUPPORTED_VERSION, +}; + +DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(pinctrl, scmi_pinctrl) diff --git a/drivers/firmware/arm_scmi/protocols.h b/drivers/firmware/arm_scmi/protocols.h index 3e91536a77a3..c02cbfd2bb03 100644 --- a/drivers/firmware/arm_scmi/protocols.h +++ b/drivers/firmware/arm_scmi/protocols.h @@ -355,6 +355,7 @@ void __exit scmi_##name##_unregister(void) \ DECLARE_SCMI_REGISTER_UNREGISTER(base); DECLARE_SCMI_REGISTER_UNREGISTER(clock); DECLARE_SCMI_REGISTER_UNREGISTER(perf); +DECLARE_SCMI_REGISTER_UNREGISTER(pinctrl); DECLARE_SCMI_REGISTER_UNREGISTER(power); DECLARE_SCMI_REGISTER_UNREGISTER(reset); DECLARE_SCMI_REGISTER_UNREGISTER(sensors); diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h index b807141acc14..fd647f805e5f 100644 --- a/include/linux/scmi_protocol.h +++ b/include/linux/scmi_protocol.h @@ -737,6 +737,80 @@ struct scmi_powercap_proto_ops { u32 *power_thresh_high); }; +enum scmi_pinctrl_selector_type { + PIN_TYPE = 0, + GROUP_TYPE, + FUNCTION_TYPE, +}; + +enum scmi_pinctrl_conf_type { + SCMI_PIN_NONE = 0x0, + SCMI_PIN_BIAS_BUS_HOLD = 0x1, + SCMI_PIN_BIAS_DISABLE = 0x2, + SCMI_PIN_BIAS_HIGH_IMPEDANCE = 0x3, + SCMI_PIN_BIAS_PULL_UP = 0x4, + SCMI_PIN_BIAS_PULL_DEFAULT = 0x5, + SCMI_PIN_BIAS_PULL_DOWN = 0x6, + SCMI_PIN_DRIVE_OPEN_DRAIN = 0x7, + SCMI_PIN_DRIVE_OPEN_SOURCE = 0x8, + SCMI_PIN_DRIVE_PUSH_PULL = 0x9, + SCMI_PIN_DRIVE_STRENGTH = 0xA, + SCMI_PIN_INPUT_DEBOUNCE = 0xB, + SCMI_PIN_INPUT_MODE = 0xC, + SCMI_PIN_PULL_MODE = 0xD, + SCMI_PIN_INPUT_VALUE = 0xE, + SCMI_PIN_INPUT_SCHMITT = 0xF, + SCMI_PIN_LOW_POWER_MODE = 0x10, + SCMI_PIN_OUTPUT_MODE = 0x11, + SCMI_PIN_OUTPUT_VALUE = 0x12, + SCMI_PIN_POWER_SOURCE = 0x13, + SCMI_PIN_SLEW_RATE = 0x20, + SCMI_PIN_OEM_START = 0xC0, + SCMI_PIN_OEM_END = 0xFF, +}; + +/** + * struct scmi_pinctrl_proto_ops - represents the various operations provided + * by SCMI Pinctrl Protocol + * + * @count_get: returns count of the registered elements in given type + * @name_get: returns name by index of given type + * @group_pins_get: returns the set of pins, assigned to the specified group + * @function_groups_get: returns the set of groups, assigned to the specified + * function + * @mux_set: set muxing function for groups of pins + * @config_get: returns configuration parameter for pin or group + * @config_set: sets the configuration parameter for pin or group + * @pin_request: aquire pin before selecting mux setting + * @pin_free: frees pin, acquired by request_pin call + */ +struct scmi_pinctrl_proto_ops { + int (*count_get)(const struct scmi_protocol_handle *ph, + enum scmi_pinctrl_selector_type type); + int (*name_get)(const struct scmi_protocol_handle *ph, u32 selector, + enum scmi_pinctrl_selector_type type, + const char **name); + int (*group_pins_get)(const struct scmi_protocol_handle *ph, + u32 selector, const unsigned int **pins, + unsigned int *nr_pins); + int (*function_groups_get)(const struct scmi_protocol_handle *ph, + u32 selector, unsigned int *nr_groups, + const unsigned int **groups); + int (*mux_set)(const struct scmi_protocol_handle *ph, u32 selector, + u32 group); + int (*config_get)(const struct scmi_protocol_handle *ph, u32 selector, + enum scmi_pinctrl_selector_type type, + enum scmi_pinctrl_conf_type config_type, + u32 *config_value); + int (*config_set)(const struct scmi_protocol_handle *ph, u32 selector, + enum scmi_pinctrl_selector_type type, + unsigned int nr_configs, + enum scmi_pinctrl_conf_type *config_type, + u32 *config_value); + int (*pin_request)(const struct scmi_protocol_handle *ph, u32 pin); + int (*pin_free)(const struct scmi_protocol_handle *ph, u32 pin); +}; + /** * struct scmi_notify_ops - represents notifications' operations provided by * SCMI core @@ -844,6 +918,7 @@ enum scmi_std_protocol { SCMI_PROTOCOL_RESET = 0x16, SCMI_PROTOCOL_VOLTAGE = 0x17, SCMI_PROTOCOL_POWERCAP = 0x18, + SCMI_PROTOCOL_PINCTRL = 0x19, }; enum scmi_system_events { From patchwork Thu Mar 14 13:35:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Peng Fan \(OSS\)" X-Patchwork-Id: 780642 Received: from EUR04-VI1-obe.outbound.protection.outlook.com (mail-vi1eur04on2049.outbound.protection.outlook.com [40.107.8.49]) (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 7B7636EB6E; Thu, 14 Mar 2024 13:27:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.8.49 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710422857; cv=fail; b=GS/rbd31PN2n/o1bSX2SZVc99rJI4XBmHfSX4fzKRUsrlW4Mwzf43/a8nDwpmywFc8XDJ9Nca4QiffVC09isrCHoedHPv7wpD8VzmRwXJd1928xsZx+kku243DtdRMQ/8b0buXevRq33YlDUDa5kn8k6ZuLOPHD9B0EYkylvfbc= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710422857; c=relaxed/simple; bh=UnDOff+Ugxpm9ISuXVn0WsuMZ575zMEYgwV3AI8HJNg=; h=From:Date:Subject:Content-Type:Message-Id:References:In-Reply-To: To:Cc:MIME-Version; b=OKZLVEo1zzjF/FkCTVrlFGe4zqwXRyI1YKelRZ7HWYN266XJrEOuDdy4wnzM32COTZeQeCX2nXjQUCzYYLvHMH5ihqh4MdFB+RIqaFnCGy+3eiwFJpZsUyQ/0bynwWNgGpo6KsxoOr0WP/mTfEBBeO+omPiigvhvkRK+/YVjAoc= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=oss.nxp.com; spf=pass smtp.mailfrom=oss.nxp.com; dkim=pass (1024-bit key) header.d=NXP1.onmicrosoft.com header.i=@NXP1.onmicrosoft.com header.b=jc8jhzbX; arc=fail smtp.client-ip=40.107.8.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=oss.nxp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.nxp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=NXP1.onmicrosoft.com header.i=@NXP1.onmicrosoft.com header.b="jc8jhzbX" ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=mPT0xYnQIoiDoqfFbp3PYf/fCWnZ3AyUXE8POFtKU8/Yto4opDYDTT1mjaG02Lk7DswVJj3U8WqMmhKaLn+PVuh2fmdmj+pnJafYpuDJVNUrP3Azx+2KiXO6J9HNQ7/yRuDbBL7ESQ4TBqIppQ8G3s/9dLRZZbPEq3tTID/RrBtPFGbR9ALgSL81wBenzNek4SG77KEmJGaAV1/vGmYxndhKTPtw/6a7l9pbjX+cp52OueJFrTn1ZORCupLRoB52xbkzfC8+7wNvRbR6NK29sl1ZqYq3dcOfaep5+nXcdblbNkT9ZMa9dm51ItLtCUGtQkfeO9sTk2rZucFx0V35Xg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=eQl9dhhnjGjSao3RfqErnZmcadVzodCzM1wsuuq4MF0=; b=bKFNLQns2Yh15RabLVz4ipCneHVLHsHo2da89a8InywlMh8HeeEenHwmQWqQb5h7wocyy/vYUAE30h8r2uQysB9VLkmDt5G+D5RE10QHf3hxFMOXWh6Pym8l8ivcSLAAmIHyvzUcAMVZDYhibV8e0XPJLvJGKJ23M9jO/itlcvZlmiYZD+QegU0EZpXoGZggXWWF5AQlJQ2Zj9GCU+X9376AfCutnPV1lElVrvrFnsdEadfN33DWFHWdVYmYR0GoRlNfDlg2ERHdK+8Z3dXl2JmRdh0PewrFRpOGQw3zl8UHAgBHLaBTD20NAyouL2xFJiqR67K9oNCiixSNInxHDg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oss.nxp.com; dmarc=pass action=none header.from=oss.nxp.com; dkim=pass header.d=oss.nxp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=NXP1.onmicrosoft.com; s=selector2-NXP1-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=eQl9dhhnjGjSao3RfqErnZmcadVzodCzM1wsuuq4MF0=; b=jc8jhzbXjhYIHDpMK5FtBDyDaVqq2wNprq7+kV7c/jI7IvQCh2PCWcu/fjh415Xj1hZiDHocwDdSsZsWHUM+QX34GWmmd9OuG/TD00+PX4fFeXsSxQwy21vgGUOmaw91PNx1i57S9KzcKXk/ICOURX8vQGtPVpKDRAuCQS0aPog= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=oss.nxp.com; Received: from DU0PR04MB9417.eurprd04.prod.outlook.com (2603:10a6:10:358::11) by PAWPR04MB9861.eurprd04.prod.outlook.com (2603:10a6:102:381::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7362.36; Thu, 14 Mar 2024 13:27:30 +0000 Received: from DU0PR04MB9417.eurprd04.prod.outlook.com ([fe80::d30b:44e7:e78e:662d]) by DU0PR04MB9417.eurprd04.prod.outlook.com ([fe80::d30b:44e7:e78e:662d%4]) with mapi id 15.20.7386.017; Thu, 14 Mar 2024 13:27:30 +0000 From: "Peng Fan (OSS)" Date: Thu, 14 Mar 2024 21:35:21 +0800 Subject: [PATCH v5 4/4] pinctrl: Implementation of the generic scmi-pinctrl driver Message-Id: <20240314-pinctrl-scmi-v5-4-b19576e557f2@nxp.com> References: <20240314-pinctrl-scmi-v5-0-b19576e557f2@nxp.com> In-Reply-To: <20240314-pinctrl-scmi-v5-0-b19576e557f2@nxp.com> To: Sudeep Holla , Cristian Marussi , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Oleksii Moisieiev , Linus Walleij , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam , NXP Linux Team Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-gpio@vger.kernel.org, AKASHI Takahiro , Peng Fan X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1710423327; l=19239; i=peng.fan@nxp.com; s=20230812; h=from:subject:message-id; bh=QS4um6Bx3c1L9Yftty5oVvx70EDHXttygs6rhhcPjjE=; b=WtQ+GUndxmIpFOUF6e/DHsQEeXK9zHJPold0rzkTR8g4/PToLcn4MR0uNvgD9U0Zka10YUFfk yyGuKs3DwveBtwbazd6YPi3MZ1lsjtgn188m/oaf9ngiRZ+qvxhKWp0 X-Developer-Key: i=peng.fan@nxp.com; a=ed25519; pk=I4sJg7atIT1g63H7bb5lDRGR2gJW14RKDD0wFL8TT1g= X-ClientProxiedBy: SG2PR06CA0188.apcprd06.prod.outlook.com (2603:1096:4:1::20) To DU0PR04MB9417.eurprd04.prod.outlook.com (2603:10a6:10:358::11) Precedence: bulk X-Mailing-List: linux-gpio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DU0PR04MB9417:EE_|PAWPR04MB9861:EE_ X-MS-Office365-Filtering-Correlation-Id: 410a746e-271d-48ee-9d7f-08dc442a7fbb X-MS-Exchange-SharedMailbox-RoutingAgent-Processed: True X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: +PBtMekM02v2lCv4a2AgUCrTDk6Z9PaZyiQ9uPunAwjrDwBg86+0Qd71IQXsYYznuePsU9Nh/7ISP6JZDcON1YxHJNAUjd/EwvESdz3fwK6mehD6cytAVA3SxaXENzOG9G7Rq1QaSYwnOSX2+7RUvDFQmD1waS6D94mw1O6GeTL1mEtidIhv66JFvkEr7AenccknL2kRgalbPX3BQMwFEvgMsn12z9GC5aDNyj0tkZOl3IbRC3Uzn3fS3WFKz3UzE1NUwVHhFMfZ/scvF2cqDc3jH8J2qSaHoi/dST1etDL5EhQ9uNc482ZsrD0V7HweUBN+KsKVqcWGg34mKIjztxr7fEGdxcPwj5Jaj5Rh5O62ZOKVchJn5Di8yESYG33gUOQPYGUod5pOr0e0WGhksyoSD8vl/2miUA3Er24faUhKTGroyv2OJ17Saf8nj0OHUgPLtq6zeo5TjMpq//Pps5xWYjUIHV1UzK4ZVMk7TMTWK3niNu1VJRgP4QYG9ZGheeWbdn0butDe/Xh221MLoK+TLrbioDHmDIqquvv/O+qru0dUx84naiB0em214vMA75HB9alX7yqiluf5XfW8o4LVnDJYuRK2+QXywYu0SgzL4djKa5nViNgIArezSko9SjkYR8cqOpN7TvinevlLgVfJEgUoRNq80b2Lv+9BDHNwg2Owuhl2DOYuulZ1M3StZHK6/OmmGYSoJNsoK7oIDCEngA9o+lvwHLWdAV98lS8= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:DU0PR04MB9417.eurprd04.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230031)(376005)(52116005)(7416005)(1800799015)(38350700005)(921011); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?+yrv5cdNA2CQPAQeUOMYpTn6KvzN?= =?utf-8?q?HC/pJmoMvuiJRNd1UYRf8PC/XbjkmlsDEwPigQfqijvufP2ehkmfOn/tqH9AhVYdT?= =?utf-8?q?ejeCh5LZVuawOVFWZcfjfCb9l+iDCSEbbwKCITyLu4aB9qq5EEbgGyieTq3qu3Pku?= =?utf-8?q?bjMfnFnCSZGGZcj74ZEu7CgGDo8Mc1WX+ANGIe7xO449vmpFrfd7TQ6iNwt+A8dTZ?= =?utf-8?q?q5hBWq4nBTu5WKxefUeRjY/8jsuLPKv/IbF0BX3U/kfHp+b+qpGYACMlRe3N+QC/G?= =?utf-8?q?3TyAhZ/hXwVNtfQNaitUM0DsuM4sCcygPNUookVRP8ZTkkhVx1CIASsSB6uqkenzC?= =?utf-8?q?23vr50aPjaa3QpBNpoGOw6wu28jF/g8cP6dUYDtHCXj/Grtl05sBFfkcKxs5mGBOw?= =?utf-8?q?V0HmiAUAGs7dR9Gb1j31QbdZ67cnv0BqYwWgYZ6H9U4XUolshUwidyrkbk0jFHEHn?= =?utf-8?q?l8jrnHvuiHHkljOpDNVewh/TaFv3GS/8YcGLid1sm9ZzQeDZQR7Hj5JqChR4pglTH?= =?utf-8?q?29jkhrG+1X8l56ANBJf8aP03upE3OA1cgFCDHCq6o1gHXBkrNmfnxSKBoH8MzQDP7?= =?utf-8?q?QsrXMk7nOE/yFmecqPZ3mY/LNF66/U+P7i6AqDa5snFlE1uLU2PJgFIsb0DhpiemZ?= =?utf-8?q?5AP4dtP724KJLpBr7vXKYyGzhkcVMqA9J0gyjNiripUG0dlahxP5YL10AgUb6E7VY?= =?utf-8?q?WXOa5cmIsuLzsN6xZUp4q9vduSVumaepVDyl8uOBXHWopDSc/Nmax66UG+6GRb2m6?= =?utf-8?q?6E/aTMc5tFz2uYX+Nx9DseKUlSGkUzwuxAeedi5gVSEy1UIOYTRO0Lr1l2cVBW1LJ?= =?utf-8?q?wDQazcOVzqYj5UCeNZTOuGhXPxN3vLp7e0WvUJ9iFdH9yF2K6OwzyWJAAGG6WYUwx?= =?utf-8?q?hI1LJq+E/rQyVxPAn7zndDkJguuzEKyJ463PLxhJ8A073Bo01Hfnqm7KN3sECH68/?= =?utf-8?q?kjkiAeLzWPKQoJjG6ay1EZZt73z0uicmJFdt8a5/P4ZRy80N3T3Q9NGMlrDgO2Bc8?= =?utf-8?q?5VkUfi7V+34VnMAkzpMVvVNM6+U4CZSMqDlV0j3TdTZ+nSU+AR74DDxYJhdn3kq+Y?= =?utf-8?q?JwDdHHEOcRX+ymvV+5ses/iBeL4JDiY70zcBotuhgn15CDdIaNoOtVXLT1RRGi9bX?= =?utf-8?q?VSepNWpvBq5M4Tn0wIZR5VuLS1YFNWBd8GGGaec1DN796Xft0O3V1w9rIpm61mk4n?= =?utf-8?q?+rBS1IfMAJtZIDW/1jVWzk+rANaGS6FpBLF9rguGe9NVBuWmNAr/OyUC3nsMfgsSb?= =?utf-8?q?Mgbd4w3fjgCsPUW0KbByXgnwHs1Y1j/DvGz2ldSZAJIi23R6EzHShv5ZC11i0SzVa?= =?utf-8?q?mP0USI75ROz/Vs2JGKuKs4tloOSS/YCsUNcD7oDzKkMO8rl84PFyRTKe/FsBL5NlY?= =?utf-8?q?uZfxd3bnNrkH+/N7KSBmkPmqr1L4pZeNcocmRY7rgnaODwOo7rggEformXItrbxUZ?= =?utf-8?q?b4JXBW86c4l0gg7AZ9aGvRJpbjK1WsrtkbEw7OPTdrBUnhcZoNTlqQUb2PunhqzgF?= =?utf-8?q?qvubiliZQebo?= X-OriginatorOrg: oss.nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 410a746e-271d-48ee-9d7f-08dc442a7fbb X-MS-Exchange-CrossTenant-AuthSource: DU0PR04MB9417.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 14 Mar 2024 13:27:30.4116 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: AZKOVBrHIA+y1ZI1zXAJgJi1zaP0AUzSr6PVV+7jMT7JFLWTTZiTluWtK//yCx2IqCcLLWBGVNIlNe2DeziVGA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAWPR04MB9861 From: Peng Fan scmi-pinctrl driver implements pinctrl driver interface and using SCMI protocol to redirect messages from pinctrl subsystem SDK to SCMI platform firmware, which does the changes in HW. Reviewed-by: Cristian Marussi Tested-by: Cristian Marussi Reviewed-by: Linus Walleij Co-developed-by: Oleksii Moisieiev Signed-off-by: Oleksii Moisieiev Signed-off-by: Peng Fan --- MAINTAINERS | 1 + drivers/pinctrl/Kconfig | 11 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-scmi.c | 593 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 606 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index b43102ca365d..aa9eb9476bbd 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -21474,6 +21474,7 @@ F: drivers/cpufreq/sc[mp]i-cpufreq.c F: drivers/firmware/arm_scmi/ F: drivers/firmware/arm_scpi.c F: drivers/hwmon/scmi-hwmon.c +F: drivers/pinctrl/pinctrl-scmi.c F: drivers/pmdomain/arm/ F: drivers/powercap/arm_scmi_powercap.c F: drivers/regulator/scmi-regulator.c diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index d45657aa986a..4e6f65cf0e76 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -450,6 +450,17 @@ config PINCTRL_ROCKCHIP help This support pinctrl and GPIO driver for Rockchip SoCs. +config PINCTRL_SCMI + tristate "Pinctrl driver using SCMI protocol interface" + depends on ARM_SCMI_PROTOCOL || COMPILE_TEST + select PINMUX + select GENERIC_PINCONF + help + This driver provides support for pinctrl which is controlled + by firmware that implements the SCMI interface. + It uses SCMI Message Protocol to interact with the + firmware providing all the pinctrl controls. + config PINCTRL_SINGLE tristate "One-register-per-pin type device tree based pinctrl driver" depends on OF diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 2152539b53d5..cc809669405a 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -45,6 +45,7 @@ obj-$(CONFIG_PINCTRL_PIC32) += pinctrl-pic32.o obj-$(CONFIG_PINCTRL_PISTACHIO) += pinctrl-pistachio.o obj-$(CONFIG_PINCTRL_RK805) += pinctrl-rk805.o obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o +obj-$(CONFIG_PINCTRL_SCMI) += pinctrl-scmi.o obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o obj-$(CONFIG_PINCTRL_STMFX) += pinctrl-stmfx.o diff --git a/drivers/pinctrl/pinctrl-scmi.c b/drivers/pinctrl/pinctrl-scmi.c new file mode 100644 index 000000000000..f2fef3fb85ae --- /dev/null +++ b/drivers/pinctrl/pinctrl-scmi.c @@ -0,0 +1,593 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * System Control and Power Interface (SCMI) Protocol based pinctrl driver + * + * Copyright (C) 2024 EPAM + * Copyright 2024 NXP + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "pinctrl-utils.h" +#include "core.h" +#include "pinconf.h" + +#define DRV_NAME "scmi-pinctrl" + +/* Define num configs, if not large than 4 use stack, else use kcalloc */ +#define SCMI_NUM_CONFIGS 4 + +static const struct scmi_pinctrl_proto_ops *pinctrl_ops; + +struct scmi_pinctrl_funcs { + unsigned int num_groups; + const char **groups; +}; + +struct scmi_pinctrl { + struct device *dev; + struct scmi_protocol_handle *ph; + struct pinctrl_dev *pctldev; + struct pinctrl_desc pctl_desc; + struct scmi_pinctrl_funcs *functions; + unsigned int nr_functions; + char **groups; + unsigned int nr_groups; + struct pinctrl_pin_desc *pins; + unsigned int nr_pins; +}; + +static int pinctrl_scmi_get_groups_count(struct pinctrl_dev *pctldev) +{ + struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); + + return pinctrl_ops->count_get(pmx->ph, GROUP_TYPE); +} + +static const char *pinctrl_scmi_get_group_name(struct pinctrl_dev *pctldev, + unsigned int selector) +{ + int ret; + const char *name; + struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); + + ret = pinctrl_ops->name_get(pmx->ph, selector, GROUP_TYPE, &name); + if (ret) { + dev_err(pmx->dev, "get name failed with err %d", ret); + return NULL; + } + + return name; +} + +static int pinctrl_scmi_get_group_pins(struct pinctrl_dev *pctldev, + unsigned int selector, + const unsigned int **pins, + unsigned int *num_pins) +{ + struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); + + return pinctrl_ops->group_pins_get(pmx->ph, selector, pins, num_pins); +} + +static const struct pinctrl_ops pinctrl_scmi_pinctrl_ops = { + .get_groups_count = pinctrl_scmi_get_groups_count, + .get_group_name = pinctrl_scmi_get_group_name, + .get_group_pins = pinctrl_scmi_get_group_pins, +#ifdef CONFIG_OF + .dt_node_to_map = pinconf_generic_dt_node_to_map_all, + .dt_free_map = pinconf_generic_dt_free_map, +#endif +}; + +static int pinctrl_scmi_get_functions_count(struct pinctrl_dev *pctldev) +{ + struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); + + return pinctrl_ops->count_get(pmx->ph, FUNCTION_TYPE); +} + +static const char *pinctrl_scmi_get_function_name(struct pinctrl_dev *pctldev, + unsigned int selector) +{ + int ret; + const char *name; + struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); + + ret = pinctrl_ops->name_get(pmx->ph, selector, FUNCTION_TYPE, &name); + if (ret) { + dev_err(pmx->dev, "get name failed with err %d", ret); + return NULL; + } + + return name; +} + +static int pinctrl_scmi_get_function_groups(struct pinctrl_dev *pctldev, + unsigned int selector, + const char * const **groups, + unsigned int * const num_groups) +{ + const unsigned int *group_ids; + int ret, i; + struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); + + if (!groups || !num_groups) + return -EINVAL; + + if (selector < pmx->nr_functions && + pmx->functions[selector].num_groups) { + *groups = (const char * const *)pmx->functions[selector].groups; + *num_groups = pmx->functions[selector].num_groups; + return 0; + } + + ret = pinctrl_ops->function_groups_get(pmx->ph, selector, + &pmx->functions[selector].num_groups, + &group_ids); + if (ret) { + dev_err(pmx->dev, "Unable to get function groups, err %d", ret); + return ret; + } + + *num_groups = pmx->functions[selector].num_groups; + if (!*num_groups) + return -EINVAL; + + pmx->functions[selector].groups = + devm_kcalloc(pmx->dev, *num_groups, + sizeof(*pmx->functions[selector].groups), + GFP_KERNEL); + if (!pmx->functions[selector].groups) + return -ENOMEM; + + for (i = 0; i < *num_groups; i++) { + pmx->functions[selector].groups[i] = + pinctrl_scmi_get_group_name(pmx->pctldev, + group_ids[i]); + if (!pmx->functions[selector].groups[i]) { + ret = -ENOMEM; + goto err_free; + } + } + + *groups = (const char * const *)pmx->functions[selector].groups; + + return 0; + +err_free: + devm_kfree(pmx->dev, pmx->functions[selector].groups); + + return ret; +} + +static int pinctrl_scmi_func_set_mux(struct pinctrl_dev *pctldev, + unsigned int selector, unsigned int group) +{ + struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); + + return pinctrl_ops->mux_set(pmx->ph, selector, group); +} + +static int pinctrl_scmi_request(struct pinctrl_dev *pctldev, + unsigned int offset) +{ + struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); + + return pinctrl_ops->pin_request(pmx->ph, offset); +} + +static int pinctrl_scmi_free(struct pinctrl_dev *pctldev, unsigned int offset) +{ + struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); + + return pinctrl_ops->pin_free(pmx->ph, offset); +} + +static const struct pinmux_ops pinctrl_scmi_pinmux_ops = { + .request = pinctrl_scmi_request, + .free = pinctrl_scmi_free, + .get_functions_count = pinctrl_scmi_get_functions_count, + .get_function_name = pinctrl_scmi_get_function_name, + .get_function_groups = pinctrl_scmi_get_function_groups, + .set_mux = pinctrl_scmi_func_set_mux, +}; + +static int pinctrl_scmi_map_pinconf_type(enum pin_config_param param, + enum scmi_pinctrl_conf_type *type) +{ + u32 arg = param; + + switch (arg) { + case PIN_CONFIG_BIAS_BUS_HOLD: + *type = SCMI_PIN_BIAS_BUS_HOLD; + break; + case PIN_CONFIG_BIAS_DISABLE: + *type = SCMI_PIN_BIAS_DISABLE; + break; + case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: + *type = SCMI_PIN_BIAS_HIGH_IMPEDANCE; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + *type = SCMI_PIN_BIAS_PULL_DOWN; + break; + case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: + *type = SCMI_PIN_BIAS_PULL_DEFAULT; + break; + case PIN_CONFIG_BIAS_PULL_UP: + *type = SCMI_PIN_BIAS_PULL_UP; + break; + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + *type = SCMI_PIN_DRIVE_OPEN_DRAIN; + break; + case PIN_CONFIG_DRIVE_OPEN_SOURCE: + *type = SCMI_PIN_DRIVE_OPEN_SOURCE; + break; + case PIN_CONFIG_DRIVE_PUSH_PULL: + *type = SCMI_PIN_DRIVE_PUSH_PULL; + break; + case PIN_CONFIG_DRIVE_STRENGTH: + *type = SCMI_PIN_DRIVE_STRENGTH; + break; + case PIN_CONFIG_DRIVE_STRENGTH_UA: + *type = SCMI_PIN_DRIVE_STRENGTH; + break; + case PIN_CONFIG_INPUT_DEBOUNCE: + *type = SCMI_PIN_INPUT_DEBOUNCE; + break; + case PIN_CONFIG_INPUT_ENABLE: + *type = SCMI_PIN_INPUT_MODE; + break; + case PIN_CONFIG_INPUT_SCHMITT: + *type = SCMI_PIN_INPUT_SCHMITT; + break; + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: + *type = SCMI_PIN_INPUT_MODE; + break; + case PIN_CONFIG_MODE_LOW_POWER: + *type = SCMI_PIN_LOW_POWER_MODE; + break; + case PIN_CONFIG_OUTPUT: + *type = SCMI_PIN_OUTPUT_VALUE; + break; + case PIN_CONFIG_OUTPUT_ENABLE: + *type = SCMI_PIN_OUTPUT_MODE; + break; + case PIN_CONFIG_OUTPUT_IMPEDANCE_OHMS: + *type = SCMI_PIN_OUTPUT_VALUE; + break; + case PIN_CONFIG_POWER_SOURCE: + *type = SCMI_PIN_POWER_SOURCE; + break; + case PIN_CONFIG_SLEW_RATE: + *type = SCMI_PIN_SLEW_RATE; + break; + case SCMI_PIN_OEM_START ... SCMI_PIN_OEM_END: + *type = arg; + break; + default: + return -EOPNOTSUPP; + } + + return 0; +} + +static int pinctrl_scmi_pinconf_get(struct pinctrl_dev *pctldev, + unsigned int _pin, unsigned long *config) +{ + int ret; + struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); + enum pin_config_param config_type; + enum scmi_pinctrl_conf_type type; + u32 config_value; + + if (!config) + return -EINVAL; + + config_type = pinconf_to_config_param(*config); + + ret = pinctrl_scmi_map_pinconf_type(config_type, &type); + if (ret) { + dev_err(pmx->dev, "Error map pinconf_type %d\n", ret); + return ret; + } + + ret = pinctrl_ops->config_get(pmx->ph, _pin, PIN_TYPE, type, + &config_value); + if (ret) + return ret; + + *config = pinconf_to_config_packed(config_type, config_value); + + return 0; +} + +static int +pinctrl_scmi_alloc_configs(struct pinctrl_dev *pctldev, u32 num_configs, + u32 **p_config_value, + enum scmi_pinctrl_conf_type **p_config_type) +{ + if (num_configs <= SCMI_NUM_CONFIGS) + return 0; + + *p_config_value = kcalloc(num_configs, sizeof(u32), GFP_KERNEL); + *p_config_type = kcalloc(num_configs, + sizeof(enum scmi_pinctrl_conf_type), + GFP_KERNEL); + + if (!*p_config_value || !*p_config_type) { + kfree(*p_config_value); + kfree(*p_config_type); + return -ENOMEM; + } + + return 0; +} + +static void +pinctrl_scmi_free_configs(struct pinctrl_dev *pctldev, u32 num_configs, + u32 **p_config_value, + enum scmi_pinctrl_conf_type **p_config_type) +{ + if (num_configs <= SCMI_NUM_CONFIGS) + return; + + kfree(*p_config_value); + kfree(*p_config_type); +} + +static int pinctrl_scmi_pinconf_set(struct pinctrl_dev *pctldev, + unsigned int _pin, + unsigned long *configs, + unsigned int num_configs) +{ + int i, ret; + struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); + enum scmi_pinctrl_conf_type config_type[SCMI_NUM_CONFIGS]; + u32 config_value[SCMI_NUM_CONFIGS]; + enum scmi_pinctrl_conf_type *p_config_type = config_type; + u32 *p_config_value = config_value; + enum pin_config_param param; + + if (!configs || !num_configs) + return -EINVAL; + + ret = pinctrl_scmi_alloc_configs(pctldev, num_configs, &p_config_type, + &p_config_value); + if (ret) + return ret; + + for (i = 0; i < num_configs; i++) { + param = pinconf_to_config_param(configs[i]); + ret = pinctrl_scmi_map_pinconf_type(param, &p_config_type[i]); + if (ret) { + dev_err(pmx->dev, "Error map pinconf_type %d\n", ret); + goto free_config; + } + p_config_value[i] = pinconf_to_config_argument(configs[i]); + } + + ret = pinctrl_ops->config_set(pmx->ph, _pin, PIN_TYPE, num_configs, + p_config_type, p_config_value); + if (ret) + dev_err(pmx->dev, "Error parsing config %d\n", ret); + +free_config: + pinctrl_scmi_free_configs(pctldev, num_configs, &p_config_type, + &p_config_value); + return ret; +} + +static int pinctrl_scmi_pinconf_group_set(struct pinctrl_dev *pctldev, + unsigned int group, + unsigned long *configs, + unsigned int num_configs) +{ + int i, ret; + struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); + enum scmi_pinctrl_conf_type config_type[SCMI_NUM_CONFIGS]; + u32 config_value[SCMI_NUM_CONFIGS]; + enum scmi_pinctrl_conf_type *p_config_type = config_type; + u32 *p_config_value = config_value; + enum pin_config_param param; + + if (!configs || !num_configs) + return -EINVAL; + + ret = pinctrl_scmi_alloc_configs(pctldev, num_configs, &p_config_type, + &p_config_value); + if (ret) + return ret; + + for (i = 0; i < num_configs; i++) { + param = pinconf_to_config_param(configs[i]); + ret = pinctrl_scmi_map_pinconf_type(param, + &p_config_type[i]); + if (ret) { + dev_err(pmx->dev, "Error map pinconf_type %d\n", ret); + goto free_config; + } + + p_config_value[i] = pinconf_to_config_argument(configs[i]); + } + + ret = pinctrl_ops->config_set(pmx->ph, group, GROUP_TYPE, num_configs, + p_config_type, p_config_value); + if (ret) + dev_err(pmx->dev, "Error parsing config %d", ret); + +free_config: + pinctrl_scmi_free_configs(pctldev, num_configs, &p_config_type, + &p_config_value); + return ret; +}; + +static int pinctrl_scmi_pinconf_group_get(struct pinctrl_dev *pctldev, + unsigned int group, + unsigned long *config) +{ + int ret; + struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); + enum pin_config_param config_type; + enum scmi_pinctrl_conf_type type; + u32 config_value; + + if (!config) + return -EINVAL; + + config_type = pinconf_to_config_param(*config); + ret = pinctrl_scmi_map_pinconf_type(config_type, &type); + if (ret) { + dev_err(pmx->dev, "Error map pinconf_type %d\n", ret); + return ret; + } + + ret = pinctrl_ops->config_get(pmx->ph, group, GROUP_TYPE, type, + &config_value); + if (ret) + return ret; + + *config = pinconf_to_config_packed(config_type, config_value); + + return 0; +} + +static const struct pinconf_ops pinctrl_scmi_pinconf_ops = { + .is_generic = true, + .pin_config_get = pinctrl_scmi_pinconf_get, + .pin_config_set = pinctrl_scmi_pinconf_set, + .pin_config_group_set = pinctrl_scmi_pinconf_group_set, + .pin_config_group_get = pinctrl_scmi_pinconf_group_get, + .pin_config_config_dbg_show = pinconf_generic_dump_config, +}; + +static int pinctrl_scmi_get_pins(struct scmi_pinctrl *pmx, + unsigned int *nr_pins, + const struct pinctrl_pin_desc **pins) +{ + int ret, i; + + if (!pins || !nr_pins) + return -EINVAL; + + if (pmx->nr_pins) { + *pins = pmx->pins; + *nr_pins = pmx->nr_pins; + return 0; + } + + *nr_pins = pinctrl_ops->count_get(pmx->ph, PIN_TYPE); + + pmx->nr_pins = *nr_pins; + pmx->pins = devm_kmalloc_array(pmx->dev, *nr_pins, sizeof(*pmx->pins), + GFP_KERNEL); + if (!pmx->pins) + return -ENOMEM; + + for (i = 0; i < *nr_pins; i++) { + pmx->pins[i].number = i; + ret = pinctrl_ops->name_get(pmx->ph, i, PIN_TYPE, + &pmx->pins[i].name); + if (ret) { + dev_err(pmx->dev, "Can't get name for pin %d: rc %d", i, ret); + pmx->nr_pins = 0; + return ret; + } + } + + *pins = pmx->pins; + dev_dbg(pmx->dev, "got pins %d", *nr_pins); + + return 0; +} + +static const struct scmi_device_id scmi_id_table[] = { + { SCMI_PROTOCOL_PINCTRL, "pinctrl" }, + { } +}; +MODULE_DEVICE_TABLE(scmi, scmi_id_table); + +static int scmi_pinctrl_probe(struct scmi_device *sdev) +{ + int ret; + struct device *dev = &sdev->dev; + struct scmi_pinctrl *pmx; + const struct scmi_handle *handle; + struct scmi_protocol_handle *ph; + + if (!sdev || !sdev->handle) + return -EINVAL; + + handle = sdev->handle; + + pinctrl_ops = handle->devm_protocol_get(sdev, SCMI_PROTOCOL_PINCTRL, + &ph); + if (IS_ERR(pinctrl_ops)) + return PTR_ERR(pinctrl_ops); + + pmx = devm_kzalloc(dev, sizeof(*pmx), GFP_KERNEL); + if (!pmx) + return -ENOMEM; + + pmx->ph = ph; + + pmx->dev = dev; + pmx->pctl_desc.name = DRV_NAME; + pmx->pctl_desc.owner = THIS_MODULE; + pmx->pctl_desc.pctlops = &pinctrl_scmi_pinctrl_ops; + pmx->pctl_desc.pmxops = &pinctrl_scmi_pinmux_ops; + pmx->pctl_desc.confops = &pinctrl_scmi_pinconf_ops; + + ret = pinctrl_scmi_get_pins(pmx, &pmx->pctl_desc.npins, + &pmx->pctl_desc.pins); + if (ret) + return ret; + + ret = devm_pinctrl_register_and_init(dev, &pmx->pctl_desc, pmx, + &pmx->pctldev); + if (ret) + return dev_err_probe(dev, ret, "Failed to register pinctrl\n"); + + pmx->nr_functions = pinctrl_scmi_get_functions_count(pmx->pctldev); + pmx->nr_groups = pinctrl_scmi_get_groups_count(pmx->pctldev); + + if (pmx->nr_functions) { + pmx->functions = devm_kcalloc(dev, pmx->nr_functions, + sizeof(*pmx->functions), + GFP_KERNEL); + if (!pmx->functions) + return -ENOMEM; + } + + if (pmx->nr_groups) { + pmx->groups = devm_kcalloc(dev, pmx->nr_groups, + sizeof(*pmx->groups), GFP_KERNEL); + if (!pmx->groups) + return -ENOMEM; + } + + return pinctrl_enable(pmx->pctldev); +} + +static struct scmi_driver scmi_pinctrl_driver = { + .name = DRV_NAME, + .probe = scmi_pinctrl_probe, + .id_table = scmi_id_table, +}; +module_scmi_driver(scmi_pinctrl_driver); + +MODULE_AUTHOR("Oleksii Moisieiev "); +MODULE_AUTHOR("Peng Fan "); +MODULE_DESCRIPTION("ARM SCMI pin controller driver"); +MODULE_LICENSE("GPL");