[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260129183646.558866-9-sathyanarayanan.kuppuswamy@linux.intel.com>
Date: Thu, 29 Jan 2026 10:36:45 -0800
From: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@...ux.intel.com>
To: "Rafael J . Wysocki" <rafael@...nel.org>,
Daniel Lezcano <daniel.lezcano@...aro.org>
Cc: Zhang Rui <rui.zhang@...el.com>,
Lukasz Luba <lukasz.luba@....com>,
Srinivas Pandruvada <srinivas.pandruvada@...ux.intel.com>,
linux-pm@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: [PATCH v1 8/9] powercap: intel_rapl: Register PM notifier only when RAPL package exists
The PM notifier callbacks are needed only when a valid RAPL package
device is registered. Register and unregister the PM notifier callbacks
when a RAPL package device is added or removed.
This is a preparatory patch before moving MSR rapl_defaults into the
MSR RAPL interface driver.
Co-developed-by: Zhang Rui <rui.zhang@...el.com>
Signed-off-by: Zhang Rui <rui.zhang@...el.com>
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@...ux.intel.com>
---
drivers/powercap/intel_rapl_common.c | 130 +++++++++++++--------------
1 file changed, 64 insertions(+), 66 deletions(-)
diff --git a/drivers/powercap/intel_rapl_common.c b/drivers/powercap/intel_rapl_common.c
index 54d88f1311ed..648bef1d5de1 100644
--- a/drivers/powercap/intel_rapl_common.c
+++ b/drivers/powercap/intel_rapl_common.c
@@ -2077,6 +2077,64 @@ void rapl_package_remove_pmu(struct rapl_package *rp)
EXPORT_SYMBOL_NS_GPL(rapl_package_remove_pmu, "INTEL_RAPL");
#endif
+/* pm notifier for saving/restoring Power Limit settings */
+static void power_limit_state_save(void)
+{
+ struct rapl_package *rp;
+ struct rapl_domain *rd;
+ int ret;
+
+ cpus_read_lock();
+ list_for_each_entry(rp, &rapl_packages, plist) {
+ if (!rp->power_zone)
+ continue;
+ rd = power_zone_to_rapl_domain(rp->power_zone);
+ for (int i = POWER_LIMIT1; i < NR_POWER_LIMITS; i++) {
+ ret = rapl_read_pl_data(rd, i, PL_LIMIT, true,
+ &rd->rpl[i].last_power_limit);
+ if (ret)
+ rd->rpl[i].last_power_limit = 0;
+ }
+ }
+ cpus_read_unlock();
+}
+
+static void power_limit_state_restore(void)
+{
+ struct rapl_package *rp;
+ struct rapl_domain *rd;
+
+ cpus_read_lock();
+ list_for_each_entry(rp, &rapl_packages, plist) {
+ if (!rp->power_zone)
+ continue;
+ rd = power_zone_to_rapl_domain(rp->power_zone);
+ for (int i = POWER_LIMIT1; i < NR_POWER_LIMITS; i++)
+ if (rd->rpl[i].last_power_limit)
+ rapl_write_pl_data(rd, i, PL_LIMIT,
+ rd->rpl[i].last_power_limit);
+ }
+ cpus_read_unlock();
+}
+
+static int rapl_pm_callback(struct notifier_block *nb,
+ unsigned long mode, void *_unused)
+{
+ switch (mode) {
+ case PM_SUSPEND_PREPARE:
+ power_limit_state_save();
+ break;
+ case PM_POST_SUSPEND:
+ power_limit_state_restore();
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block rapl_pm_notifier = {
+ .notifier_call = rapl_pm_callback,
+};
+
/* called from CPU hotplug notifier, hotplug lock held */
void rapl_remove_package_cpuslocked(struct rapl_package *rp)
{
@@ -2106,6 +2164,9 @@ void rapl_remove_package_cpuslocked(struct rapl_package *rp)
&rd_package->power_zone);
list_del(&rp->plist);
kfree(rp);
+
+ if (list_empty(&rapl_packages))
+ unregister_pm_notifier(&rapl_pm_notifier);
}
EXPORT_SYMBOL_NS_GPL(rapl_remove_package_cpuslocked, "INTEL_RAPL");
@@ -2208,6 +2269,8 @@ struct rapl_package *rapl_add_package_cpuslocked(int id, struct rapl_if_priv *pr
}
ret = rapl_package_register_powercap(rp);
if (!ret) {
+ if (list_empty(&rapl_packages))
+ register_pm_notifier(&rapl_pm_notifier);
INIT_LIST_HEAD(&rp->plist);
list_add(&rp->plist, &rapl_packages);
return rp;
@@ -2227,64 +2290,6 @@ struct rapl_package *rapl_add_package(int id, struct rapl_if_priv *priv, bool id
}
EXPORT_SYMBOL_NS_GPL(rapl_add_package, "INTEL_RAPL");
-static void power_limit_state_save(void)
-{
- struct rapl_package *rp;
- struct rapl_domain *rd;
- int ret, i;
-
- cpus_read_lock();
- list_for_each_entry(rp, &rapl_packages, plist) {
- if (!rp->power_zone)
- continue;
- rd = power_zone_to_rapl_domain(rp->power_zone);
- for (i = POWER_LIMIT1; i < NR_POWER_LIMITS; i++) {
- ret = rapl_read_pl_data(rd, i, PL_LIMIT, true,
- &rd->rpl[i].last_power_limit);
- if (ret)
- rd->rpl[i].last_power_limit = 0;
- }
- }
- cpus_read_unlock();
-}
-
-static void power_limit_state_restore(void)
-{
- struct rapl_package *rp;
- struct rapl_domain *rd;
- int i;
-
- cpus_read_lock();
- list_for_each_entry(rp, &rapl_packages, plist) {
- if (!rp->power_zone)
- continue;
- rd = power_zone_to_rapl_domain(rp->power_zone);
- for (i = POWER_LIMIT1; i < NR_POWER_LIMITS; i++)
- if (rd->rpl[i].last_power_limit)
- rapl_write_pl_data(rd, i, PL_LIMIT,
- rd->rpl[i].last_power_limit);
- }
- cpus_read_unlock();
-}
-
-static int rapl_pm_callback(struct notifier_block *nb,
- unsigned long mode, void *_unused)
-{
- switch (mode) {
- case PM_SUSPEND_PREPARE:
- power_limit_state_save();
- break;
- case PM_POST_SUSPEND:
- power_limit_state_restore();
- break;
- }
- return NOTIFY_OK;
-}
-
-static struct notifier_block rapl_pm_notifier = {
- .notifier_call = rapl_pm_callback,
-};
-
static struct platform_device *rapl_msr_platdev;
static int __init rapl_init(void)
@@ -2307,19 +2312,12 @@ static int __init rapl_init(void)
}
}
- ret = register_pm_notifier(&rapl_pm_notifier);
- if (ret && rapl_msr_platdev) {
- platform_device_del(rapl_msr_platdev);
- platform_device_put(rapl_msr_platdev);
- }
-
- return ret;
+ return 0;
}
static void __exit rapl_exit(void)
{
platform_device_unregister(rapl_msr_platdev);
- unregister_pm_notifier(&rapl_pm_notifier);
}
fs_initcall(rapl_init);
--
2.43.0
Powered by blists - more mailing lists