Commit 60d69a7e authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branches 'pm-core' and 'pm-runtime'

Merge a core power management update and runtime PM framework updates
for 6.19-rc1:

 - Add WQ_UNBOUND to pm_wq workqueue (Marco Crivellari)

 - Add runtime PM wrapper macros for ACQUIRE()/ACQUIRE_ERR() and use
   them in the PCI core and the ACPI TAD driver (Rafael Wysocki)

 - Improve runtime PM in the ACPI TAD driver (Rafael Wysocki)

 - Update pm_runtime_allow/forbid() documentation (Rafael Wysocki)

 - Fix typos in runtime.c comments (Malaya Kumar Rout)

* pm-core:
  PM: WQ_UNBOUND added to pm_wq workqueue

* pm-runtime:
  PCI/sysfs: Use PM_RUNTIME_ACQUIRE()/PM_RUNTIME_ACQUIRE_ERR()
  ACPI: TAD: Use PM_RUNTIME_ACQUIRE()/PM_RUNTIME_ACQUIRE_ERR()
  PM: runtime: Wrapper macros for ACQUIRE()/ACQUIRE_ERR()
  PM: runtime: fix typos in runtime.c comments
  ACPI: TAD: Improve runtime PM using guard macros
  ACPI: TAD: Rearrange runtime PM operations in acpi_tad_remove()
  PM: runtime: docs: Update pm_runtime_allow/forbid() documentation
Loading
Loading
Loading
Loading
+0 −10
Original line number Diff line number Diff line
@@ -480,16 +480,6 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
  `bool pm_runtime_status_suspended(struct device *dev);`
    - return true if the device's runtime PM status is 'suspended'

  `void pm_runtime_allow(struct device *dev);`
    - set the power.runtime_auto flag for the device and decrease its usage
      counter (used by the /sys/devices/.../power/control interface to
      effectively allow the device to be power managed at run time)

  `void pm_runtime_forbid(struct device *dev);`
    - unset the power.runtime_auto flag for the device and increase its usage
      counter (used by the /sys/devices/.../power/control interface to
      effectively prevent the device from being power managed at run time)

  `void pm_runtime_no_callbacks(struct device *dev);`
    - set the power.no_callbacks flag for the device and remove the runtime
      PM attributes from /sys/devices/.../power (or prevent them from being
+39 −34
Original line number Diff line number Diff line
@@ -90,19 +90,18 @@ static int acpi_tad_set_real_time(struct device *dev, struct acpi_tad_rt *rt)
	args[0].buffer.pointer = (u8 *)rt;
	args[0].buffer.length = sizeof(*rt);

	pm_runtime_get_sync(dev);
	PM_RUNTIME_ACQUIRE(dev, pm);
	if (PM_RUNTIME_ACQUIRE_ERR(&pm))
		return -ENXIO;

	status = acpi_evaluate_integer(handle, "_SRT", &arg_list, &retval);

	pm_runtime_put_sync(dev);

	if (ACPI_FAILURE(status) || retval)
		return -EIO;

	return 0;
}

static int acpi_tad_get_real_time(struct device *dev, struct acpi_tad_rt *rt)
static int acpi_tad_evaluate_grt(struct device *dev, struct acpi_tad_rt *rt)
{
	acpi_handle handle = ACPI_HANDLE(dev);
	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER };
@@ -111,12 +110,7 @@ static int acpi_tad_get_real_time(struct device *dev, struct acpi_tad_rt *rt)
	acpi_status status;
	int ret = -EIO;

	pm_runtime_get_sync(dev);

	status = acpi_evaluate_object(handle, "_GRT", NULL, &output);

	pm_runtime_put_sync(dev);

	if (ACPI_FAILURE(status))
		goto out_free;

@@ -139,6 +133,21 @@ static int acpi_tad_get_real_time(struct device *dev, struct acpi_tad_rt *rt)
	return ret;
}

static int acpi_tad_get_real_time(struct device *dev, struct acpi_tad_rt *rt)
{
	int ret;

	PM_RUNTIME_ACQUIRE(dev, pm);
	if (PM_RUNTIME_ACQUIRE_ERR(&pm))
		return -ENXIO;

	ret = acpi_tad_evaluate_grt(dev, rt);
	if (ret)
		return ret;

	return 0;
}

static char *acpi_tad_rt_next_field(char *s, int *val)
{
	char *p;
@@ -266,12 +275,11 @@ static int acpi_tad_wake_set(struct device *dev, char *method, u32 timer_id,
	args[0].integer.value = timer_id;
	args[1].integer.value = value;

	pm_runtime_get_sync(dev);
	PM_RUNTIME_ACQUIRE(dev, pm);
	if (PM_RUNTIME_ACQUIRE_ERR(&pm))
		return -ENXIO;

	status = acpi_evaluate_integer(handle, method, &arg_list, &retval);

	pm_runtime_put_sync(dev);

	if (ACPI_FAILURE(status) || retval)
		return -EIO;

@@ -314,12 +322,11 @@ static ssize_t acpi_tad_wake_read(struct device *dev, char *buf, char *method,

	args[0].integer.value = timer_id;

	pm_runtime_get_sync(dev);
	PM_RUNTIME_ACQUIRE(dev, pm);
	if (PM_RUNTIME_ACQUIRE_ERR(&pm))
		return -ENXIO;

	status = acpi_evaluate_integer(handle, method, &arg_list, &retval);

	pm_runtime_put_sync(dev);

	if (ACPI_FAILURE(status))
		return -EIO;

@@ -370,12 +377,11 @@ static int acpi_tad_clear_status(struct device *dev, u32 timer_id)

	args[0].integer.value = timer_id;

	pm_runtime_get_sync(dev);
	PM_RUNTIME_ACQUIRE(dev, pm);
	if (PM_RUNTIME_ACQUIRE_ERR(&pm))
		return -ENXIO;

	status = acpi_evaluate_integer(handle, "_CWS", &arg_list, &retval);

	pm_runtime_put_sync(dev);

	if (ACPI_FAILURE(status) || retval)
		return -EIO;

@@ -411,12 +417,11 @@ static ssize_t acpi_tad_status_read(struct device *dev, char *buf, u32 timer_id)

	args[0].integer.value = timer_id;

	pm_runtime_get_sync(dev);
	PM_RUNTIME_ACQUIRE(dev, pm);
	if (PM_RUNTIME_ACQUIRE_ERR(&pm))
		return -ENXIO;

	status = acpi_evaluate_integer(handle, "_GWS", &arg_list, &retval);

	pm_runtime_put_sync(dev);

	if (ACPI_FAILURE(status))
		return -EIO;

@@ -563,8 +568,6 @@ static void acpi_tad_remove(struct platform_device *pdev)

	device_init_wakeup(dev, false);

	pm_runtime_get_sync(dev);

	if (dd->capabilities & ACPI_TAD_RT)
		sysfs_remove_group(&dev->kobj, &acpi_tad_time_attr_group);

@@ -573,14 +576,16 @@ static void acpi_tad_remove(struct platform_device *pdev)

	sysfs_remove_group(&dev->kobj, &acpi_tad_attr_group);

	scoped_guard(pm_runtime_noresume, dev) {
		acpi_tad_disable_timer(dev, ACPI_TAD_AC_TIMER);
		acpi_tad_clear_status(dev, ACPI_TAD_AC_TIMER);
		if (dd->capabilities & ACPI_TAD_DC_WAKE) {
			acpi_tad_disable_timer(dev, ACPI_TAD_DC_TIMER);
			acpi_tad_clear_status(dev, ACPI_TAD_DC_TIMER);
		}
	}

	pm_runtime_put_sync(dev);
	pm_runtime_suspend(dev);
	pm_runtime_disable(dev);
	acpi_remove_cmos_rtc_space_handler(handle);
}
+16 −7
Original line number Diff line number Diff line
@@ -90,7 +90,7 @@ static void update_pm_runtime_accounting(struct device *dev)
	/*
	 * Because ktime_get_mono_fast_ns() is not monotonic during
	 * timekeeping updates, ensure that 'now' is after the last saved
	 * timesptamp.
	 * timestamp.
	 */
	if (now < last)
		return;
@@ -217,7 +217,7 @@ static int dev_memalloc_noio(struct device *dev, void *data)
 *     resume/suspend callback of any one of its ancestors(or the
 *     block device itself), the deadlock may be triggered inside the
 *     memory allocation since it might not complete until the block
 *     device becomes active and the involed page I/O finishes. The
 *     device becomes active and the involved page I/O finishes. The
 *     situation is pointed out first by Alan Stern. Network device
 *     are involved in iSCSI kind of situation.
 *
@@ -1210,7 +1210,7 @@ EXPORT_SYMBOL_GPL(__pm_runtime_resume);
 *
 * Otherwise, if its runtime PM status is %RPM_ACTIVE and (1) @ign_usage_count
 * is set, or (2) @dev is not ignoring children and its active child count is
 * nonero, or (3) the runtime PM usage counter of @dev is not zero, increment
 * nonzero, or (3) the runtime PM usage counter of @dev is not zero, increment
 * the usage counter of @dev and return 1.
 *
 * Otherwise, return 0 without changing the usage counter.
@@ -1664,9 +1664,12 @@ EXPORT_SYMBOL_GPL(devm_pm_runtime_get_noresume);
 * pm_runtime_forbid - Block runtime PM of a device.
 * @dev: Device to handle.
 *
 * Increase the device's usage count and clear its power.runtime_auto flag,
 * so that it cannot be suspended at run time until pm_runtime_allow() is called
 * for it.
 * Resume @dev if already suspended and block runtime suspend of @dev in such
 * a way that it can be unblocked via the /sys/devices/.../power/control
 * interface, or otherwise by calling pm_runtime_allow().
 *
 * Calling this function many times in a row has the same effect as calling it
 * once.
 */
void pm_runtime_forbid(struct device *dev)
{
@@ -1687,7 +1690,13 @@ EXPORT_SYMBOL_GPL(pm_runtime_forbid);
 * pm_runtime_allow - Unblock runtime PM of a device.
 * @dev: Device to handle.
 *
 * Decrease the device's usage count and set its power.runtime_auto flag.
 * Unblock runtime suspend of @dev after it has been blocked by
 * pm_runtime_forbid() (for instance, if it has been blocked via the
 * /sys/devices/.../power/control interface), check if @dev can be
 * suspended and suspend it in that case.
 *
 * Calling this function many times in a row has the same effect as calling it
 * once.
 */
void pm_runtime_allow(struct device *dev)
{
+2 −2
Original line number Diff line number Diff line
@@ -1517,8 +1517,8 @@ static ssize_t reset_method_store(struct device *dev,
		return count;
	}

	ACQUIRE(pm_runtime_active_try, pm)(dev);
	if (ACQUIRE_ERR(pm_runtime_active_try, &pm))
	PM_RUNTIME_ACQUIRE(dev, pm);
	if (PM_RUNTIME_ACQUIRE_ERR(&pm))
		return -ENXIO;

	if (sysfs_streq(buf, "default")) {
+24 −0
Original line number Diff line number Diff line
@@ -637,6 +637,30 @@ DEFINE_GUARD_COND(pm_runtime_active_auto, _try,
DEFINE_GUARD_COND(pm_runtime_active_auto, _try_enabled,
		  pm_runtime_resume_and_get(_T), _RET == 0)

/* ACQUIRE() wrapper macros for the guards defined above. */

#define PM_RUNTIME_ACQUIRE(_dev, _var)			\
	ACQUIRE(pm_runtime_active_try, _var)(_dev)

#define PM_RUNTIME_ACQUIRE_AUTOSUSPEND(_dev, _var)	\
	ACQUIRE(pm_runtime_active_auto_try, _var)(_dev)

#define PM_RUNTIME_ACQUIRE_IF_ENABLED(_dev, _var)	\
	ACQUIRE(pm_runtime_active_try_enabled, _var)(_dev)

#define PM_RUNTIME_ACQUIRE_IF_ENABLED_AUTOSUSPEND(_dev, _var)	\
	ACQUIRE(pm_runtime_active_auto_try_enabled, _var)(_dev)

/*
 * ACQUIRE_ERR() wrapper macro for guard pm_runtime_active.
 *
 * Always check PM_RUNTIME_ACQUIRE_ERR() after using one of the
 * PM_RUNTIME_ACQUIRE*() macros defined above (yes, it can be used with
 * any of them) and if it is nonzero, avoid accessing the given device.
 */
#define PM_RUNTIME_ACQUIRE_ERR(_var_ptr)	\
	ACQUIRE_ERR(pm_runtime_active, _var_ptr)

/**
 * pm_runtime_put_sync - Drop device usage counter and run "idle check" if 0.
 * @dev: Target device.
Loading