From nobody Tue May 21 23:10:46 2024 Received: from EUR03-DBA-obe.outbound.protection.outlook.com (mail-dbaeur03on2064.outbound.protection.outlook.com [40.107.104.64]) (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 316A01DA4C; Thu, 18 Apr 2024 01:24:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.104.64 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713403483; cv=fail; b=TQWx35W99tZ1h9roNZz9U85/9PtQ1REEbBSuf93xDowup6gVb4zfDWCbza4j67oWQevRhY2PYPBoTL+yU1gjXKZm9r15KizMHYb6AD9VynjgWjcl6Xr8DcJ5KzkAs4XYtUn2uCr8Do1c0WzIHqZodf7KzdGcYfcZ00mCoe1DM2Q= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713403483; c=relaxed/simple; bh=RhCldLpWFoBisg6JxF8FQ42efMI/x7hxyuGNT8KbSHI=; h=From:Date:Subject:Content-Type:Message-Id:References:In-Reply-To: To:Cc:MIME-Version; b=mCl+ZRxDIPLNQ6MK4FgjgeZdgJavQqMDZSiPbAtQXsVWav6YhIaIok0mWEoi6Ue6ESgfojh/3fhg/lYUptPHvviGflEGyNeFDBTNoSD6tZ24snzg35ieRuaUEhxJmM0wZPKMrQV5aWH+Dg3gTD/7Hhrhz4AzWEVbUN2vlBpVJp0= 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=PMDumWxw; arc=fail smtp.client-ip=40.107.104.64 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="PMDumWxw" ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=PP8eVU9tQSmdQY27I6kCokUWWv+MeneGiwBzxV/y4KS0yAW8EoyzJQHENjEBys7cF1gK0CHDt46U9NIlNCgHpGZhnghjky0x3uIjcHGcwDpC/aYF1v6R2kGb0AlUlusELgPUzpARieiTxqv85Cjrrj7nkEA9kmwLwurg0oipAPrrmF/KGYpq82mN+fV5i4Dss+r+NdbP1fgcH5jXa22vbkgPa3RI9Vo92tLtLrpmSEnxDET3Ou3K4A96stUAhCtntr9d93f4TqPiZn1mk5gyBmGGt/qVlamuOMqVWrCSMbiHUxSu8JBBX54swr+bx3qBIGGc2JXA/JMEGmKOsp69+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=y32EPUygoezOrwpSdGDK5Cezq+RoDLA6Ci/XuseYkwM=; b=gu6W/oy+Clkvt9+gj6WHbJHe1ZZrefbjXJ2Gs6iBsWnL/OhZi0VRxTTmSViUeEVlmhMTu2832Jfae1E38X5UMuCHKTbLvMZE0qJTn+Ysn/8vI+QLyBuNiGwqfGRVYSLPOiyEg4MDAgy4lM9otldHmb4FSEwDGpkT71GnC4H4Qgi7X7hesAQop6QHzHTrt6n9gFBrL5ny+LF6G6E8fEtG5GdMLDAsL+DB3Vpzx21+ZxHcheRf2H7Pq2ZqETOt2UqFKll/XSDJ6uN4khdaOI4pczs9x8DLGdoUiaIYtUgG1dL2aGpn3wFXxNhRvI5k8qW5wIYn7fnWu9Y9vbf5sz2/DQ== 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=y32EPUygoezOrwpSdGDK5Cezq+RoDLA6Ci/XuseYkwM=; b=PMDumWxwNmd5rq/S0BvKVcAWRrbbN1ME3ujEixkcX2GaTGeW5MNMURK8ja1IpVQNNOxzYGrCVz/mo3htpSwisWnzz/c9zySCy9TXJeo6SpNmGnlDdGGacTbquXGj0THq1ISlOYJznBmGgw24uF6vFfmoDVQQ5xa4F1//CR2Ajp0= 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 AS1PR04MB9264.eurprd04.prod.outlook.com (2603:10a6:20b:4c4::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7452.50; Thu, 18 Apr 2024 01:24:36 +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.7452.049; Thu, 18 Apr 2024 01:24:36 +0000 From: "Peng Fan (OSS)" Date: Thu, 18 Apr 2024 09:32:28 +0800 Subject: [PATCH v11 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: <20240418-pinctrl-scmi-v11-1-499dca9864a7@nxp.com> References: <20240418-pinctrl-scmi-v11-0-499dca9864a7@nxp.com> In-Reply-To: <20240418-pinctrl-scmi-v11-0-499dca9864a7@nxp.com> To: Sudeep Holla , Cristian Marussi , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Linus Walleij , Dan Carpenter Cc: Dhruva Gole , Andy Shevchenko , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-gpio@vger.kernel.org, Peng Fan X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1713403963; l=2695; i=peng.fan@nxp.com; s=20230812; h=from:subject:message-id; bh=fC1f9Mz+AZ7lC+TNU94i2E/beyKrQPUiXgoBP0YzZ74=; b=uvGNPiYqgihRcYCo3u01MEoYWEnTApbl6WtoFdgkeg2yPSLHnNnHKxaYow7E0JYtw3Y2Ph5oJ VMjur4H9GOMBVLegt5x3bUzYI4sZ0oWyo+cl7HVxPTP1d2auoz/7RJj X-Developer-Key: i=peng.fan@nxp.com; a=ed25519; pk=I4sJg7atIT1g63H7bb5lDRGR2gJW14RKDD0wFL8TT1g= X-ClientProxiedBy: SG2PR03CA0116.apcprd03.prod.outlook.com (2603:1096:4:91::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_|AS1PR04MB9264:EE_ X-MS-Office365-Filtering-Correlation-Id: 788082d5-b6c1-4ac7-0827-08dc5f464f40 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: dIbXlh/XHPprriWeHssC8P2/XQGG2ou4/k3PeLQfG/MChKG12So4vKxnfVhXsivb0jog2ilYSKbexijEFSqww0H1TDkOhzzhIPwtaDzlEpK9+w/sDUYPF9MyyBvULZG+oHgqkrgdcDKZnQ66TNEyR/jXfA9eXRSHJ3s5Enjj+GfSlCdFwg/9GFWM5lEg5D/54ypT1364fviJEi7AbDP3lu6NcGZX2hBrikBZynM/qo9eQWn3VNp50jwF9k70KuforU2flO05KA3bWxw3eUv0kFh/Nw79/UIYKXCZ2BfZQoOd5UWMbtw89Ey8Dv4Ra+Vw5q0LIx9CFxHn56BBYnCCL5v1wAZbKgBDlQfQC0x3ygA1UbXPgGW3d73kYYy11g1/aNsNNVTmf770i9KFRhYvGMNN/B+9S8kQACPIprXl4bpHaDKzVng7ToNu85it7DgNoOXjNrdoc7auyP5mcasCHge3vHQIhOB831+UMqHNdkvuBJed3ZuohO6hAOTgefKMKAsfqoSksGMGS2XekbdeMQUTNezqKQaF7Df5Ks9qD5/wXBV9MHqWUKfcKIxCMXcdYBO7P9TwumTV35ONNMPBgIyRo/YfuGlGSzvEUGYUoG17YD2dXHRVhzGbaCQ6LZqhol9EsAvuONvhyy7s+0tQgoafhw3RDTboMoUFl0IE+iuqcomDk7lnVO0lQcG8/9XaiBho1sY3CQeAysgQ7XCEBcjgbAJ4tj2+cTewpk6fjy4= 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)(52116005)(366007)(1800799015)(376005)(7416005)(38350700005);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?d1FhbjFlNkhvUkNBOU1pMWVYdW90QlZZOWVzZm9RcFlRTXpBeCtyTkd2RWVL?= =?utf-8?B?ZVN2UmpBbTE5WmFIZXdHcEVpbktGdjBJWkhINUJUMkNyOWZjMmlSN2Nac3lk?= =?utf-8?B?MVVaaDRJNmtVR1cwTitVYWc5bGhSR21FN2E4RmZNb1h1U1hSSnphNWVScnBB?= =?utf-8?B?Z3JQdDVuY1BVSjA4aTZGY3VTRU1QZUVQNkNoWVgrOEhOWjJBcWZlbzBkZHMy?= =?utf-8?B?V1A2NDNORnRiTERWdVdreGJHTTdiV1pTb0FNcFB6bnpPSlZTTnptNE5GMFZw?= =?utf-8?B?eUVEOHlzU0l3cHlORkZRaFRRU2paRW9hQVN3YW1RMlhyVFJmWDZhTE00eDJM?= =?utf-8?B?R0RBT0l6bHgyeEZEOTQwWmc3SlkrVTNqZXdsM2UzOTMvWU5ZamlPMk5FUUd4?= =?utf-8?B?bXIxU000dGFyRW5YazhpVXVqMEdJOUh6Z05hNTdLSmhSaE5BVlR4Y0lQMk5H?= =?utf-8?B?WG9zK3pUTi9TM3lwNUdxOXZabVBxUWJhT3hUOWVzRlFTcGxpNUhCT0RFcmEx?= =?utf-8?B?TkhldUNRNlp1aTAwQWVtZ21tWVYvNjJySkordUhlMmc3SzhkSWlwT3Z3VC9t?= =?utf-8?B?clJ6VnFMRjlMRDJyb2dsUUFNR0JjNEt1eXVZVjFIbmI0b2R0d3RxK0pQTDlC?= =?utf-8?B?cXM3WnVCSzloemZzTVMwdUJLQ3FaZHB4U1F5TVo2U1NRNjd5OVYxd00yckNp?= =?utf-8?B?aW8xKzdjSzlLQ1lwL0d3V1ZqdmVsRHRsTTAzbVdpWUtJSDlpOTd1YXU3a1VX?= =?utf-8?B?T3luUnFkc1NaZ3lOOHVoVHZ1b2hmdXY2c2VlVFVTWHBkclJTMDFHdTFQNUZx?= =?utf-8?B?OWVSUmJseXJLUktyOTJFSFRPNGxyNnNoQ3A1WTJDWjM0Zm5BTVZXV0MwellW?= =?utf-8?B?b0x1VWs4WG8xVkdUSXl4N0U1K1pEWUxtKzc3V3NKU2FDR3FxdE9mQ2xkUjJm?= =?utf-8?B?eTZmZHUrQVVRUzJPTW5odU1OSkxsMnNGWHlaeDVqNm5kRUpWT0dqcUl2V3NR?= =?utf-8?B?cjQySC9VaDU3b0w2a0V3M2RWTmQ0eDhaL1lBTlhkV010dXFkZ1dLNFdDQmls?= =?utf-8?B?dnRtOE1yTDJlWisrNVUxRk1LeVl1Zjhjamx6VHl0a1RaM3NNNlpQM09YSHZ0?= =?utf-8?B?Z2I1M0JGSG4vL0tXSisvUkNmVlhCTGdzcTl4QmpSWXo2TG9hekF6MU1oa1JZ?= =?utf-8?B?a2pqMHhWZkpUMnFYOTI4VEVlME5Hdmp2bTlnYTBpd3Urdi9LSXQ1UlgzU3Vk?= =?utf-8?B?K2dRKzJiZXJ3U3crMm1SSE1PbExJdmRrUHorRjJCNHdNK29CNHRlUzdtSDZ5?= =?utf-8?B?SlI5TlNmcEVpYjNxZStMQ0M4d1JLektGTXFBalVSV0ZGczZnTnM3YjFjYlZY?= =?utf-8?B?MWc5MzRlbEQ4OWNxZmwvajBXU2U2eU13L05MZmZRSXdYRnpEdDB5VnpVTmlG?= =?utf-8?B?QnNsTVIxNzFxWUVjK24vbjcydnpLVWVWQnA1N0J0VlR4UEtkMHRLVFlZYmxu?= =?utf-8?B?bjZpT1FnNlluM2I5VkFyK0lyQmd3Um1KQTdJVElWcWJqaCtrTDNOZHZYZG5k?= =?utf-8?B?OVRVTklLRXdZbXZuVHE0dmtzdVVjcVBuWVVaYW1KSnpFbkpnSWQ1V0R5YlVF?= =?utf-8?B?c2NBMnY2N1JKZmdsamk3WWl2dzJuUTYzM05mNFpDVUhaVi9sU0xIKzdXV0gz?= =?utf-8?B?cE5vbkU1SEZaZGIyZHY3Q1dUUzhkUjdLNHp0OWM0N25EbDF0OXJQYTI2QlBy?= =?utf-8?B?Qkl4OUhSVFpkSWRMYXo2UVFPSWh5MjlkOVlpS1RDMWlxOTYrWktvUy9Ec1Zt?= =?utf-8?B?b2w5cllxSzlTN1MzZGJDUHVhWW5VVHNWeFRpRkhJU2JFWC9iVGNEYmhIcGZG?= =?utf-8?B?NXo4N3FPZGxzRGFGU0J5ckhMQXdPNmxtcW5rTXhXcnRqU0pueFFvSWh2WTdQ?= =?utf-8?B?d1h1RDBnY1Z5RlZyOExaWGZabUcyMEt4NkxTaHFwUjE2OUttc05FbS9raFdT?= =?utf-8?B?YU5qRVBOTFBNYWIvMCttZjFxRmtmby90STY1OWQ0aUNDMVpPRktSbVFEWDBy?= =?utf-8?B?bWQ3Ui92c0g1aGlOenBLelMvTDlpSDFSdWlYdENXNGR0MldoSUREeGFGcGhv?= =?utf-8?Q?7hpw7en8oboRciWV/UMDGLGYF?= X-OriginatorOrg: oss.nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 788082d5-b6c1-4ac7-0827-08dc5f464f40 X-MS-Exchange-CrossTenant-AuthSource: DU0PR04MB9417.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 18 Apr 2024 01:24:36.2573 (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: TcHroXCLo7dpV/guGAsreR2hLW1g66iXDLqF1zuHTBj1PqdFxwqONv1KX+dIQdcooNWIre+wgN4i/OD6tMW+4w== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS1PR04MB9264 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 Reviewed-by: Dhruva Gole Signed-off-by: Peng Fan Acked-by: Linus Walleij --- 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 36e3eb50a8d4..a1e0e8fa4bb7 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -1537,6 +1537,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 @@ -1848,6 +1862,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 Tue May 21 23:10:46 2024 Received: from EUR03-DBA-obe.outbound.protection.outlook.com (mail-dbaeur03on2064.outbound.protection.outlook.com [40.107.104.64]) (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 806AC39ACD; Thu, 18 Apr 2024 01:24:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.104.64 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713403485; cv=fail; b=UJLTMiG+NuHbA7zM/mnBLKVm+WulXszjG/WPAcipSAsxnYvO6oYpsULUIOgdFoj4u8TsE43WxCCRotutAkwqIPgN1eXqhpFjCxqRuJd1EWp1WmbKT9eMhjPBCsRnmf0t81/hDLgsZQnUkM6odVwGsPCuST/fpdj3FckAgbzxXVE= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713403485; c=relaxed/simple; bh=1zPbtoCNbOl7ALpohlegcy1tsXoTHb4w9RVFmhetJ9Y=; h=From:Date:Subject:Content-Type:Message-Id:References:In-Reply-To: To:Cc:MIME-Version; b=kLQqzIawRbOFItjKjynBTnpBWP0ePqMqK6bLQjPtFVkl1JOkh9PEJxrU24ojAIcsmoTUk6sj7Z0mQs6Yqnvf3nfM2y6C48Pmy2ECOT7h/590SgSZ7wrDmME5t/54kWqW295vgNWwHtX8qLsyir0q+lMzS5/KJoHeeoi8NVCxfR0= 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=kjwTSg5V; arc=fail smtp.client-ip=40.107.104.64 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="kjwTSg5V" ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=bmx4M6DmYthWkAZTlgkqwiXBzig/AKPzSaxvzt+ItPRoXBr+nBGquQ3LmlddTVKON/4/B18jbg/ZkOsNxPUbi0sumOrN1POe+BEnEEWcYtaYKNaMDUjAUNBuancibyIeWu4heYcCqWeis1NJ01uta3yGiCdl5KJshGa0k9tqMycwUnPD0lEL+gegdgKNerJMC0x5Rf0rv2BVvCicB92TEAKHJFEol0rRJUWjCsCBBjxXOXMxbAEXhU+0QqQiAOt+MevGpkG3cisKcFrheu1QaWhfPXa8xMytxxm+52oKE4/ugiaiAtt6vInfGpqb7uSL+Yqu9nSN4S+U0NX2GKrmCg== 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=SEk/KyCGYEIR0nJYohvLG9OMHTkixQzPWb3gCR+cLZs=; b=dE6qJoElMWNLsazEnC5CTq2Leqa+lQC8TRiHiDfDg9BF4THRhW8/qx/SXFAM5cg9oTFDNh1XWaR/hQX4IMU3oGpY1rSAtfUsiNnIkr3Ultw6TEE2oJTb2VN/BMaQcQyjU5C+lqwqMDxrDPWdT+SlmjO+D/3fMHRtbX21MgCSXH2BXSyhmHdCWjb4KoIdamgqkzgPWtho0L1xkgpF/hVcpIuwxtaS5/koi7KTDzGw90HL/IUMEucwzRBq8Pp2PAfq6ePSpOYglgGF4TpXv01Cgse/4qJuhpPpP5fVEDVvdNVs8X3xs8P4TEv8eUiCCYXLy99/gAMEUw0SKRXTK3Su3w== 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=SEk/KyCGYEIR0nJYohvLG9OMHTkixQzPWb3gCR+cLZs=; b=kjwTSg5VxcNBkuY36fN5P4WfPaRW0UsTILdt9Qv2zUMU2Cg+AU2fPtB8xy/xSssOUAh5gCCl+QVoSYr7DYQkFAKtpv2ID2pTfHABRkWG48bKRjN3Qee7jQ9IjPLQJgslbXm7ixgxTJIs13Z3bttol018ySbSYTnyfK4J0eQEWp8= 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 AS1PR04MB9264.eurprd04.prod.outlook.com (2603:10a6:20b:4c4::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7452.50; Thu, 18 Apr 2024 01:24:41 +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.7452.049; Thu, 18 Apr 2024 01:24:40 +0000 From: "Peng Fan (OSS)" Date: Thu, 18 Apr 2024 09:32:29 +0800 Subject: [PATCH v11 2/4] dt-bindings: firmware: arm,scmi: support pinctrl protocol Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240418-pinctrl-scmi-v11-2-499dca9864a7@nxp.com> References: <20240418-pinctrl-scmi-v11-0-499dca9864a7@nxp.com> In-Reply-To: <20240418-pinctrl-scmi-v11-0-499dca9864a7@nxp.com> To: Sudeep Holla , Cristian Marussi , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Linus Walleij , Dan Carpenter Cc: Dhruva Gole , Andy Shevchenko , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-gpio@vger.kernel.org, Peng Fan X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1713403963; l=2404; i=peng.fan@nxp.com; s=20230812; h=from:subject:message-id; bh=VDmWstcwBhpk6d9BmY1+Svq0j29w4hdHyHMqV4zPF24=; b=AEFUHmUtjgaFBXU1c1XH+FePDq7n6ISgIkzc1WwUltmtdeZNhCpeNJ/whfAiuuNxdZI+SGXWv R8PyapOu6d1CK4vd6UzCpcVKAXMNc0+lwLF+u95R3efsw/rvp7BlzAC X-Developer-Key: i=peng.fan@nxp.com; a=ed25519; pk=I4sJg7atIT1g63H7bb5lDRGR2gJW14RKDD0wFL8TT1g= X-ClientProxiedBy: SG2PR03CA0116.apcprd03.prod.outlook.com (2603:1096:4:91::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_|AS1PR04MB9264:EE_ X-MS-Office365-Filtering-Correlation-Id: 174c9a6d-00df-4393-907d-08dc5f4651cc 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: xGKZ4KM9RevLsFhaXgEoA3OjexNonP7J7fVUasU5EouuimIra4ZpSxkvWKfnvgotHbIBcIMg3+RZs+x0C+IhV+KRqUlu6Q/StXFuyCxbqsxpD9IsK10AGr+wATxYFTQ0+AdrnLFsZX0Af7fKv50mOuz5rz2JnjDjGOw48KBbJaPykQ6NSAhcgqehPKm2S0Pxr0qDcrepNy2Vx6pmVA/bQ0sbrsEt0n3gI0EW0IDTjDfnNBwBdJAHL7G5imWs4i3XolTrowB8v0r0eTvJ5qR45DR0rftUyOti7vFJBO104TN2uZvoBEYFhSZe/ewf7wOlAdlRVrGpZrO3E6qe5Wva2huJTynCD/gXErATKBegmEAzyLtF1AsOvSuAva+hUPRsjEpaUiTmLRxlqoJBL/W388oZg2nyUFHacO9Lq9XGdPmPv7ShPFdePJz+EiNpX+yqDVlT/9lG737EL2DHUzUDzPjEKToixn8BdHk9+fRuErE6esvRqfVu/MOKw1fEV7AvH8O015ORmppnOYT/1v5k6lFVUdRyoFXGZeCt31ATyVVxZw1w/erBcxDywE+FbqpjFz0ITUy/FQJclvtvYRLAbtI1F8LHyiCTAXce+G3jUPmCiHKhR9SaPido7DDBwfUel982Od9HK6lvtxBG6HcRFUOTTnbLRpjOMgDlcq2b0msFkPfNIKJut5G0ritoSi56YzE/CWyCq1WwrzNQznxsBaFtcjoMleHauxvsWSzdct4= 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)(52116005)(366007)(1800799015)(376005)(7416005)(38350700005);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?V0ovSmNBRHlHWkEzVmRDa0V1K01rZnRvQkY2RUxRTFppTFVoQlJFMGRMRm1Q?= =?utf-8?B?VzE4TGNxODNKekxjTjc2a2N2SkhBSU9CUEt0c0lab2tjY2hHUEFMUHcyQjZy?= =?utf-8?B?dnpEOWF5YitoYjBUWFRVaWNUZ1ZDSVRkVnBqTjQvaE9yUno3dEhPeDJFdTdi?= =?utf-8?B?aGJidENyTGdVbWlSdjZMcTREOHRmVGxia3lYRmgvWUxzcC9UQmdVUFlXdUt4?= =?utf-8?B?YUM2eTI2UTY5NTV6eWlkMk05UHVDQlN4Z1dwOWNKT3kydXVUQzJtZSs0cngx?= =?utf-8?B?cXQvaHowU1J2b3EwVmRXdHBqWU5tL0lCNFhqWmxueTV3aGNQTmpCNldOMDV1?= =?utf-8?B?WWtJWDRJczRJOEVUeC9DQ0h3cXo2QUREVVErRGFYaDBwaHBhYW5DSTJEK1Ix?= =?utf-8?B?K2VSaFBoc0JUdFplbU4wYzYzaGxuQTVFZndBcHozQTRCSE16dks5R0hObk1K?= =?utf-8?B?SGtkd2hHbnNCUWJDek9remQwaEdmVm45V3YvMGppbzRSa3IxY1lab1hYOU45?= =?utf-8?B?dW1NdVFjRHp5V2I2aTZLMXRzUEJIYWtNdHFlMnFCcmlUMDNGRUkvdHhFV1dm?= =?utf-8?B?VFYyWDU3MTdZaEpsWktuUEZQVDRSdVM3dTg5Nks1MFZMKytGUXlDRVpEbWFG?= =?utf-8?B?UUQzaVJaQTdJODJ5TUlyUmM3SFpHZ0lOWmRwVWN4dDRwQ2FVL0ZoMDJOUFpZ?= =?utf-8?B?TE9MUUtmTUk0RnBGeGYybkdvViszUXpNZWZJckJBMEJWWC9SVkd5VlBlczVF?= =?utf-8?B?d1lSMjI0SWw4eUpZUVRld0RDREhIV2hkK0NQVi84SlA3RWVDRm5XTHpIcm04?= =?utf-8?B?RHVHdEZwWG1sZFR1amptQ0RlRHp1Z0RoQno3YWdWM1FMdGVLY1BTcnllanlZ?= =?utf-8?B?VTZ6NmwvM1J2bVhtcVFtYVJ2c1gxMkNXNTF4QVYrWUYwZWtGZzZFMmpkTURL?= =?utf-8?B?bXd3b1BUbmRHeWI0WlVNRjZTVVUxQ0JVbGxTQWpDUFdtMzAwaTZmVk1NQ0Qz?= =?utf-8?B?WlhKVzBQQWprTGRDTXp0NUZNWXRJaDZYTDRaeGJESW52MW5QMHpXOEhpaG1X?= =?utf-8?B?UFFPWEhmbk91WFltVXl2WXBwYnBMcTBJTTBONEw5U0lVZ0lpeGxBeTB4b3Jo?= =?utf-8?B?cS9IWTNBeW96VVQxMXVCNEkvSzIwMmJ1KzVleE8vVlFyU0VBbENvZnpSajNa?= =?utf-8?B?RVBtQXhIMlUxMzc4WGtweDBjSmZ5YzVieEp0cWlMOUtMVGF5VnBSVmY1STZ1?= =?utf-8?B?R09laGhEWDcyUGRpblhZV0Z2OGRaWjBZeUIwNnB4cVdlTVFZK0xYRVpjVGly?= =?utf-8?B?UVcvc1VOOEZKL21SWlZzczF0MFpsdUtoNjMza1dZRjVSeHVvY3pIVWp0NmNH?= =?utf-8?B?YjZZQUFrek5icHlYSGh2M3ZPMzVrTjZMbDh2aFZFQW9OWnRtOVN4YWI5S2pV?= =?utf-8?B?S2E5TGhROVdnem15TE5CcU91TzdDS2pYeWFkVks3YXh4eno5bTJleGRZQmxw?= =?utf-8?B?aDAwdE1MZUR5NVMrYjlvRmV4SGN1OGxBS243ek9WZzY1OTJ1emt4M3NrUDNh?= =?utf-8?B?S0E1OGh1SE9SMnRWeXRyVXpTdkM4U0VIdzJPRkZUcG1tNXRXV3JkSE5aSzQr?= =?utf-8?B?ZS84enB2dEN2aEdGWmw5RG91R1RUaEZJRkQ0cTUrTDhvQkM4L0ZyOWZuL2NW?= =?utf-8?B?clErT1M0ektTbU5ISTc4M3hGd2loak11Q1g0cC9JVEtsT09ESVl5d2o0akZG?= =?utf-8?B?T2M1TXRCdGNSeXJUZGFzSm80VUo5UVZuVWd5MmxFTWFoMno5WGpDSm5GaklT?= =?utf-8?B?Ulh6UXlZR0QxNWUyRXlkMjB0R1loakR4cm1GMmVFZHpuWXJoZXhSVXFiQkJr?= =?utf-8?B?NEkwMWxkRXVVZnNoWFhCTTd3UElERDhpbGRWNWxUZmMzRHpibldUSU1OVHRY?= =?utf-8?B?OE03UnJEbUpUaFVmamJneW03ZTVaS0d6MzhZVlNnMXBWK05XNkg2RjliVWZJ?= =?utf-8?B?d2NkODVGOVV2VnY3R0R0YTVmWDlzY3RORWN2YnlhYnU5d2MxYWRWa2lSdXFY?= =?utf-8?B?dXQyZm9MMG5KdzdSWkF3dFlvcy9lS0hJTFZ5UFF2NWtaZUd6MjA4OFZkS1ox?= =?utf-8?Q?lNg4No8aLPYBTzU+POrMgYFCV?= X-OriginatorOrg: oss.nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 174c9a6d-00df-4393-907d-08dc5f4651cc X-MS-Exchange-CrossTenant-AuthSource: DU0PR04MB9417.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 18 Apr 2024 01:24:40.5292 (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: 9HyyocxzqcSUBMmwP6qyQ/YMXKWX4mUj2gGFua1wyfnJNcwOR45aMmhJrvFQZa+51CRMScXRCDgvWtmaeMugBw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS1PR04MB9264 From: Peng Fan Add SCMI v3.2 pinctrl protocol bindings and example. Reviewed-by: Rob Herring Reviewed-by: Linus Walleij Reviewed-by: Dhruva Gole Signed-off-by: Peng Fan Acked-by: Linus Walleij --- .../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 93fb7d05f849..7de2c29606e5 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 describes how to configure a + set of pins in some desired function. + A single sub-node may define several pin configurations. + This sub-node is using the default pinctrl bindings to configure + pin multiplexing and using SCMI protocol to apply a specified + configuration. + + 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 Tue May 21 23:10:46 2024 Received: from EUR03-DBA-obe.outbound.protection.outlook.com (mail-dbaeur03on2084.outbound.protection.outlook.com [40.107.104.84]) (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 095DE4F1EB; Thu, 18 Apr 2024 01:24:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.104.84 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713403491; cv=fail; b=gc9gyxtepDGYxkENUJl+5cyJz5oHIleWILx75vvF+hOVvh9GNRAmz1XXszTiilfeenJeGVNscpuIN4dli/uIaCmtaLRTpkoozL8nZrq7N8JX1woRFokkWR+Lj6JV3SrwM+InSroXiFjTNve6zIbgiGrWeQ7La16eQMXuyM8zYLc= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713403491; c=relaxed/simple; bh=YlwrH+eQS9F7MOeVCzzuGup799W4C6ZI78AJteK4rKw=; h=From:Date:Subject:Content-Type:Message-Id:References:In-Reply-To: To:Cc:MIME-Version; b=Qa46kRh7vimYxy3kaOfqRgnxXrFNOJO63VL9oDJJZ5+6dxgaEsQi2HR9qPAH9S+u8/UJPNmxTXjtD3Yq4G87bBGXA+nlhed4Q32le1mZMH9GxI5tkEL5+nCjJ3txnXuy3j7KOFMnM+lJ76h1FQ2T+18HuhZR2+IHYbD3dngojG0= 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=i1lpJ0c1; arc=fail smtp.client-ip=40.107.104.84 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="i1lpJ0c1" ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=gaZsEErHVy6dlAdiksPBN1GWFbG9i7iO9ME3gPhkSsB54CWdHHmIYZj+GZSVEBiTJwnkT7AjzDxXtVusHu9EEE6esc4DWosn3byuyoW0qzXQx4JBDzJqssjhPe/iIOXhmTIGUTYlYIvhpE5ijnSmo/wnRbvy1Vc42yKMnvJC+UHCnmNXUSY9llehiREehNTZyl6pN/QQ2+MI7pzDdkHaTOk+0XeJdxS9zIkIKbG1BpeKLayKED552gvRymCcrNRtAVTRnkncy36mGUFQhs8QeFra54S2zytawuS2eikxoYEff1LT7fH/crx9VHt8VszxwXlku53W+SjOmpqG+EacWw== 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=E6cSrPxrT85E+2sEoi3YYX8D8I3wXNefinoNnLyn7Qk=; b=WXakTQDW/hFtGPucEpO6QQ/SIuPsBe2KBqge78XczmzfUk8m/QX8VFHGAG9Uviz494UQs34IPOXBtUfxmJGFh1h8xYWPrX38wbwU32Hi9wU/f3+uBHy+xiCv90OQsII8a1kLTn/ThE/hUjY8hXXii9JPf4a3bwFiB3nsMepWcPa2Y3YRM6nNzEvsjwQuHgWhYpcjrq6uy3WuYTkJdXLXvm0Zk6+s8BAt4BWkRqNgOdY7eAf7cjV3/l+lRTl57CcGlHcE7+Qb9aC1xSyouQqNH13rTkMgA2CImVdv3o+6UZl3oLlsV+tzv1Lb9VJLOK3w2fSfSJ1W/00XjW5tHt3qPQ== 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=E6cSrPxrT85E+2sEoi3YYX8D8I3wXNefinoNnLyn7Qk=; b=i1lpJ0c14fBbTvn2uY4YZZkW7l+ift/ENMSyaFDrYTSUalIb4yCy0g4LTsiGxuRlW32/Pcb29Kc+b41A7Y+1PHj2RyCzYqC63lRqewll/aO5v6CC6dx/vuq6Ldz0ncSuGvSeSSAnpBXg58JlTMNu/T5C6ir9GAfAkMRugEtCRYc= 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 AS1PR04MB9264.eurprd04.prod.outlook.com (2603:10a6:20b:4c4::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7452.50; Thu, 18 Apr 2024 01:24:45 +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.7452.049; Thu, 18 Apr 2024 01:24:45 +0000 From: "Peng Fan (OSS)" Date: Thu, 18 Apr 2024 09:32:30 +0800 Subject: [PATCH v11 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: <20240418-pinctrl-scmi-v11-3-499dca9864a7@nxp.com> References: <20240418-pinctrl-scmi-v11-0-499dca9864a7@nxp.com> In-Reply-To: <20240418-pinctrl-scmi-v11-0-499dca9864a7@nxp.com> To: Sudeep Holla , Cristian Marussi , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Linus Walleij , Dan Carpenter Cc: Dhruva Gole , Andy Shevchenko , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-gpio@vger.kernel.org, Peng Fan , Oleksii Moisieiev X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1713403963; l=30412; i=peng.fan@nxp.com; s=20230812; h=from:subject:message-id; bh=YuGhTXxfU5NKLJFYyDuKKzadNTpWoQRGvlpy5+5N94w=; b=FrciAiUDPkErcX41ox8q4myXZEJkTRc+DTdHzYBdvly+ZY5PW6k7BqLbrygtT4pYgnveYLI8j av1sGVfrvOnCWyk6KDrQwlYYAzMDmbaXxfyd5B08+C14XnLRJE/Ky4Y X-Developer-Key: i=peng.fan@nxp.com; a=ed25519; pk=I4sJg7atIT1g63H7bb5lDRGR2gJW14RKDD0wFL8TT1g= X-ClientProxiedBy: SG2PR03CA0116.apcprd03.prod.outlook.com (2603:1096:4:91::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_|AS1PR04MB9264:EE_ X-MS-Office365-Filtering-Correlation-Id: 2bc59104-b935-406b-a735-08dc5f465484 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: 64aqMbXC+lXgqckFOgnNsL+SkRC9f8aRvgmHsT0VHD0xLU2fblUAT7M5JZPI776N8oNcRt94YPpAZwSsWKgOsfpGsQubFgUpsyUiVt5hAn36l1sIR903wBYh4KwCYK5WqwvYMSwSxuKU8DD5hG+AveoS50aWLHvhdTz+iiRtMrLPzXAE3oHk2TS716yNeYRWljIyC+ZYgVo/pPB5hZImcgvSI+mUqnSRexQbROyZCDxSakPT38rqwssNGfE+cjhJ29Vz2qJSdd6SbTGeWBu/2GN27WbxPP+4NHZEqfKqoqrxJ6P31CjMrpY4/IA8aj2a+kwcxwTPhjhmwJEcUYRo6DsBqZPUYSqa72WL/5O55HWWqzND1eyNdmtOpF5iFL82opTcix5HiV+/vnZ7qVEReoSnck5YgSbTkC78qg7dSH/v3nY63qgSwQfpZson1DJ+NoJaj/fs7Ox6eUHA6HA/m3RDbf9kYIVgtAQHnJ6HcEZhnhAYBqFfb/mDolm0Hz6bBYFuBVHpsft7i/xCC9tYKgnMcOyW5auT4xymfBErOjS1kvy5TRE3unI8sL5ywYj0Gsn5BldjWCT1egJrRlyfgZIvtpXHJASXYo83li3iVs01XtYp4CEZdFYuCwS4jljhD9oy6TUUBjRWIr3mRWp2bjv5t5nvqKj+mJ4egT/7/nGB8dZBenVgFLj1cqne2C5+V/mSRXppmytoxfhzU8JLDkwBy/boVehulbKi+sdqz8A= 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)(52116005)(366007)(1800799015)(376005)(7416005)(38350700005);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?Zlhnbm5Bazd3akhrRkZFeWNUUTMybmdWUkNGd2I5ZEphSGxTVUlzbHlJWXpM?= =?utf-8?B?K1RvdXQ1dGcxd1pjMmZuUUVkNk1iakNGcmhla1hUTTJKeE1kZGpjSkR5Qm9n?= =?utf-8?B?a3RVdVB4Q3FZVytZZ1ZrcHc5eHpLcVg1cEYzREVDdUFuNlRNb2luZXpuTmow?= =?utf-8?B?aWsrSmFoTHg4dmRJL09RNTRpYnlZczVPWm81SDEyS2cyaGxDZEhiUDRUeU5I?= =?utf-8?B?TXBTM0tWa3VES0YzQWVzdkIxRGtzKzJlWnFlOHh2ZERQbm1YdEg2M3FYV1RB?= =?utf-8?B?TkdQQ2l1Y1VjOGZud3lJK1JQQ2MvNVBsMitWR2RILzBiVTZNTUNMNFlYTXJF?= =?utf-8?B?T2h4OW82MWdwamh0KzdYVDBJZDQvdnk1bVgvL01LT2xRU0psYm9XbXZFR2RO?= =?utf-8?B?bUIwODQvd0VwR1Z0NzB6Y3ZFNVVMMHQ1b3JUbkdSK2t5WS9QamRRL0MrUUxa?= =?utf-8?B?N2d6ckZKbXJGUXl1aG56MEI2STZhOFZTeFFMelJVK1ZRanFsbzFGbHpnZDBM?= =?utf-8?B?bWNNU2cwNWtFSnpEdkNxOEtuVnBZZ0xQVWs2L0VONVR1Ykk1cWNZSWtEajB1?= =?utf-8?B?MTRHSDd0M2hWRUdBOTdyZkY1WHFvWDdjRjB3b2R0ZkkrbXZTWWNab0F5WFdr?= =?utf-8?B?NnJqZkNKaGNDNm9WdEUvZ0wvSmFDL3VXcUpFNU1Xa2hjVy9qdXhXa0REVysr?= =?utf-8?B?bkI5MFZMeWJXUUZ6S1FBREw5WWRRMWJWYWQ4WWhVdGs3c29Icm45enphaUhx?= =?utf-8?B?SkEvYUVNYnBqWjRaZUJNeGt4Z0pFR2d3THhUYWJ1RXJCbHBmSUdZcERva2FN?= =?utf-8?B?bWJIVXVXREZ5MXZoMCt1SHlYRjVqZXI3VTVoTHc3NVRZUmYwMGlmenBLeXAv?= =?utf-8?B?eHRpZ0xnbk45SU1BdWhuaXVhS0UxQkV0b1ovMS9wZlowM3lkejVyTllXZHNm?= =?utf-8?B?cHpKODBYR3JBNDA0a0FxaThjcnY0S2ptaVppanNVOVpka09qY3hEbFJVUjdw?= =?utf-8?B?Z042SWpvV0E5b1ZtcStVZjV4eitOcUF6UkJjd01tRFpqaUpyOS9PRmU1SGNE?= =?utf-8?B?cXkvRWdRWEFvSHZpRURzT0IwRmsvejJCYnU3dWZMeXVwRVB1RHRIQ0VhbFkv?= =?utf-8?B?em5WRFVIMm9INHRSQmVOTGg5UzRlR2ljenVvdVFlSk5jNTkyZUk2QXVKZmxy?= =?utf-8?B?cFM3OXgwUHRtZ091Zi9PdkUySDY0YXFqUG5GYTVEc2xWY3hNOU90M1drL1dm?= =?utf-8?B?YkJjcHE0MkhkMU44M1MzVE5KWVZZK0E1UCtnSHVaQkt4NHZ4bFNzeDVSY1Ba?= =?utf-8?B?WmVwY1I2b1l5L0s3T3U5d3NMYW4vZk9xdkIxd1NOZW56aUVtSktqNUd2Z1l3?= =?utf-8?B?YmdBeUc5RGFkYnpsMHEzNjVlaTdWTjhjdlBEMmMzQmtadHpRajNsT2I4SnZE?= =?utf-8?B?bHJ6MFRpSnBvVENJeTlJN0tRdEpKOVVoL0V6b0JESmR2dzFOcVZZYXlZWXBK?= =?utf-8?B?ZVErS3NUdUNhZHJIYTR0cmh4b3Z4TEd1Q2o5Zjl5bFF1YlNpV0tERjlYMFZM?= =?utf-8?B?dDIzajAwRzZsYjZwSmVwbk52blFRL3VzS05Pc0VGUkVzMGJ0SnlSalh2M29w?= =?utf-8?B?L05rOEJJSGpjK3crVkpTaEU1NGpnazgrS3J0MWhxOG50MXdWaUs4eERoREt6?= =?utf-8?B?NDN3b3FGdEpRczQvd3lSRW13TTJqWUVZOFM5SU1xRGxYVStuVk81OW5wTmhw?= =?utf-8?B?dndjdHIxY1RGeFJ1Q1U1VWJGM0tKbnhCcUJBMVRLbWtFeW0vTHI3VEN2bmMx?= =?utf-8?B?ZCtoUEtnNm1Wd0NDSjlHNmRxWU1pdjNsMFBNSUE1RHdDMHcrdjBNOFlMSGFI?= =?utf-8?B?dUlPNHdOb01qMnUzK01NK0NCc3BMai9RZ2VpeDNSbnVWclBFKzg1WllYQllP?= =?utf-8?B?S1l0L0Vhc2kzVy9uZjErbXRDNmdDYzc5cEgwbXZTZGJqTzIxSVAvODNHVEJw?= =?utf-8?B?d2s3ZFhhUDY5cGpkc0ZZL2lZT2M3NjZOUU5RRjlxMWd5bENxd2EyV08rVkZX?= =?utf-8?B?T2JtZDJZU3VUWmZ1NHZiWkx6cDVLV0k1N0FVQll0bDVDeHVoQkJBMHg3SU1r?= =?utf-8?Q?zw2vwAAV42w69bqQjl1oUfszF?= X-OriginatorOrg: oss.nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2bc59104-b935-406b-a735-08dc5f465484 X-MS-Exchange-CrossTenant-AuthSource: DU0PR04MB9417.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 18 Apr 2024 01:24:45.1219 (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: SHrUmYRIHsUaZFo7XB001vVALcIcto40Wk17+HdgMNPgUWG01QSR2cf1F5pglaKx3Sy/S7YMblC1yZ/3cRd76w== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS1PR04MB9264 From: Peng Fan Add basic implementation of the SCMI v3.2 pincontrol protocol. Co-developed-by: Oleksii Moisieiev Signed-off-by: Oleksii Moisieiev Co-developed-by: Cristian Marussi Signed-off-by: Cristian Marussi Signed-off-by: Peng Fan Acked-by: Linus Walleij --- drivers/firmware/arm_scmi/Makefile | 3 +- drivers/firmware/arm_scmi/driver.c | 2 + drivers/firmware/arm_scmi/pinctrl.c | 916 ++++++++++++++++++++++++++++++= ++++ drivers/firmware/arm_scmi/protocols.h | 1 + include/linux/scmi_protocol.h | 84 ++++ 5 files changed, 1005 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/arm_scmi= /Makefile index a7bc4796519c..fd59f58ce8a2 100644 --- a/drivers/firmware/arm_scmi/Makefile +++ b/drivers/firmware/arm_scmi/Makefile @@ -10,7 +10,8 @@ scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) +=3D smc.o 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 base.o clock.o perf.o power.o reset.o sensors.o syst= em.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 a1e0e8fa4bb7..08ecb918e684 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -3209,6 +3209,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); } @@ -3226,6 +3227,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..a2a7f880d6a3 --- /dev/null +++ b/drivers/firmware/arm_scmi/pinctrl.c @@ -0,0 +1,916 @@ +// 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 +#include +#include +#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 0x10000 + +#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)) + +#define CONFIG_FLAG_MASK GENMASK(19, 18) +#define SELECTOR_MASK GENMASK(17, 16) +#define SKIP_CONFIGS_MASK GENMASK(15, 8) +#define CONFIG_TYPE_MASK GENMASK(7, 0) + +enum scmi_pinctrl_protocol_cmd { + PINCTRL_ATTRIBUTES =3D 0x3, + PINCTRL_LIST_ASSOCIATIONS =3D 0x4, + PINCTRL_SETTINGS_GET =3D 0x5, + PINCTRL_SETTINGS_CONFIGURE =3D 0x6, + PINCTRL_REQUEST =3D 0x7, + PINCTRL_RELEASE =3D 0x8, + PINCTRL_NAME_GET =3D 0x9, + PINCTRL_SET_PERMISSIONS =3D 0xa, +}; + +struct scmi_msg_settings_conf { + __le32 identifier; + __le32 function_id; + __le32 attributes; + __le32 configs[]; +}; + +struct scmi_msg_settings_get { + __le32 identifier; + __le32 attributes; +}; + +struct scmi_resp_settings_get { + __le32 function_selected; + __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_request { + __le32 identifier; + __le32 flags; +}; + +struct scmi_group_info { + char name[SCMI_MAX_STR_SIZE]; + bool present; + u32 *group_pins; + u32 nr_pins; +}; + +struct scmi_function_info { + char name[SCMI_MAX_STR_SIZE]; + bool present; + u32 *groups; + u32 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); + if (pi->nr_pins =3D=3D 0) { + dev_warn(ph->dev, "returned zero pins\n"); + ret =3D -EINVAL; + } + } + + 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 selector, + enum scmi_pinctrl_selector_type type) +{ + int value; + + value =3D scmi_pinctrl_count_get(ph, type); + if (value < 0) + return value; + + if (selector >=3D value || value =3D=3D 0) + 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, + u32 *n_elems) +{ + int ret; + struct scmi_xfer *t; + struct scmi_msg_pinctrl_attributes *tx; + struct scmi_resp_pinctrl_attributes *rx; + bool ext_name_flag; + + 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); + + ext_name_flag =3D !!EXT_NAME_FLAG(rx->attributes); + } + + ph->xops->xfer_put(ph, t); + + if (ret) + return ret; + /* + * If supported overwrite short name with the extended one; + * on error just carry on and use already provided short name. + */ + if (ext_name_flag) + ret =3D 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; + u32 *array; +}; + +static void iter_pinctrl_assoc_prepare_message(void *message, + u32 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); + 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, u32 *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_settings_get_ipriv { + u32 selector; + enum scmi_pinctrl_selector_type type; + bool get_all; + unsigned int *nr_configs; + enum scmi_pinctrl_conf_type *config_types; + u32 *config_values; +}; + +static void +iter_pinctrl_settings_get_prepare_message(void *message, u32 desc_index, + const void *priv) +{ + struct scmi_msg_settings_get *msg =3D message; + const struct scmi_settings_get_ipriv *p =3D priv; + u32 attributes; + + attributes =3D FIELD_PREP(SELECTOR_MASK, p->type); + + if (p->get_all) { + attributes |=3D FIELD_PREP(CONFIG_FLAG_MASK, 1) | + FIELD_PREP(SKIP_CONFIGS_MASK, desc_index); + } else { + attributes |=3D FIELD_PREP(CONFIG_TYPE_MASK, p->config_types[0]); + } + + msg->attributes =3D cpu_to_le32(attributes); + msg->identifier =3D cpu_to_le32(p->selector); +} + +static int +iter_pinctrl_settings_get_update_state(struct scmi_iterator_state *st, + const void *response, void *priv) +{ + const struct scmi_resp_settings_get *r =3D response; + struct scmi_settings_get_ipriv *p =3D priv; + + if (p->get_all) { + 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)); + } else { + st->num_returned =3D 1; + st->num_remaining =3D 0; + } + + return 0; +} + +static int +iter_pinctrl_settings_get_process_response(const struct scmi_protocol_hand= le *ph, + const void *response, + struct scmi_iterator_state *st, + void *priv) +{ + const struct scmi_resp_settings_get *r =3D response; + struct scmi_settings_get_ipriv *p =3D priv; + u32 type =3D le32_get_bits(r->configs[st->loop_idx * 2], GENMASK(7, 0)); + u32 val =3D le32_to_cpu(r->configs[st->loop_idx * 2 + 1]); + + if (p->get_all) { + p->config_types[st->desc_index + st->loop_idx] =3D type; + } else { + if (p->config_types[0] !=3D type) + return -EINVAL; + } + + p->config_values[st->desc_index + st->loop_idx] =3D val; + ++*p->nr_configs; + + return 0; +} + +static int +scmi_pinctrl_settings_get(const struct scmi_protocol_handle *ph, u32 selec= tor, + enum scmi_pinctrl_selector_type type, + unsigned int *nr_configs, + enum scmi_pinctrl_conf_type *config_types, + u32 *config_values) +{ + int ret; + void *iter; + unsigned int max_configs =3D *nr_configs; + struct scmi_iterator_ops ops =3D { + .prepare_message =3D iter_pinctrl_settings_get_prepare_message, + .update_state =3D iter_pinctrl_settings_get_update_state, + .process_response =3D iter_pinctrl_settings_get_process_response, + }; + struct scmi_settings_get_ipriv ipriv =3D { + .selector =3D selector, + .type =3D type, + .get_all =3D (max_configs > 1), + .nr_configs =3D nr_configs, + .config_types =3D config_types, + .config_values =3D config_values, + }; + + if (!config_types || !config_values || type =3D=3D FUNCTION_TYPE) + return -EINVAL; + + ret =3D scmi_pinctrl_validate_id(ph, selector, type); + if (ret) + return ret; + + /* Prepare to count returned configs */ + *nr_configs =3D 0; + iter =3D ph->hops->iter_response_init(ph, &ops, max_configs, + PINCTRL_SETTINGS_GET, + sizeof(struct scmi_msg_settings_get), + &ipriv); + if (IS_ERR(iter)) + return PTR_ERR(iter); + + return ph->hops->iter_response_run(iter); +} + +static int scmi_pinctrl_settings_get_one(const struct scmi_protocol_handle= *ph, + u32 selector, + enum scmi_pinctrl_selector_type type, + enum scmi_pinctrl_conf_type config_type, + u32 *config_value) +{ + unsigned int nr_configs =3D 1; + + return scmi_pinctrl_settings_get(ph, selector, type, &nr_configs, + &config_type, config_value); +} + +static int scmi_pinctrl_settings_get_all(const struct scmi_protocol_handle= *ph, + u32 selector, + enum scmi_pinctrl_selector_type type, + unsigned int *nr_configs, + enum scmi_pinctrl_conf_type *config_types, + u32 *config_values) +{ + if (!nr_configs || *nr_configs =3D=3D 0) + return -EINVAL; + + return scmi_pinctrl_settings_get(ph, selector, type, nr_configs, + config_types, config_values); +} + +static int +scmi_pinctrl_settings_conf(const struct scmi_protocol_handle *ph, + u32 selector, + enum scmi_pinctrl_selector_type type, + u32 nr_configs, + enum scmi_pinctrl_conf_type *config_type, + u32 *config_value) +{ + struct scmi_xfer *t; + struct scmi_msg_settings_conf *tx; + u32 attributes; + int ret, i; + u32 configs_in_chunk, conf_num =3D 0; + u32 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_SETTINGS_CONFIGURE, + sizeof(*tx) + + chunk * 2 * sizeof(__le32), 0, &t); + if (ret) + break; + + tx =3D t->tx.buf; + tx->identifier =3D cpu_to_le32(selector); + tx->function_id =3D cpu_to_le32(0xFFFFFFFF); + 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 group, + enum scmi_pinctrl_selector_type type, + u32 function_id) +{ + int ret; + struct scmi_xfer *t; + struct scmi_msg_settings_conf *tx; + u32 attributes; + + ret =3D scmi_pinctrl_validate_id(ph, group, type); + if (ret) + return ret; + + ret =3D ph->xops->xfer_get_init(ph, PINCTRL_SETTINGS_CONFIGURE, + sizeof(*tx), 0, &t); + if (ret) + return ret; + + tx =3D t->tx.buf; + tx->identifier =3D cpu_to_le32(group); + tx->function_id =3D cpu_to_le32(function_id); + attributes =3D FIELD_PREP(GENMASK(1, 0), type) | BIT(10); + tx->attributes =3D cpu_to_le32(attributes); + + ret =3D ph->xops->do_xfer(ph, t); + ph->xops->xfer_put(ph, t); + + return ret; +} + +static int scmi_pinctrl_request_free(const struct scmi_protocol_handle *ph, + u32 identifier, + enum scmi_pinctrl_selector_type type, + enum scmi_pinctrl_protocol_cmd cmd) +{ + int ret; + struct scmi_xfer *t; + struct scmi_msg_request *tx; + + if (type =3D=3D FUNCTION_TYPE) + return -EINVAL; + + if (cmd !=3D PINCTRL_REQUEST && cmd !=3D PINCTRL_RELEASE) + return -EINVAL; + + ret =3D scmi_pinctrl_validate_id(ph, identifier, type); + if (ret) + return ret; + + ret =3D ph->xops->xfer_get_init(ph, cmd, sizeof(*tx), 0, &t); + if (ret) + return ret; + + 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_free(ph, pin, PIN_TYPE, PINCTRL_REQUEST); +} + +static int scmi_pinctrl_pin_free(const struct scmi_protocol_handle *ph, u3= 2 pin) +{ + return scmi_pinctrl_request_free(ph, pin, PIN_TYPE, PINCTRL_RELEASE); +} + +static int scmi_pinctrl_get_group_info(const struct scmi_protocol_handle *= ph, + u32 selector, + struct scmi_group_info *group) +{ + int ret; + + 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 || pi->nr_groups =3D=3D 0) + 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 u32 **pins, + u32 *nr_pins) +{ + struct scmi_pinctrl_info *pi =3D ph->get_priv(ph); + + if (!pins || !nr_pins) + return -EINVAL; + + if (selector >=3D pi->nr_groups || pi->nr_groups =3D=3D 0) + 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; + + 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 || pi->nr_functions =3D=3D 0) + 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, u32 *nr_groups, + const u32 **groups) +{ + struct scmi_pinctrl_info *pi =3D ph->get_priv(ph); + + if (!groups || !nr_groups) + return -EINVAL; + + if (selector >=3D pi->nr_functions || pi->nr_functions =3D=3D 0) + 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, + .settings_get_one =3D scmi_pinctrl_settings_get_one, + .settings_get_all =3D scmi_pinctrl_settings_get_all, + .settings_conf =3D scmi_pinctrl_settings_conf, + .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); + + /* Free groups_pins allocated in scmi_pinctrl_get_group_info */ + 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; + } + } + + /* Free groups allocated in scmi_pinctrl_get_function_info */ + 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 a3addb07e00a..3a9bb5b9a9e8 100644 --- a/include/linux/scmi_protocol.h +++ b/include/linux/scmi_protocol.h @@ -737,6 +737,89 @@ 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_DEFAULT =3D 0, + SCMI_PIN_BIAS_BUS_HOLD =3D 1, + SCMI_PIN_BIAS_DISABLE =3D 2, + SCMI_PIN_BIAS_HIGH_IMPEDANCE =3D 3, + SCMI_PIN_BIAS_PULL_UP =3D 4, + SCMI_PIN_BIAS_PULL_DEFAULT =3D 5, + SCMI_PIN_BIAS_PULL_DOWN =3D 6, + SCMI_PIN_DRIVE_OPEN_DRAIN =3D 7, + SCMI_PIN_DRIVE_OPEN_SOURCE =3D 8, + SCMI_PIN_DRIVE_PUSH_PULL =3D 9, + SCMI_PIN_DRIVE_STRENGTH =3D 10, + SCMI_PIN_INPUT_DEBOUNCE =3D 11, + SCMI_PIN_INPUT_MODE =3D 12, + SCMI_PIN_PULL_MODE =3D 13, + SCMI_PIN_INPUT_VALUE =3D 14, + SCMI_PIN_INPUT_SCHMITT =3D 15, + SCMI_PIN_LOW_POWER_MODE =3D 16, + SCMI_PIN_OUTPUT_MODE =3D 17, + SCMI_PIN_OUTPUT_VALUE =3D 18, + SCMI_PIN_POWER_SOURCE =3D 19, + SCMI_PIN_SLEW_RATE =3D 20, + SCMI_PIN_OEM_START =3D 192, + SCMI_PIN_OEM_END =3D 255, +}; + +/** + * 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 + * @settings_get_one: returns one configuration parameter for pin or group + * specified by config_type + * @settings_get_all: returns all configuration parameters for pin or group + * @settings_conf: 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 (*settings_get_one)(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 (*settings_get_all)(const struct scmi_protocol_handle *ph, + u32 selector, + enum scmi_pinctrl_selector_type type, + unsigned int *nr_configs, + enum scmi_pinctrl_conf_type *config_types, + u32 *config_values); + int (*settings_conf)(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 @@ -842,6 +925,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 Tue May 21 23:10:46 2024 Received: from EUR02-AM0-obe.outbound.protection.outlook.com (mail-am0eur02on2066.outbound.protection.outlook.com [40.107.247.66]) (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 8552A4F8A3; Thu, 18 Apr 2024 01:24:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.247.66 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713403496; cv=fail; b=p2CrjWscKAfxA5VHWXfJEOtz3uGAGqAoHprBf16eqJM4/MET1xet6dpbpWwYdGHuKfY3oZ8p2sFYayCotISEDjr1q17czIbWvMEIrwjyQCoXzxo0Qufl8YJGGntRU6IE5RzGlx1yYDszB56kGateOAWa8ihVbLh4gncCBK7Gs6E= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713403496; c=relaxed/simple; bh=7p7R760b36eQQgH4IIwL9zI1uBEyJ1P1JaWJObXpa5U=; h=From:Date:Subject:Content-Type:Message-Id:References:In-Reply-To: To:Cc:MIME-Version; b=PFf1WyYNrFgnUjqbdz0rl3bJnKE24plnINkXGUFRh6ufmRQF5wPweZl4RMj0VfHbXYBY4NBuJL58TNI7PvT+ojmWuiJ/LNa6p+O/+mr6e3l4etQ5la7qyu69W9lgtOMYt/Q2/5A2bpquCclPZM2w46r6m0EK5r1RC1LLJAOAfR8= 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=Vz9E2+yH; arc=fail smtp.client-ip=40.107.247.66 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="Vz9E2+yH" ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=TwBQ8xdcIqtgLfVipuFUISbOFRNue5MydRnp28ak92h4py0oFoYa2ztc7U/mTKgxS5LpfF5SkMYQ3kPt4Vsbp1huG+5YHY0HT6Bm/X+LRHRoPiH6/StU6nYXDCjIEDAHvOVoKcD0aJG44R9TiEI4C1bnZy7yVLW2XLEEbxFS/F4J0JGV7dqZFRAEqLoMo725eOBCe2dvo/PfH+SHRRJIKPOc6qnRt6V1Wfj++d8Ph2B1lmZA0ObmwiQLnQxoxOr7awCwhXJsHZSjynj8apWYhisewyIftsXbNCsqZVwJbJTAAxYwF7Qf49L6iffLTuKjNw63aJsWAmbGTWhgxUkcZQ== 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=HdTqCJnUPXMf0EXaB/2Sjjabw4CHiCSwDMNNHya1rMM=; b=Bm6b9lwBUe2bfe3ynm8kbn5fhI1Q+G2T40OkwDBHh0I/ViTtVI68Rhj4FjrmGbxBMvU7HDwracYVO59OXydphX2ejirQL4RTQzuIWp4/j2zmb+PesHdM2jufoGhqINNqAQ/xK4zA2nFxO1RBZUg4xlAJPJ27Hrgwd4H+iLdBQ8ltyWO3IggLnxqzY0kGGdB3syY3ocMbImNPbJDRJFJJuQkHQge8hc/XyirE68h4bdpTzqYbcKyMukz+hvqyenxhk5JU7pBDXsh2gYIyPRgLLJTZMuqWXSF5K4hoVzwM8bj0vCk4nKgRVEa9phoYB5klqhY9kVV7AZbBcJ5Nlyt0rQ== 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=HdTqCJnUPXMf0EXaB/2Sjjabw4CHiCSwDMNNHya1rMM=; b=Vz9E2+yHPcST3Mt66JkU59ahCrpq6FAHut7x+DVP6adGgE3vdC8wwIoisv2YpRvASY4Bf/TWSKIeM5at6yxEmIVFfMZM26EZK4mEpLkOc+eiKreBHSgdZfu7Qvil+pI1RV35UdFzWdN6nc44n0IUPuHrkBzmpnoBXpzjEEuGqRw= 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 AM7PR04MB7110.eurprd04.prod.outlook.com (2603:10a6:20b:119::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7452.50; Thu, 18 Apr 2024 01:24:50 +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.7452.049; Thu, 18 Apr 2024 01:24:49 +0000 From: "Peng Fan (OSS)" Date: Thu, 18 Apr 2024 09:32:31 +0800 Subject: [PATCH v11 4/4] pinctrl: Implementation of the generic scmi-pinctrl driver Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240418-pinctrl-scmi-v11-4-499dca9864a7@nxp.com> References: <20240418-pinctrl-scmi-v11-0-499dca9864a7@nxp.com> In-Reply-To: <20240418-pinctrl-scmi-v11-0-499dca9864a7@nxp.com> To: Sudeep Holla , Cristian Marussi , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Linus Walleij , Dan Carpenter Cc: Dhruva Gole , Andy Shevchenko , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-gpio@vger.kernel.org, Peng Fan , Oleksii Moisieiev , Andy Shevchenko X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1713403963; l=18594; i=peng.fan@nxp.com; s=20230812; h=from:subject:message-id; bh=frIY1kOz5TJs/gHZBgAO0T8Kpa1lYIWOgEfr1Im7os4=; b=Z8jFpGvLlmPyD6/nOljzUOW9IO3U3UWKuF/auwzSVqvwmTLHH08OzIoCt2X7qeLXY9GAOSvqp mK4RcXvnUoaCk9NdLVEH9EjMgvSBmqIE+c3c0DNY4AnQvNe/mvi6Tpu X-Developer-Key: i=peng.fan@nxp.com; a=ed25519; pk=I4sJg7atIT1g63H7bb5lDRGR2gJW14RKDD0wFL8TT1g= X-ClientProxiedBy: SG2PR03CA0116.apcprd03.prod.outlook.com (2603:1096:4:91::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_|AM7PR04MB7110:EE_ X-MS-Office365-Filtering-Correlation-Id: 21c97aac-3bd3-484e-4035-08dc5f46575d 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: azjz329YfckjZShlmN85hvzziDW6PmMaUV2EDgdRKoh2jddFdBuWQ/LlAkXWvtdGUeSZ63LD1RMLDRvp9ZPqSllUpESFn7HEbnyRvCakxp6CXlG9T3HQc+HxGfG8mPvSO2j5qfFNuzca1WpMrKlmTpRWzfA9dkzKtCM9alofu5IacPcWMd+cpY6GCl7JIdDTLwvIJtUgTt3jqKFt1odl9XMoZRw22FXmHW0CO9fpgQCNetUCrOR8T0Mg9ZicisgTei4W8igUYnDa/WgrdgU0csrJZQWjpbmVI75OzVJM0z3Ejk+qQFLFCz6olHxjiv7SZvAgv61OfTHvAcqDgdbhCS84NK+NojSan/BmQW9ZVTIYBnXYoDWAjQds5HaBUUf3tY5i5HgXQ9CiyxZ7cyw3UeKKsWChByX3OunatMxLA3muFiFQv1yqjjFEsUkrxtDFCNVuzBGKCoVrSxzPW52mEX0Thx3aOYo7ZzCZ074VqK1KX9EgIqqob0cIlqHGkKRUn3OY6f+wm/mzb5EcuF9tZC9SCmUvYB8oY5KvOso9HrBche/tOEzodu46dLdE723hhklfzBhYABDSqZ+TL4WAdLrDsqHVuXGYrNuOaq6OYwx/otVFcbvNR/trqwaDAB3cn7pyKC5E9mL5e6XQnHyWI9VdTn3Dw6L54THruEtwNlkiywfGl0yE2Fb7wbU5mFsQQH5QXqsX7aLXzAAR4VuPq1tafroVElp7DasH526HrTU= 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)(52116005)(366007)(1800799015)(7416005)(376005)(38350700005);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?N2tRdnFVb25IVGtXS1ZwaStZS1NQU25WWWRHSUJWaS9jaWJJZHFXTUEvVmhO?= =?utf-8?B?ZlR4OHNjUTBLSWJNSUJTclFIR1lzSWNaaDhRV3p4eEhpbnpxeTJXUUxkOUVh?= =?utf-8?B?UEE5bXdmR3hraW9Od2xvbURUaUl6S1NrcW51TzJOU1dxNHVETDNyUHV4VSto?= =?utf-8?B?UjFHNlVEVDJnNCt0YXpqalh1YVNCOWp5eUhTS1ZvUFdBRGRuYmUvOGpJR0Zh?= =?utf-8?B?bWtPSlN3Uk42MGE5a280YU1Ed3ZWRXdBU2EyYWtrcUFIOEFoaGZmM3pHRzJO?= =?utf-8?B?aThoa1lhT1I4alkrd1JhSXFoSkQrQU9paWY0TzdxUmg3RnlmMzhNREthK20x?= =?utf-8?B?YjQwRitVa0tudG9GNzI1czB6MTVaVFZxUklTWVJjOWpocXFkOWMvMDg2Mk44?= =?utf-8?B?RmlsMm1LeEFQWXFuUFhoTks0NWZQUnMzVlVCQ0NjZFdJaUF4T0JVbjd1d1BD?= =?utf-8?B?Q0RhNVFXN1hsU1R0VzRJallkWEo0UzJianQ4K2ZzQUZjdEpDQUZGdzFBc2I2?= =?utf-8?B?VTRBLzBkR3dyekttWHNIRFhoNC9yZUszNW9xZVZVRjZUd1VtYjczaTdDcnF2?= =?utf-8?B?TDZZQVJuaUZxcjk3eDZ3TDFmWXlHL2ZzNHRBNU5WbFYzK2tiemhLNzVUc0hE?= =?utf-8?B?RXFrV25PRWFldm5LMkhTT1lJT2pueFVza0U5azZtcFZBT2V1aFJuY2owM25Y?= =?utf-8?B?bWtxMUFlLzUrZEg0TzRxSUJxbTdSdnBlUm1SZm1uUm8vVmVhVGV0eEJaSmo2?= =?utf-8?B?VHlPU1JiZkc3ak5kcW5pVFNubTNnendWYVlaMjZEblZaallqd25XSEVKSTA2?= =?utf-8?B?Mk9FNzFoYVhkTEJMZTRKNEYxRkVKL0dhbVZXa01LUjlaUytRbUpoYmU3WU93?= =?utf-8?B?MW12eGUwelRUblNFNVNzbTQ3UzRsTENJOGFWY1pqd2VPL2RkUUNVWmhnOXFV?= =?utf-8?B?bmlodjBwalZabnhqN2ptNU41VEFhRWR6ZEpVODh2UzhRWS9hOFRoaVdPaHIv?= =?utf-8?B?YUtsOU5aVG9tTlZTZm5CbWs4Q2VLejc4NGZqOFZtMnVUbFBnc3ZNVERCQWdr?= =?utf-8?B?blRtb3lGUHpFa08xVW4xNWtKRkpzTUVUY0JZVzBsV0RHbXh0M1hEZEtMd1Fq?= =?utf-8?B?YjRHSE9BK3NuTDM2NXVUbElWOFlqeElLQ0hqay94RDI4WW1Xd0lORXV0NHBX?= =?utf-8?B?WWlKbjVQRE9aVk41eVRnRGVGL3hlRHU2SFpRbE5NRDhkSmhFV05teXhyZ0pt?= =?utf-8?B?ZDJCVVN5UEdyNHoxelhXc1dpbFhaYVpFbklhTnRBSlRMbWhMYUNqaVlxcnFs?= =?utf-8?B?SStCclRPZWJnQkNMRkg2NlNsYlIxUFNaM1pJeHArSG1IekNCMnRPQTBoZmxB?= =?utf-8?B?Uk13d2h6MlIyWjBSWDJsamZWNTVLeXRneXFNdzIyUkV0RkgyRnVtYnVVUDJY?= =?utf-8?B?Y002bS8wUlZ2N2NERndUb3paY1ZuY2dzSnVQeExXK05IZjUxLzEzMGEremVH?= =?utf-8?B?OG90Q0k2Y3gzdzlNbDRDby9qQ1ZpZUNYdmgvanEyRDVVMFc1OXNOMGdHMkdT?= =?utf-8?B?TVk4WXhJVmIxZ2JCV2FsYnhOUENBeWdWUURWbG5SOTkxWm9iMDhJSlIwcmpv?= =?utf-8?B?MWR1Y2I3MTdBazJDRW5ackhRUk13UEtNeWREOXJvUWZlUEFCVGJDVU85U3V0?= =?utf-8?B?OWN6TFl0NlJxMCtVVWIxb0VUSlFwM0ozM0tqMlQ2b3ZxbTBCMlFJTGxURk1u?= =?utf-8?B?Tld3L2h5VnE2ckxlWFJYZVpscThMQVNRcDYvc250ME1yNS9zTTdpNlROcS9q?= =?utf-8?B?cmkyTFdySWdWcVhjN3E0QjYraHpQQTVKNWNocXRxNGdocTc2c0xNNjd3eHU2?= =?utf-8?B?aThUeVVXdGxDdlMxMm55QXpxMDhNVlY1STd4QnRsbEprdlN0VmlwZlhSME5y?= =?utf-8?B?UCtSMTU5OXN4akRPdlNNbkFxbitnVnY4cVU5YVVvYjV4TVJjUTRHSDNRKzdl?= =?utf-8?B?Sy9Xb3ZuNi9oWFRnUkwySkREKzAyeXZYa0w0SlhtY0w1RXRYMXZVNnMrSm12?= =?utf-8?B?c3ZWU3k0M3hMWTZRbEMwUXhUU3FLazkraHhhbkNMbHduU2h4NnFRZkNJUEpo?= =?utf-8?Q?QNocwj+Vh3z2Lm2CIYTnDya73?= X-OriginatorOrg: oss.nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 21c97aac-3bd3-484e-4035-08dc5f46575d X-MS-Exchange-CrossTenant-AuthSource: DU0PR04MB9417.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 18 Apr 2024 01:24:49.9230 (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: KqKZ0au5J/etB26Q1TlO8/MEjFG1kBDGmFLriTSH+XNbWKijr+fFDJd9w6RFFyDjtGbfo7PjNec9OTzHPQj1Yg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM7PR04MB7110 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. Co-developed-by: Oleksii Moisieiev Signed-off-by: Oleksii Moisieiev Reviewed-by: Dhruva Gole Reviewed-by: Andy Shevchenko Signed-off-by: Peng Fan Acked-by: Linus Walleij --- MAINTAINERS | 1 + drivers/pinctrl/Kconfig | 11 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-scmi.c | 571 +++++++++++++++++++++++++++++++++++++= ++++ 4 files changed, 584 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index b1b074ce2cf3..a37aaff190c7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -21615,6 +21615,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 1be05efccc29..7e4f93a3bc7a 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..036bc1e3fc6c --- /dev/null +++ b/drivers/pinctrl/pinctrl-scmi.c @@ -0,0 +1,571 @@ +// 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 +#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 { + struct device *dev; + struct scmi_protocol_handle *ph; + struct pinctrl_dev *pctldev; + struct pinctrl_desc pctl_desc; + struct pinfunction *functions; + unsigned int nr_functions; + 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 **p_groups, + unsigned int * const p_num_groups) +{ + struct pinfunction *func; + const unsigned int *group_ids; + unsigned int num_groups; + const char **groups; + int ret, i; + struct scmi_pinctrl *pmx =3D pinctrl_dev_get_drvdata(pctldev); + + if (!p_groups || !p_num_groups) + return -EINVAL; + + if (selector >=3D pmx->nr_functions) + return -EINVAL; + + func =3D &pmx->functions[selector]; + if (func->ngroups) + goto done; + + ret =3D pinctrl_ops->function_groups_get(pmx->ph, selector, &num_groups, + &group_ids); + if (ret) { + dev_err(pmx->dev, "Unable to get function groups, err %d", ret); + return ret; + } + if (!num_groups) + return -EINVAL; + + groups =3D kcalloc(num_groups, sizeof(*groups), GFP_KERNEL); + if (!groups) + return -ENOMEM; + + for (i =3D 0; i < num_groups; i++) { + groups[i] =3D pinctrl_scmi_get_group_name(pctldev, group_ids[i]); + if (!groups[i]) { + ret =3D -EINVAL; + goto err_free; + } + } + + func->ngroups =3D num_groups; + func->groups =3D groups; +done: + *p_groups =3D func->groups; + *p_num_groups =3D func->ngroups; + + return 0; + +err_free: + kfree(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 -EINVAL; + } + + 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) + return ret; + + ret =3D pinctrl_ops->settings_get_one(pmx->ph, pin, PIN_TYPE, type, + &config_value); + /* Convert SCMI error code to PINCTRL expected error code */ + if (ret =3D=3D -EOPNOTSUPP) + return -ENOTSUPP; + 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(**p_config_value), GFP_KE= RNEL); + if (!*p_config_value) + return -ENOMEM; + + *p_config_type =3D kcalloc(num_configs, sizeof(**p_config_type), GFP_KERN= EL); + if (!*p_config_type) { + kfree(*p_config_value); + 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->settings_conf(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->settings_conf(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->settings_get_one(pmx->ph, group, GROUP_TYPE, type, + &config_value); + /* Convert SCMI error code to PINCTRL expected error code */ + if (ret =3D=3D -EOPNOTSUPP) + return -ENOTSUPP; + 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, + struct pinctrl_desc *desc) +{ + struct pinctrl_pin_desc *pins; + unsigned int npins; + int ret, i; + + npins =3D pinctrl_ops->count_get(pmx->ph, PIN_TYPE); + /* + * npins will never be zero, the scmi pinctrl driver has bailed out + * if npins is zero. + */ + pins =3D devm_kmalloc_array(pmx->dev, npins, sizeof(*pins), GFP_KERNEL); + if (!pins) + return -ENOMEM; + + for (i =3D 0; i < npins; i++) { + pins[i].number =3D i; + /* + * The memory for name is handled by the scmi firmware driver, + * no need free here + */ + ret =3D pinctrl_ops->name_get(pmx->ph, i, PIN_TYPE, &pins[i].name); + if (ret) + return dev_err_probe(pmx->dev, ret, + "Can't get name for pin %d", i); + } + + desc->npins =3D npins; + desc->pins =3D pins; + dev_dbg(pmx->dev, "got pins %u", npins); + + return 0; +} + +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->handle) + return -EINVAL; + + handle =3D sdev->handle; + + pinctrl_ops =3D handle->devm_protocol_get(sdev, SCMI_PROTOCOL_PINCTRL, &p= h); + 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); + 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->functions =3D devm_kcalloc(dev, pmx->nr_functions, + sizeof(*pmx->functions), GFP_KERNEL); + if (!pmx->functions) + return -ENOMEM; + + return pinctrl_enable(pmx->pctldev); +} + +static const struct scmi_device_id scmi_id_table[] =3D { + { SCMI_PROTOCOL_PINCTRL, "pinctrl" }, + { } +}; +MODULE_DEVICE_TABLE(scmi, scmi_id_table); + +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