Skip to content

Commit 95f2ce5

Browse files
committed
Merge branches 'pm-core', 'pm-sleep' and 'powercap'
Merge PM core changes, updates related to system sleep and power capping updates for 5.19-rc1: - Export dev_pm_ops instead of suspend() and resume() in the IIO chemical scd30 driver (Jonathan Cameron). - Add namespace variants of EXPORT[_GPL]_SIMPLE_DEV_PM_OPS and PM-runtime counterparts (Jonathan Cameron). - Move symbol exports in the IIO chemical scd30 driver into the IIO_SCD30 namespace (Jonathan Cameron). - Avoid device PM-runtime usage count underflows (Rafael Wysocki). - Allow dynamic debug to control printing of PM messages (David Cohen). - Fix some kernel-doc comments in hibernation code (Yang Li, Haowen Bai). - Preserve ACPI-table override during hibernation (Amadeusz Sławiński). - Improve support for suspend-to-RAM for PSCI OSI mode (Ulf Hansson). - Make Intel RAPL power capping driver support the RaptorLake and AlderLake N processors (Zhang Rui, Sumeet Pawnikar). - Remove redundant store to value after multiply in the RAPL power capping driver (Colin Ian King). * pm-core: PM: runtime: Avoid device usage count underflows iio: chemical: scd30: Move symbol exports into IIO_SCD30 namespace PM: core: Add NS varients of EXPORT[_GPL]_SIMPLE_DEV_PM_OPS and runtime pm equiv iio: chemical: scd30: Export dev_pm_ops instead of suspend() and resume() * pm-sleep: cpuidle: PSCI: Improve support for suspend-to-RAM for PSCI OSI mode PM: runtime: Allow to call __pm_runtime_set_status() from atomic context PM: hibernate: Don't mark comment as kernel-doc x86/ACPI: Preserve ACPI-table override during hibernation PM: hibernate: Fix some kernel-doc comments PM: sleep: enable dynamic debug support within pm_pr_dbg() PM: sleep: Narrow down -DDEBUG on kernel/power/ files * powercap: powercap: intel_rapl: remove redundant store to value after multiply powercap: intel_rapl: add support for ALDERLAKE_N powercap: RAPL: Add Power Limit4 support for RaptorLake powercap: intel_rapl: add support for RaptorLake
4 parents 42d2607 + 82586a7 + 171b66e + 59cafa7 commit 95f2ce5

16 files changed

Lines changed: 172 additions & 73 deletions

File tree

arch/x86/kernel/acpi/boot.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1772,7 +1772,7 @@ int __acpi_release_global_lock(unsigned int *lock)
17721772

17731773
void __init arch_reserve_mem_area(acpi_physical_address addr, size_t size)
17741774
{
1775-
e820__range_add(addr, size, E820_TYPE_ACPI);
1775+
e820__range_add(addr, size, E820_TYPE_NVS);
17761776
e820__update_table_print();
17771777
}
17781778

drivers/base/power/runtime.c

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ static int rpm_check_suspend_allowed(struct device *dev)
263263
retval = -EINVAL;
264264
else if (dev->power.disable_depth > 0)
265265
retval = -EACCES;
266-
else if (atomic_read(&dev->power.usage_count) > 0)
266+
else if (atomic_read(&dev->power.usage_count))
267267
retval = -EAGAIN;
268268
else if (!dev->power.ignore_children &&
269269
atomic_read(&dev->power.child_count))
@@ -1039,13 +1039,33 @@ int pm_schedule_suspend(struct device *dev, unsigned int delay)
10391039
}
10401040
EXPORT_SYMBOL_GPL(pm_schedule_suspend);
10411041

1042+
static int rpm_drop_usage_count(struct device *dev)
1043+
{
1044+
int ret;
1045+
1046+
ret = atomic_sub_return(1, &dev->power.usage_count);
1047+
if (ret >= 0)
1048+
return ret;
1049+
1050+
/*
1051+
* Because rpm_resume() does not check the usage counter, it will resume
1052+
* the device even if the usage counter is 0 or negative, so it is
1053+
* sufficient to increment the usage counter here to reverse the change
1054+
* made above.
1055+
*/
1056+
atomic_inc(&dev->power.usage_count);
1057+
dev_warn(dev, "Runtime PM usage count underflow!\n");
1058+
return -EINVAL;
1059+
}
1060+
10421061
/**
10431062
* __pm_runtime_idle - Entry point for runtime idle operations.
10441063
* @dev: Device to send idle notification for.
10451064
* @rpmflags: Flag bits.
10461065
*
10471066
* If the RPM_GET_PUT flag is set, decrement the device's usage count and
1048-
* return immediately if it is larger than zero. Then carry out an idle
1067+
* return immediately if it is larger than zero (if it becomes negative, log a
1068+
* warning, increment it, and return an error). Then carry out an idle
10491069
* notification, either synchronous or asynchronous.
10501070
*
10511071
* This routine may be called in atomic context if the RPM_ASYNC flag is set,
@@ -1057,7 +1077,10 @@ int __pm_runtime_idle(struct device *dev, int rpmflags)
10571077
int retval;
10581078

10591079
if (rpmflags & RPM_GET_PUT) {
1060-
if (!atomic_dec_and_test(&dev->power.usage_count)) {
1080+
retval = rpm_drop_usage_count(dev);
1081+
if (retval < 0) {
1082+
return retval;
1083+
} else if (retval > 0) {
10611084
trace_rpm_usage_rcuidle(dev, rpmflags);
10621085
return 0;
10631086
}
@@ -1079,7 +1102,8 @@ EXPORT_SYMBOL_GPL(__pm_runtime_idle);
10791102
* @rpmflags: Flag bits.
10801103
*
10811104
* If the RPM_GET_PUT flag is set, decrement the device's usage count and
1082-
* return immediately if it is larger than zero. Then carry out a suspend,
1105+
* return immediately if it is larger than zero (if it becomes negative, log a
1106+
* warning, increment it, and return an error). Then carry out a suspend,
10831107
* either synchronous or asynchronous.
10841108
*
10851109
* This routine may be called in atomic context if the RPM_ASYNC flag is set,
@@ -1091,7 +1115,10 @@ int __pm_runtime_suspend(struct device *dev, int rpmflags)
10911115
int retval;
10921116

10931117
if (rpmflags & RPM_GET_PUT) {
1094-
if (!atomic_dec_and_test(&dev->power.usage_count)) {
1118+
retval = rpm_drop_usage_count(dev);
1119+
if (retval < 0) {
1120+
return retval;
1121+
} else if (retval > 0) {
10951122
trace_rpm_usage_rcuidle(dev, rpmflags);
10961123
return 0;
10971124
}
@@ -1210,12 +1237,13 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status)
12101237
{
12111238
struct device *parent = dev->parent;
12121239
bool notify_parent = false;
1240+
unsigned long flags;
12131241
int error = 0;
12141242

12151243
if (status != RPM_ACTIVE && status != RPM_SUSPENDED)
12161244
return -EINVAL;
12171245

1218-
spin_lock_irq(&dev->power.lock);
1246+
spin_lock_irqsave(&dev->power.lock, flags);
12191247

12201248
/*
12211249
* Prevent PM-runtime from being enabled for the device or return an
@@ -1226,7 +1254,7 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status)
12261254
else
12271255
error = -EAGAIN;
12281256

1229-
spin_unlock_irq(&dev->power.lock);
1257+
spin_unlock_irqrestore(&dev->power.lock, flags);
12301258

12311259
if (error)
12321260
return error;
@@ -1247,7 +1275,7 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status)
12471275
device_links_read_unlock(idx);
12481276
}
12491277

1250-
spin_lock_irq(&dev->power.lock);
1278+
spin_lock_irqsave(&dev->power.lock, flags);
12511279

12521280
if (dev->power.runtime_status == status || !parent)
12531281
goto out_set;
@@ -1288,7 +1316,7 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status)
12881316
dev->power.runtime_error = 0;
12891317

12901318
out:
1291-
spin_unlock_irq(&dev->power.lock);
1319+
spin_unlock_irqrestore(&dev->power.lock, flags);
12921320

12931321
if (notify_parent)
12941322
pm_request_idle(parent);
@@ -1527,14 +1555,17 @@ EXPORT_SYMBOL_GPL(pm_runtime_forbid);
15271555
*/
15281556
void pm_runtime_allow(struct device *dev)
15291557
{
1558+
int ret;
1559+
15301560
spin_lock_irq(&dev->power.lock);
15311561
if (dev->power.runtime_auto)
15321562
goto out;
15331563

15341564
dev->power.runtime_auto = true;
1535-
if (atomic_dec_and_test(&dev->power.usage_count))
1565+
ret = rpm_drop_usage_count(dev);
1566+
if (ret == 0)
15361567
rpm_idle(dev, RPM_AUTO | RPM_ASYNC);
1537-
else
1568+
else if (ret > 0)
15381569
trace_rpm_usage_rcuidle(dev, RPM_AUTO | RPM_ASYNC);
15391570

15401571
out:

drivers/cpuidle/cpuidle-psci.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <linux/pm_runtime.h>
2424
#include <linux/slab.h>
2525
#include <linux/string.h>
26+
#include <linux/syscore_ops.h>
2627

2728
#include <asm/cpuidle.h>
2829

@@ -131,13 +132,58 @@ static int psci_idle_cpuhp_down(unsigned int cpu)
131132
return 0;
132133
}
133134

135+
static void psci_idle_syscore_switch(bool suspend)
136+
{
137+
bool cleared = false;
138+
struct device *dev;
139+
int cpu;
140+
141+
for_each_possible_cpu(cpu) {
142+
dev = per_cpu_ptr(&psci_cpuidle_data, cpu)->dev;
143+
144+
if (dev && suspend) {
145+
dev_pm_genpd_suspend(dev);
146+
} else if (dev) {
147+
dev_pm_genpd_resume(dev);
148+
149+
/* Account for userspace having offlined a CPU. */
150+
if (pm_runtime_status_suspended(dev))
151+
pm_runtime_set_active(dev);
152+
153+
/* Clear domain state to re-start fresh. */
154+
if (!cleared) {
155+
psci_set_domain_state(0);
156+
cleared = true;
157+
}
158+
}
159+
}
160+
}
161+
162+
static int psci_idle_syscore_suspend(void)
163+
{
164+
psci_idle_syscore_switch(true);
165+
return 0;
166+
}
167+
168+
static void psci_idle_syscore_resume(void)
169+
{
170+
psci_idle_syscore_switch(false);
171+
}
172+
173+
static struct syscore_ops psci_idle_syscore_ops = {
174+
.suspend = psci_idle_syscore_suspend,
175+
.resume = psci_idle_syscore_resume,
176+
};
177+
134178
static void psci_idle_init_cpuhp(void)
135179
{
136180
int err;
137181

138182
if (!psci_cpuidle_use_cpuhp)
139183
return;
140184

185+
register_syscore_ops(&psci_idle_syscore_ops);
186+
141187
err = cpuhp_setup_state_nocalls(CPUHP_AP_CPU_PM_STARTING,
142188
"cpuidle/psci:online",
143189
psci_idle_cpuhp_up,

drivers/iio/chemical/scd30.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,7 @@ struct scd30_state {
6868
scd30_command_t command;
6969
};
7070

71-
int scd30_suspend(struct device *dev);
72-
int scd30_resume(struct device *dev);
73-
74-
static __maybe_unused SIMPLE_DEV_PM_OPS(scd30_pm_ops, scd30_suspend, scd30_resume);
71+
extern const struct dev_pm_ops scd30_pm_ops;
7572

7673
int scd30_probe(struct device *dev, int irq, const char *name, void *priv, scd30_command_t command);
7774

drivers/iio/chemical/scd30_core.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ static const struct iio_chan_spec scd30_channels[] = {
517517
IIO_CHAN_SOFT_TIMESTAMP(3),
518518
};
519519

520-
int __maybe_unused scd30_suspend(struct device *dev)
520+
static int scd30_suspend(struct device *dev)
521521
{
522522
struct iio_dev *indio_dev = dev_get_drvdata(dev);
523523
struct scd30_state *state = iio_priv(indio_dev);
@@ -529,9 +529,8 @@ int __maybe_unused scd30_suspend(struct device *dev)
529529

530530
return regulator_disable(state->vdd);
531531
}
532-
EXPORT_SYMBOL(scd30_suspend);
533532

534-
int __maybe_unused scd30_resume(struct device *dev)
533+
static int scd30_resume(struct device *dev)
535534
{
536535
struct iio_dev *indio_dev = dev_get_drvdata(dev);
537536
struct scd30_state *state = iio_priv(indio_dev);
@@ -543,7 +542,8 @@ int __maybe_unused scd30_resume(struct device *dev)
543542

544543
return scd30_command_write(state, CMD_START_MEAS, state->pressure_comp);
545544
}
546-
EXPORT_SYMBOL(scd30_resume);
545+
546+
EXPORT_NS_SIMPLE_DEV_PM_OPS(scd30_pm_ops, scd30_suspend, scd30_resume, IIO_SCD30);
547547

548548
static void scd30_stop_meas(void *data)
549549
{
@@ -759,7 +759,7 @@ int scd30_probe(struct device *dev, int irq, const char *name, void *priv,
759759

760760
return devm_iio_device_register(dev, indio_dev);
761761
}
762-
EXPORT_SYMBOL(scd30_probe);
762+
EXPORT_SYMBOL_NS(scd30_probe, IIO_SCD30);
763763

764764
MODULE_AUTHOR("Tomasz Duszynski <tomasz.duszynski@octakon.com>");
765765
MODULE_DESCRIPTION("Sensirion SCD30 carbon dioxide sensor core driver");

drivers/iio/chemical/scd30_i2c.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ static struct i2c_driver scd30_i2c_driver = {
128128
.driver = {
129129
.name = KBUILD_MODNAME,
130130
.of_match_table = scd30_i2c_of_match,
131-
.pm = &scd30_pm_ops,
131+
.pm = pm_sleep_ptr(&scd30_pm_ops),
132132
},
133133
.probe_new = scd30_i2c_probe,
134134
};
@@ -137,3 +137,4 @@ module_i2c_driver(scd30_i2c_driver);
137137
MODULE_AUTHOR("Tomasz Duszynski <tomasz.duszynski@octakon.com>");
138138
MODULE_DESCRIPTION("Sensirion SCD30 carbon dioxide sensor i2c driver");
139139
MODULE_LICENSE("GPL v2");
140+
MODULE_IMPORT_NS(IIO_SCD30);

drivers/iio/chemical/scd30_serial.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ static struct serdev_device_driver scd30_serdev_driver = {
252252
.driver = {
253253
.name = KBUILD_MODNAME,
254254
.of_match_table = scd30_serdev_of_match,
255-
.pm = &scd30_pm_ops,
255+
.pm = pm_sleep_ptr(&scd30_pm_ops),
256256
},
257257
.probe = scd30_serdev_probe,
258258
};
@@ -261,3 +261,4 @@ module_serdev_device_driver(scd30_serdev_driver);
261261
MODULE_AUTHOR("Tomasz Duszynski <tomasz.duszynski@octakon.com>");
262262
MODULE_DESCRIPTION("Sensirion SCD30 carbon dioxide sensor serial driver");
263263
MODULE_LICENSE("GPL v2");
264+
MODULE_IMPORT_NS(IIO_SCD30);

drivers/powercap/intel_rapl_common.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1010,7 +1010,7 @@ static u64 rapl_compute_time_window_atom(struct rapl_package *rp, u64 value,
10101010
* where time_unit is default to 1 sec. Never 0.
10111011
*/
10121012
if (!to_raw)
1013-
return (value) ? value *= rp->time_unit : rp->time_unit;
1013+
return (value) ? value * rp->time_unit : rp->time_unit;
10141014

10151015
value = div64_u64(value, rp->time_unit);
10161016

@@ -1107,6 +1107,8 @@ static const struct x86_cpu_id rapl_ids[] __initconst = {
11071107
X86_MATCH_INTEL_FAM6_MODEL(ROCKETLAKE, &rapl_defaults_core),
11081108
X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, &rapl_defaults_core),
11091109
X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, &rapl_defaults_core),
1110+
X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_N, &rapl_defaults_core),
1111+
X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, &rapl_defaults_core),
11101112
X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &rapl_defaults_spr_server),
11111113
X86_MATCH_INTEL_FAM6_MODEL(LAKEFIELD, &rapl_defaults_core),
11121114

drivers/powercap/intel_rapl_msr.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ static const struct x86_cpu_id pl4_support_ids[] = {
140140
{ X86_VENDOR_INTEL, 6, INTEL_FAM6_TIGERLAKE_L, X86_FEATURE_ANY },
141141
{ X86_VENDOR_INTEL, 6, INTEL_FAM6_ALDERLAKE, X86_FEATURE_ANY },
142142
{ X86_VENDOR_INTEL, 6, INTEL_FAM6_ALDERLAKE_L, X86_FEATURE_ANY },
143+
{ X86_VENDOR_INTEL, 6, INTEL_FAM6_RAPTORLAKE, X86_FEATURE_ANY },
143144
{}
144145
};
145146

include/linux/pm.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -368,13 +368,13 @@ const struct dev_pm_ops name = { \
368368

369369
#ifdef CONFIG_PM
370370
#define _EXPORT_DEV_PM_OPS(name, suspend_fn, resume_fn, runtime_suspend_fn, \
371-
runtime_resume_fn, idle_fn, sec) \
371+
runtime_resume_fn, idle_fn, sec, ns) \
372372
_DEFINE_DEV_PM_OPS(name, suspend_fn, resume_fn, runtime_suspend_fn, \
373373
runtime_resume_fn, idle_fn); \
374-
_EXPORT_SYMBOL(name, sec)
374+
__EXPORT_SYMBOL(name, sec, ns)
375375
#else
376376
#define _EXPORT_DEV_PM_OPS(name, suspend_fn, resume_fn, runtime_suspend_fn, \
377-
runtime_resume_fn, idle_fn, sec) \
377+
runtime_resume_fn, idle_fn, sec, ns) \
378378
static __maybe_unused _DEFINE_DEV_PM_OPS(__static_##name, suspend_fn, \
379379
resume_fn, runtime_suspend_fn, \
380380
runtime_resume_fn, idle_fn)
@@ -391,9 +391,13 @@ static __maybe_unused _DEFINE_DEV_PM_OPS(__static_##name, suspend_fn, \
391391
_DEFINE_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL)
392392

393393
#define EXPORT_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \
394-
_EXPORT_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL, "")
394+
_EXPORT_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL, "", "")
395395
#define EXPORT_GPL_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \
396-
_EXPORT_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL, "_gpl")
396+
_EXPORT_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL, "_gpl", "")
397+
#define EXPORT_NS_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn, ns) \
398+
_EXPORT_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL, "", #ns)
399+
#define EXPORT_NS_GPL_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn, ns) \
400+
_EXPORT_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL, "_gpl", #ns)
397401

398402
/* Deprecated. Use DEFINE_SIMPLE_DEV_PM_OPS() instead. */
399403
#define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \

0 commit comments

Comments
 (0)