From nobody Fri Sep 25 05:29:21 2026 Received: from CH4PR04CU002.outbound.protection.outlook.com (mail-northcentralusazon11013070.outbound.protection.outlook.com [40.107.201.70]) (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 904614FECC1; Wed, 16 Sep 2026 10:39:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.201.70 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789555165; cv=fail; b=eCj9Y2KhfhrejdraOGRpZEdZECIhqaDyBUXR9YsLiu7yG5qV/E9+EIRqEdtE3CdWoh/PsQB/mQHMrHyE/ZzHCHZE6zoGqrX27OvGlq9nS8anuDPMXfhTBih02qvQ8JnnDbTGQbDGlli+o9h1ELza41eUVmRDXehGK4adv6pF+4c= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789555165; c=relaxed/simple; bh=nYz8R7vXFLhK3Wh1A8vGvJDs2yiL9SC2pfoQoN8+Apk=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=i6tTajqYYHo7kFU3/D5Pm3AuQlwf8cpKT37mi/PTGG7W8TLYeZuCZ+nkciJa/LNHBqiUWhUed07MFwYLRghQPEvctqMbiWdgzi9qtTaGCL8g/RUU/RRs5WBGAoMnd4br0lvTgyEUM90xmd7LyuGnPiso4HHhMHrUYhuybYsFbYg= 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=VPWFVy2y; arc=fail smtp.client-ip=40.107.201.70 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="VPWFVy2y" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=sCYBGccUs9O9KBa0cuvN7fMyZ+vfFX+yAYQH4c7ZTgvJl9fa2ZF+wuPWCHct52ER9d/49GJCyjw9WZKp0iTyOmcPon3UylXJxXny9Mz8XgkU/xS3StWx57f7BqL62AhnEVkQEa1aHBBDFzoxWJvNtBfGSViTOpiA+HtL0gLxiKI5Bw2/pC8ZL5himwWhk4vy9u5XEIQZPWfZI847U3jJMBiQTOmcL2sVaPhoUnA7ZoIHX+me9lKR1bO4mXI7focIeqfStnh69YhhjAgl/mNk3VScnNMqgjbAdZk33YTb1OPVzgdrVOLceY9D4RIDgYWNerj5QWImcXcWl3ip1b80/w== 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=VB9X7TuPdcla+XhemCJdJPG4Vxnl1kOuRCW4uXtaiU0=; b=oSVDzxCHB5xzzu3HbgvpXYR0PVh6nJFossUgaj4Ie0jptkTb8kTNy9Jj2RwIQpd1Ovc/HiI8sRV96tJ8d1kWH0BI9r+FlxNDOqJuLx8LDvQDixXuMz6+GpbgcXv7AOS/a+Iv6VgHamEs9hZ2IRcP2NKNiImFKuT8TB8Z/qA89vDbEeUNIl/C55v1+bBNOsKQZ2l+Bjy8B5d+Uj97dSRXT278vALvocT8kb1IQfFSvqUjPuEVcngji637mI1RsgkV31g16VJR9Q1jX0G6Rekn+v80DdoFGSy3n7vqMKl2rNI1d1CxlDHYG7KyABQTd3fEDCLtwgdGRMeWEwJ3dzExSQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.117.160) smtp.rcpttodomain=kernel.org 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=VB9X7TuPdcla+XhemCJdJPG4Vxnl1kOuRCW4uXtaiU0=; b=VPWFVy2yeMeqfpyNCM3vGGjaC3dIztUJg/redYyQT2s+fzFQOmEXFLo5j7SXPuoY6S6E5mw2qzzAgZnO0uOQ0jtIa0pbY88uEwL/MwrTnwqxOEOAY7Yvh/gizTk4tt5sfAFuG6bIt33iq24tARMLjwACOO4u41YuQMNQMUgkohTU1P5bqi3oPsEL3UvPCaa+9kAafaC6mIbdDbTMsEgm3sw8APImjuRDSQIh2tDkgoDhJphhUdmTUrQ9p95xmjbYi6GM2tuTiBN7YQv3xPTiuqA0bmMM4+1D5sKdxef2EcX8KOnIIexVnNm6y6gmY1pVwi34QivYwHHlaO29bynJEg== Received: from SJ2PR07CA0005.namprd07.prod.outlook.com (2603:10b6:a03:505::29) by DS7PR12MB6286.namprd12.prod.outlook.com (2603:10b6:8:95::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.428.9; Wed, 16 Sep 2026 10:39:06 +0000 Received: from BY1PEPF00026966.namprd05.prod.outlook.com (2603:10b6:a03:505:cafe::6f) by SJ2PR07CA0005.outlook.office365.com (2603:10b6:a03:505::29) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.406.12 via Frontend Transport; Wed, 16 Sep 2026 10:39:03 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.117.160) 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.117.160 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.117.160; helo=mail.nvidia.com; pr=C Received: from mail.nvidia.com (216.228.117.160) by BY1PEPF00026966.mail.protection.outlook.com (10.167.244.150) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.428.7 via Frontend Transport; Wed, 16 Sep 2026 10:39:03 +0000 Received: from rnnvmail203.nvidia.com (10.129.68.9) by mail.nvidia.com (10.129.200.66) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.49; Wed, 16 Sep 2026 03:38:41 -0700 Received: from rnnvmail204.nvidia.com (10.129.68.6) by rnnvmail203.nvidia.com (10.129.68.9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.49; Wed, 16 Sep 2026 03:38:40 -0700 Received: from sumitg-l4t.nvidia.com (10.127.8.14) by mail.nvidia.com (10.129.68.6) with Microsoft SMTP Server id 15.2.2562.46 via Frontend Transport; Wed, 16 Sep 2026 03:38:33 -0700 From: Sumit Gupta To: , , , , , , , , , , , , , , , , CC: , , , , , , , Subject: [PATCH v5 1/4] cpufreq: CPPC: Keep the policy across CPU hotplug Date: Wed, 16 Sep 2026 16:08:17 +0530 Message-ID: <20260916103820.1760297-2-sumitg@nvidia.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260916103820.1760297-1-sumitg@nvidia.com> References: <20260916103820.1760297-1-sumitg@nvidia.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-NVConfidentiality: public Content-Transfer-Encoding: quoted-printable X-NV-OnPremToCloud: ExternallySecured X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BY1PEPF00026966:EE_|DS7PR12MB6286:EE_ X-MS-Office365-Filtering-Correlation-Id: 6138d4c7-3c30-44c6-fe0b-08df13deb9f3 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|23010399003|36860700016|376014|7416014|82310400026|1800799024|921020|10067099003|56012099006|11063799006|22082099003|18002099003; X-Microsoft-Antispam-Message-Info: njf+LMBPPGBRGcHSPvkhXwxeD7Nq9OmmgXT7YwCkDumrE8VkDPaPFRW8PQRfV+QDAV1Aw/5879d2DSVVp48Oyngzi/GnmQtGP5BWZEKbySAG+S08OW49dCtIxQV5djd3Go4vYvJjS6dmht5i7q74mt/jX2LVrBXac31sXf9VrRwgGYbMuC2gcHoGUdcTEyewUcAimBun1VqpQBfdod5dP4AsVRn6xMHg3kssGo8WL88WR90G3v5nqYuaqZZlNQ1AhguqBoTeMO2h3KdGGIpYMFqwr9et4LDS8TmJxJsrGAQQ6yFP+thA8El3cR3fLFYZmcya2McrhH5fGVz+kXOVQ1BN1+xWhqxZ9wPXBc+bERQHgeMIBskfcoSvQnShBt20w2uoPfeuV297HOgJJenKVEZNiwM7fPfngUFCHnvZFzQ9bXUNBCiizRrVIg48lXy0bPBPMtP/eqZNPbfUXGiR6IewaWj2IULYhZLni7VtErcnyBsizcIp0UY5hPzAQF2YSHSkJ1anc71Dyu5u9AU6AUpWIzIrx/JM6ENm8Y0flr2uhr9PLJn0iifhyrvVqLzwMBi+tNLzbf4BQU1vKw4GfuR3bavupxuPhBhfwJc7dGqHPSjXfiF1t1MRLzlsBtwU4Tmz5/E9inKiCh6x30/Qg4LyWG+9vYk6xyRLHFXPv9YrczXkmtFuURauDXWTKNxonAJBeYLblGVb8w2f4QH424Uni9ZOlcPUtYHdspg2edKB2BSadxpBlf1B6tSlbh5z X-Forefront-Antispam-Report: CIP:216.228.117.160;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mail.nvidia.com;PTR:dc6edge1.nvidia.com;CAT:NONE;SFS:(13230040)(23010399003)(36860700016)(376014)(7416014)(82310400026)(1800799024)(921020)(10067099003)(56012099006)(11063799006)(22082099003)(18002099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: FlEjx1boELIXzzfctl+tDeIu8ovmwB1+HefQsdIjXrwF1/ch/9IQ8RFaVBl4B8ZhxUSAnLuGSw7Da2YWz4QfT6HOmiFYB81Wis5Ie5mzhdMpE9l0T+6PU0oM7cpP0HjABfe9ICsYmTFVrxUGo/zPuyZ93CL4f/NU5ZulUsxZ3UhQpqwS+cAUUTgJPPVZXzk52zBBY8nIZRNqngOnvKBIJvExNwpT9Coyxe6t1josAPoyGUQaN6qJI0eOSgW07bAgwYQxHELqLXg2iTRZfGAmVi0F3NL3uADkUvliRpraIG2dK8soSJWOWyP2iAK+0ubXNgj6zHbB57th7ZMPiG68caqGRJSDUXnuNhlSRSkh/6LBTlDRrSA1JPdMQW1agkr9aFuR0n7oQFNwuK5swiThkrEFqaIkkePuoNgoWvPWWJ1zUSV8yQgRWORxaGvegXW+ X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Sep 2026 10:39:03.3014 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 6138d4c7-3c30-44c6-fe0b-08df13deb9f3 X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a;Ip=[216.228.117.160];Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: BY1PEPF00026966.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS7PR12MB6286 Content-Type: text/plain; charset="utf-8" Without online()/offline() callbacks, the cpufreq core calls exit() when a policy's last online CPU goes down. That drops the driver's per-policy data, which init() rebuilds when a CPU comes back. Add lightweight online()/offline() callbacks so the core instead keeps the policy live and reuses the driver's cpu_data across CPU hotplug. init() then runs once instead of on every hotplug, making CPU hotplug faster. The driver can now save what the OS set in offline() and put it back in online(). A later patch in this series uses this to preserve the OSPM-set registers. Move what init() and exit() did on hotplug into the new callbacks: - offline() requests the lowest desired performance and stops the frequency invariance updates, as exit() did. - online() re-enables CPPC and restores the performance controls, as the platform may have reset them. Failures are logged, not returned, as the core would free the policy. It also restarts the frequency invariance updates with a new counter snapshot, as init() did, so that no sample spans the offline window. The restore in online() uses cppc_set_perf(), which writes MIN before MAX. Each write takes effect on its own unless the registers are accessed through PCC. If the saved MIN is above the MAX the platform currently has, restoring it would leave MIN above MAX until the MAX write lands, so raise MAX first. Signed-off-by: Sumit Gupta Tested-by: K Prateek Nayak --- drivers/cpufreq/cppc_cpufreq.c | 130 ++++++++++++++++++++++++++++++++- 1 file changed, 126 insertions(+), 4 deletions(-) diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index f767898ebfb5..37ead7f6c179 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c @@ -184,12 +184,10 @@ static void cppc_cpufreq_cpu_fie_init(struct cpufreq_= policy *policy) } =20 /* - * We free all the resources on policy's removal and not on CPU removal as= the + * We free the resources for the whole policy and not per CPU as the * irq-work are per-cpu and the hotplug core takes care of flushing the pe= nding * irq-works (hint: smpcfd_dying_cpu()) on CPU hotplug. Even if the kthrea= d-work * fires on another CPU after the concerned CPU is removed, it won't harm. - * - * We just need to make sure to remove them all on policy->exit(). */ static void cppc_cpufreq_cpu_fie_exit(struct cpufreq_policy *policy) { @@ -199,7 +197,7 @@ static void cppc_cpufreq_cpu_fie_exit(struct cpufreq_po= licy *policy) if (fie_disabled) return; =20 - /* policy->cpus will be empty here, use related_cpus instead */ + /* policy->cpus excludes the offline CPUs, use related_cpus */ topology_clear_scale_freq_source(SCALE_FREQ_SOURCE_CPPC, policy->related_= cpus); =20 for_each_cpu(cpu, policy->related_cpus) { @@ -754,6 +752,128 @@ static void cppc_cpufreq_cpu_exit(struct cpufreq_poli= cy *policy) cppc_cpufreq_put_cpu_data(policy); } =20 +/* + * Prepare the restore in online() so that the platform never sees MIN abo= ve + * MAX. + * + * cppc_set_perf() writes MIN before MAX, and each write takes effect on i= ts + * own unless the registers are accessed through PCC, which delivers them = in + * one transaction. If the MIN being restored is above the MAX currently + * programmed, the CPU sits with MIN above MAX until the MAX write lands, = so + * raise MAX first. Restoring a lower MAX needs no preparation. Both values + * come from the policy limits, which keep MIN below MAX, so the MIN writt= en + * first is never above the MAX that follows it. + */ +static int +cppc_cpufreq_prepare_perf_restore(unsigned int cpu, + const struct cppc_perf_ctrls *target) +{ + struct cppc_perf_ctrls cur =3D {}, prep =3D {}; + int ret; + + ret =3D cppc_get_perf(cpu, &cur); + if (ret) + return ret; + + if (!cur.max_perf || target->min_perf <=3D cur.max_perf) + return 0; + + prep.desired_perf =3D target->desired_perf; + prep.min_perf =3D 0; /* Zero leaves MIN unchanged. */ + prep.max_perf =3D target->max_perf; + + return cppc_set_perf(cpu, &prep); +} + +/* + * Run when the policy's first CPU comes back online, the counterpart of + * offline(). + * + * The platform may have disabled CPPC and reset the performance controls + * (desired, min and max performance) while the CPU was offline, so re-ena= ble + * CPPC and reprogram them. + * + * Report failures without returning them, or the core would free the poli= cy and + * leave the CPU without cpufreq. A failed write to the performance contro= ls is + * not fatal, as the governor's next request programs them again. A failed= CPPC + * enable stops the restore, as the writes that follow may not reach the + * platform. + */ +static int cppc_cpufreq_cpu_online(struct cpufreq_policy *policy) +{ + struct cppc_cpudata *cpu_data =3D policy->driver_data; + unsigned int cpu =3D policy->cpu; + int ret; + + ret =3D cppc_set_enable(cpu, true); + if (ret && ret !=3D -EOPNOTSUPP) { + pr_warn("Failed to re-enable CPPC for CPU%u (%d)\n", cpu, ret); + goto out_fie; + } + + /* + * Recompute min/max from the policy, clamp desired_perf into range, and + * reprogram the performance controls. + */ + cppc_cpufreq_update_perf_limits(cpu_data, policy); + + cpu_data->perf_ctrls.desired_perf =3D + clamp_t(u32, cpu_data->perf_ctrls.desired_perf, + cpu_data->perf_ctrls.min_perf, + cpu_data->perf_ctrls.max_perf); + + ret =3D cppc_cpufreq_prepare_perf_restore(cpu, &cpu_data->perf_ctrls); + if (ret) + pr_debug("Failed to prepare perf restore on CPU%u (%d)\n", + cpu, ret); + + ret =3D cppc_set_perf(cpu, &cpu_data->perf_ctrls); + if (ret) + pr_debug("Failed to restore perf controls on CPU%u (%d)\n", + cpu, ret); + +out_fie: + /* Restart what offline() stopped, with a new counter snapshot. */ + cppc_cpufreq_cpu_fie_init(policy); + + return 0; +} + +/* + * Run when the policy's last online CPU goes down, undoing what online() = did. + * Defining offline() is what makes the core keep the policy alive instead= of + * tearing it down. + */ +static int cppc_cpufreq_cpu_offline(struct cpufreq_policy *policy) +{ + struct cppc_cpudata *cpu_data =3D policy->driver_data; + struct cppc_perf_ctrls perf_ctrls =3D cpu_data->perf_ctrls; + unsigned int cpu =3D policy->cpu; + int ret; + + /* + * Stop the frequency invariance updates and cancel the pending work, so + * that no sample spans the offline window. online() restarts them with + * a new counter snapshot. + */ + cppc_cpufreq_cpu_fie_exit(policy); + + /* + * Request the lowest desired performance while the policy has no online + * CPU. Zeroing MIN and MAX makes cppc_set_perf() leave them unchanged. + */ + perf_ctrls.desired_perf =3D cpu_data->perf_caps.lowest_perf; + perf_ctrls.min_perf =3D 0; + perf_ctrls.max_perf =3D 0; + + ret =3D cppc_set_perf(cpu, &perf_ctrls); + if (ret) + pr_debug("Err setting perf value:%u on CPU:%u. ret:%d\n", + cpu_data->perf_caps.lowest_perf, cpu, ret); + + return 0; +} + static inline u64 get_delta(u64 t1, u64 t0) { if (t1 > t0 || t0 > ~(u32)0) @@ -1047,6 +1167,8 @@ static struct cpufreq_driver cppc_cpufreq_driver =3D { .fast_switch =3D cppc_cpufreq_fast_switch, .init =3D cppc_cpufreq_cpu_init, .exit =3D cppc_cpufreq_cpu_exit, + .online =3D cppc_cpufreq_cpu_online, + .offline =3D cppc_cpufreq_cpu_offline, .set_boost =3D cppc_cpufreq_set_boost, .attr =3D cppc_cpufreq_attr, .name =3D "cppc_cpufreq", --=20 2.34.1 From nobody Fri Sep 25 05:29:21 2026 Received: from CO1PR03CU002.outbound.protection.outlook.com (mail-westus2azon11010012.outbound.protection.outlook.com [52.101.46.12]) (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 40E10501F39; Wed, 16 Sep 2026 10:39:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.46.12 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789555169; cv=fail; b=Nv/Yn9SVKXqNrs65wogpiQnHnNm4hB4ebSuGe1uztKyBrLNGsK2yOPbifMSfim2ULMuVCOb1JqnbFA65LrAbpGLrMgRzLo11qR2Qcknvks7SOyStkq7VkgyE0Kwfu0sSBhXVsv4EPOn/oFM1x4BfbbOMee9I19Ab00ACBYDSZnc= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789555169; c=relaxed/simple; bh=b4Iyz6TcpExBktTMo7utxus7AY610Wq4N2USllXC1mA=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=YusJL39tod/j8YbMBvGLrsmXwfIgNPFYrk8FCEepor1sGMGtkfRWvasHctOji7STq6TmZaTbEwmyIHaHmSOCu/VLXhykJeQMGAtTPtTqpSDcXYvLK8LuV7mLp/o9gR/4USXBARzngCSaEus+sDVoj7c0/9yqgqW/m093Qdd74DQ= 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=REPsg6kj; arc=fail smtp.client-ip=52.101.46.12 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="REPsg6kj" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=mQBcDwthThPuP3i+32j8ay/VuHj3gSTe0DwOON6BOa04ifxh2KiNJtCFcFYQjlMzmKIxgmOki01C2oHUoLbVZv+21Tb+ACEuvkYy4YEYMA4Z3m5P61F7UhZP0umPLC5XYoR4fs4r5VLHe2Tq2anAGkJjH2ZuA+KCPL7GVn3tOPqiZ3V8rLm45/IKIunz2fvD9pSu7jA7gcYqnOcuSfXH8UlGEYPWrUBdcQWTH+MJ6s/r74ylj/owtOJZv7IwWjCWbcHzJSaqrq6UGh4+lQtbHjW66F3dLB/dOkcIGcuHnMpwDbN3xbtVvs6bFSZlO5hx7/epwbIH/0F2jcxv7Ea2cg== 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=qSjJorp+NJxn+KUpZW10oyvcxrOcq69++07oUBicI+8=; b=kv9GpuPBBqe1SHDh8Rn0OcL+70OkB43mSnjQa77jO5zPSppCBj+DLxK+y977w4hyGAtvHCF0KAyy3maIK/rgHvjp0k3O17EoFqhApHb8ACZ+4q6sEzDPFv+TH8TtNlacGDDcmw7zlv46LaOlHr7SDNWfX93TJgBZkXbNUk5vFi+epDxhzYeIduUhEnAY8q2qfW2N+65XLrU8OzK3h1VFVqPbUMTfJJS4LoDBKVw78In/xfdcvH/oR/mHg+E8MZXIBVZvX1HapaAiB1w5h3dwU8SMk6GzYw6q+gHdzYT8Me16Au8hP4ve7Y/ljvjWF7ck4vN+pa4iuuswm01AfrKheQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.117.161) smtp.rcpttodomain=kernel.org 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=qSjJorp+NJxn+KUpZW10oyvcxrOcq69++07oUBicI+8=; b=REPsg6kjGFdZGZD9CoZeK24gn7IDqODsr0aDkLC/bOvCzA+5vQ76EWWjlCyMpLoC5wQiX0JXdJ1EJg7ADhR8dEzsIQkzSVIFj/guvSTdwe/u9s0mcJIzB5hwnwEgLwtkmvrPwRwFI+Lf6vtwEgcKSpG7qNqYFJBK13yWiKgarPoD9CSQUauUdlQ7O6UnSkZVLJh9H/cjVDrEhBC3cBf7MIuyZMQtELgPybsKAw1ECpYMoWLcN8TYwND7VQR1U1xTMZpzvcmt2U83iDfJ7DiX7uLbSbQDCkfc9kcDbHi0I4R+ydp8z3dUH+cNm+h7vkCvHx2A6cupbNiqtdAQGZ8dsQ== Received: from BY3PR05CA0037.namprd05.prod.outlook.com (2603:10b6:a03:39b::12) by PH8PR12MB8607.namprd12.prod.outlook.com (2603:10b6:510:1cf::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.428.11; Wed, 16 Sep 2026 10:39:07 +0000 Received: from SJ1PEPF000026C8.namprd04.prod.outlook.com (2603:10b6:a03:39b:cafe::a8) by BY3PR05CA0037.outlook.office365.com (2603:10b6:a03:39b::12) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.451.7 via Frontend Transport; Wed, 16 Sep 2026 10:39:07 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.117.161) 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.117.161 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.117.161; helo=mail.nvidia.com; pr=C Received: from mail.nvidia.com (216.228.117.161) by SJ1PEPF000026C8.mail.protection.outlook.com (10.167.244.105) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.428.7 via Frontend Transport; Wed, 16 Sep 2026 10:39:07 +0000 Received: from rnnvmail202.nvidia.com (10.129.68.7) by mail.nvidia.com (10.129.200.67) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.49; Wed, 16 Sep 2026 03:38:50 -0700 Received: from rnnvmail204.nvidia.com (10.129.68.6) by rnnvmail202.nvidia.com (10.129.68.7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.46; Wed, 16 Sep 2026 03:38:49 -0700 Received: from sumitg-l4t.nvidia.com (10.127.8.14) by mail.nvidia.com (10.129.68.6) with Microsoft SMTP Server id 15.2.2562.46 via Frontend Transport; Wed, 16 Sep 2026 03:38:42 -0700 From: Sumit Gupta To: , , , , , , , , , , , , , , , , CC: , , , , , , , Subject: [PATCH v5 2/4] ACPI: CPPC: Make autonomous selection helpers take a u64 Date: Wed, 16 Sep 2026 16:08:18 +0530 Message-ID: <20260916103820.1760297-3-sumitg@nvidia.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260916103820.1760297-1-sumitg@nvidia.com> References: <20260916103820.1760297-1-sumitg@nvidia.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-NVConfidentiality: public Content-Transfer-Encoding: quoted-printable X-NV-OnPremToCloud: ExternallySecured X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF000026C8:EE_|PH8PR12MB8607:EE_ X-MS-Office365-Filtering-Correlation-Id: 648bd8cd-2abe-448c-c336-08df13debc9b X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|23010399003|82310400026|36860700016|7416014|376014|1800799024|10067099003|6133799003|18002099003|22082099003|56012099006|11063799006|921020; X-Microsoft-Antispam-Message-Info: 1uukuzgAQTZVaGp6xec456zVt4wmNDcsizXHzqJFhvkSzLm7w9riyoe3NmhC75azkeQk5PQKK5Ju/EdAaDpHFZqOHWmkvLxiXOGlrL4QUqwlRIiwTrlyV/BFSWP1xtqEhu4P8enNaZZYr9TOsBZ6RZusQEY/+l69BA5wPShkxDm9dx9j2BDV0md6x8t5H4Zaf4avuH6Jedu3K6hiv37F+JiYSs6PGNJU4pXIUsfqwvwoSc36n+Z6p97IyHUzd0qwrfqjtBg2vR0FKKSZf9dYbF6Ig+LOdwWX5UaF2awTJ92pYG0UC1uO511u/CCuSYPy4yL2MUWxfXcn+DgLFmIjUTEHLU7zk9JK4nK62w95Z2oM8j0tUAJ/cS7JNieFnkId2K+Xfn8HcqSdOhj0anh7jbisJAx2JBmDDSJWc8xUcv4rVeEdbm/JojuVw/0A4hygvp7r+jnZMfTxNaCCDHbPi5LS3rXZAFu+gJhCiLJNS9EBhfcg2EBgfDuI29p6eF5KF2u7stAkee3ydh9VO2P01DSffIBUzi0diriQ9AuPhsTS1bTXiJpkGFbUNosSlHlulIbfAgVQkeAEuyEBb42YEX5xE8SGkXXamz0OyKjt3tSih4ylpyoarE02FRAd3HvY/mQ+yKcLsEC5WWUuUSZXivkVMmRf+wswOEaqBV8Ykt6muSZ8vJekrffZYhKuUsPX8EU4sxDcg7U7pd8pyKQWdmsuIDKFwLfBDz1GIxW/nNgQVbc2iWPxeWXSe25KpLF1 X-Forefront-Antispam-Report: CIP:216.228.117.161;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mail.nvidia.com;PTR:dc6edge2.nvidia.com;CAT:NONE;SFS:(13230040)(23010399003)(82310400026)(36860700016)(7416014)(376014)(1800799024)(10067099003)(6133799003)(18002099003)(22082099003)(56012099006)(11063799006)(921020);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: mAXJ+sU83234iD5+2Wzu4qsiV0ELFfffw5mjvgNUE2inUdMLURGSXjehhtn50Mt5U6PoKCFxjE/mPA/Lmuj2CV8ibIQ81EaTo7VUAtDrXDi/N19ga+KH/gFbqcDBlIdOfkUPxYnC8wx/F7ZL17T8bs4ocIkOxXJ9PYY1pJD2Vu0+xqwC8JdI/xC3plZuYNk87gtXubiAxJ9BwUkg6rK8KGHRsNPPIDEt4nN8u+GV50ZUWy4nHrcT/Qiec2GEjRRDN+1qC9dQ7j8rRDfeEkXYU0rew5X/QPKXh5hBk9Ko0cuEskvuHFLazt3/nivtZQPM0xmTGXq4XcqYiT2s8MUVvqIH3mgG9vBseLMQQOJ9lVcgV/sSqMc9At7UceZ3hbbdsoGa87QUFptb5TUkUxKr3NcKHYsENLiYcsRnl5JqD8mEqFDrzpf1lWdvqXZkNDQ8 X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Sep 2026 10:39:07.6500 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 648bd8cd-2abe-448c-c336-08df13debc9b X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a;Ip=[216.228.117.161];Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: SJ1PEPF000026C8.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH8PR12MB8607 Content-Type: text/plain; charset="utf-8" cppc_get_auto_sel()/cppc_set_auto_sel() use a bool, unlike the other CPPC register get/set helpers which use a u64. The next patch in this series saves and restores the OSPM-set registers across CPU hotplug and driver unload through a common table of register get/set helpers that all take a u64. The bool autonomous selection helpers cannot be added to that table. Change cppc_get_auto_sel()/cppc_set_auto_sel() to take a u64 so the autonomous selection register fits alongside the others, and update their callers. Signed-off-by: Sumit Gupta Reviewed-by: K Prateek Nayak Tested-by: K Prateek Nayak --- drivers/acpi/cppc_acpi.c | 20 ++++---------------- drivers/cpufreq/amd-pstate.c | 2 +- drivers/cpufreq/cppc_cpufreq.c | 4 ++-- include/acpi/cppc_acpi.h | 8 ++++---- 4 files changed, 11 insertions(+), 23 deletions(-) diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index fef54fcd00b7..9e882b3911e6 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -1904,23 +1904,11 @@ EXPORT_SYMBOL_GPL(cppc_set_auto_act_window); /** * cppc_get_auto_sel() - Read autonomous selection register. * @cpu: CPU from which to read register. - * @enable: Return address. + * @enable: Return address, set to 0 or 1. */ -int cppc_get_auto_sel(int cpu, bool *enable) +int cppc_get_auto_sel(int cpu, u64 *enable) { - u64 auto_sel; - int ret; - - if (enable =3D=3D NULL) - return -EINVAL; - - ret =3D cppc_get_reg_val(cpu, AUTO_SEL_ENABLE, &auto_sel); - if (ret) - return ret; - - *enable =3D (bool)auto_sel; - - return 0; + return cppc_get_reg_val(cpu, AUTO_SEL_ENABLE, enable); } EXPORT_SYMBOL_GPL(cppc_get_auto_sel); =20 @@ -1929,7 +1917,7 @@ EXPORT_SYMBOL_GPL(cppc_get_auto_sel); * @cpu : CPU to which to write register. * @enable : the desired value of autonomous selection resiter to be updat= ed. */ -int cppc_set_auto_sel(int cpu, bool enable) +int cppc_set_auto_sel(int cpu, u64 enable) { return cppc_set_reg_val(cpu, AUTO_SEL_ENABLE, enable); } diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index 8bfd46d60843..20b9e216670c 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -499,7 +499,7 @@ static int shmem_init_perf(struct amd_cpudata *cpudata) struct cppc_perf_caps cppc_perf; union perf_cached perf =3D READ_ONCE(cpudata->perf); u64 numerator; - bool auto_sel; + u64 auto_sel; =20 int ret =3D cppc_get_perf_caps(cpudata->cpu, &cppc_perf); if (ret) diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index 37ead7f6c179..d7d96fe0da1b 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c @@ -984,7 +984,7 @@ static ssize_t show_freqdomain_cpus(struct cpufreq_poli= cy *policy, char *buf) =20 static ssize_t show_auto_select(struct cpufreq_policy *policy, char *buf) { - bool val; + u64 val; int ret; =20 ret =3D cppc_get_auto_sel(policy->cpu, &val); @@ -996,7 +996,7 @@ static ssize_t show_auto_select(struct cpufreq_policy *= policy, char *buf) if (ret) return ret; =20 - return sysfs_emit(buf, "%d\n", val); + return sysfs_emit(buf, "%llu\n", val); } =20 static ssize_t store_auto_select(struct cpufreq_policy *policy, diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h index 94a6277edab2..3394e1b208be 100644 --- a/include/acpi/cppc_acpi.h +++ b/include/acpi/cppc_acpi.h @@ -187,8 +187,8 @@ extern int cppc_set_epp_perf(int cpu, struct cppc_perf_= ctrls *perf_ctrls, bool e extern int cppc_set_epp(int cpu, u64 epp_val); extern int cppc_get_auto_act_window(int cpu, u64 *auto_act_window); extern int cppc_set_auto_act_window(int cpu, u64 auto_act_window); -extern int cppc_get_auto_sel(int cpu, bool *enable); -extern int cppc_set_auto_sel(int cpu, bool enable); +extern int cppc_get_auto_sel(int cpu, u64 *enable); +extern int cppc_set_auto_sel(int cpu, u64 enable); extern int cppc_get_perf_limited(int cpu, u64 *perf_limited); extern int cppc_set_perf_limited(int cpu, u64 bits_to_clear); extern int amd_get_highest_perf(unsigned int cpu, u32 *highest_perf); @@ -285,11 +285,11 @@ static inline int cppc_set_auto_act_window(int cpu, u= 64 auto_act_window) { return -EOPNOTSUPP; } -static inline int cppc_get_auto_sel(int cpu, bool *enable) +static inline int cppc_get_auto_sel(int cpu, u64 *enable) { return -EOPNOTSUPP; } -static inline int cppc_set_auto_sel(int cpu, bool enable) +static inline int cppc_set_auto_sel(int cpu, u64 enable) { return -EOPNOTSUPP; } --=20 2.34.1 From nobody Fri Sep 25 05:29:21 2026 Received: from SN4PR0501CU005.outbound.protection.outlook.com (mail-southcentralusazon11011040.outbound.protection.outlook.com [40.93.194.40]) (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 2BE0B4FECD1; Wed, 16 Sep 2026 10:39:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.194.40 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789555178; cv=fail; b=GSSp4zUlrYaRSsknDhf/IIGyWc8ZcybnU1uTOt5KbXCP+BNE2C4H5VFIsR0Y8MQ0zncYyvPnxY/jtubRXZSO7ZNhW5dMGR1h+gyvcz6Ydva8AWmr/aFLXsK+/3iKBaTLnuT1bJo/YLNPl7wARcP5RsRtLF/9epR/ePWuhmHy6As= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789555178; c=relaxed/simple; bh=R3KfGLagMjMBM2TpLXoM47suK8AQQssODNSuxLCtSUI=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=YDCrudef3II8HHyffjUDJD+JKHVmVPdMtIU/fPZjsLtUNDhq2Z5MygUJVQprhZfDsM/Japc85o5iGWxOB5tNiqyri69xpTE3eJv7TgIRxaWhrVpGscMzHDzya6Y8hsw/cRHyFJ+IrmOibRPi/rt63ch8FemeOs7HA8io6SdqUm8= 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=ZTPfvQXh; arc=fail smtp.client-ip=40.93.194.40 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="ZTPfvQXh" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=YuoN41OD5vDCFsKYWJbGN9WhvJjK2GWy2tEP0y+DHTpyClwJuAlPQuFm0IPLC+MnS4JebaVW1ivDRk9eNRXb2vaZOTy88AlVMasbj2CDaFvLsonrd0iGCePT4eITX295Mb8mcHBeGqoiqYJVyDrnCt2HK/w/xkpTjb5rPeOtubia8Wq5TgQpDttK7h2OeY6Pxi2Vq/zcxm6Ks5oszcQKjJStrf0LAkAOzt7hOlgDKJO2ZcAY/D02k+6E5r8MNqAUUPVVOQmBo8//PNWCN6vbNglvTvJTyc4eizhzYQ53w0kdVzL/bdu/b1KjcTsbEcC5S7fmBdLAU+dfvQa4qoxYvQ== 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=tXr9gQ01yMVT2+PPfl7nlpwjXuJiYtgnLPxNOnDaOIM=; b=O+hu9vhbVYPGuIAWxhXUMYcPDsQ9UaowEF70Q1Gv9CrU15aEUwavUNNIYpwA7RKTt4AAJ5p70mKA0FHZirtCkYP8e9RESLJjMRNzZOoZt4+FNSzC7n2mxLWzKLynFng/aXCzMvadM9Z0kql2LH0Gg+ctUUGPEL++IeCR9qxnqUlnpxffLID7ELTpFhrj2pWFrRkciyKpobxOSIOz67JPkHhPCmX5XU3XgVivq9sYekdayMBku6zGPleQOd3jrkt8zdZtj68vSWnYYWVCmfxzhZCryXWq6r2XPxSEfacKaz95nk/yhNJ6z/07P+F+uf3mtF8N8iPGGsKilzkXqThNZA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.117.161) smtp.rcpttodomain=kernel.org 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=tXr9gQ01yMVT2+PPfl7nlpwjXuJiYtgnLPxNOnDaOIM=; b=ZTPfvQXhUErPigJtO0VCnPgdPK6Ivme8AMYCeicdvht3nZR+/UUggkghfqhqsDCw9TFsqcIKfzikP18Vhmde7Sr87aVdhLXFHe1JpgPvftYJpEnN0kd1ktyhd0pfUzmIj0svpuW38I46xULyfol9zyzeuwAFPzfTa9gJjEOmJRPnWxLETZ2nb5zYTqungukjaf3qecvDeyCi7+Eb7Cb8f0qWZTyOyMyLuCZDw6WOXwcWKN/4OHFl5Vp5NUvP507g+cakQ3SBnRpDJSmWC9TZ58pueenf2Y7DR9Gr8gfLUAKW8/WJlQhKO+z4QrxN88pleB/jWrkMQxtvjVUxMW+cog== Received: from BY3PR05CA0039.namprd05.prod.outlook.com (2603:10b6:a03:39b::14) by SJ0PR12MB5674.namprd12.prod.outlook.com (2603:10b6:a03:42c::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.406.9; Wed, 16 Sep 2026 10:39:20 +0000 Received: from SJ1PEPF000026C8.namprd04.prod.outlook.com (2603:10b6:a03:39b:cafe::71) by BY3PR05CA0039.outlook.office365.com (2603:10b6:a03:39b::14) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.428.9 via Frontend Transport; Wed, 16 Sep 2026 10:39:20 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.117.161) 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.117.161 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.117.161; helo=mail.nvidia.com; pr=C Received: from mail.nvidia.com (216.228.117.161) by SJ1PEPF000026C8.mail.protection.outlook.com (10.167.244.105) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.428.7 via Frontend Transport; Wed, 16 Sep 2026 10:39:20 +0000 Received: from rnnvmail205.nvidia.com (10.129.68.10) by mail.nvidia.com (10.129.200.67) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.49; Wed, 16 Sep 2026 03:39:00 -0700 Received: from rnnvmail204.nvidia.com (10.129.68.6) by rnnvmail205.nvidia.com (10.129.68.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.46; Wed, 16 Sep 2026 03:38:59 -0700 Received: from sumitg-l4t.nvidia.com (10.127.8.14) by mail.nvidia.com (10.129.68.6) with Microsoft SMTP Server id 15.2.2562.46 via Frontend Transport; Wed, 16 Sep 2026 03:38:52 -0700 From: Sumit Gupta To: , , , , , , , , , , , , , , , , CC: , , , , , , , Subject: [PATCH v5 3/4] cpufreq: CPPC: Preserve OSPM-set registers across hotplug and unload Date: Wed, 16 Sep 2026 16:08:19 +0530 Message-ID: <20260916103820.1760297-4-sumitg@nvidia.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260916103820.1760297-1-sumitg@nvidia.com> References: <20260916103820.1760297-1-sumitg@nvidia.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-NVConfidentiality: public Content-Transfer-Encoding: quoted-printable X-NV-OnPremToCloud: ExternallySecured X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF000026C8:EE_|SJ0PR12MB5674:EE_ X-MS-Office365-Filtering-Correlation-Id: 75613a40-71bd-4c6e-c4b3-08df13dec43e X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|36860700016|376014|23010399003|7416014|1800799024|82310400026|13003099007|921020|6133799003|22082099003|10067099003|56012099006|5023799004|11063799006|18002099003; X-Microsoft-Antispam-Message-Info: wt+4RM1e7mpQufwzanq5fYT2v8hdUNbTHquFmcXd1762xgjlGwL1h4bBWy5Pycv8dLXyJUjZLy/2OOw8FUWrSwKuWa3M7E/nBcvTme7ea1B+P/hrJWbRtcF5SID7bpj+mqf3kmxSEoDM3sFGSwRAp29MVx2RtO2u16e3OO1R/39D7jsjyKxUR/IcEH/GSXfptgKiyADnOryO8iUzccGch2SjbjEGpDhIsPb98mVCl2cB8J25PYoPQ3hwB7vg33/364n/et5ciCs/jsEwm0b8jq+q0yjK5IX9If6gkkWgaxAhVqBR1BzzJk9NBsV6sskIJixns8CMMiYWCygMJHJXY+uWZ6Ye9vahYPfisPvCy6tsaUlIGFwSKgM8+4sV+3BkTvuQSPWiFuFIsJ5dRI+4EOY91oVKs5K2pCU89E2559nG1vCYoJcfyZNtAe//NJQAMEBsQmiuH4R29KcFYBI1urv3ksFFteSz8z8j14aJwj+2Ou0b0wLQfs4SMPafd3f/yLrBx+BzGoO9hgaZWH9suzMmGK2HylH/+fruIjtnB7Y0/jXYm8qesUDFuAZwOig9bMrn/MJwVWpYrPP81lzsLclykEnqrRAg1VhlNfyvTXOGbXvLCdSl7vAvOpS7egER9j8apuDryBaiy8LEeGNOHlQ2psYM8JoNI6P5zaLwJhjPXUCgov+MGC+iCQsOEQBYVJRqYneElhtG32Od99b0dnm5IWMOBqcDVbFXgqtby0vDpcf2Y6ZMP+5/3Ve6JA6e X-Forefront-Antispam-Report: CIP:216.228.117.161;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mail.nvidia.com;PTR:dc6edge2.nvidia.com;CAT:NONE;SFS:(13230040)(36860700016)(376014)(23010399003)(7416014)(1800799024)(82310400026)(13003099007)(921020)(6133799003)(22082099003)(10067099003)(56012099006)(5023799004)(11063799006)(18002099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: YmcV1ReGx5r9EtXz/TvIcUAqcLdQq+6MmXT1boVPXq9RQrZHGR4m7Z2wVlVlbuYDgbb/L5csfX+m+VbVs/HEgUrLCW26u5DQr+LX0p5uIpFchyKjIby1ORBLGpSuPMTNuh+p7eY5FhTsWLOwVJtUPZLBPLaMJGRaUVNKXo6oi2qOlJb8FIjwCyGzxIg5/n03oPQTBOS5xtzKXY8dNFJccVUaIXcO8JyaaexAFCnj767f/wqSBoEV+qpBuZ6rgmR6eicnXj0oGTNWjhxXaKHJ797pyeEuYaA4oK1MrKOrMJQQ0HJTia95Zvnj9UyTGVbh2HmB+ove6zPJViAhaM4sH8UAEC6j0oHd90hAKpa6UMF5sbVMkmHlMeAsV5rjTRoyzbhSaJQIJ+Ah0GjGTrBbZiYkOVDpgN1ar7wTmW5Tq6thi0x/aJGlUVGioxdveVfl X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Sep 2026 10:39:20.4626 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 75613a40-71bd-4c6e-c4b3-08df13dec43e X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a;Ip=[216.228.117.161];Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: SJ1PEPF000026C8.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SJ0PR12MB5674 Content-Type: text/plain; charset="utf-8" Values written to OSPM-set CPPC registers via sysfs can be lost in two ways: - Across CPU hotplug: the platform may reset a CPU's registers while it is offline. - On driver unload: the value the driver wrote is left in the register instead of returning to its pre-driver state. Add a small table-driven mechanism that handles both: - On init(), capture each register's firmware value before the driver programs anything. - On offline(), read back each register's current value (whatever was last set via sysfs) so it can be reapplied, then restore the firmware value. - On online(), reapply the value captured at offline() after reprogramming the performance controls. A failed write to the controls does not skip the reapply, as no other path restores these registers. - On exit(), nothing is needed, as the core calls offline() first, which already restored the firmware values. Cover the Autonomous Selection (auto_sel), Energy Performance Preference (EPP) and Autonomous Activity Window (auto_act_window) registers. Writes to EPP and auto_act_window only have meaning while auto_sel is enabled, so write auto_sel before them when enabling it and after them when disabling it. While autonomous selection stays disabled, the platform may ignore those writes. Suggested-by: Pierre Gondois Link: https://lore.kernel.org/all/86780f97-29ee-4a72-b311-38c89434b707@arm.= com/ Signed-off-by: Sumit Gupta Tested-by: K Prateek Nayak --- drivers/cpufreq/cppc_cpufreq.c | 193 ++++++++++++++++++++++++++++++++- 1 file changed, 190 insertions(+), 3 deletions(-) diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index d7d96fe0da1b..ac315071a979 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c @@ -28,6 +28,183 @@ =20 static struct cpufreq_driver cppc_cpufreq_driver; =20 +/* + * OSPM-set CPPC registers tracked for save/restore. A value the OS wrote = is + * reapplied from online() across CPU hotplug, and the firmware value is + * restored from offline(). + * + * Autonomous Selection (auto_sel) is kept first, as the registers after it + * only have meaning while it is enabled. + */ +enum cppc_saved_reg_id { + CPPC_SAVED_AUTO_SEL, + CPPC_SAVED_EPP, + CPPC_SAVED_AUTO_ACT_WINDOW, + CPPC_NR_SAVED_REGS, +}; + +struct cppc_saved_reg { + const char *name; + int (*get)(int cpu, u64 *val); + int (*set)(int cpu, u64 val); +}; + +static const struct cppc_saved_reg cppc_saved_regs[CPPC_NR_SAVED_REGS] =3D= { + [CPPC_SAVED_AUTO_SEL] =3D { + .name =3D "auto_sel", + .get =3D cppc_get_auto_sel, + .set =3D cppc_set_auto_sel, + }, + [CPPC_SAVED_EPP] =3D { + .name =3D "epp", + .get =3D cppc_get_epp_perf, + .set =3D cppc_set_epp, + }, + [CPPC_SAVED_AUTO_ACT_WINDOW] =3D { + .name =3D "auto_act_window", + .get =3D cppc_get_auto_act_window, + .set =3D cppc_set_auto_act_window, + }, +}; + +enum cppc_saved_type { + CPPC_SAVED_FIRMWARE, + CPPC_SAVED_REQUESTED, +}; + +/* + * Per-policy values saved for each register in cppc_saved_regs[]: + * firmware_val - value before the driver touched it, captured at init() + * and written back when the policy goes offline. U64_MAX + * if it could not be read + * requested_val - value in effect when the policy last went offline, + * reapplied at online(). U64_MAX if none + */ +struct cppc_saved_vals { + u64 firmware_val; + u64 requested_val; +}; + +struct cppc_policy_state { + struct cppc_saved_vals regs[CPPC_NR_SAVED_REGS]; +}; + +static DEFINE_PER_CPU(struct cppc_policy_state, cppc_policy_state); + +/* + * Per-policy state is kept in the per-CPU variable of the first CPU the p= olicy + * manages. related_cpus (the policy's full set of CPUs) never changes whi= le the + * policy exists, so this CPU (unlike policy->cpu) stays the same across C= PU + * hotplug, and every callback reaches the same copy. + */ +static struct cppc_policy_state * +cppc_cpufreq_policy_state(struct cpufreq_policy *policy) +{ + const struct cpumask *policy_cpus =3D policy->related_cpus; + + /* + * related_cpus is empty until the core fills it in after init(), so + * fall back to policy->cpus, which has the same first CPU. + */ + if (cpumask_empty(policy_cpus)) + policy_cpus =3D policy->cpus; + + return &per_cpu(cppc_policy_state, cpumask_first(policy_cpus)); +} + +/* + * Save each register's current value, either as the firmware value, captu= red + * before the driver programs anything, or as the requested value, to reap= ply + * at online(). + */ +static void cppc_cpufreq_save_regs(struct cpufreq_policy *policy, + enum cppc_saved_type saved_type) +{ + struct cppc_policy_state *st =3D cppc_cpufreq_policy_state(policy); + unsigned int cpu =3D policy->cpu; + u64 val; + int i; + + for (i =3D 0; i < CPPC_NR_SAVED_REGS; i++) { + if (cppc_saved_regs[i].get(cpu, &val)) + val =3D U64_MAX; + + if (saved_type =3D=3D CPPC_SAVED_FIRMWARE) { + st->regs[i].firmware_val =3D val; + st->regs[i].requested_val =3D U64_MAX; + } else { + st->regs[i].requested_val =3D val; + } + } +} + +static u64 cppc_cpufreq_saved_reg_value(const struct cppc_saved_vals *st, + enum cppc_saved_reg_id reg, + enum cppc_saved_type saved_type) +{ + if (saved_type =3D=3D CPPC_SAVED_FIRMWARE) + return st[reg].firmware_val; + + return st[reg].requested_val; +} + +/* + * Write one tracked register, skipping it when there is no saved value. + * A register the platform does not allow writing is not an error. + */ +static void cppc_cpufreq_write_saved_reg(unsigned int cpu, + enum cppc_saved_reg_id reg, u64 val, + enum cppc_saved_type saved_type) +{ + const char *op =3D (saved_type =3D=3D CPPC_SAVED_FIRMWARE) ? + "restore firmware" : "reapply saved"; + int ret; + + if (val =3D=3D U64_MAX) + return; + + ret =3D cppc_saved_regs[reg].set(cpu, val); + if (ret =3D=3D -EOPNOTSUPP) + return; + if (ret) + pr_debug("Failed to %s %s=3D%llu on CPU%u (%d)\n", op, + cppc_saved_regs[reg].name, val, cpu, ret); +} + +/* + * Apply the saved firmware or requested value to each tracked register. + * + * Write auto_sel first when the value being applied enables autonomous + * selection and last when it disables it, so the writes to the dependent + * registers can still take effect. While autonomous selection stays disab= led, + * the platform may ignore those writes. Do not enable it temporarily to f= orce + * them through. + */ +static void cppc_cpufreq_apply_saved_regs(struct cpufreq_policy *policy, + enum cppc_saved_type saved_type) +{ + const struct cppc_saved_vals *st =3D cppc_cpufreq_policy_state(policy)->r= egs; + unsigned int cpu =3D policy->cpu; + u64 auto_sel, val; + int i; + + auto_sel =3D cppc_cpufreq_saved_reg_value(st, CPPC_SAVED_AUTO_SEL, + saved_type); + + if (auto_sel) + cppc_cpufreq_write_saved_reg(cpu, CPPC_SAVED_AUTO_SEL, auto_sel, + saved_type); + + for (i =3D CPPC_SAVED_AUTO_SEL + 1; i < CPPC_NR_SAVED_REGS; i++) { + val =3D cppc_cpufreq_saved_reg_value(st, i, saved_type); + cppc_cpufreq_write_saved_reg(cpu, i, val, saved_type); + } + + if (!auto_sel) + cppc_cpufreq_write_saved_reg(cpu, CPPC_SAVED_AUTO_SEL, auto_sel, + saved_type); +} + #ifdef CONFIG_ACPI_CPPC_CPUFREQ_FIE static enum { FIE_UNSET =3D -1, @@ -718,6 +895,8 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy = *policy) policy->cur =3D cppc_perf_to_khz(caps, caps->highest_perf); cpu_data->perf_ctrls.desired_perf =3D caps->highest_perf; =20 + cppc_cpufreq_save_regs(policy, CPPC_SAVED_FIRMWARE); + ret =3D cppc_set_perf(cpu, &cpu_data->perf_ctrls); if (ret) { pr_debug("Err setting perf value:%d on CPU:%d. ret:%d\n", @@ -791,12 +970,14 @@ cppc_cpufreq_prepare_perf_restore(unsigned int cpu, * * The platform may have disabled CPPC and reset the performance controls * (desired, min and max performance) while the CPU was offline, so re-ena= ble - * CPPC and reprogram them. + * CPPC and reprogram them. Also reapply the OSPM-set registers that offli= ne() + * reset to firmware values. * * Report failures without returning them, or the core would free the poli= cy and * leave the CPU without cpufreq. A failed write to the performance contro= ls is - * not fatal, as the governor's next request programs them again. A failed= CPPC - * enable stops the restore, as the writes that follow may not reach the + * not fatal, as the governor's next request programs them again. The OSPM= -set + * registers are reapplied even then, as no other path restores them. A fa= iled + * CPPC enable skips both restores, as the writes that follow may not reac= h the * platform. */ static int cppc_cpufreq_cpu_online(struct cpufreq_policy *policy) @@ -832,6 +1013,8 @@ static int cppc_cpufreq_cpu_online(struct cpufreq_poli= cy *policy) pr_debug("Failed to restore perf controls on CPU%u (%d)\n", cpu, ret); =20 + cppc_cpufreq_apply_saved_regs(policy, CPPC_SAVED_REQUESTED); + out_fie: /* Restart what offline() stopped, with a new counter snapshot. */ cppc_cpufreq_cpu_fie_init(policy); @@ -851,6 +1034,10 @@ static int cppc_cpufreq_cpu_offline(struct cpufreq_po= licy *policy) unsigned int cpu =3D policy->cpu; int ret; =20 + /* Save what the OS set, and leave the platform in its pre-driver state. = */ + cppc_cpufreq_save_regs(policy, CPPC_SAVED_REQUESTED); + cppc_cpufreq_apply_saved_regs(policy, CPPC_SAVED_FIRMWARE); + /* * Stop the frequency invariance updates and cancel the pending work, so * that no sample spans the offline window. online() restarts them with --=20 2.34.1 From nobody Fri Sep 25 05:29:21 2026 Received: from SN4PR2101CU001.outbound.protection.outlook.com (mail-southcentralusazon11012032.outbound.protection.outlook.com [40.93.195.32]) (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 2B65950AC05; Wed, 16 Sep 2026 10:39:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.195.32 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789555204; cv=fail; b=SHbhWGFmt9rPmphTXfZKt1A7wuHWHa05ctDeJxV01ZxT1N2KX9UJQivX1pfjbDFjIluRMVVcf4BH9MT6S93iJcTOcuHbYxXV+6tXxEPL5E1hg2HQLoK0Rjdtl13q93lYsaXMGVHBbpvVCWICZDp6yZteIRqwLQZRmo+BA0Ws7NQ= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789555204; c=relaxed/simple; bh=Qvduej68MGeX+BC3BOqc01C35uajYgGBUbKkzN7f7tk=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=aiwExWg+GyOKlnycDZ9eP/uVuxr85FhDAdBgYav5fitrrsRd9pMOtnA1e8XSRBiJEhCSt1vGyck84YlIfxU/0iTddRhQVWoVMr2ov63hjdwaMQMd3zJffoLIiorORscHuS6nmQZ5Nqt0zlQA8X3pSAmGuCyHnTg+cSCDd8omXmM= 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=EWRzkJLv; arc=fail smtp.client-ip=40.93.195.32 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="EWRzkJLv" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=AvDduda84gbr1CwU92a/JTb/7GNpZCcJB9kh5DtICP5C7fRxISMriTqf5eKbmoZlj9cmC9pz/dwaAhReFEpiVpVIz9nnKSY+ITneVguEPC4ag2PPWsYM/n+HdI+kUMN92KWksUB2lkSF9sEIz7Ab+Wun7LvXhLt3nOtXW7tyofan7M4AusrNAkXsIixlHx+uqAwDhUR9y6YpGJFJhKaZ5UB4AKeFBojz8p6WXALF7lDAIti+f/3JhEKhGNqfasKpJgTTLUBrTJXgCesn6svVXaSQFMrGMknBQSRcH1VYEi7VZv0OSAX+JvhyAoaATyrhgBVvZFMMQMc2wVVvWxB7Fw== 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=vGoWmDSTUR34xt2WPPu+cAoxUpR34J7mn0r46m34R3k=; b=JVKiHOl3IH0+oqYsU+MvbzeSoJpXEx/j+wYyW/EzXM43ZeKiolL1IBQ6T+oaOtcO7f1xBWTF+22FM1DMrW+RXcNA9lBcJPkiRJ3oHIScsS6GcCSXv9mJYYrfzsCeaCUoJg/Evir9MaoMvIFn+L3ZZZdT0luyAyzhCnlrSmfwgb2z/M5Iwpllny4zdPxWfhlk/+sDQDmnCVz0kwO0XAjvqfJsjQK/CciibLVPV0xG6ddb4WVoFGsCSzGttezFkxxwPTRScuTyFrOrSe23d5W1cyJ+IeMYWkCw16Q6spvO8mi7SHnjoY+JCrKbo0m0XXDfZwzav4flPcnZL1EHJSxwbg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.117.160) smtp.rcpttodomain=kernel.org 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=vGoWmDSTUR34xt2WPPu+cAoxUpR34J7mn0r46m34R3k=; b=EWRzkJLvUzivTA3D6OPrjBjhu5P/YUptOnmL6hH/IiT9jiwETLMTMbV+c4rPpcYZ+g27XT7ogSQAetIbJJAIBwmrl8ZoF+vRCHGIHPCmwtSSsDINQVzKmXJpmfij0sTOM5WYHrX0jjAWlY9mQ7a86lJAaqtNJXJqEjxoRa5oMYOEHZZ+QHCAffQVnCJjVx+Dkf2mjOyNo2WnTFWzzzh9ZB0WWJeLqi0rgAWLXK79m6fod16QmNU/QMbnns3UFgUpk/Wd633/9NN9mu+5Z3xhStYzb7c3ff3abxmYXNNNFV60bZTGfuKGT72G4YhTiiZiczKBSTgXOIRmn51cQKOjFQ== Received: from SJ2PR07CA0014.namprd07.prod.outlook.com (2603:10b6:a03:505::7) by DSVPR12MB999150.namprd12.prod.outlook.com (2603:10b6:8:388::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.406.11; Wed, 16 Sep 2026 10:39:31 +0000 Received: from BY1PEPF00026966.namprd05.prod.outlook.com (2603:10b6:a03:505:cafe::28) by SJ2PR07CA0014.outlook.office365.com (2603:10b6:a03:505::7) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.428.9 via Frontend Transport; Wed, 16 Sep 2026 10:39:30 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.117.160) 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.117.160 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.117.160; helo=mail.nvidia.com; pr=C Received: from mail.nvidia.com (216.228.117.160) by BY1PEPF00026966.mail.protection.outlook.com (10.167.244.150) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.428.7 via Frontend Transport; Wed, 16 Sep 2026 10:39:30 +0000 Received: from rnnvmail202.nvidia.com (10.129.68.7) by mail.nvidia.com (10.129.200.66) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.49; Wed, 16 Sep 2026 03:39:13 -0700 Received: from rnnvmail204.nvidia.com (10.129.68.6) by rnnvmail202.nvidia.com (10.129.68.7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.46; Wed, 16 Sep 2026 03:39:13 -0700 Received: from sumitg-l4t.nvidia.com (10.127.8.14) by mail.nvidia.com (10.129.68.6) with Microsoft SMTP Server id 15.2.2562.46 via Frontend Transport; Wed, 16 Sep 2026 03:39:06 -0700 From: Sumit Gupta To: , , , , , , , , , , , , , , , , CC: , , , , , , , Subject: [PATCH v5 4/4] cpufreq: CPPC: Preserve OSPM-set registers across suspend/resume Date: Wed, 16 Sep 2026 16:08:20 +0530 Message-ID: <20260916103820.1760297-5-sumitg@nvidia.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260916103820.1760297-1-sumitg@nvidia.com> References: <20260916103820.1760297-1-sumitg@nvidia.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-NVConfidentiality: public Content-Transfer-Encoding: quoted-printable X-NV-OnPremToCloud: ExternallySecured X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BY1PEPF00026966:EE_|DSVPR12MB999150:EE_ X-MS-Office365-Filtering-Correlation-Id: 6562345d-f95a-414d-97f9-08df13deca37 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|82310400026|1800799024|7416014|23010399003|36860700016|22082099003|18002099003|921020|11063799006|10067099003|56012099006; X-Microsoft-Antispam-Message-Info: fcGNp9R8LhFLhRLxhW5oG5+NZY5PXvsjr/7q8lPp1qlcSjHjScdTvzbMHafE618M0NuEnPY6HAa8xKhVAzfITZqgP75G8w1h7I2JCarUEOAW8TIEou26tSLJL5kav+24VF36rSdNpTzt3q5o8UgFM3TUB8m7lFfOGHFOYdJr2sEcpjNb6IUwQnWBb9qZvi9QdIFmnqutJLP2YZkt74WepWWgbadQl5yU/3UfNOwc2T7W9D/YdJOHvp35kntfPWjsxaMmPZAP+vy/pariksePhM9JZ9A1pgfuGTwlY0OXxH7dCxxoqn+aCx7quDS2+MbJ3nhtRO/82OMzriRGDb4Z1Siqj7Q2GDvJZ9eEpJeU7gOxPJLooUjSWevTPTk+xRB1jUGK34MUQD1nSooduOGKq8AxAk22P5zU/tNUjY8uSiBU8IrT13+aFB5EGGf/GxpgxsQGcOSKCK3HEBjTRqMT12ieKcL0nwRnS+gGh7MNFG0lE4qMHgNg9PyxNIl17rqzJsBK3DZA/heyvr9hhnRL7nuj5AAdHySREUqPi4+5f3hX8G4RIP+xQVCYlogTrIp98GMLyKOi1Szvt7pReIc5XAaOQT+oHz5ZKYjKImF0PLYMj85E2k18ZxBvN8bKtdLI5Y/1YSRX2X5DuoZWrlombrZb2OSKN8jk8e3Kpt1DWRiofrzJOKJ/p2lonjKpv7HkH8FSvBqvXombkeEUuz2fJ87Pyd6a6JgkXGOANbJkzqmNPfO+QmofrG/xbFcboSOu X-Forefront-Antispam-Report: CIP:216.228.117.160;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mail.nvidia.com;PTR:dc6edge1.nvidia.com;CAT:NONE;SFS:(13230040)(376014)(82310400026)(1800799024)(7416014)(23010399003)(36860700016)(22082099003)(18002099003)(921020)(11063799006)(10067099003)(56012099006);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: ye1sYuSm5OhWDqJOOgM+g9Z7Kxu31eyjAxefdHQbcOBcXlSiJCUWkCbtU4k7YiOQSGef38hShxzxXCRD27+c/ufciaUPTRzmGZzdclopHb1+7u02c8P3ZPw0JYZkdyevaR3SA6KH7IEx6855vGa58I2gOLylOoCP2Sd9ETGmAYYXBOK02aZ9WguAgTWbfyq3mFZsoStxJZOGbc2mxczLWWU4TmxRXoA5H4D1rd7nr1rOHKTl6E+9vUYAglgARZ1DEdQ3viT0++0kyljIKR0I7tAys1or3SIdQOGvZIsWBd86CS7khXRfgCeab7337sA94tAZTSdqfhJ85cVb+kuvai1Dzek5HEfOoV3RZCIlWlCEv2ahn1Fsr+1s7thWqvvdQHVbFnZXWqxh7fW/RQMwFCZT4/leVuCYiz9ajAb/71bwodcGY23paVIcbbkJUPIT X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Sep 2026 10:39:30.5760 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 6562345d-f95a-414d-97f9-08df13deca37 X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a;Ip=[216.228.117.160];Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: BY1PEPF00026966.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DSVPR12MB999150 Content-Type: text/plain; charset="utf-8" The driver preserves the OSPM-set registers across CPU hotplug, but system suspend/resume is a separate path. On platforms that reset those registers or the performance controls across suspend, the values are lost. The hotplug callbacks cannot cover suspend on their own. Secondary CPUs go offline only after devices are suspended, too late to touch the CPPC registers. offline() does not run for every policy either, as the boot CPU stays up during suspend-to-RAM and no CPU goes offline during suspend-to-idle. The driver's suspend() callback runs earlier, from cpufreq_suspend(), while all CPUs are still online and no device is suspended, so CPPC access is still safe. Reuse the same save/restore mechanism for suspend/resume: - suspend() saves the current OSPM-set values, restores the firmware ones and sets a per-policy flag, suspend_regs_handled, to record that. It also stops the frequency invariance updates, so that no sample spans the suspend window. - offline() sees the flag and skips the save and restore, as suspend() has already done both. Saving again would capture the firmware values that suspend() wrote back and lose what the OS set. It still requests the lowest desired performance. - online() clears the flag, so that a later offline() takes a fresh snapshot. It also restarts the frequency invariance updates. - resume() calls online() for a policy that still has the flag set. CPUs offlined during suspend come back before the core calls resume(), so online() has already run for their policies and cleared the flag. Suggested-by: Christian Loehle Signed-off-by: Sumit Gupta Tested-by: K Prateek Nayak --- drivers/cpufreq/cppc_cpufreq.c | 63 ++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index ac315071a979..11f2e8111ef9 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c @@ -87,6 +87,12 @@ struct cppc_saved_vals { =20 struct cppc_policy_state { struct cppc_saved_vals regs[CPPC_NR_SAVED_REGS]; + /* + * Set by suspend() after it saves the OSPM-set values and restores the + * firmware ones, so a later offline() does not repeat those accesses. + * Cleared at init() and by online(). + */ + bool suspend_regs_handled; }; =20 static DEFINE_PER_CPU(struct cppc_policy_state, cppc_policy_state); @@ -895,6 +901,7 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy = *policy) policy->cur =3D cppc_perf_to_khz(caps, caps->highest_perf); cpu_data->perf_ctrls.desired_perf =3D caps->highest_perf; =20 + cppc_cpufreq_policy_state(policy)->suspend_regs_handled =3D false; cppc_cpufreq_save_regs(policy, CPPC_SAVED_FIRMWARE); =20 ret =3D cppc_set_perf(cpu, &cpu_data->perf_ctrls); @@ -986,6 +993,8 @@ static int cppc_cpufreq_cpu_online(struct cpufreq_polic= y *policy) unsigned int cpu =3D policy->cpu; int ret; =20 + cppc_cpufreq_policy_state(policy)->suspend_regs_handled =3D false; + ret =3D cppc_set_enable(cpu, true); if (ret && ret !=3D -EOPNOTSUPP) { pr_warn("Failed to re-enable CPPC for CPU%u (%d)\n", cpu, ret); @@ -1034,9 +1043,14 @@ static int cppc_cpufreq_cpu_offline(struct cpufreq_p= olicy *policy) unsigned int cpu =3D policy->cpu; int ret; =20 - /* Save what the OS set, and leave the platform in its pre-driver state. = */ - cppc_cpufreq_save_regs(policy, CPPC_SAVED_REQUESTED); - cppc_cpufreq_apply_saved_regs(policy, CPPC_SAVED_FIRMWARE); + /* + * Save what the OS set and leave the platform in its pre-driver state, + * unless suspend() already did so earlier in this suspend cycle. + */ + if (!cppc_cpufreq_policy_state(policy)->suspend_regs_handled) { + cppc_cpufreq_save_regs(policy, CPPC_SAVED_REQUESTED); + cppc_cpufreq_apply_saved_regs(policy, CPPC_SAVED_FIRMWARE); + } =20 /* * Stop the frequency invariance updates and cancel the pending work, so @@ -1061,6 +1075,47 @@ static int cppc_cpufreq_cpu_offline(struct cpufreq_p= olicy *policy) return 0; } =20 +/* + * Run for every active policy when the system suspends, before any CPU go= es + * offline. + * + * Save the OSPM-set values and restore the firmware values here, while CP= PC + * access is still safe. Secondary CPUs go offline much later, with devices + * already suspended. That is too late for these accesses, so offline() sk= ips + * them. Doing it here also covers a policy whose CPUs stay online, for wh= ich + * offline() never runs. + * + * Stop the frequency invariance updates here as well, so that no sample s= pans + * the suspend window. offline() would not do it for a policy whose CPUs s= tay + * online. online() restarts them on the way back. + */ +static int cppc_cpufreq_cpu_suspend(struct cpufreq_policy *policy) +{ + cppc_cpufreq_save_regs(policy, CPPC_SAVED_REQUESTED); + cppc_cpufreq_apply_saved_regs(policy, CPPC_SAVED_FIRMWARE); + cppc_cpufreq_policy_state(policy)->suspend_regs_handled =3D true; + + cppc_cpufreq_cpu_fie_exit(policy); + + return 0; +} + +/* + * Run the online() restore for a policy whose CPUs stayed online through + * suspend. + * + * CPUs offlined during suspend come back before the core calls resume(), = so + * online() has already run for their policies and cleared the flag. Only a + * policy that still has it set needs online() here. + */ +static int cppc_cpufreq_cpu_resume(struct cpufreq_policy *policy) +{ + if (!cppc_cpufreq_policy_state(policy)->suspend_regs_handled) + return 0; + + return cppc_cpufreq_cpu_online(policy); +} + static inline u64 get_delta(u64 t1, u64 t0) { if (t1 > t0 || t0 > ~(u32)0) @@ -1356,6 +1411,8 @@ static struct cpufreq_driver cppc_cpufreq_driver =3D { .exit =3D cppc_cpufreq_cpu_exit, .online =3D cppc_cpufreq_cpu_online, .offline =3D cppc_cpufreq_cpu_offline, + .suspend =3D cppc_cpufreq_cpu_suspend, + .resume =3D cppc_cpufreq_cpu_resume, .set_boost =3D cppc_cpufreq_set_boost, .attr =3D cppc_cpufreq_attr, .name =3D "cppc_cpufreq", --=20 2.34.1