From nobody Sun Feb 8 12:57:49 2026 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 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable 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-kernel@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?B?d0YrMEtFd29PdlF4cGRIYi9aeENpWFdIaHBWcmVPcG5PQjBrWXJTV1c1ZGNF?= =?utf-8?B?STlvZmZ3Y1RIdWZXSVRMWCtFYVpWQ0R2UDhqY3BHQ1FtVzRRcG9iUUo5czV1?= =?utf-8?B?bVlZcjdzWVMzNGVwQTh3dHdVRmk5REt4SXRHQWY0TmEwVUJJNWFBVzNyYk1h?= =?utf-8?B?SVc5N0tWN2h2L0x1eGFlVjEzL0R3dXc1OEdXODhIaTNxNiswaElWZEVGQWhX?= =?utf-8?B?cWd0VEpQVXhtNXZPRlY0aWRyS2xKQXA3K1FjY29GYlNrampyVjNDNTBJNjR2?= =?utf-8?B?Tms2T0owdkU5d2w3aWRGM3hmVVVCOHVzelpJZlRwYjVDTGJnQlZJeklySEhQ?= =?utf-8?B?TXUxNjFJcWx0b2tLSzBVZFAyYjlFU2hKd3UyTFYyR2J4eVJHanoxNFZHZFFi?= =?utf-8?B?NmNEZExiSFRka2JhODNIM21STmVhWGxwek5sdkFmUGpCbk9CT2NjRlB3ZU5L?= =?utf-8?B?NDMxMWQvQnVzSDg0MmdZOUZtVmZiSG5PNWtQTGRkaFhDTE43ZGVCQUx1TEhD?= =?utf-8?B?U053UmNneDFmUmJQU0tSSHFTSHdEeHdqTzc0cmFuYnhyMXlsdHlUNWxrLzRk?= =?utf-8?B?YnJWSjQ3a0xBZnVHblBneVlRVWxzalAzeGZGTEVxb29ManVvT29ZY2FLaFhw?= =?utf-8?B?Mi9YbGs0cTlHdEd3QWp1dWk2YU9McXdlVjdZVWJqVlhHdXVwL3hXOE9BSXV5?= =?utf-8?B?L2FWNGVZOUFLSjZNTHlCR0pnMTBOZlgzeFZsQWU4K2NvL1IwcTl1cm5wOXpv?= =?utf-8?B?ZGo0T2RJYWpkT3BzVk1hb0thYXZLTytXb3pXRG52UW9ITU9XeVlQQmJhNVlO?= =?utf-8?B?K1RLVXFRalNtZjNIUFBMTFR3NXI1R21MRGwxV3g4MllRWWszd0dsUEc4dkN1?= =?utf-8?B?VDNiOEY3Z3RVVGR5YzVEYlhWK0VmZU9QZVVFeVYrQjUzREh5OUFwVGRzeGJI?= =?utf-8?B?akozbkphcFg5Rk9RdWFLSHRaNmhSeTd2aXJ2VG0xbVVTR2c5QXhMSGdUQ0tv?= =?utf-8?B?TmhWaWNGVmlNZmRJRUNNZldCcnN0NEo5dHhLS0xoeEJ2cHlvMVc4b3VGVFhj?= =?utf-8?B?L2xoUkdXZGRaY1luL09JbXJCLzlVSmxUemo4NDRhaEdwNHRwdHFEQUpya0Nq?= =?utf-8?B?azZvRW1BVUxmQzdUM2g4RjNUK01Ta3QxZ3ZleWl1a0hpR08wVWVKZ1FnOUtP?= =?utf-8?B?T2FOQlFVWHErbzBuaHFQVzNEWnBtMmltNC9tOVZLaVFWazZEVlptU2pMd0Fp?= =?utf-8?B?cXhJcXp3bUhTNFc0VEo1OFdYcExUb2w2OFBZZmVhZDJGeVJnckt6blR1em5E?= =?utf-8?B?Z3NqOEs4SDUyUzNGb1IwOUo5VEFZbFVoK093bHRQb2x1UWMwc1EvVkVjRGhy?= =?utf-8?B?V0J5cWtUV3hoVllHeWdoelZLVHdVbUxDOGlUeVhoYXRPRlNQVGl3Yi9TdzJu?= =?utf-8?B?QVRDMFJUejU4eGZ0K3VRd1lOdlBEN0o0aGV2SHNZVXZFZ1c5cFRicmxTL0Ri?= =?utf-8?B?U1RvcDhSZHk2Q3RScjVTSko3L1haMFZOWDM5RWZSRVVMM2ZkSmN6a21xUW1U?= =?utf-8?B?R2Q5YmJSU3lZbm9SbTBFSFd5K3V3bldTNXd0akZwQ2hJTTFicUUzWjhENHdY?= =?utf-8?B?Uks1R0xrNmpjNVZkbU9uQUJraVhNUExIcFBtK0c2R0J1SkJaVk9XZVhRYXRH?= =?utf-8?B?Q2MyeWtmc1dDNXJSZkhQQUduUVRlNEExbVJjbUU1RlJTVUxzeW4vdVY4WitK?= =?utf-8?B?N3k4SHg0MFF3ZDlkeFN0SWFOaEkva1ErVlNFMjRrODIrZThjSldZYXltVkND?= =?utf-8?B?ZmVuSUN1dDlub2V0ZUh2OHBaOGZFME1WNGtYMzhmN1NSUDdQRFRpT3JJZmJm?= =?utf-8?B?YzVZc1Q2a2Y3cEEwMWZYdUpnZDcvakVmQzlPY1ZZdThwWitXTWtQQ28vdmdm?= =?utf-8?B?a0M3aGROQ3VUQmpQVGUybitnaTdzY0JpejNBbGYxMllmeFU5Zld2NzNGaWRU?= =?utf-8?B?VlZpa3FQdTJKRy84T0RzdTFKRHoxL3Y5Z0hmMkFLQWx4eHFRazF3VFRBbVY3?= =?utf-8?B?NTdBMTBISXBURVlGQlBRTCtVakJpRithcDh6VE8xd2h2eXFURSt4Yzc5b1Q2?= =?utf-8?Q?X822JF602bLCF5vna69l4sLWb?= 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 struc= t scmi_protocol_handle *ph, return ret; } =20 +/** + * 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 =3D ph_to_pi(ph); + struct scmi_info *info =3D 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, =20 static const struct scmi_proto_helpers_ops helpers_ops =3D { .extended_name_get =3D scmi_common_extended_name_get, + .get_max_msg_size =3D scmi_common_get_max_msg_size, .iter_response_init =3D scmi_iterator_init, .iter_response_run =3D scmi_iterator_run, .protocol_msg_check =3D scmi_protocol_msg_check, diff --git a/drivers/firmware/arm_scmi/protocols.h b/drivers/firmware/arm_s= cmi/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); }; =20 /** --=20 2.37.1 From nobody Sun Feb 8 12:57:49 2026 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 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable 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-kernel@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?B?WDV2VHRiaXNoNFpqRXlrRnE4YzNyTDRQdmc3QmR5TUlGUi9iVERVQU9nYmtw?= =?utf-8?B?VExZL1V0aHpIY2tyemhldkc0TTR3Uno2ak9maTJjVVpKTmJ5aE9qNDIyejlz?= =?utf-8?B?emVlYm9YSTRycWJKTnR5VjA2R2lyTWEyWXFZaXBsaEZ3Rm12Y0plRjE3WXhr?= =?utf-8?B?aUpSeVNsMzc5WUdINjZKekd3dWtYRzdER1FuTk1SZ001TUtYWDlwRXFEOUdU?= =?utf-8?B?azlkbmg3T0tpUk5WZ3lnVTlFUU54UXVkNk5KN3E5T2NqUHVXaGR1Sk1PaXdy?= =?utf-8?B?bVdBQVdsNGNSb1JOZFFvMXg2SUMzTkJ5VnBSZzZWYW5EckpJenppWjR2b29T?= =?utf-8?B?NFdsNTJRUWpnb0p0K3BQYWpTNDBiOWtSUnE1aGp6ZXh5UWMrb2YzdktBaC9X?= =?utf-8?B?SXNOZjZuR1dVeVVvTHlyenJVZjk2N1kzUzMxUE1ZT0I5OWd2b2ppUXJCTVVq?= =?utf-8?B?MGs4V1J3RUFzWGpldFp3OWZvWFZMVUxQUE9KZEdDTXY2RTh6M2x5Q0x2eGJR?= =?utf-8?B?TzdsdkVCd2l0V1ZIQzUza3NDa1pIVmU4L0N6ZXBNK24venpXRmFjMlBPNWR5?= =?utf-8?B?cTFWZnJwamx3S0l1WjZyU2JZcEphS3o3R1cxVkRhcEhjL3lqUXlmMTJvSGZ1?= =?utf-8?B?OHJ3REdhYmpqclBuZTQyZUtKR0VkRVUvcjVaSUZwcWdjbjgrTUFjRE9HUzZq?= =?utf-8?B?OEJubkJsdkQ4VU9HQmN2RnZaZ29DVXQ3L2VRN1c2MlFnS3F6MlZUWDlLdnJm?= =?utf-8?B?Y1ZaY3ZlckZsQnpUVFM0S1lzSjFyMGwraGIzaHpkQmNER1g3N0pOUWJtM0NK?= =?utf-8?B?ZjgxR1FBakJGUU5BTlFTdGtHWW1vTlk0aG02QUpWS3Z5WUxCMW1xZDhFWmVt?= =?utf-8?B?SkRyVjlDVkZEVjdzd3JtblhxMDNKREgvVDJSd2lHTzFrSU51cWZzQXkybTJN?= =?utf-8?B?UnNSeDdJZC9zTTM5Q0YyRDU4dXdXbzB0b0RhaC92OGw1SkxPVkJaanB1QjNY?= =?utf-8?B?V1I0TElQQ1M4ZmdJM1JxZFNBMklTTk04akw1VFBtR1ZKVUo2NUtMdmZjMjZ4?= =?utf-8?B?eWcxb242dzFOUWJQOTlJUFFtVXZnUFdHNHFqNHZXVUpKZ1JCZlIvb250QTdi?= =?utf-8?B?LzllZHR4aE1UK2ZYdHMyMEg2SlJBNTZGOEM5T1BJUUp2cnFkdUtuZi9kclBr?= =?utf-8?B?SFVrOUo1bEFTQmdiQzhTdUlmOUNCbDhmdG1iVnp5eWFBa2MrVXZ6ZXF0Z1Vx?= =?utf-8?B?UUZudG0yRituaENnY1BqWlBTNW9lRDNqY0hkTkJRUFhIRmNteVd4cng3M0g4?= =?utf-8?B?WnpNV1lCSElmajRQOWludVluUHY3ajN6STdiZEFqR25TWWJOd3RDYjhDbW1N?= =?utf-8?B?UjJuNThOVmNyZkJNT2dISkZ1bDJMVXpXTWtxUGRYdGFRMW1sZkRVSHVYZCsz?= =?utf-8?B?VVp3ZzVJa2srZEZYZGovVFZEQkRFRmZQWlNjQ1E3ZEZoZHJENmFNRkxZZXU3?= =?utf-8?B?SkE5ZGVmcHM2RUZmbkk2NHJrVnZGSm80YXZLdXlYS2hvdDBVV2ltMWlKWDFK?= =?utf-8?B?UmJRZ1cxcHdkNWcwdHkzazcxRUl3bElDMW1mL0ZpejJlY3V0QXFzdzJiQnZk?= =?utf-8?B?a3o2cmg2aHdRdGpzMk0rT09NMVl6R0k3ZHhycmpRdkdvc2RFNE5mZTdHZkFh?= =?utf-8?B?aUtQcXRRa3hHZzZndzRQdFJvVnhBeTlQSWhQQ1FSclJReGlOczBLNU9WZ0tq?= =?utf-8?B?NzBxZlZnZ0xUZnVDMjA3dmFidXFDak9ya1BBOG1BbHBVblFQZ3lqU0V0a08r?= =?utf-8?B?b2xvM2hseUhva00zNkNtbkwrSjl0VjNIWTZicnVleXhVRHBXWmREV2Nubkpi?= =?utf-8?B?TXAzTDR0ZFpFRkpTTUROSFZNRGliTkMrV1IxSk0xazFhL3lrSElWUEFCTWdN?= =?utf-8?B?aFRmZWZFaklyVkNVaTRsaXRkaTFrSGdtRjF2bWRqVkQ1QnQwWCtTZVNrOHl4?= =?utf-8?B?ZXVONkhHVHdsLzIxZlN5ZFk1YlF2ZmVEdWQrZUsyWlBVODZYUFNEcGk2VjA2?= =?utf-8?B?a3V1T01hUXdCdmkrSnc1aGVaVCsvOXRzTXI3bUM3ZGVIdGdsckYzdlNGRXVl?= =?utf-8?Q?XchIfu9+LNMMwvmOxsg+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/Doc= umentation/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 =20 + 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 =20 $defs: @@ -401,6 +432,25 @@ examples: scmi_powercap: protocol@18 { reg =3D <0x18>; }; + + scmi_pinctrl: protocol@19 { + reg =3D <0x19>; + + i2c2-pins { + groups =3D "g_i2c2_a", "g_i2c2_b"; + function =3D "f_i2c2"; + }; + + mdio-pins { + groups =3D "g_avb_mdio"; + drive-strength =3D <24>; + }; + + keys_pins: keys-pins { + pins =3D "gpio_5_17", "gpio_5_20", "gpio_5_22", "gpio_= 2_1"; + bias-pull-up; + }; + }; }; }; =20 --=20 2.37.1 From nobody Sun Feb 8 12:57:49 2026 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 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable 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-kernel@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?B?Vm1tZWU3cjgxdGhrQm1ycnptbm1KKzBrR1RORUlPN0ZJVXU0QVhBbUdVMjVN?= =?utf-8?B?L2lUdHc0V0xoUWhMRnduTE5HaU5HS3VnYjIvNXhVVHdHdnBkN0NqejI0cXl1?= =?utf-8?B?ODFxTXNNWUdOSzd1K3RvUGJHZmwzRVQ0bEE0V0tzT2pmek16dUl5S1BEdUR2?= =?utf-8?B?T29GSWxVZmt2U2R3YUZWeDRWWHhQTnAybklJdEI0N0VCOGVqK1crQ2V2d25B?= =?utf-8?B?ZVp3bEhFMEg4L25HNW9jS0x1bk9ROXhWZ2pLSlIxZkNyK3JxTytWUkxsUEI0?= =?utf-8?B?dEdSUVdVWnp1djdpR0oxSDdKSWxyaHoxZ2o0ek45NE0vUFRrY200MUwzTmZN?= =?utf-8?B?NitKUUl5UTlqeGdaM2FabHZHVXhLK1phRmZNd0hJVUFyNk4rVXVWSlNZdVJU?= =?utf-8?B?Qm9LSHlhTTZ5YkNRS3JNaWoyb2hqZXFmanlSZU1NWDJrVWxkY0ZwS25neUIy?= =?utf-8?B?bm5PWTdBbkJEK0o2Wm0wTDBRUVJZVFQ5MHJvU3lPcXFaV0hVeGc0NHJCQW5G?= =?utf-8?B?NVFObTgrWTZrMTZUOHNZaXVQZVNNeXlyNHlzZVY4dGZ2ck84RFN2Qkg4UzVC?= =?utf-8?B?aTRBZFpqK3Nrc3ZXQVNMNWFkeE9GZ0QwUWtiVkpnVkF6STJOOXkvaWJpRXlo?= =?utf-8?B?Ukp3Z0Z3eGplS09TTHBGVmdkczN5emZYMjZBM0hrTFJCcWVnckJRUDlyME1F?= =?utf-8?B?RFpwcWhlUEI0ZDlUNHhiSGxHMnFpSXBDL05EV1EvQktuZi9ZbG4rVjhJbnVC?= =?utf-8?B?dmI0eVNhV2R1RkxTTWp4MFlQOFZOV1FDTmVZVTRSREFWZjh6Q04rbWFUZmht?= =?utf-8?B?UmxTTHZIcTBuakFpU0ZMcHBNTnAxT0pWQUMrcGpRUkYxK29vQWg2Z2w5SDFL?= =?utf-8?B?TXZuZUJBejVhTi9tN2FYdlBBUlVmRkxFWEdRMVI0TVNQQVB1cVYrcEM3RXps?= =?utf-8?B?SGJXME05SWtxSStUOVhZaFJ2MS9uZW1QTTl5UFU0bURXQlA1L2dJSUNVTEF2?= =?utf-8?B?L3Z6N0dXVnR5QjlpWWNVN09ybEZ5NDBBVGRaY1ZSUHU1QXhVLzl1Mnd5YlFh?= =?utf-8?B?SlVjT2ZkamNDVHFtUURSbVIrZmRBYUl3cFUzOHltMi9NN2Q5SUtQU1ZaaXNS?= =?utf-8?B?OVN2WHQ5Q3VzZmM0NU1GdS9NTTcrN1cvcHBVNDRGN2NaaGErT3JVYVpHMTdP?= =?utf-8?B?SWRLZ1VRQUpubW9TUWxzb0E0bU4zcWhjU0c1bGdEWFRxTXVHUyszTW9RRWsr?= =?utf-8?B?Z3VOeWw3bjZWU2VzeU0reVFBNmxsdjV5Z25xWGh0bk5PVnNqL20rOFZ1NzZi?= =?utf-8?B?S0RZZ2hVR1VvUkprQXp5QmM1cElsb3Fnd1BlOHlrd1F3RU5uVUNHdlJXUTIy?= =?utf-8?B?Njd4b0FsQnZINjlTYmhtVC84TitqL05BSDZFbGRYa0ZrMTlNdnJ0TzkraS9u?= =?utf-8?B?T2VEMWxTMFJublNkQ3dTQ3pJelg0Y2p2aThMYS9EZTZDb04wU3VCZ0tRb0pk?= =?utf-8?B?ek5NU3p2Y0hhd1RQVTNONExPdUJlQmhVT1dGMEJJMzVZRDNnYXhNYkJIT2oz?= =?utf-8?B?Rm9ZcWx4ZWN0YWtIUmZISEZqTlg0eVY0WFJpMks0WG0valBxZC8yWTRTS2FE?= =?utf-8?B?MWNvK01aV1Yya2VjWEUvWU1GYTd2c2s3ZytDaEpaS2c1L0Z5eGd2UVZKSWpp?= =?utf-8?B?NUw4WndBSFFGM05wcTUzWlMya0l2M2RJOFhVakR2Qzc0djJSYmdHdG5ZZEM2?= =?utf-8?B?akZxcmhSVktNMFhBV0pxT29OOGRtUGlKcXRsZUdpUjdVSDlMdnVnYmJ1U05p?= =?utf-8?B?bk9rWThuTHN1VlJoSGFUeXJTK1lUbC9COGVaQmRwdVZKNjR1ekpWZVFDTnJZ?= =?utf-8?B?dCtuTTh6cU1aMmtFZ0NJYmh2YlFkQnh1NjVXN2Fla2xVcUplbUNOVXlnSXhs?= =?utf-8?B?TW95UFl3aUZQVnNhZWFYSTZ0M0xXTStxYWJhUXUxc3FZaGpxU1dDOVVOMGl6?= =?utf-8?B?bVNPaW51Ylp1ek91K0oyQXFwQnN5MStFc3RkRUZzdWJoMDZER1VaN1Z4SE9i?= =?utf-8?B?WDJPYUJvcUlOdENnNEpkOHlOZ29jVWtIQkV0OEtCR211em9vUmZjUTZTaC8x?= =?utf-8?Q?kjInU+ye8hr3p0uGaheq7hGX9?= 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) +=3D msg.o scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO) +=3D virtio.o scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) +=3D optee.o scmi-protocols-y =3D base.o clock.o perf.o power.o reset.o sensors.o syste= m.o voltage.o powercap.o +scmi-protocols-y +=3D pinctrl.o scmi-module-objs :=3D $(scmi-driver-y) $(scmi-protocols-y) $(scmi-transpor= t-y) =20 obj-$(CONFIG_ARM_SCMI_PROTOCOL) +=3D 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(); =20 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(); =20 scmi_transports_exit(); =20 diff --git a/drivers/firmware/arm_scmi/pinctrl.c b/drivers/firmware/arm_scm= i/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 merg= ed */ +#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 =3D 0x3, + PINCTRL_LIST_ASSOCIATIONS =3D 0x4, + PINCTRL_CONFIG_GET =3D 0x5, + PINCTRL_CONFIG_SET =3D 0x6, + PINCTRL_FUNCTION_SELECT =3D 0x7, + PINCTRL_REQUEST =3D 0x8, + PINCTRL_RELEASE =3D 0x9, + PINCTRL_NAME_GET =3D 0xa, + PINCTRL_SET_PERMISSIONS =3D 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 =3D ph->xops->xfer_get_init(ph, PROTOCOL_ATTRIBUTES, 0, sizeof(*attr), + &t); + if (ret) + return ret; + + attr =3D t->rx.buf; + + ret =3D ph->xops->do_xfer(ph, t); + if (!ret) { + pi->nr_functions =3D GET_FUNCTIONS_NR(attr->attributes_high); + pi->nr_groups =3D GET_GROUPS_NR(attr->attributes_low); + pi->nr_pins =3D 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 =3D 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 =3D scmi_pinctrl_count_get(ph, type); + if (value < 0) + return value; + + if (identifier >=3D 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 =3D scmi_pinctrl_validate_id(ph, selector, type); + if (ret) + return ret; + + ret =3D ph->xops->xfer_get_init(ph, PINCTRL_ATTRIBUTES, sizeof(*tx), + sizeof(*rx), &t); + if (ret) + return ret; + + tx =3D t->tx.buf; + rx =3D t->rx.buf; + tx->identifier =3D cpu_to_le32(selector); + tx->flags =3D cpu_to_le32(type); + + ret =3D ph->xops->do_xfer(ph, t); + if (!ret) { + if (n_elems) + *n_elems =3D 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 =3D message; + const struct scmi_pinctrl_ipriv *p =3D priv; + + msg->identifier =3D cpu_to_le32(p->selector); + msg->flags =3D cpu_to_le32(p->type); + /* Set the number of OPPs to be skipped/already read */ + msg->index =3D 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 =3D response; + + st->num_returned =3D RETURNED(r->flags); + st->num_remaining =3D 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 =3D response; + struct scmi_pinctrl_ipriv *p =3D priv; + + p->array[st->desc_index + st->loop_idx] =3D + le16_to_cpu(r->array[st->loop_idx]); + + return 0; +} + +static int scmi_pinctrl_list_associations(const struct scmi_protocol_handl= e *ph, + u32 selector, + enum scmi_pinctrl_selector_type type, + u16 size, unsigned int *array) +{ + int ret; + void *iter; + struct scmi_iterator_ops ops =3D { + .prepare_message =3D iter_pinctrl_assoc_prepare_message, + .update_state =3D iter_pinctrl_assoc_update_state, + .process_response =3D iter_pinctrl_assoc_process_response, + }; + struct scmi_pinctrl_ipriv ipriv =3D { + .selector =3D selector, + .type =3D type, + .array =3D array, + }; + + if (!array || !size || type =3D=3D PIN_TYPE) + return -EINVAL; + + ret =3D scmi_pinctrl_validate_id(ph, selector, type); + if (ret) + return ret; + + iter =3D 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 =3D message; + const struct scmi_conf_get_ipriv *p =3D priv; + u32 attributes; + + attributes =3D FIELD_PREP(BIT(18), p->all) | + FIELD_PREP(GENMASK(17, 16), p->type); + + if (p->all) + attributes |=3D FIELD_PREP(GENMASK(15, 8), desc_index); + else + attributes |=3D FIELD_PREP(GENMASK(7, 0), p->config_types[0]); + + msg->attributes =3D cpu_to_le32(attributes); + msg->identifier =3D 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 =3D response; + struct scmi_conf_get_ipriv *p =3D priv; + + if (!p->all) { + st->num_returned =3D 1; + st->num_remaining =3D 0; + } else { + st->num_returned =3D le32_get_bits(r->num_configs, GENMASK(7, 0)); + st->num_remaining =3D 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 =3D response; + struct scmi_conf_get_ipriv *p =3D priv; + + if (!p->all) { + if (p->config_types[0] !=3D + le32_get_bits(r->configs[st->loop_idx * 2], GENMASK(7, 0))) + return -EINVAL; + } else { + p->config_types[st->desc_index + st->loop_idx] =3D + le32_get_bits(r->configs[st->loop_idx * 2], + GENMASK(7, 0)); + } + + p->config_values[st->desc_index + st->loop_idx] =3D + 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 selecto= r, + 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 =3D { + .prepare_message =3D iter_pinctrl_conf_get_prepare_message, + .update_state =3D iter_pinctrl_conf_get_update_state, + .process_response =3D iter_pinctrl_conf_get_process_response, + }; + struct scmi_conf_get_ipriv ipriv =3D { + .selector =3D selector, + .type =3D type, + .all =3D 0, + .config_types =3D &config_type, + .config_values =3D config_value, + }; + + if (!config_value || type =3D=3D FUNCTION_TYPE) + return -EINVAL; + + ret =3D scmi_pinctrl_validate_id(ph, selector, type); + if (ret) + return ret; + + iter =3D 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 selecto= r, + 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 =3D 0; + unsigned int chunk; + int max_msg_size =3D ph->hops->get_max_msg_size(ph); + + if (!config_type || !config_value || type =3D=3D FUNCTION_TYPE) + return -EINVAL; + + ret =3D scmi_pinctrl_validate_id(ph, selector, type); + if (ret) + return ret; + + configs_in_chunk =3D (max_msg_size - sizeof(*tx)) / (sizeof(__le32) * 2); + while (conf_num < nr_configs) { + chunk =3D (nr_configs - conf_num > configs_in_chunk) ? + configs_in_chunk : nr_configs - conf_num; + + ret =3D ph->xops->xfer_get_init(ph, PINCTRL_CONFIG_SET, + sizeof(*tx) + + chunk * 2 * sizeof(__le32), + 0, &t); + if (ret) + return ret; + + tx =3D t->tx.buf; + tx->identifier =3D cpu_to_le32(selector); + attributes =3D FIELD_PREP(GENMASK(1, 0), type) | + FIELD_PREP(GENMASK(9, 2), chunk); + tx->attributes =3D cpu_to_le32(attributes); + + for (i =3D 0; i < chunk; i++) { + tx->configs[i * 2] =3D + cpu_to_le32(config_type[conf_num + i]); + tx->configs[i * 2 + 1] =3D + cpu_to_le32(config_value[conf_num + i]); + } + + ret =3D ph->xops->do_xfer(ph, t); + + ph->xops->xfer_put(ph, t); + + if (ret) + break; + + conf_num +=3D 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 =3D=3D FUNCTION_TYPE) + return -EINVAL; + + ret =3D scmi_pinctrl_validate_id(ph, identifier, type); + if (ret) + return ret; + + ret =3D ph->xops->xfer_get_init(ph, PINCTRL_FUNCTION_SELECT, sizeof(*tx), + 0, &t); + if (ret) + return ret; + + tx =3D t->tx.buf; + tx->identifier =3D cpu_to_le32(identifier); + tx->function_id =3D cpu_to_le32(function_id); + tx->flags =3D cpu_to_le32(type); + + ret =3D 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 =3D=3D FUNCTION_TYPE) + return -EINVAL; + + ret =3D scmi_pinctrl_validate_id(ph, identifier, type); + if (ret) + return ret; + + ret =3D ph->xops->xfer_get_init(ph, PINCTRL_REQUEST, sizeof(*tx), 0, &t); + + tx =3D t->tx.buf; + tx->identifier =3D cpu_to_le32(identifier); + tx->flags =3D cpu_to_le32(type); + + ret =3D 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 =3D=3D FUNCTION_TYPE) + return -EINVAL; + + ret =3D scmi_pinctrl_validate_id(ph, identifier, type); + if (ret) + return ret; + + ret =3D ph->xops->xfer_get_init(ph, PINCTRL_RELEASE, sizeof(*tx), 0, &t); + + tx =3D t->tx.buf; + tx->identifier =3D cpu_to_le32(identifier); + tx->flags =3D cpu_to_le32(type); + + ret =3D 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, u3= 2 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 =3D 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 =3D kmalloc_array(group->nr_pins, + sizeof(*group->group_pins), + GFP_KERNEL); + if (!group->group_pins) + return -ENOMEM; + + ret =3D scmi_pinctrl_list_associations(ph, selector, GROUP_TYPE, + group->nr_pins, group->group_pins); + if (ret) { + kfree(group->group_pins); + return ret; + } + + group->present =3D 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 =3D ph->get_priv(ph); + + if (!name) + return -EINVAL; + + if (selector >=3D pi->nr_groups) + return -EINVAL; + + if (!pi->groups[selector].present) { + int ret; + + ret =3D scmi_pinctrl_get_group_info(ph, selector, + &pi->groups[selector]); + if (ret) + return ret; + } + + *name =3D 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 =3D ph->get_priv(ph); + + if (!pins || !nr_pins) + return -EINVAL; + + if (selector >=3D pi->nr_groups) + return -EINVAL; + + if (!pi->groups[selector].present) { + int ret; + + ret =3D scmi_pinctrl_get_group_info(ph, selector, + &pi->groups[selector]); + if (ret) + return ret; + } + + *pins =3D pi->groups[selector].group_pins; + *nr_pins =3D pi->groups[selector].nr_pins; + + return 0; +} + +static int scmi_pinctrl_get_function_info(const struct scmi_protocol_handl= e *ph, + u32 selector, + struct scmi_function_info *func) +{ + int ret; + + if (!func) + return -EINVAL; + + ret =3D 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 =3D kmalloc_array(func->nr_groups, sizeof(*func->groups), + GFP_KERNEL); + if (!func->groups) + return -ENOMEM; + + ret =3D scmi_pinctrl_list_associations(ph, selector, FUNCTION_TYPE, + func->nr_groups, func->groups); + if (ret) { + kfree(func->groups); + return ret; + } + + func->present =3D true; + return 0; +} + +static int scmi_pinctrl_get_function_name(const struct scmi_protocol_handl= e *ph, + u32 selector, const char **name) +{ + struct scmi_pinctrl_info *pi =3D ph->get_priv(ph); + + if (!name) + return -EINVAL; + + if (selector >=3D pi->nr_functions) + return -EINVAL; + + if (!pi->functions[selector].present) { + int ret; + + ret =3D scmi_pinctrl_get_function_info(ph, selector, + &pi->functions[selector]); + if (ret) + return ret; + } + + *name =3D 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 =3D ph->get_priv(ph); + + if (!groups || !nr_groups) + return -EINVAL; + + if (selector >=3D pi->nr_functions) + return -EINVAL; + + if (!pi->functions[selector].present) { + int ret; + + ret =3D scmi_pinctrl_get_function_info(ph, selector, + &pi->functions[selector]); + if (ret) + return ret; + } + + *groups =3D pi->functions[selector].groups; + *nr_groups =3D 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 =3D scmi_pinctrl_attributes(ph, PIN_TYPE, selector, + pin->name, NULL); + if (ret) + return ret; + + pin->present =3D 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 =3D ph->get_priv(ph); + + if (!name) + return -EINVAL; + + if (selector >=3D pi->nr_pins) + return -EINVAL; + + if (!pi->pins[selector].present) { + int ret; + + ret =3D scmi_pinctrl_get_pin_info(ph, selector, + &pi->pins[selector]); + if (ret) + return ret; + } + + *name =3D 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 =3D { + .count_get =3D scmi_pinctrl_count_get, + .name_get =3D scmi_pinctrl_name_get, + .group_pins_get =3D scmi_pinctrl_group_pins_get, + .function_groups_get =3D scmi_pinctrl_function_groups_get, + .mux_set =3D scmi_pinctrl_mux_set, + .config_get =3D scmi_pinctrl_config_get, + .config_set =3D scmi_pinctrl_config_set, + .pin_request =3D scmi_pinctrl_pin_request, + .pin_free =3D scmi_pinctrl_pin_free, +}; + +static int scmi_pinctrl_protocol_init(const struct scmi_protocol_handle *p= h) +{ + int ret; + u32 version; + struct scmi_pinctrl_info *pinfo; + + ret =3D 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 =3D devm_kzalloc(ph->dev, sizeof(*pinfo), GFP_KERNEL); + if (!pinfo) + return -ENOMEM; + + ret =3D scmi_pinctrl_attributes_get(ph, pinfo); + if (ret) + return ret; + + pinfo->pins =3D devm_kcalloc(ph->dev, pinfo->nr_pins, + sizeof(*pinfo->pins), + GFP_KERNEL); + if (!pinfo->pins) + return -ENOMEM; + + pinfo->groups =3D devm_kcalloc(ph->dev, pinfo->nr_groups, + sizeof(*pinfo->groups), + GFP_KERNEL); + if (!pinfo->groups) + return -ENOMEM; + + pinfo->functions =3D devm_kcalloc(ph->dev, pinfo->nr_functions, + sizeof(*pinfo->functions), + GFP_KERNEL); + if (!pinfo->functions) + return -ENOMEM; + + pinfo->version =3D 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 =3D ph->get_priv(ph); + + for (i =3D 0; i < pi->nr_groups; i++) { + if (pi->groups[i].present) { + kfree(pi->groups[i].group_pins); + pi->groups[i].present =3D false; + } + } + + for (i =3D 0; i < pi->nr_functions; i++) { + if (pi->functions[i].present) { + kfree(pi->functions[i].groups); + pi->functions[i].present =3D false; + } + } + + return 0; +} + +static const struct scmi_protocol scmi_pinctrl =3D { + .id =3D SCMI_PROTOCOL_PINCTRL, + .owner =3D THIS_MODULE, + .instance_init =3D &scmi_pinctrl_protocol_init, + .instance_deinit =3D &scmi_pinctrl_protocol_deinit, + .ops =3D &pinctrl_proto_ops, + .supported_version =3D 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_s= cmi/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); }; =20 +enum scmi_pinctrl_selector_type { + PIN_TYPE =3D 0, + GROUP_TYPE, + FUNCTION_TYPE, +}; + +enum scmi_pinctrl_conf_type { + SCMI_PIN_NONE =3D 0x0, + SCMI_PIN_BIAS_BUS_HOLD =3D 0x1, + SCMI_PIN_BIAS_DISABLE =3D 0x2, + SCMI_PIN_BIAS_HIGH_IMPEDANCE =3D 0x3, + SCMI_PIN_BIAS_PULL_UP =3D 0x4, + SCMI_PIN_BIAS_PULL_DEFAULT =3D 0x5, + SCMI_PIN_BIAS_PULL_DOWN =3D 0x6, + SCMI_PIN_DRIVE_OPEN_DRAIN =3D 0x7, + SCMI_PIN_DRIVE_OPEN_SOURCE =3D 0x8, + SCMI_PIN_DRIVE_PUSH_PULL =3D 0x9, + SCMI_PIN_DRIVE_STRENGTH =3D 0xA, + SCMI_PIN_INPUT_DEBOUNCE =3D 0xB, + SCMI_PIN_INPUT_MODE =3D 0xC, + SCMI_PIN_PULL_MODE =3D 0xD, + SCMI_PIN_INPUT_VALUE =3D 0xE, + SCMI_PIN_INPUT_SCHMITT =3D 0xF, + SCMI_PIN_LOW_POWER_MODE =3D 0x10, + SCMI_PIN_OUTPUT_MODE =3D 0x11, + SCMI_PIN_OUTPUT_VALUE =3D 0x12, + SCMI_PIN_POWER_SOURCE =3D 0x13, + SCMI_PIN_SLEW_RATE =3D 0x20, + SCMI_PIN_OEM_START =3D 0xC0, + SCMI_PIN_OEM_END =3D 0xFF, +}; + +/** + * struct scmi_pinctrl_proto_ops - represents the various operations provi= ded + * 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 gro= up + * @function_groups_get: returns the set of groups, assigned to the specif= ied + * 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 =3D 0x16, SCMI_PROTOCOL_VOLTAGE =3D 0x17, SCMI_PROTOCOL_POWERCAP =3D 0x18, + SCMI_PROTOCOL_PINCTRL =3D 0x19, }; =20 enum scmi_system_events { --=20 2.37.1 From nobody Sun Feb 8 12:57:49 2026 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 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable 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-kernel@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?B?K3lydjVjZE5BMkNRUEFRZVVPTVlwVG42S3Z6TkhDL3BKbW9NdnVpSlJOZDFV?= =?utf-8?B?WVJmOFBDL1hiamttbHNERXdQaWdRZnFpanZ1ZlAyZWhrbWZPbi90cUg5QWhW?= =?utf-8?B?WWRUZWplQ2g1TFpWdWF3T1ZGV1pjZmpmQ2I5bCtpRENTRWJid0tDSVR5THU0?= =?utf-8?B?YUI5cXE1RUViZ0d5aWVUcTNxdTNQa3Viak1mbkZuQ1NaR0daY2o3NFpFdTdD?= =?utf-8?B?Z0dEbzhNYzFXWCtBTkdJZTd4TzQ0OXZtcEZyZmQ3VFE2aU53dCtBOGRUWnE1?= =?utf-8?B?aEJXcTRuQlR1NVdLeGVmVWVSalkvOGpzdUxQS3YvSWJGMEJYM1Uva2ZIcCti?= =?utf-8?B?K3FwR1lBQ01sUmUzTitRQy9HM1R5QWhaL2hYd1ZOdGZRTmFpdFVNMERzdU00?= =?utf-8?B?c0NjeWdQTlVvb2tWUlA4WlRra2hWeDFDSUFTc1NCNnVxa2VuekMyM3ZyNTBh?= =?utf-8?B?UGphYTNRcEJOcG9HT3c2d3UyOGpGL2c4Y1A2ZFVZRHRIQ1hqL0dydGwwNXNC?= =?utf-8?B?RmZrY0t4czVtR0JPd1YwSG1pQVVBR3M3ZFI5R2IxajMxUWJkWjY3Y252MEJx?= =?utf-8?B?WXdXZ1laNkg5VTRYVW9sc2hVd2lkeXJrYmswakZIRUhubDhqcm5IdnVpSEhr?= =?utf-8?B?bGpPcEROVmV3aC9UYUZ2M0dTLzhZY0dMaWQxc205WnpRZURaUVI3SGo1SnFD?= =?utf-8?B?aFI0cGdsVEgyOWpraHJHKzFYOGw1NkFOQkpmOGFQMDN1cEUzT0ExY2dGQ0RI?= =?utf-8?B?Q3E2bzFnSFhCa3JObWZueFNLQm9IOE16UURQN1FzclhNazduT0UveUZtZWNx?= =?utf-8?B?UFozbVkvTE5GNjYvVStQN2k2QXFEYTVzbkZsRTF1TFUyUEpnRklzYjBEaHBp?= =?utf-8?B?ZW1aNUFQNGR0UDcyNEtKTHBCcjd2WEtZeUd6aGtjVk1xQTlKMGd5ak5pcmlw?= =?utf-8?B?VUcwZGxhaHhQNVlMMTBBZ1ViNkU3VllXWE9hNWNtSXN1THpzTjZ4WlVwNHE5?= =?utf-8?B?dmR1U1Z1bWFlcFZEeWw4dU9CWEhXb3BEU2MvTm1heDY2VUcrNkdSYjJtNjZF?= =?utf-8?B?L2FUTWM1dEZ6MnVZWCtOeDlEc2VLVWxTR2tVend1eEFlZWRpNWdWU0V5MVVJ?= =?utf-8?B?T1lUUk8wTHIxbDJjVkJXMUxKd0RRYXpjT1Z6cVlqNVVDZU5aVE91R2hYUHhO?= =?utf-8?B?M3ZMcDdlMFd2VUo5aUZkSDl5RjJLNk93enlXSkFBR0c2V1lVd3hoSTFMSnEr?= =?utf-8?B?RS9yUXlWeFBBbjd6bmREa0pndXV6RUt5SjQ2M1BMeGhKOEEwNzNCbzAxSGZu?= =?utf-8?B?cW03S04zc0VDSDY4L2tqa2lBZUx6V1BLUW9Kakc2YXkxRVpadDczejB1aWNt?= =?utf-8?B?SkZkdDhhNS9QNFpSeTgwTjNUM1E5TkdNbHJEZ08yQmM4NVZrVWZpN1YrMzRW?= =?utf-8?B?bk1Ba3pwTVZ2Vk5NNitVNENaU01xRGxWMGozVGRUWituU1UrQVI3NEREeFlK?= =?utf-8?B?aGRuM2txK1lKd0RkSEhFT2NSWCt5bXZWKzVzZXMvaUJlTDRKRGlZNzB6Y0Jv?= =?utf-8?B?dHVoZ24xNUNEZElhTm9PdFZYTFQxUlJHaTliWFZTZXBOV3B2QnE1TTRUbjB3?= =?utf-8?B?SVpSNVZ1TFMxWUZOV0JkOEdHR2FlYzFETjc5NlhmdDBPM1YxdzlySXBtNjFt?= =?utf-8?B?azRuK3JCUzFJZk1BSnRaSURXLzFqVld6aytyQU5hR1M2RnBCTEY5cmd1R2U5?= =?utf-8?B?TlZCdVdtTkFyL095VUMzbnNNZmdzU2JNZ2JkNHczZmpnQ3NQVVcwS2JCeVhn?= =?utf-8?B?bndIczFZMWovRHZHejJsZFNaQUpJaTIzUjZFekhTaHY1WkMxMWkwU3pWYW1Q?= =?utf-8?B?MFVTSTc1Uk96L1ZzMkpHS3VLczR0bG9PU1MvWUNzVU5jRDdvRHpLa01POHJs?= =?utf-8?B?ODRQRnlSVEtlL0ZzQkw1TmxZdVpmeGQzYm5OcmtIKy9ON0tTQm1rUG1xcjFM?= =?utf-8?B?NHBaZU5jb2NtUlk3cmduYU9Ed09vN3JnZ0Vmb3JtWEl0cmJ4VVpiNEpYQlc4?= =?utf-8?B?NmM0bDBnZzdBWjlhR3ZSSnBiaksxV3NydGtiRXc3T1BUZHJCVW5oY1pvTlRs?= =?utf-8?Q?qQUb2PunhqzgFqvubiliZQebo?= 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. =20 +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) +=3D pinctrl-pic32.o obj-$(CONFIG_PINCTRL_PISTACHIO) +=3D pinctrl-pistachio.o obj-$(CONFIG_PINCTRL_RK805) +=3D pinctrl-rk805.o obj-$(CONFIG_PINCTRL_ROCKCHIP) +=3D pinctrl-rockchip.o +obj-$(CONFIG_PINCTRL_SCMI) +=3D pinctrl-scmi.o obj-$(CONFIG_PINCTRL_SINGLE) +=3D pinctrl-single.o obj-$(CONFIG_PINCTRL_ST) +=3D pinctrl-st.o obj-$(CONFIG_PINCTRL_STMFX) +=3D 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 =3D 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 =3D pinctrl_dev_get_drvdata(pctldev); + + ret =3D 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 =3D 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 =3D { + .get_groups_count =3D pinctrl_scmi_get_groups_count, + .get_group_name =3D pinctrl_scmi_get_group_name, + .get_group_pins =3D pinctrl_scmi_get_group_pins, +#ifdef CONFIG_OF + .dt_node_to_map =3D pinconf_generic_dt_node_to_map_all, + .dt_free_map =3D pinconf_generic_dt_free_map, +#endif +}; + +static int pinctrl_scmi_get_functions_count(struct pinctrl_dev *pctldev) +{ + struct scmi_pinctrl *pmx =3D 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 *pctl= dev, + unsigned int selector) +{ + int ret; + const char *name; + struct scmi_pinctrl *pmx =3D pinctrl_dev_get_drvdata(pctldev); + + ret =3D 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 =3D pinctrl_dev_get_drvdata(pctldev); + + if (!groups || !num_groups) + return -EINVAL; + + if (selector < pmx->nr_functions && + pmx->functions[selector].num_groups) { + *groups =3D (const char * const *)pmx->functions[selector].groups; + *num_groups =3D pmx->functions[selector].num_groups; + return 0; + } + + ret =3D 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 =3D pmx->functions[selector].num_groups; + if (!*num_groups) + return -EINVAL; + + pmx->functions[selector].groups =3D + devm_kcalloc(pmx->dev, *num_groups, + sizeof(*pmx->functions[selector].groups), + GFP_KERNEL); + if (!pmx->functions[selector].groups) + return -ENOMEM; + + for (i =3D 0; i < *num_groups; i++) { + pmx->functions[selector].groups[i] =3D + pinctrl_scmi_get_group_name(pmx->pctldev, + group_ids[i]); + if (!pmx->functions[selector].groups[i]) { + ret =3D -ENOMEM; + goto err_free; + } + } + + *groups =3D (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 =3D 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 =3D pinctrl_dev_get_drvdata(pctldev); + + return pinctrl_ops->pin_request(pmx->ph, offset); +} + +static int pinctrl_scmi_free(struct pinctrl_dev *pctldev, unsigned int off= set) +{ + struct scmi_pinctrl *pmx =3D pinctrl_dev_get_drvdata(pctldev); + + return pinctrl_ops->pin_free(pmx->ph, offset); +} + +static const struct pinmux_ops pinctrl_scmi_pinmux_ops =3D { + .request =3D pinctrl_scmi_request, + .free =3D pinctrl_scmi_free, + .get_functions_count =3D pinctrl_scmi_get_functions_count, + .get_function_name =3D pinctrl_scmi_get_function_name, + .get_function_groups =3D pinctrl_scmi_get_function_groups, + .set_mux =3D 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 =3D param; + + switch (arg) { + case PIN_CONFIG_BIAS_BUS_HOLD: + *type =3D SCMI_PIN_BIAS_BUS_HOLD; + break; + case PIN_CONFIG_BIAS_DISABLE: + *type =3D SCMI_PIN_BIAS_DISABLE; + break; + case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: + *type =3D SCMI_PIN_BIAS_HIGH_IMPEDANCE; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + *type =3D SCMI_PIN_BIAS_PULL_DOWN; + break; + case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: + *type =3D SCMI_PIN_BIAS_PULL_DEFAULT; + break; + case PIN_CONFIG_BIAS_PULL_UP: + *type =3D SCMI_PIN_BIAS_PULL_UP; + break; + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + *type =3D SCMI_PIN_DRIVE_OPEN_DRAIN; + break; + case PIN_CONFIG_DRIVE_OPEN_SOURCE: + *type =3D SCMI_PIN_DRIVE_OPEN_SOURCE; + break; + case PIN_CONFIG_DRIVE_PUSH_PULL: + *type =3D SCMI_PIN_DRIVE_PUSH_PULL; + break; + case PIN_CONFIG_DRIVE_STRENGTH: + *type =3D SCMI_PIN_DRIVE_STRENGTH; + break; + case PIN_CONFIG_DRIVE_STRENGTH_UA: + *type =3D SCMI_PIN_DRIVE_STRENGTH; + break; + case PIN_CONFIG_INPUT_DEBOUNCE: + *type =3D SCMI_PIN_INPUT_DEBOUNCE; + break; + case PIN_CONFIG_INPUT_ENABLE: + *type =3D SCMI_PIN_INPUT_MODE; + break; + case PIN_CONFIG_INPUT_SCHMITT: + *type =3D SCMI_PIN_INPUT_SCHMITT; + break; + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: + *type =3D SCMI_PIN_INPUT_MODE; + break; + case PIN_CONFIG_MODE_LOW_POWER: + *type =3D SCMI_PIN_LOW_POWER_MODE; + break; + case PIN_CONFIG_OUTPUT: + *type =3D SCMI_PIN_OUTPUT_VALUE; + break; + case PIN_CONFIG_OUTPUT_ENABLE: + *type =3D SCMI_PIN_OUTPUT_MODE; + break; + case PIN_CONFIG_OUTPUT_IMPEDANCE_OHMS: + *type =3D SCMI_PIN_OUTPUT_VALUE; + break; + case PIN_CONFIG_POWER_SOURCE: + *type =3D SCMI_PIN_POWER_SOURCE; + break; + case PIN_CONFIG_SLEW_RATE: + *type =3D SCMI_PIN_SLEW_RATE; + break; + case SCMI_PIN_OEM_START ... SCMI_PIN_OEM_END: + *type =3D 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 =3D 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 =3D pinconf_to_config_param(*config); + + ret =3D pinctrl_scmi_map_pinconf_type(config_type, &type); + if (ret) { + dev_err(pmx->dev, "Error map pinconf_type %d\n", ret); + return ret; + } + + ret =3D pinctrl_ops->config_get(pmx->ph, _pin, PIN_TYPE, type, + &config_value); + if (ret) + return ret; + + *config =3D 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 <=3D SCMI_NUM_CONFIGS) + return 0; + + *p_config_value =3D kcalloc(num_configs, sizeof(u32), GFP_KERNEL); + *p_config_type =3D 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 <=3D 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 =3D 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 =3D config_type; + u32 *p_config_value =3D config_value; + enum pin_config_param param; + + if (!configs || !num_configs) + return -EINVAL; + + ret =3D pinctrl_scmi_alloc_configs(pctldev, num_configs, &p_config_type, + &p_config_value); + if (ret) + return ret; + + for (i =3D 0; i < num_configs; i++) { + param =3D pinconf_to_config_param(configs[i]); + ret =3D 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] =3D pinconf_to_config_argument(configs[i]); + } + + ret =3D 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 =3D 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 =3D config_type; + u32 *p_config_value =3D config_value; + enum pin_config_param param; + + if (!configs || !num_configs) + return -EINVAL; + + ret =3D pinctrl_scmi_alloc_configs(pctldev, num_configs, &p_config_type, + &p_config_value); + if (ret) + return ret; + + for (i =3D 0; i < num_configs; i++) { + param =3D pinconf_to_config_param(configs[i]); + ret =3D 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] =3D pinconf_to_config_argument(configs[i]); + } + + ret =3D 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 =3D 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 =3D pinconf_to_config_param(*config); + ret =3D pinctrl_scmi_map_pinconf_type(config_type, &type); + if (ret) { + dev_err(pmx->dev, "Error map pinconf_type %d\n", ret); + return ret; + } + + ret =3D pinctrl_ops->config_get(pmx->ph, group, GROUP_TYPE, type, + &config_value); + if (ret) + return ret; + + *config =3D pinconf_to_config_packed(config_type, config_value); + + return 0; +} + +static const struct pinconf_ops pinctrl_scmi_pinconf_ops =3D { + .is_generic =3D true, + .pin_config_get =3D pinctrl_scmi_pinconf_get, + .pin_config_set =3D pinctrl_scmi_pinconf_set, + .pin_config_group_set =3D pinctrl_scmi_pinconf_group_set, + .pin_config_group_get =3D pinctrl_scmi_pinconf_group_get, + .pin_config_config_dbg_show =3D 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 =3D pmx->pins; + *nr_pins =3D pmx->nr_pins; + return 0; + } + + *nr_pins =3D pinctrl_ops->count_get(pmx->ph, PIN_TYPE); + + pmx->nr_pins =3D *nr_pins; + pmx->pins =3D devm_kmalloc_array(pmx->dev, *nr_pins, sizeof(*pmx->pins), + GFP_KERNEL); + if (!pmx->pins) + return -ENOMEM; + + for (i =3D 0; i < *nr_pins; i++) { + pmx->pins[i].number =3D i; + ret =3D 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 =3D 0; + return ret; + } + } + + *pins =3D pmx->pins; + dev_dbg(pmx->dev, "got pins %d", *nr_pins); + + return 0; +} + +static const struct scmi_device_id scmi_id_table[] =3D { + { 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 =3D &sdev->dev; + struct scmi_pinctrl *pmx; + const struct scmi_handle *handle; + struct scmi_protocol_handle *ph; + + if (!sdev || !sdev->handle) + return -EINVAL; + + handle =3D sdev->handle; + + pinctrl_ops =3D handle->devm_protocol_get(sdev, SCMI_PROTOCOL_PINCTRL, + &ph); + if (IS_ERR(pinctrl_ops)) + return PTR_ERR(pinctrl_ops); + + pmx =3D devm_kzalloc(dev, sizeof(*pmx), GFP_KERNEL); + if (!pmx) + return -ENOMEM; + + pmx->ph =3D ph; + + pmx->dev =3D dev; + pmx->pctl_desc.name =3D DRV_NAME; + pmx->pctl_desc.owner =3D THIS_MODULE; + pmx->pctl_desc.pctlops =3D &pinctrl_scmi_pinctrl_ops; + pmx->pctl_desc.pmxops =3D &pinctrl_scmi_pinmux_ops; + pmx->pctl_desc.confops =3D &pinctrl_scmi_pinconf_ops; + + ret =3D pinctrl_scmi_get_pins(pmx, &pmx->pctl_desc.npins, + &pmx->pctl_desc.pins); + if (ret) + return ret; + + ret =3D 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 =3D pinctrl_scmi_get_functions_count(pmx->pctldev); + pmx->nr_groups =3D pinctrl_scmi_get_groups_count(pmx->pctldev); + + if (pmx->nr_functions) { + pmx->functions =3D devm_kcalloc(dev, pmx->nr_functions, + sizeof(*pmx->functions), + GFP_KERNEL); + if (!pmx->functions) + return -ENOMEM; + } + + if (pmx->nr_groups) { + pmx->groups =3D 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 =3D { + .name =3D DRV_NAME, + .probe =3D scmi_pinctrl_probe, + .id_table =3D 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"); --=20 2.37.1