From nobody Fri Dec 19 08:56:24 2025 Received: from BN1PR04CU002.outbound.protection.outlook.com (mail-eastus2azon11010071.outbound.protection.outlook.com [52.101.56.71]) (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 B7E601F9EC0 for ; Wed, 8 Oct 2025 19:10:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.56.71 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759950610; cv=fail; b=ELvSMGQzca0Q7gnSTFPi7p9PrpTuctb+Uc+/i4tTQGMKCH41d/Oy17XZTS/YpMXqt4rqzWnEyOabfvDpK/9FaohYqnAD+Ee5fOOTz6qfYh8sODTAJKwui4TxYTbyJ7XEZ+LP6vyduJjU6MiLmWnhZ/lNTfb0E/jYS0+VWkq45vY= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759950610; c=relaxed/simple; bh=MUZqoQQSunhMSakVJ+bU7rwve5OX4Eom6gkPxqOtawI=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=KmFg0dKk+Vo6j9GB5ytzqjjzqjRb1AShPjPcRD86Vu4HQlZrHnOVnyxOMQLL/uFUfvHAhNapXxNThca5MyXycmvO8MpYUdLd5W/E2Bhc/K8Hz9gJvmLEnSk7Er0yD2FejQvAXHrn6n5HidM0oQodI9iqaKxgNnZQfx8D7v2hWIU= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com; spf=fail smtp.mailfrom=nvidia.com; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b=f1i1XD82; arc=fail smtp.client-ip=52.101.56.71 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=nvidia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b="f1i1XD82" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=tyqfskeyaqNvM4ZUIjWYditL71OZO7ICiMQttWzbaNU3HDGg+AeuJXahMSNiegYrjbDCYWvlhI0T+TFTLJpbLi+IigKCq3wXzwcQ9omgviR1o/J2/BxhhNJmKWqLdYI0+E4Nnvq29nupWaGP3EPZB9mXU3Uk0bVGMyuITv+1xzvRJKwmblbYPIa/To6zsHBFf0IGqqp1XLL/b9gLQ6fC797EnyjiML39dnefV2fnL5qZHF0suefFjuPsRcorPV6/zJt4GA9bo2I8ncQYCm8yZiBtQctTwTjEjtKwgBoqBkP3ejkEleok7JQZSmbqArF5QRoWiuEk0ay1DaZNmkxKbQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=jidatQNOkEdavEkWfDkhye5C63/P3ytt1dd7M8Rl2Vw=; b=aFRyNsCtSNLu5b71xZLyyejoS414WohNiOOSfrpowChqWmvv2bkNyWM7O6VyqyvcffveZa+/x5lqsZAj4WnCJM4i39JuboIqs17kQ/baQ/phE2hEOm58G0xiCE776UT5t7tr8EeLzuwDRdB72O49gmYDXMBSutMOzQXFfDyvub7+u19mrn+DbwLSy0bEKaYhJXGXkE3XyJ6fRpowksim3x9bPlZ/rpcBaWNw2XfKdIPB4UYnSH9SXk/goS206qaBurN1oXuSMhn4+CtdcbbrspJAARhuToPx+FkaZkkNV06BuPK0IG/fS2Mp5Uv3IMDEaawOGrO9+V67SWc2Gv8xvw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.118.232) smtp.rcpttodomain=arm.com smtp.mailfrom=nvidia.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=jidatQNOkEdavEkWfDkhye5C63/P3ytt1dd7M8Rl2Vw=; b=f1i1XD82RML25RteFlnLitmunJJMYykOcC5BFjzMLKLR3rkYsr7NPHITlysr8v3MZczL9JgJr3enLB8rp5G8d/C8LYI0T1z3MBGJ6H0um0DJAPcrSv1HQX9+932G63QuGl6h8G9EE4mqZARrzmgy84jkTKjHUuMrGllxT6tEGmOKSG6imNu3H7AfzrF7QcD6nGHnoU9YHQ3CkHzzpDolqUwuaV0DXRdYKifSkNorSuqb4Jf1oSaUBlPYAd3nJ+EFT4JFXvY6fUZW7kjpqr/oU1HF0SInAULoV7g0UV6WqnNh4hQSXMfQZBgupelX8H2EPC9tcVSC0qdvzaqwGRRjOQ== Received: from BN9PR03CA0363.namprd03.prod.outlook.com (2603:10b6:408:f7::8) by DS5PPFB8FBD73EA.namprd12.prod.outlook.com (2603:10b6:f:fc00::65e) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9115.22; Wed, 8 Oct 2025 19:09:57 +0000 Received: from BL02EPF0001A0FF.namprd03.prod.outlook.com (2603:10b6:408:f7:cafe::f9) by BN9PR03CA0363.outlook.office365.com (2603:10b6:408:f7::8) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9203.9 via Frontend Transport; Wed, 8 Oct 2025 19:09:57 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.118.232) smtp.mailfrom=nvidia.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.118.232 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.118.232; helo=mail.nvidia.com; pr=C Received: from mail.nvidia.com (216.228.118.232) by BL02EPF0001A0FF.mail.protection.outlook.com (10.167.242.106) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9203.9 via Frontend Transport; Wed, 8 Oct 2025 19:09:56 +0000 Received: from drhqmail201.nvidia.com (10.126.190.180) by mail.nvidia.com (10.127.129.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.14; Wed, 8 Oct 2025 12:09:42 -0700 Received: from drhqmail203.nvidia.com (10.126.190.182) by drhqmail201.nvidia.com (10.126.190.180) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.20; Wed, 8 Oct 2025 12:09:41 -0700 Received: from build-vvidwans-focal-20250627.internal (10.127.8.10) by mail.nvidia.com (10.126.190.182) with Microsoft SMTP Server id 15.2.2562.20 via Frontend Transport; Wed, 8 Oct 2025 12:09:41 -0700 From: Vedashree Vidwans To: , , , , CC: , , , , , , , , Vedashree Vidwans Subject: [RFC PATCH 1/3] firmware: smccc: LFA: use smcc 1.2 Date: Wed, 8 Oct 2025 19:09:05 +0000 Message-ID: <20251008190907.181412-2-vvidwans@nvidia.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20251008190907.181412-1-vvidwans@nvidia.com> References: <20251008190907.181412-1-vvidwans@nvidia.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-NV-OnPremToCloud: ExternallySecured X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BL02EPF0001A0FF:EE_|DS5PPFB8FBD73EA:EE_ X-MS-Office365-Filtering-Correlation-Id: ee521611-c931-4b24-d700-08de069e454b X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|1800799024|7416014|376014|36860700013; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?1EFvbtZuYgtaSlrkeprdjkFGgRMt8dCPSO9YdtTN6Oqrw+GxqnLEK0r6VfwB?= =?us-ascii?Q?BRaNf4Hu4TOeGI5GyRxR3J259hNy4mO6YJjCV4BoVcsWj7D3rrbB2wVIz4NN?= =?us-ascii?Q?fuse8DDe+PqyFPx7YQG1bUmICN6esgJKy93DihSvmLHj36eJQh4NWnRe1fjN?= =?us-ascii?Q?XwlxwDTSoRzPs42AHZK4qDr2SvzLZMgLAwATNAXeM8buQxK6OPCkho1I+1ok?= =?us-ascii?Q?iRbtblhEzISNHgajeTuPB0Sfc1LcrG9hGVpDyJ4r97r8Vihd1ecgfyQZKjBj?= =?us-ascii?Q?v/Lb9PFCtpv75ObrbfP5Rtiog8b0EARaM3Nx0DLk0IzFxJtdjrmQy2v7upQ2?= =?us-ascii?Q?NCECRkR+n3zQ5Vt88EmMb9c/fglGqBs6s4g2yKfGYIvC3s/MKXSCRiYTg0rG?= =?us-ascii?Q?L95SqQN61uw2ZzCXwy6jRyh8J0rag/Xu0e4jaTFLx1QccrHc3BvVgTK8JxJQ?= =?us-ascii?Q?wM82mm3EdTwSqU8n9xSYEAQlAxP0X34igHpgNQQJucdxjfhTfuLzmuiF5SvD?= =?us-ascii?Q?ds004nTYt9vxrEpdVn5Dc7uDQsRCxKlcBepcf5VqhnuB7RfEjlbZtzLojSBt?= =?us-ascii?Q?WTP/Ot1M3kMBkC5mL21JgWUsCgVw3ySVASDju8wNzpyszcbK9ToOLs4BJi8D?= =?us-ascii?Q?H4tDjgJkxGjpVRaneMSPO1AJv6iOz+z3honjgNtAH68rq+y9vrygU7aZvpXT?= =?us-ascii?Q?rmNSrrjdFiaXGmQo1j3PZO/pBEOaqd9OCEJt5Kt7IAqSwtTw08ZquKInJZON?= =?us-ascii?Q?hAes2SFjU8SSPRjzNiZF5qP/pP9+rVrfoSdbCAdwRoG11a6/hR+CwiSCobQf?= =?us-ascii?Q?q8o4fyoDKjtgQGmQvW2scoo+8qKdgcRm9x2w3DvnCSdO0swSyJUMyJmLuWcT?= =?us-ascii?Q?VNVNyW7c8VibF5x0VZVQxyOeKDAIWcwpnaYT7sQEVrOrD9Jldir0HQ50aUzx?= =?us-ascii?Q?uqYcKx5xqM5wL05PIQH4RLmpWfDHQ28bBsranSlYqa5EGL0WOs2kYVgev7hO?= =?us-ascii?Q?Ub2muUpnP+f/96bx/slh80p+FFgdxiHVxa/URl4kDj7/FI9paazavLroQNRD?= =?us-ascii?Q?zvOqf8PFL2XqKZ8RGemKJ1+aNuaPEr/W2VwomqzKbJ+B9uarvPrrhnMENKu8?= =?us-ascii?Q?CvhjLoUIL0kv4pNnIOrPwCTalkbT2RdzgaSAa78kzd3fsaN3T+WlfuzXmue6?= =?us-ascii?Q?LHhA8OjJaxoTJK6ijBMSmHFNQxrm2GYG98aInqZnPT+OaHW/O8O6ohCQncjO?= =?us-ascii?Q?Zx/Wod2t7GUYoNiv2TLAlDA6pa+qmKbiLxzmdeESxcRWn2z8xkgBo1rj8bhP?= =?us-ascii?Q?5YBiB7/yicL3IU/vnDaIQZhF8+qhCZMTuFpZQa0p8mnzu+9281CSBtg0AFI5?= =?us-ascii?Q?ZYLeNhCQ9v8biCtMhBu+lOlKpy7CMhnCY6ka6lyfx4lV7LkCVaOJrlsDZ0+Q?= =?us-ascii?Q?7/lj6fluiliFasMX81HP/U1KufIPJAj4LA336ZyV1G6KRjNWFmHZcn8FjNXS?= =?us-ascii?Q?imllNgr+uZPyoz62dJe/YmluEQPACOPJh50UUmnts9hWcKXY7rhEgvWeMbg4?= =?us-ascii?Q?NFlqW10aB0PNH5SUMNo=3D?= X-Forefront-Antispam-Report: CIP:216.228.118.232;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mail.nvidia.com;PTR:dc7edge1.nvidia.com;CAT:NONE;SFS:(13230040)(82310400026)(1800799024)(7416014)(376014)(36860700013);DIR:OUT;SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 Oct 2025 19:09:56.8591 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: ee521611-c931-4b24-d700-08de069e454b X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a;Ip=[216.228.118.232];Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: BL02EPF0001A0FF.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS5PPFB8FBD73EA Content-Type: text/plain; charset="utf-8" Update driver to use SMCCC 1.2+ version as mentioned in the LFA spec. Signed-off-by: Vedashree Vidwans --- drivers/firmware/smccc/lfa_fw.c | 80 +++++++++++++++++++++++---------- 1 file changed, 56 insertions(+), 24 deletions(-) diff --git a/drivers/firmware/smccc/lfa_fw.c b/drivers/firmware/smccc/lfa_f= w.c index 1f333237271d8..49f7feb6a211b 100644 --- a/drivers/firmware/smccc/lfa_fw.c +++ b/drivers/firmware/smccc/lfa_fw.c @@ -117,9 +117,13 @@ static struct kobject *lfa_dir; =20 static int get_nr_lfa_components(void) { - struct arm_smccc_res res =3D { 0 }; + struct arm_smccc_1_2_regs args =3D { 0 }; + struct arm_smccc_1_2_regs res =3D { 0 }; =20 - arm_smccc_1_1_invoke(LFA_1_0_FN_GET_INFO, 0x0, &res); + args.a0 =3D LFA_1_0_FN_GET_INFO; + args.a1 =3D 0; /* lfa_info_selector =3D 0 */ + + arm_smccc_1_2_invoke(&args, &res); if (res.a0 !=3D LFA_SUCCESS) return res.a0; =20 @@ -129,20 +133,23 @@ static int get_nr_lfa_components(void) static int call_lfa_activate(void *data) { struct image_props *attrs =3D data; - struct arm_smccc_res res =3D { 0 }; + struct arm_smccc_1_2_regs args =3D { 0 }; + struct arm_smccc_1_2_regs res =3D { 0 }; + + args.a0 =3D LFA_1_0_FN_ACTIVATE; + args.a1 =3D attrs->fw_seq_id; /* fw_seq_id under consideration */ + /* + * As we do not support updates requiring a CPU reset (yet), + * we pass 0 in args.a3 and args.a4, holding the entry point and context + * ID respectively. + * We want to force CPU rendezvous if either cpu_rendezvous or + * cpu_rendezvous_forced is set. The flag value is flipped as + * it is called skip_cpu_rendezvous in the spec. + */ + args.a2 =3D !(attrs->cpu_rendezvous_forced || attrs->cpu_rendezvous); =20 do { - /* - * As we do not support updates requiring a CPU reset (yet), - * we pass 0 in x3 and x4, holding the entry point and context - * ID respectively. - * We want to force CPU rendezvous if either cpu_rendezvous or - * cpu_rendezvous_forced is set. The flag value is flipped as - * it is called skip_cpu_rendezvous in the spec. - */ - arm_smccc_1_1_invoke(LFA_1_0_FN_ACTIVATE, attrs->fw_seq_id, - !(attrs->cpu_rendezvous_forced || attrs->cpu_rendezvous), - 0, 0, &res); + arm_smccc_1_2_invoke(&args, &res); } while (res.a0 =3D=3D 0 && res.a1 =3D=3D 1); =20 return res.a0; @@ -150,7 +157,8 @@ static int call_lfa_activate(void *data) =20 static int activate_fw_image(struct image_props *attrs) { - struct arm_smccc_res res =3D { 0 }; + struct arm_smccc_1_2_regs args =3D { 0 }; + struct arm_smccc_1_2_regs res =3D { 0 }; int ret; =20 /* @@ -159,8 +167,10 @@ static int activate_fw_image(struct image_props *attrs) * LFA_PRIME/ACTIVATE will need to be called again. * res.a1 will become 0 once the prime/activate process completes. */ + args.a0 =3D LFA_1_0_FN_PRIME; + args.a1 =3D attrs->fw_seq_id; /* fw_seq_id under consideration */ do { - arm_smccc_1_1_invoke(LFA_1_0_FN_PRIME, attrs->fw_seq_id, &res); + arm_smccc_1_2_invoke(&args, &res); if (res.a0 !=3D LFA_SUCCESS) { pr_err("LFA_PRIME failed: %s\n", lfa_error_strings[-res.a0]); @@ -211,13 +221,16 @@ static ssize_t activation_pending_show(struct kobject= *kobj, { struct image_props *attrs =3D container_of(attr, struct image_props, image_attrs[LFA_ATTR_ACT_PENDING]); - struct arm_smccc_res res =3D { 0 }; + struct arm_smccc_1_2_regs args =3D { 0 }; + struct arm_smccc_1_2_regs res =3D { 0 }; =20 /* * Activation pending status can change anytime thus we need to update * and return its current value */ - arm_smccc_1_1_invoke(LFA_1_0_FN_GET_INVENTORY, attrs->fw_seq_id, &res); + args.a0 =3D LFA_1_0_FN_GET_INVENTORY; + args.a1 =3D attrs->fw_seq_id; + arm_smccc_1_2_invoke(&args, &res); if (res.a0 =3D=3D LFA_SUCCESS) attrs->activation_pending =3D !!(res.a3 & BIT(1)); =20 @@ -298,9 +311,12 @@ static ssize_t cancel_store(struct kobject *kobj, stru= ct kobj_attribute *attr, { struct image_props *attrs =3D container_of(attr, struct image_props, image_attrs[LFA_ATTR_CANCEL]); - struct arm_smccc_res res =3D { 0 }; + struct arm_smccc_1_2_regs args =3D { 0 }; + struct arm_smccc_1_2_regs res =3D { 0 }; =20 - arm_smccc_1_1_invoke(LFA_1_0_FN_CANCEL, attrs->fw_seq_id, &res); + args.a0 =3D LFA_1_0_FN_CANCEL; + args.a1 =3D attrs->fw_seq_id; + arm_smccc_1_2_invoke(&args, &res); =20 /* * When firmware activation is called with "skip_cpu_rendezvous=3D1", @@ -395,14 +411,17 @@ static int create_fw_inventory(char *fw_uuid, int seq= _id, u32 image_flags) =20 static int create_fw_images_tree(void) { - struct arm_smccc_res res =3D { 0 }; + struct arm_smccc_1_2_regs args =3D { 0 }; + struct arm_smccc_1_2_regs res =3D { 0 }; struct uuid_regs image_uuid; char image_id_str[40]; int ret, num_of_components; =20 num_of_components =3D get_nr_lfa_components(); + args.a0 =3D LFA_1_0_FN_GET_INVENTORY; for (int i =3D 0; i < num_of_components; i++) { - arm_smccc_1_1_invoke(LFA_1_0_FN_GET_INVENTORY, i, &res); + args.a1 =3D i; /* fw_seq_id under consideration */ + arm_smccc_1_2_invoke(&args, &res); if (res.a0 =3D=3D LFA_SUCCESS) { image_uuid.uuid_lo =3D res.a1; image_uuid.uuid_hi =3D res.a2; @@ -420,10 +439,23 @@ static int create_fw_images_tree(void) =20 static int __init lfa_init(void) { - struct arm_smccc_res res =3D { 0 }; + struct arm_smccc_1_2_regs args =3D { 0 }; + struct arm_smccc_1_2_regs res =3D { 0 }; int err; =20 - arm_smccc_1_1_invoke(LFA_1_0_FN_GET_VERSION, &res); + /* LFA requires SMCCC version >=3D 1.2 */ + if (arm_smccc_get_version() < ARM_SMCCC_VERSION_1_2) { + pr_err("Not supported with SMCCC version %u", arm_smccc_get_version()); + return -ENODEV; + } + + if (arm_smccc_1_1_get_conduit() =3D=3D SMCCC_CONDUIT_NONE) { + pr_err("Invalid SMCCC conduit"); + return -ENODEV; + } + + args.a0 =3D LFA_1_0_FN_GET_VERSION; + arm_smccc_1_2_invoke(&args, &res); if (res.a0 =3D=3D -LFA_NOT_SUPPORTED) { pr_err("Arm Live Firmware activation(LFA): no firmware agent found\n"); return -ENODEV; --=20 2.25.1 From nobody Fri Dec 19 08:56:24 2025 Received: from SJ2PR03CU001.outbound.protection.outlook.com (mail-westusazon11012003.outbound.protection.outlook.com [52.101.43.3]) (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 E72832C2340 for ; Wed, 8 Oct 2025 19:10:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.43.3 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759950617; cv=fail; b=LW7HNwZSoWGbzGd6uNAtVtjIrFFt65rYe35A5ZGi/OXliRdY27vcsYshUI214DWAPEbMiSTeT/J5mo+LeFoR+sdpOyZLCiX/RptwSLViYV7HcBQmxRMT1koPWfMCMRjuaI4pFGz5/YLAMvBKAprPDHnvCDIWEFMo+5EpxLRhKls= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759950617; c=relaxed/simple; bh=BPTOi6ttMNgIbbZWnlAZHDydVd8WTzT+9f/LnaOnvD8=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=NTsEJN5jJD4oiH5FEWDQzo9pZK3Lt026tbKNXmWN0/W15BE5pcblzvdNBo5FM8290IlsCCfpgJGfPRgTB9rnrvR1gzJlzvmCU2N1C+vBo0qsUGGsH0aiP9JwBEsGu6PJQcFeP/yROW5BtPgiY7RnFGI/YnYynU6b40GEfdZQhZI= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com; spf=fail smtp.mailfrom=nvidia.com; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b=FSB5gdmg; arc=fail smtp.client-ip=52.101.43.3 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=nvidia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b="FSB5gdmg" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=FmTA1NDn/BCdHrZokXMpLqmCYMmvDueeDHXVj2pfJvQYxBT8pchd5RXpqkYMz4uzBKvdAOGAlXaM0TidsM1gES1DO0Sq6B5sboYs5Fgcmx0YzbNBVeCkep3KMWne4smqD+GlV6Dq47W5PMjjWyimYN3FqXZIIjqybnJvatiWdpoMHKFQy0rhYV46o0iUx8VjGvcP8fwZezG3aX2dVLt8QlIPfhzBd568ylxFwr56JxsnixeJSdsnORgpPMVleEh5kvzKtSrLdf1Zx+Np6Gofvy/zjyxitnbSGGwg2L4EBSlsh/zx62ft1/CXP2qTXOPyzZLBepESsN7y6o6tx+56QA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=1BRfeeZGZh3+oKfXlY2bcwZghQirtOG/oCAELffLJtQ=; b=NDAUuFK6yz+XavYB3m20OS28FK8/ZqIEnavHvbncIvbHjYu+zYN2ZthzvZmkQWUeYjpQKtGIHudM87Sq3dgV1QZJf2DkLcE59RGKBC4ggkwAi7jGrJ78fzOoxUAcD8gKpiON0N9dB973cnQkCQTHDfZ+jOxI2WKSK31FpUCEIRBGKJBTdgBZSFKC90jKmlGBsWvJ5sJPrlLGqiCWCJvJnTK5Hv6HlgfpCFO/eUZRYJmCuyG36h8ZB4o/ft+Y/C/yxyS0zT1AXN6RdysCzg2Krnsd3RULbtHU0kftC0uHpcuOE8lwZmlw8iW+/pNN8Ng1OicRHU73mCf0tq1Cj5Xrig== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.118.233) smtp.rcpttodomain=arm.com smtp.mailfrom=nvidia.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=1BRfeeZGZh3+oKfXlY2bcwZghQirtOG/oCAELffLJtQ=; b=FSB5gdmg28NgMF1CorScYklaAehlzbHTDFPi1Z4t4y7BqXVB5hwMQiiq9k3ykpqeWh6EPCMJGOcU/yGkvgDGVSraANdSk3cJ/U/qorumCUZaJGYHw4E7bv3sPuguXdWAWCoK4yNoMSEeGRjIVS+PgtIFC9JP4QEZAH5IGpxUr8b71l2ku67YtONLsBFtTaH5REWwuERGci7jsf7K+1fkNLXJbqq7sijdcIdzoaFP3syldiYkk5tLySs4xcxbyXrb0hlJ27o6NAADOZOeGh0D4B6L7FteF5qow/4pjgyYtpk0PoLk5focfobn2zkegwFdGZHzVGbDLXPhPBdx0AKvcQ== Received: from MW4PR03CA0306.namprd03.prod.outlook.com (2603:10b6:303:dd::11) by LV2PR12MB5893.namprd12.prod.outlook.com (2603:10b6:408:175::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9182.20; Wed, 8 Oct 2025 19:09:58 +0000 Received: from SJ1PEPF00002314.namprd03.prod.outlook.com (2603:10b6:303:dd:cafe::69) by MW4PR03CA0306.outlook.office365.com (2603:10b6:303:dd::11) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.20 via Frontend Transport; Wed, 8 Oct 2025 19:09:43 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.118.233) smtp.mailfrom=nvidia.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.118.233 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.118.233; helo=mail.nvidia.com; pr=C Received: from mail.nvidia.com (216.228.118.233) by SJ1PEPF00002314.mail.protection.outlook.com (10.167.242.168) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9203.9 via Frontend Transport; Wed, 8 Oct 2025 19:09:57 +0000 Received: from drhqmail201.nvidia.com (10.126.190.180) by mail.nvidia.com (10.127.129.6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.14; Wed, 8 Oct 2025 12:09:42 -0700 Received: from drhqmail203.nvidia.com (10.126.190.182) by drhqmail201.nvidia.com (10.126.190.180) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.20; Wed, 8 Oct 2025 12:09:42 -0700 Received: from build-vvidwans-focal-20250627.internal (10.127.8.10) by mail.nvidia.com (10.126.190.182) with Microsoft SMTP Server id 15.2.2562.20 via Frontend Transport; Wed, 8 Oct 2025 12:09:42 -0700 From: Vedashree Vidwans To: , , , , CC: , , , , , , , , Vedashree Vidwans Subject: [RFC PATCH 2/3] firmware: smccc: LFA: refactor, add device node support Date: Wed, 8 Oct 2025 19:09:06 +0000 Message-ID: <20251008190907.181412-3-vvidwans@nvidia.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20251008190907.181412-1-vvidwans@nvidia.com> References: <20251008190907.181412-1-vvidwans@nvidia.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-NV-OnPremToCloud: ExternallySecured X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF00002314:EE_|LV2PR12MB5893:EE_ X-MS-Office365-Filtering-Correlation-Id: 5711667d-379a-48e6-9b95-08de069e45ae X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|7416014|82310400026|1800799024|36860700013; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?PlAalFvmwOH3L1VIK3r90u3xUD9+7EVcCvXJEUagnyugXGTrFiLkVzrpBo29?= =?us-ascii?Q?ETlK2bfQQoZq7g2rHoLRu4v30Hl1Paj0FEoRCi4xdwlMi8sUQdEMGiG0Bjt0?= =?us-ascii?Q?NDV32rRyq8f1EFP0hXSCN9Zd0wmbRrTnPxwLGnw+AFJyAS3pItI58PMh5AE5?= =?us-ascii?Q?19cgcfZWeT2bBFduoVBFBnkQBXlVfQLb95Nhhg2GXCjzt7xTYGHiQ1+yhD81?= =?us-ascii?Q?OF54j36SY8Y/u8hoNbocn4wlHcjQl+E5kGGTMT2ISDpLxElNxqselbkuUdYU?= =?us-ascii?Q?AUZSZKHsfqnD7h5n9KLvgtjgrSNbkRHcrc9vIz2EhCBAbqrGm8vMLf9BKWbG?= =?us-ascii?Q?sk3BJwwSm4VyjKDoHVl99WyShhHQ0Zu+ML28uA96cgqTL2EGPp3w5RwYV0rg?= =?us-ascii?Q?JH6vmcTp51M7JSuafBI0vAu8O9Jr8yy/IFHjsBrCo77Ov4l2pad0n3EFlSc1?= =?us-ascii?Q?W7bRqImqJWztJWV3U0Wrfy/M1nE5Q/ebCoH4sk3JBDRxwb8Mi4dNZUnlBb3F?= =?us-ascii?Q?pUqJOLFEoh7o5Iq1KoPskKr5DPiOkRsjlWM0Za92qhmG7zAh6sHdumAU5MM/?= =?us-ascii?Q?znvCD3JU+ZLAZQeIEifJyvppLMZ4Cxoqgne3qgsLPatGsHur7mdKhmw2KdE/?= =?us-ascii?Q?u8xHivJVF2BqQETgiEdDOgsQ6mMI1UjXCGrN6U+DEXIvne5Od89WF+3wkceH?= =?us-ascii?Q?79VZxcHlwGAGzKM7bR+pyMChWeKsQKCV7R3kdnXGnbwxa8Mh+V/gPmPcY/U1?= =?us-ascii?Q?5+YrUDGUUFZjihH2MQe4pC7w1PWVNuq11sIJaSrO6iU6yoe1hSjRf4RF0Dxh?= =?us-ascii?Q?SOX/yMkY1cM3S9s0f39Ik97hCRLCR1GgtOkYVIK4Huno2Mae0vphdrT6+9FO?= =?us-ascii?Q?4JGX08HGLX8b3mQYiTx/pqtgx90aPmKEdrG+146Ea2zIw9JzYWigs/jG/am3?= =?us-ascii?Q?R01tzYhs1dyn1B/fPeyUSoQC+q3p2ZGZgd5LTS63uGC9Ka1rNnu3xnXA+3wA?= =?us-ascii?Q?w1WcH7CRKFj3kGbjOZvM3Rtbwo7ONue7myUB+XIlVw5HS01SQm2eL+p7jXWW?= =?us-ascii?Q?pjYlhBxs+lFnenhfZiy+uursc7elNk3cClwa20rkEcOqiIcm8lANzd+LzJWu?= =?us-ascii?Q?MVCfMPqKqviOnEAsi5OIH6Cul7BUhjoShg0DDWesr0ObtJDdsxmL3Ga7XcWj?= =?us-ascii?Q?JPKxbpUUBBOFn07yLRusAdcvYWLd250qM+jRoy+5WlVJHJ93HzhcBfHMRXVe?= =?us-ascii?Q?VUABCCtn+zUn34XhxpJApANh9tqvt2upBx4f4kDYG7Ur0hiITD8R/NoVvpIf?= =?us-ascii?Q?32x+o4cfcUF8a3qBqbAXKLWipsm5KBi0nzcOgqe+KY6kigprnM1XMK4fl2XN?= =?us-ascii?Q?nQzgG7ZtXL8Gq5PdFHM3w8fKdCfVnj0izRAn0cNls3x5v0hz9M6KRbjymRki?= =?us-ascii?Q?l+7mReO8MMPL2o5KaHLJBjcKrno18NHf7Tj31cazZrMhrEnJo1ZDOAC+hHqi?= =?us-ascii?Q?grwRRZvf610WxwEILFFmKQTB/nXpLZ1SBxPpn+tLLMsillaTSI+5OnhdfJVy?= =?us-ascii?Q?P0x0ZnqDL7lDf2yidQM=3D?= X-Forefront-Antispam-Report: CIP:216.228.118.233;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mail.nvidia.com;PTR:dc7edge2.nvidia.com;CAT:NONE;SFS:(13230040)(376014)(7416014)(82310400026)(1800799024)(36860700013);DIR:OUT;SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 Oct 2025 19:09:57.6595 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 5711667d-379a-48e6-9b95-08de069e45ae X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a;Ip=[216.228.118.233];Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: SJ1PEPF00002314.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: LV2PR12MB5893 Content-Type: text/plain; charset="utf-8" - Add support for LFA device node in the kernel driver. Implement probe() to register LFA interrupt and threaded interrupt service function. - CPUs will be rendezvoused during activation. - On IRQ, driver will query FW components then triggers activation of capable and pending components. - Mutex synchronization is implemented to avoid concurrent LFA updates through interrupt and sysfs interfaces. - Refactor LFA CANCEL logic into independent lfa_cancel() function. - Enhance PRIME/ACTIVATION functions to touch watchdog and implement timeouts. Signed-off-by: Vedashree Vidwans --- drivers/firmware/smccc/lfa_fw.c | 299 ++++++++++++++++++++++++++++---- 1 file changed, 262 insertions(+), 37 deletions(-) diff --git a/drivers/firmware/smccc/lfa_fw.c b/drivers/firmware/smccc/lfa_f= w.c index 49f7feb6a211b..b36b8d7457c30 100644 --- a/drivers/firmware/smccc/lfa_fw.c +++ b/drivers/firmware/smccc/lfa_fw.c @@ -16,7 +16,15 @@ #include #include #include - +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "ARM_LFA" #define LFA_ERROR_STRING(name) \ [name] =3D #name #undef pr_fmt @@ -34,6 +42,18 @@ #define LFA_1_0_FN_ACTIVATE LFA_1_0_FN(5) #define LFA_1_0_FN_CANCEL LFA_1_0_FN(6) =20 +/* CALL_AGAIN flags (returned in res.a1[0]) */ +#define LFA_PRIME_CALL_AGAIN BIT(0) +#define LFA_ACTIVATE_CALL_AGAIN BIT(0) + +/* Prime loop limits, TODO: tune after testing */ +#define LFA_PRIME_BUDGET_US 30000000 /* 30s cap */ +#define LFA_PRIME_POLL_DELAY_US 10 /* 10us between polls */ + +/* Activation loop limits, TODO: tune after testing */ +#define LFA_ACTIVATE_BUDGET_US 20000000 /* 20s cap */ +#define LFA_ACTIVATE_POLL_DELAY_US 10 /* 10us between polls */ + /* LFA return values */ #define LFA_SUCCESS 0 #define LFA_NOT_SUPPORTED 1 @@ -114,8 +134,9 @@ static const struct fw_image_uuid { }; =20 static struct kobject *lfa_dir; +static DEFINE_MUTEX(lfa_lock); =20 -static int get_nr_lfa_components(void) +static unsigned long get_nr_lfa_components(void) { struct arm_smccc_1_2_regs args =3D { 0 }; struct arm_smccc_1_2_regs res =3D { 0 }; @@ -130,11 +151,40 @@ static int get_nr_lfa_components(void) return res.a1; } =20 +static int lfa_cancel(void *data) +{ + struct image_props *attrs =3D data; + struct arm_smccc_1_2_regs args =3D { 0 }; + struct arm_smccc_1_2_regs res =3D { 0 }; + + args.a0 =3D LFA_1_0_FN_CANCEL; + args.a1 =3D attrs->fw_seq_id; + arm_smccc_1_2_invoke(&args, &res); + + /* + * When firmware activation is called with "skip_cpu_rendezvous=3D1", + * LFA_CANCEL can fail with LFA_BUSY if the activation could not be + * cancelled. + */ + if (res.a0 =3D=3D LFA_SUCCESS) { + pr_info("Activation cancelled for image %s", + attrs->image_name); + } else { + pr_err("Firmware activation could not be cancelled: %ld", + (long)res.a0); + return -EIO; + } + + return res.a0; +} + static int call_lfa_activate(void *data) { struct image_props *attrs =3D data; struct arm_smccc_1_2_regs args =3D { 0 }; struct arm_smccc_1_2_regs res =3D { 0 }; + ktime_t end =3D ktime_add_us(ktime_get(), LFA_ACTIVATE_BUDGET_US); + int ret; =20 args.a0 =3D LFA_1_0_FN_ACTIVATE; args.a1 =3D attrs->fw_seq_id; /* fw_seq_id under consideration */ @@ -148,9 +198,32 @@ static int call_lfa_activate(void *data) */ args.a2 =3D !(attrs->cpu_rendezvous_forced || attrs->cpu_rendezvous); =20 - do { + for (;;) { + /* Touch watchdog, ACTIVATE shouldn't take longer than watchdog_thresh */ + touch_nmi_watchdog(); arm_smccc_1_2_invoke(&args, &res); - } while (res.a0 =3D=3D 0 && res.a1 =3D=3D 1); + + if ((long)res.a0 < 0) { + pr_err("ACTIVATE for image %s failed: %s", + attrs->image_name, lfa_error_strings[-res.a0]); + return res.a0; + } + if (!(res.a1 & LFA_ACTIVATE_CALL_AGAIN)) + break; /* ACTIVATE successful */ + + /* SMC returned with call_again flag set */ + if (ktime_before(ktime_get(), end)) { + udelay(LFA_ACTIVATE_POLL_DELAY_US); + continue; + } + + pr_err("ACTIVATE timed out for image %s", attrs->image_name); + ret =3D lfa_cancel(attrs); + if (ret =3D=3D 0) + return -ETIMEDOUT; + else + return ret; + } =20 return res.a0; } @@ -159,8 +232,24 @@ static int activate_fw_image(struct image_props *attrs) { struct arm_smccc_1_2_regs args =3D { 0 }; struct arm_smccc_1_2_regs res =3D { 0 }; + ktime_t end =3D ktime_add_us(ktime_get(), LFA_PRIME_BUDGET_US); int ret; =20 + if (attrs->may_reset_cpu) { + pr_err("Firmware component requires unsupported CPU reset"); + return -EINVAL; + } + + /* + * We want to force CPU rendezvous if either cpu_rendezvous or + * cpu_rendezvous_forced is set. The flag value is flipped as + * it is called skip_cpu_rendezvous in the spec. + */ + if (!(attrs->cpu_rendezvous_forced || attrs->cpu_rendezvous)) { + pr_warn("CPU rendezvous is expected to be selected."); + return -EAGAIN; + } + /* * LFA_PRIME/ACTIVATE will return 1 in res.a1 if the firmware * priming/activation is still in progress. In that case @@ -169,20 +258,36 @@ static int activate_fw_image(struct image_props *attr= s) */ args.a0 =3D LFA_1_0_FN_PRIME; args.a1 =3D attrs->fw_seq_id; /* fw_seq_id under consideration */ - do { + for (;;) { + /* Touch watchdog, PRIME shouldn't take longer than watchdog_thresh */ + touch_nmi_watchdog(); arm_smccc_1_2_invoke(&args, &res); - if (res.a0 !=3D LFA_SUCCESS) { - pr_err("LFA_PRIME failed: %s\n", - lfa_error_strings[-res.a0]); =20 + if ((long)res.a0 < 0) { + pr_err("LFA_PRIME for image %s failed: %s\n", + attrs->image_name, lfa_error_strings[-res.a0]); return res.a0; } - } while (res.a1 =3D=3D 1); + if (!(res.a1 & LFA_PRIME_CALL_AGAIN)) + break; /* PRIME successful */ =20 - if (attrs->cpu_rendezvous_forced || attrs->cpu_rendezvous) - ret =3D stop_machine(call_lfa_activate, attrs, cpu_online_mask); - else - ret =3D call_lfa_activate(attrs); + /* SMC returned with call_again flag set */ + if (ktime_before(ktime_get(), end)) { + udelay(LFA_PRIME_POLL_DELAY_US); + continue; + } + + pr_err("PRIME timed out for image %s", attrs->image_name); + ret =3D lfa_cancel(attrs); + if (ret =3D=3D 0) + return -ETIMEDOUT; + else + return ret; + } + + ret =3D stop_machine(call_lfa_activate, attrs, cpu_online_mask); + if (ret !=3D 0) + return lfa_cancel(attrs); =20 return ret; } @@ -286,23 +391,23 @@ static ssize_t activate_store(struct kobject *kobj, s= truct kobj_attribute *attr, image_attrs[LFA_ATTR_ACTIVATE]); int ret; =20 - if (attrs->may_reset_cpu) { - pr_err("Firmware component requires unsupported CPU reset\n"); - - return -EINVAL; + if (!mutex_trylock(&lfa_lock)) { + pr_err("Mutex locked, try again"); + return -EAGAIN; } =20 ret =3D activate_fw_image(attrs); if (ret) { pr_err("Firmware activation failed: %s\n", lfa_error_strings[-ret]); - + mutex_unlock(&lfa_lock); return -ECANCELED; } =20 pr_info("Firmware activation succeeded\n"); =20 /* TODO: refresh image flags here*/ + mutex_unlock(&lfa_lock); return count; } =20 @@ -311,26 +416,11 @@ static ssize_t cancel_store(struct kobject *kobj, str= uct kobj_attribute *attr, { struct image_props *attrs =3D container_of(attr, struct image_props, image_attrs[LFA_ATTR_CANCEL]); - struct arm_smccc_1_2_regs args =3D { 0 }; - struct arm_smccc_1_2_regs res =3D { 0 }; - - args.a0 =3D LFA_1_0_FN_CANCEL; - args.a1 =3D attrs->fw_seq_id; - arm_smccc_1_2_invoke(&args, &res); + int ret; =20 - /* - * When firmware activation is called with "skip_cpu_rendezvous=3D1", - * LFA_CANCEL can fail with LFA_BUSY if the activation could not be - * cancelled. - */ - if (res.a0 =3D=3D LFA_SUCCESS) { - pr_info("Activation cancelled for image %s\n", - attrs->image_name); - } else { - pr_err("Firmware activation could not be cancelled: %s\n", - lfa_error_strings[-res.a0]); - return -EINVAL; - } + ret =3D lfa_cancel(attrs); + if (ret !=3D 0) + return ret; =20 return count; } @@ -418,6 +508,11 @@ static int create_fw_images_tree(void) int ret, num_of_components; =20 num_of_components =3D get_nr_lfa_components(); + if (num_of_components <=3D 0) { + pr_err("Error getting number of LFA components"); + return -ENODEV; + } + args.a0 =3D LFA_1_0_FN_GET_INVENTORY; for (int i =3D 0; i < num_of_components; i++) { args.a1 =3D i; /* fw_seq_id under consideration */ @@ -437,6 +532,125 @@ static int create_fw_images_tree(void) return 0; } =20 +static int refresh_fw_images_tree(void) +{ + int ret; + /* + * Ideally, this function should invoke the GET_INVENTORY SMC + * for each firmware image and update the corresponding details + * in the firmware image tree node. + * There are several edge cases to consider: + * - The number of firmware components may change. + * - The mapping between firmware sequence IDs and + * firmware image UUIDs may be modified. + * As a result, it is possible that the firmware image tree nodes + * will require updates. Additionally, GET_INVENTORY SMC provides + * all current and revised information. Therefore, retaining the + * existing fw_images_tree data is not justified. Reconstructing + * the firmware images tree will simplify the code and keep data + * up-to-date. + */ + // Clean current inventory details + clean_fw_images_tree(); + + // Update new inventory details + ret =3D create_fw_images_tree(); + if (ret !=3D 0) + kobject_put(lfa_dir); + + return ret; +} + +static irqreturn_t lfa_irq_thread(int irq, void *data) +{ + struct image_props *attrs =3D NULL; + int ret; + + mutex_lock(&lfa_lock); + + // Update new inventory details + ret =3D refresh_fw_images_tree(); + if (ret !=3D 0) + goto exit_unlock; + + /* + * Execute PRIME and ACTIVATE for each FW component + * Start from first FW component + */ + list_for_each_entry(attrs, &lfa_fw_images, image_node) { + if ((!attrs->activation_capable) || (!attrs->activation_pending)) { + /* LFA not applicable for this FW component, continue to next component= */ + continue; + } + + ret =3D activate_fw_image(attrs); + if (ret) { + pr_err("Firmware %s activation failed: %s\n", + attrs->image_name, lfa_error_strings[-ret]); + goto exit_unlock; + } + + pr_info("Firmware %s activation succeeded", attrs->image_name); + } + + // Update new inventory details + ret =3D refresh_fw_images_tree(); + if (ret !=3D 0) + goto exit_unlock; + +exit_unlock: + mutex_unlock(&lfa_lock); + return IRQ_HANDLED; +} + +static int __init lfa_probe(struct platform_device *pdev) +{ + int err; + unsigned int irq; + + err =3D platform_get_irq_byname_optional(pdev, "fw-store-updated-interrup= t"); + if (err < 0) + err =3D platform_get_irq(pdev, 0); + if (err < 0) { + pr_err("Interrupt not found, functionality will be unavailable."); + + /* Bail out without failing the driver. */ + return 0; + } + irq =3D err; + + err =3D request_threaded_irq(irq, NULL, lfa_irq_thread, IRQF_ONESHOT, DRI= VER_NAME, NULL); + if (err !=3D 0) { + pr_err("Interrupt setup failed, functionality will be unavailable."); + + /* Bail out without failing the driver. */ + return 0; + } + + return 0; +} + +static const struct of_device_id lfa_of_ids[] =3D { + { .compatible =3D "arm,armhf000", }, + { }, +}; +MODULE_DEVICE_TABLE(of, lfa_of_ids); + +static const struct acpi_device_id lfa_acpi_ids[] =3D { + {"ARMHF000"}, + {}, +}; +MODULE_DEVICE_TABLE(acpi, lfa_acpi_ids); + +static struct platform_driver lfa_driver =3D { + .probe =3D lfa_probe, + .driver =3D { + .name =3D DRIVER_NAME, + .of_match_table =3D lfa_of_ids, + .acpi_match_table =3D ACPI_PTR(lfa_acpi_ids), + }, +}; + static int __init lfa_init(void) { struct arm_smccc_1_2_regs args =3D { 0 }; @@ -464,22 +678,33 @@ static int __init lfa_init(void) pr_info("Arm Live Firmware Activation (LFA): detected v%ld.%ld\n", res.a0 >> 16, res.a0 & 0xffff); =20 + err =3D platform_driver_register(&lfa_driver); + if (err < 0) + pr_err("Platform driver register failed"); + + lfa_dir =3D kobject_create_and_add("lfa", firmware_kobj); if (!lfa_dir) return -ENOMEM; =20 + mutex_lock(&lfa_lock); err =3D create_fw_images_tree(); if (err !=3D 0) kobject_put(lfa_dir); =20 + mutex_unlock(&lfa_lock); return err; } module_init(lfa_init); =20 static void __exit lfa_exit(void) { + mutex_lock(&lfa_lock); clean_fw_images_tree(); + mutex_unlock(&lfa_lock); + kobject_put(lfa_dir); + platform_driver_unregister(&lfa_driver); } module_exit(lfa_exit); =20 --=20 2.25.1 From nobody Fri Dec 19 08:56:24 2025 Received: from DM1PR04CU001.outbound.protection.outlook.com (mail-centralusazon11010050.outbound.protection.outlook.com [52.101.61.50]) (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 338002C0F96 for ; Wed, 8 Oct 2025 19:10:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.61.50 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759950609; cv=fail; b=C36/eebGg/eDv1yHQCIWzLXJ5jB6MRW7O9ULUuakXSO61Ozw9ns4WeNw025MuxB30ytkoTq6gMpWxRVVJq+7hgTxn81T4ffSKtkvW2nkSLprqrj28JaZeNEgqm99JsG9fSTK9goAerMYz9qSLNbym84K+NA69HrbTTGgt8g8U3I= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759950609; c=relaxed/simple; bh=J6ppa/VFKr4p6k8mhGLfOeD5Lh+oy80zjTK6orWBV4E=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=bxCDdnyA/LwlscmFFe6iG14yhGKszdxdFfoacahecIc42zlhk3/mjwDag01/wKWfPyMCgRpGcMNV3ouqS74HcAzbI6XV5HkWD9NxQnWYQK+iD84OTyBvjzI1rmiccN/9EtLEGopelpiU3pc4FI/IheLdSgJa7pm3YZwVkj9IBfM= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com; spf=fail smtp.mailfrom=nvidia.com; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b=Xy84jaOz; arc=fail smtp.client-ip=52.101.61.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=nvidia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b="Xy84jaOz" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=oAvMTj6ORZGkazNOgyTDK8IBgw9QSUupByvGAogESWzwdx2oCiOAjcP9kxqNlHXD4KX3ZIU/uOe7oxDNvuHp3gkBmzBFeGIsz9QZqDw1etFZhrWf64ahSugI01977P9/Gk1WlW/680TB1Emuz/0vT4b3jbSayZm8pB1pzaJ3JulzTYu+avhMY1il1qknEu1a1+fiZDPOiucTBM2Wt5Cya6fcq5xlBWibixka+cCX0JG6ovGbSO4vMSOynDMSrqLfBFHJpJIQSiEDH3vGJkMxwNoN4ZuPW1tIPKPKTAmqg5b+YDQP5Qjgazjv2URr7zIcan0vSzK+CD7r2OHrawx0UA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=hf+YYeTQWrcuuCIS+3A7q4yxtZaY1yZKvZdXSJmVK88=; b=ZtjKz/rEz/JYURnAG4kyf1mYpCe+0i03a0m6ZhNpz9ucGkpDyabHKfynNSeAUT7dRLg6mryy8TFcJ3f1+pZROKam38oLs3yyW9K0KZIWXx1cXUJTWGbzxV9vH6x7lFgVdiAQZggZ0Vuo8ARiSMIJCjILqysKIHQL0Set7AerNRF4yE9YP4u5FjjpPRFVxaSkXyNWadfGspH9816H4vvsG/XZJZa3qlBA9puq9AazeeJ3feJIiGqlCJJVNdh9HydJVnEGUHz9Q3bPmOcl5QAvpiffqNl/kwOU3tNXlG3rhFz3bB2DrK407gpjSgL0n8gP9n2Vszo3ZsyVj9rAq/xDHw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.118.232) smtp.rcpttodomain=arm.com smtp.mailfrom=nvidia.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=hf+YYeTQWrcuuCIS+3A7q4yxtZaY1yZKvZdXSJmVK88=; b=Xy84jaOzHWjVg3MNKgCFE8GwR9/oLyrUepUc1o7oyj4pK2ed2UGztoBhyL5VAYoa8sOUqdHoILZSwCSYxRvfyWzcnUbdlxxdzJM5NDg1UaJ4RppIBzX2Qxj5G8/E5hG5eLbkTEkbNxRlZSIbkwXEHFbpEfzQdSt0I9/HTFlhbBu08YUsSZ/tWD20X7a/02EHy1N4Rz2Wvm3L1XdCnWfFi8DTc9kMsscQqV9r/FOjSOv7FR9lAvcR8S8HjR9WW4VDGTg33c2Cak0FbrLx13m7dMiBvxorCp7gAUp49s8b2geoRC8RWM2Ljbmx9udZAI2qiiUfoD984wksUylOa4LcJA== Received: from BN1PR14CA0013.namprd14.prod.outlook.com (2603:10b6:408:e3::18) by SA1PR12MB5640.namprd12.prod.outlook.com (2603:10b6:806:23e::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9203.9; Wed, 8 Oct 2025 19:09:58 +0000 Received: from BL02EPF0001A0FE.namprd03.prod.outlook.com (2603:10b6:408:e3:cafe::8c) by BN1PR14CA0013.outlook.office365.com (2603:10b6:408:e3::18) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9182.20 via Frontend Transport; Wed, 8 Oct 2025 19:09:58 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.118.232) smtp.mailfrom=nvidia.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.118.232 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.118.232; helo=mail.nvidia.com; pr=C Received: from mail.nvidia.com (216.228.118.232) by BL02EPF0001A0FE.mail.protection.outlook.com (10.167.242.105) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9203.9 via Frontend Transport; Wed, 8 Oct 2025 19:09:58 +0000 Received: from drhqmail201.nvidia.com (10.126.190.180) by mail.nvidia.com (10.127.129.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.14; Wed, 8 Oct 2025 12:09:42 -0700 Received: from drhqmail203.nvidia.com (10.126.190.182) by drhqmail201.nvidia.com (10.126.190.180) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.20; Wed, 8 Oct 2025 12:09:42 -0700 Received: from build-vvidwans-focal-20250627.internal (10.127.8.10) by mail.nvidia.com (10.126.190.182) with Microsoft SMTP Server id 15.2.2562.20 via Frontend Transport; Wed, 8 Oct 2025 12:09:42 -0700 From: Vedashree Vidwans To: , , , , CC: , , , , , , , , Vedashree Vidwans Subject: [RFC PATCH 3/3] firmware: smccc: LFA: modify activation approach Date: Wed, 8 Oct 2025 19:09:07 +0000 Message-ID: <20251008190907.181412-4-vvidwans@nvidia.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20251008190907.181412-1-vvidwans@nvidia.com> References: <20251008190907.181412-1-vvidwans@nvidia.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-NV-OnPremToCloud: ExternallySecured X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BL02EPF0001A0FE:EE_|SA1PR12MB5640:EE_ X-MS-Office365-Filtering-Correlation-Id: ae2d9bda-9bf8-40bd-b97e-08de069e4603 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|7416014|1800799024|376014|82310400026|36860700013; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?feks78hQxOLJFxzPx07hjww9a6xWEEIRC9UzdmwRujUJ9+088E1m4CMkocwN?= =?us-ascii?Q?r+Nd+XUoI7hR+d45FNryut0VXaJPRs/vJGlzqpSbrE80kx/TL3sQ3Irj1ixf?= =?us-ascii?Q?i8VJA7ctrqAhqxVEMfqgXVsLwc2EtUG1uFUXCzW9Sk9d5PdSoO9TbwcESMO4?= =?us-ascii?Q?/bY2QihVIkflxuriuFqNzAYOknFqOtG5VylttqVkGkMSC4S0O+Tyvc+l+Wad?= =?us-ascii?Q?Qw4RiqI9AA0WfZfa/2TZ5TkzSnY+6QNq/h3ZSIbJ92rXw1FLaBYxhXmk2tp4?= =?us-ascii?Q?n8oqtlh+9wsC70xFHD01cWzryp6c1KP4kg6Pufimb14QjVeMsKSh7MoU5j/g?= =?us-ascii?Q?cvnqMJsFlANns6VYTkEzaeCOQPeusDTmegZeXmvRH6/4gbQCYuEr+rZquwMC?= =?us-ascii?Q?rpjSpBjvDcxjp369acby+ThqM3Zk+PosUy0kK0++cwzV66eJYTQAzaJC1yQb?= =?us-ascii?Q?Ul59c8ZC2Nmyx/MTCft1rC6tkL/QcVjRtqiA2A30lWpClg1UHMuTb3DSQ852?= =?us-ascii?Q?Sxf0DYpqn0Ok5WyYy7DHWpcZGuHfNyiN0iTARo8TmHq6OL3shxW9kxsGkhh3?= =?us-ascii?Q?J7UcVRX4sfl/q5LI0oaFnyCkk7tJPH9lxZuTO6xHnVCdu17bJmlhiYTw+Fg6?= =?us-ascii?Q?3itf0Mj/LbFTpQF/4L9dfhqZzdomRpMMsmOL1fwOkTfpEh90Pv1JyH6pz0oO?= =?us-ascii?Q?fNEVQnJOoF+Du26PgdIz5uhsvh6lNPNPgb9RJkePm6u76Z7R/J6CQJDptUwx?= =?us-ascii?Q?uZa4CNbeJcbal7GG2S5YRJJTvmcvh0FWVt/BcsUo53/1uZILfxr99r4Rqss9?= =?us-ascii?Q?r3iG8g6sG04LYw1iEyXfZktxPEezLg8pK1J3gRm586owndLnecDJtdR6Lk87?= =?us-ascii?Q?GKi2hRWxbdImLJ8/qva2qdcC6u02VrSraekYu+yFzP/Gv2hcXd1tgxQzy/X/?= =?us-ascii?Q?xr6zUWocH3sLG21orgkhR15OdvH4aOKDDHWqTDk2E2OYSW0I7VK+soa7U+Zk?= =?us-ascii?Q?9iBkzWlKkxQeBvoINHlMZ0kCDYmsMYyiO2Rg18yQ+Y5OXLLbae40XZEfEoPb?= =?us-ascii?Q?jnXw2A18eCrmDr6sWjxcWrqkfKq2qXHX3gnDdHckiJMHn5UN/XbmrhJRt3rT?= =?us-ascii?Q?+zcae5KtyxQ7CCbei2a/IDtmbqDnfbKjTtAZnB9WBNv54mcYV2tSqsMlgOpP?= =?us-ascii?Q?MWRhtwgyqyBRnF+93bzt1JhY5L+Cs+x41SpFdXzDj4aXfOhmUq1wBWcYngbv?= =?us-ascii?Q?xa0w9YeE+f/t4Gx9L2jiZthKFm73c80p+TdFAaJUY7FYwoKi9kQQQLHh6i1o?= =?us-ascii?Q?2Szm9XkXF1c3sEfOnHFzgunF7YzDF5h5nYUi0M+0XwYPxs6/guNTOR6LAJMK?= =?us-ascii?Q?9WxEDNuCqyjnQ5vQScaRg3Pw8WT1MEeDT8+Vorvq4sDMgzRliQyjrGotO6aA?= =?us-ascii?Q?BLN2CFiSJyWAtoopmjR5GvfJLQJF/pMGGJG5tz+gpmXO/MKujgIUvB0TDWAy?= =?us-ascii?Q?1kd/CHLhA+rhqZmqMfdiWnGtMg/kR3lciE0ZMG1UYpuM9yrToEv0sN/aWbmQ?= =?us-ascii?Q?BM9NadzmYRvEMjKcF3Y=3D?= X-Forefront-Antispam-Report: CIP:216.228.118.232;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mail.nvidia.com;PTR:dc7edge1.nvidia.com;CAT:NONE;SFS:(13230040)(7416014)(1800799024)(376014)(82310400026)(36860700013);DIR:OUT;SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 Oct 2025 19:09:58.0700 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: ae2d9bda-9bf8-40bd-b97e-08de069e4603 X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a;Ip=[216.228.118.232];Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: BL02EPF0001A0FE.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA1PR12MB5640 Content-Type: text/plain; charset="utf-8" Currently, on a LFA IRQ, all activable firmware components are primed activated sequentially. Modify the approach to prime all firmware components followed by activation of all components sequentially. This approach will minimize the time where old and new firmware component images co-exist. Signed-off-by: Vedashree Vidwans --- drivers/firmware/smccc/lfa_fw.c | 74 +++++++++++++++++++++++++++++---- 1 file changed, 66 insertions(+), 8 deletions(-) diff --git a/drivers/firmware/smccc/lfa_fw.c b/drivers/firmware/smccc/lfa_f= w.c index b36b8d7457c30..dead2282cd04b 100644 --- a/drivers/firmware/smccc/lfa_fw.c +++ b/drivers/firmware/smccc/lfa_fw.c @@ -46,6 +46,10 @@ #define LFA_PRIME_CALL_AGAIN BIT(0) #define LFA_ACTIVATE_CALL_AGAIN BIT(0) =20 +/* PRIME COMPLETE status */ +#define LFA_PRIME_COMPLETE_FALSE false +#define LFA_PRIME_COMPLETE_TRUE true + /* Prime loop limits, TODO: tune after testing */ #define LFA_PRIME_BUDGET_US 30000000 /* 30s cap */ #define LFA_PRIME_POLL_DELAY_US 10 /* 10us between polls */ @@ -104,6 +108,7 @@ struct image_props { bool may_reset_cpu; bool cpu_rendezvous; bool cpu_rendezvous_forced; + bool prime_complete; struct kobject *image_dir; struct kobj_attribute image_attrs[LFA_ATTR_NR_IMAGES]; }; @@ -229,6 +234,27 @@ static int call_lfa_activate(void *data) } =20 static int activate_fw_image(struct image_props *attrs) +{ + int ret; + + /* + * We want to force CPU rendezvous if either cpu_rendezvous or + * cpu_rendezvous_forced is set. The flag value is flipped as + * it is called skip_cpu_rendezvous in the spec. + */ + if (!(attrs->cpu_rendezvous_forced || attrs->cpu_rendezvous)) { + pr_warn("CPU rendezvous is expected to be selected."); + return -EAGAIN; + } + + ret =3D stop_machine(call_lfa_activate, attrs, cpu_online_mask); + if (ret !=3D 0) + return lfa_cancel(attrs); + + return ret; +} + +static int prime_fw_image(struct image_props *attrs) { struct arm_smccc_1_2_regs args =3D { 0 }; struct arm_smccc_1_2_regs res =3D { 0 }; @@ -285,10 +311,6 @@ static int activate_fw_image(struct image_props *attrs) return ret; } =20 - ret =3D stop_machine(call_lfa_activate, attrs, cpu_online_mask); - if (ret !=3D 0) - return lfa_cancel(attrs); - return ret; } =20 @@ -396,6 +418,17 @@ static ssize_t activate_store(struct kobject *kobj, st= ruct kobj_attribute *attr, return -EAGAIN; } =20 + ret =3D prime_fw_image(attrs); + if (ret) { + pr_err("Firmware prime failed: %s\n", + lfa_error_strings[-ret]); + mutex_unlock(&lfa_lock); + return -ECANCELED; + } + + /* Update prime complete status */ + attrs->prime_complete =3D LFA_PRIME_COMPLETE_TRUE; + ret =3D activate_fw_image(attrs); if (ret) { pr_err("Firmware activation failed: %s\n", @@ -469,6 +502,8 @@ static int create_fw_inventory(char *fw_uuid, int seq_i= d, u32 image_flags) INIT_LIST_HEAD(&attrs->image_node); attrs->image_name =3D image_name; attrs->cpu_rendezvous_forced =3D 1; + /* Reset prime complete status */ + attrs->prime_complete =3D LFA_PRIME_COMPLETE_FALSE; set_image_flags(attrs, seq_id, image_flags); =20 /* @@ -573,16 +608,39 @@ static irqreturn_t lfa_irq_thread(int irq, void *data) if (ret !=3D 0) goto exit_unlock; =20 - /* - * Execute PRIME and ACTIVATE for each FW component - * Start from first FW component - */ + /* Execute PRIME for all FW components */ list_for_each_entry(attrs, &lfa_fw_images, image_node) { if ((!attrs->activation_capable) || (!attrs->activation_pending)) { /* LFA not applicable for this FW component, continue to next component= */ continue; } =20 + ret =3D prime_fw_image(attrs); + if (ret) { + pr_err("Firmware %s prime failed: %s\n", + attrs->image_name, lfa_error_strings[-ret]); + goto exit_unlock; + } + + /* Update prime complete status */ + attrs->prime_complete =3D LFA_PRIME_COMPLETE_TRUE; + } + + /* Execute ACTIVATE for all FW components */ + list_for_each_entry(attrs, &lfa_fw_images, image_node) { + if ((!attrs->activation_capable) || (!attrs->activation_pending)) { + /* LFA not applicable for this FW component, continue to next component= */ + continue; + } + + if (!attrs->prime_complete) { + /* + * ACTIVATE not applicable for this FW component, + * continue to next component + */ + continue; + } + ret =3D activate_fw_image(attrs); if (ret) { pr_err("Firmware %s activation failed: %s\n", --=20 2.25.1