Commit 95f2ce54 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

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
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1772,7 +1772,7 @@ int __acpi_release_global_lock(unsigned int *lock)

void __init arch_reserve_mem_area(acpi_physical_address addr, size_t size)
{
	e820__range_add(addr, size, E820_TYPE_ACPI);
	e820__range_add(addr, size, E820_TYPE_NVS);
	e820__update_table_print();
}

+42 −11
Original line number Diff line number Diff line
@@ -263,7 +263,7 @@ static int rpm_check_suspend_allowed(struct device *dev)
		retval = -EINVAL;
	else if (dev->power.disable_depth > 0)
		retval = -EACCES;
	else if (atomic_read(&dev->power.usage_count) > 0)
	else if (atomic_read(&dev->power.usage_count))
		retval = -EAGAIN;
	else if (!dev->power.ignore_children &&
			atomic_read(&dev->power.child_count))
@@ -1039,13 +1039,33 @@ int pm_schedule_suspend(struct device *dev, unsigned int delay)
}
EXPORT_SYMBOL_GPL(pm_schedule_suspend);

static int rpm_drop_usage_count(struct device *dev)
{
	int ret;

	ret = atomic_sub_return(1, &dev->power.usage_count);
	if (ret >= 0)
		return ret;

	/*
	 * Because rpm_resume() does not check the usage counter, it will resume
	 * the device even if the usage counter is 0 or negative, so it is
	 * sufficient to increment the usage counter here to reverse the change
	 * made above.
	 */
	atomic_inc(&dev->power.usage_count);
	dev_warn(dev, "Runtime PM usage count underflow!\n");
	return -EINVAL;
}

/**
 * __pm_runtime_idle - Entry point for runtime idle operations.
 * @dev: Device to send idle notification for.
 * @rpmflags: Flag bits.
 *
 * If the RPM_GET_PUT flag is set, decrement the device's usage count and
 * return immediately if it is larger than zero.  Then carry out an idle
 * return immediately if it is larger than zero (if it becomes negative, log a
 * warning, increment it, and return an error).  Then carry out an idle
 * notification, either synchronous or asynchronous.
 *
 * 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)
	int retval;

	if (rpmflags & RPM_GET_PUT) {
		if (!atomic_dec_and_test(&dev->power.usage_count)) {
		retval = rpm_drop_usage_count(dev);
		if (retval < 0) {
			return retval;
		} else if (retval > 0) {
			trace_rpm_usage_rcuidle(dev, rpmflags);
			return 0;
		}
@@ -1079,7 +1102,8 @@ EXPORT_SYMBOL_GPL(__pm_runtime_idle);
 * @rpmflags: Flag bits.
 *
 * If the RPM_GET_PUT flag is set, decrement the device's usage count and
 * return immediately if it is larger than zero.  Then carry out a suspend,
 * return immediately if it is larger than zero (if it becomes negative, log a
 * warning, increment it, and return an error).  Then carry out a suspend,
 * either synchronous or asynchronous.
 *
 * 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)
	int retval;

	if (rpmflags & RPM_GET_PUT) {
		if (!atomic_dec_and_test(&dev->power.usage_count)) {
		retval = rpm_drop_usage_count(dev);
		if (retval < 0) {
			return retval;
		} else if (retval > 0) {
			trace_rpm_usage_rcuidle(dev, rpmflags);
			return 0;
		}
@@ -1210,12 +1237,13 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status)
{
	struct device *parent = dev->parent;
	bool notify_parent = false;
	unsigned long flags;
	int error = 0;

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

	spin_lock_irq(&dev->power.lock);
	spin_lock_irqsave(&dev->power.lock, flags);

	/*
	 * 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)
	else
		error = -EAGAIN;

	spin_unlock_irq(&dev->power.lock);
	spin_unlock_irqrestore(&dev->power.lock, flags);

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

	spin_lock_irq(&dev->power.lock);
	spin_lock_irqsave(&dev->power.lock, flags);

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

 out:
	spin_unlock_irq(&dev->power.lock);
	spin_unlock_irqrestore(&dev->power.lock, flags);

	if (notify_parent)
		pm_request_idle(parent);
@@ -1527,14 +1555,17 @@ EXPORT_SYMBOL_GPL(pm_runtime_forbid);
 */
void pm_runtime_allow(struct device *dev)
{
	int ret;

	spin_lock_irq(&dev->power.lock);
	if (dev->power.runtime_auto)
		goto out;

	dev->power.runtime_auto = true;
	if (atomic_dec_and_test(&dev->power.usage_count))
	ret = rpm_drop_usage_count(dev);
	if (ret == 0)
		rpm_idle(dev, RPM_AUTO | RPM_ASYNC);
	else
	else if (ret > 0)
		trace_rpm_usage_rcuidle(dev, RPM_AUTO | RPM_ASYNC);

 out:
+46 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/syscore_ops.h>

#include <asm/cpuidle.h>

@@ -131,6 +132,49 @@ static int psci_idle_cpuhp_down(unsigned int cpu)
	return 0;
}

static void psci_idle_syscore_switch(bool suspend)
{
	bool cleared = false;
	struct device *dev;
	int cpu;

	for_each_possible_cpu(cpu) {
		dev = per_cpu_ptr(&psci_cpuidle_data, cpu)->dev;

		if (dev && suspend) {
			dev_pm_genpd_suspend(dev);
		} else if (dev) {
			dev_pm_genpd_resume(dev);

			/* Account for userspace having offlined a CPU. */
			if (pm_runtime_status_suspended(dev))
				pm_runtime_set_active(dev);

			/* Clear domain state to re-start fresh. */
			if (!cleared) {
				psci_set_domain_state(0);
				cleared = true;
			}
		}
	}
}

static int psci_idle_syscore_suspend(void)
{
	psci_idle_syscore_switch(true);
	return 0;
}

static void psci_idle_syscore_resume(void)
{
	psci_idle_syscore_switch(false);
}

static struct syscore_ops psci_idle_syscore_ops = {
	.suspend = psci_idle_syscore_suspend,
	.resume = psci_idle_syscore_resume,
};

static void psci_idle_init_cpuhp(void)
{
	int err;
@@ -138,6 +182,8 @@ static void psci_idle_init_cpuhp(void)
	if (!psci_cpuidle_use_cpuhp)
		return;

	register_syscore_ops(&psci_idle_syscore_ops);

	err = cpuhp_setup_state_nocalls(CPUHP_AP_CPU_PM_STARTING,
					"cpuidle/psci:online",
					psci_idle_cpuhp_up,
+1 −4
Original line number Diff line number Diff line
@@ -68,10 +68,7 @@ struct scd30_state {
	scd30_command_t command;
};

int scd30_suspend(struct device *dev);
int scd30_resume(struct device *dev);

static __maybe_unused SIMPLE_DEV_PM_OPS(scd30_pm_ops, scd30_suspend, scd30_resume);
extern const struct dev_pm_ops scd30_pm_ops;

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

+5 −5
Original line number Diff line number Diff line
@@ -517,7 +517,7 @@ static const struct iio_chan_spec scd30_channels[] = {
	IIO_CHAN_SOFT_TIMESTAMP(3),
};

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

	return regulator_disable(state->vdd);
}
EXPORT_SYMBOL(scd30_suspend);

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

	return scd30_command_write(state, CMD_START_MEAS, state->pressure_comp);
}
EXPORT_SYMBOL(scd30_resume);

EXPORT_NS_SIMPLE_DEV_PM_OPS(scd30_pm_ops, scd30_suspend, scd30_resume, IIO_SCD30);

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

	return devm_iio_device_register(dev, indio_dev);
}
EXPORT_SYMBOL(scd30_probe);
EXPORT_SYMBOL_NS(scd30_probe, IIO_SCD30);

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