Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

ACPI / PM: Allow device power states to be used for CONFIG_PM unset



Currently, drivers/acpi/device_pm.c depends on CONFIG_PM and all of
the functions defined in there are replaced with static inline stubs
if that option is unset.  However, CONFIG_PM means, roughly, "runtime
PM or suspend/hibernation support" and some of those functions are
useful regardless of that.  For example, they are used by the ACPI
fan driver for controlling fans and acpi_device_set_power() is called
during device removal.  Moreover, device initialization may depend on
setting device power states properly.

For these reasons, make the routines manipulating ACPI device power
states defined in drivers/acpi/device_pm.c available for CONFIG_PM
unset too.

Reported-by: default avatarZhang Rui <rui.zhang@intel.com>
Reported-and-tested-by: default avatarMichel Lespinasse <walken@google.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: 3.9+ <stable@vger.kernel.org>
parent c7788792
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -24,7 +24,7 @@ acpi-y += nvs.o
# Power management related files
# Power management related files
acpi-y				+= wakeup.o
acpi-y				+= wakeup.o
acpi-y				+= sleep.o
acpi-y				+= sleep.o
acpi-$(CONFIG_PM)		+= device_pm.o
acpi-y				+= device_pm.o
acpi-$(CONFIG_ACPI_SLEEP)	+= proc.o
acpi-$(CONFIG_ACPI_SLEEP)	+= proc.o




+64 −62
Original line number Original line Diff line number Diff line
@@ -37,68 +37,6 @@
#define _COMPONENT	ACPI_POWER_COMPONENT
#define _COMPONENT	ACPI_POWER_COMPONENT
ACPI_MODULE_NAME("device_pm");
ACPI_MODULE_NAME("device_pm");


static DEFINE_MUTEX(acpi_pm_notifier_lock);

/**
 * acpi_add_pm_notifier - Register PM notifier for given ACPI device.
 * @adev: ACPI device to add the notifier for.
 * @context: Context information to pass to the notifier routine.
 *
 * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of
 * PM wakeup events.  For example, wakeup events may be generated for bridges
 * if one of the devices below the bridge is signaling wakeup, even if the
 * bridge itself doesn't have a wakeup GPE associated with it.
 */
acpi_status acpi_add_pm_notifier(struct acpi_device *adev,
				 acpi_notify_handler handler, void *context)
{
	acpi_status status = AE_ALREADY_EXISTS;

	mutex_lock(&acpi_pm_notifier_lock);

	if (adev->wakeup.flags.notifier_present)
		goto out;

	status = acpi_install_notify_handler(adev->handle,
					     ACPI_SYSTEM_NOTIFY,
					     handler, context);
	if (ACPI_FAILURE(status))
		goto out;

	adev->wakeup.flags.notifier_present = true;

 out:
	mutex_unlock(&acpi_pm_notifier_lock);
	return status;
}

/**
 * acpi_remove_pm_notifier - Unregister PM notifier from given ACPI device.
 * @adev: ACPI device to remove the notifier from.
 */
acpi_status acpi_remove_pm_notifier(struct acpi_device *adev,
				    acpi_notify_handler handler)
{
	acpi_status status = AE_BAD_PARAMETER;

	mutex_lock(&acpi_pm_notifier_lock);

	if (!adev->wakeup.flags.notifier_present)
		goto out;

	status = acpi_remove_notify_handler(adev->handle,
					    ACPI_SYSTEM_NOTIFY,
					    handler);
	if (ACPI_FAILURE(status))
		goto out;

	adev->wakeup.flags.notifier_present = false;

 out:
	mutex_unlock(&acpi_pm_notifier_lock);
	return status;
}

/**
/**
 * acpi_power_state_string - String representation of ACPI device power state.
 * acpi_power_state_string - String representation of ACPI device power state.
 * @state: ACPI device power state to return the string representation of.
 * @state: ACPI device power state to return the string representation of.
@@ -385,6 +323,69 @@ bool acpi_bus_power_manageable(acpi_handle handle)
}
}
EXPORT_SYMBOL(acpi_bus_power_manageable);
EXPORT_SYMBOL(acpi_bus_power_manageable);


#ifdef CONFIG_PM
static DEFINE_MUTEX(acpi_pm_notifier_lock);

/**
 * acpi_add_pm_notifier - Register PM notifier for given ACPI device.
 * @adev: ACPI device to add the notifier for.
 * @context: Context information to pass to the notifier routine.
 *
 * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of
 * PM wakeup events.  For example, wakeup events may be generated for bridges
 * if one of the devices below the bridge is signaling wakeup, even if the
 * bridge itself doesn't have a wakeup GPE associated with it.
 */
acpi_status acpi_add_pm_notifier(struct acpi_device *adev,
				 acpi_notify_handler handler, void *context)
{
	acpi_status status = AE_ALREADY_EXISTS;

	mutex_lock(&acpi_pm_notifier_lock);

	if (adev->wakeup.flags.notifier_present)
		goto out;

	status = acpi_install_notify_handler(adev->handle,
					     ACPI_SYSTEM_NOTIFY,
					     handler, context);
	if (ACPI_FAILURE(status))
		goto out;

	adev->wakeup.flags.notifier_present = true;

 out:
	mutex_unlock(&acpi_pm_notifier_lock);
	return status;
}

/**
 * acpi_remove_pm_notifier - Unregister PM notifier from given ACPI device.
 * @adev: ACPI device to remove the notifier from.
 */
acpi_status acpi_remove_pm_notifier(struct acpi_device *adev,
				    acpi_notify_handler handler)
{
	acpi_status status = AE_BAD_PARAMETER;

	mutex_lock(&acpi_pm_notifier_lock);

	if (!adev->wakeup.flags.notifier_present)
		goto out;

	status = acpi_remove_notify_handler(adev->handle,
					    ACPI_SYSTEM_NOTIFY,
					    handler);
	if (ACPI_FAILURE(status))
		goto out;

	adev->wakeup.flags.notifier_present = false;

 out:
	mutex_unlock(&acpi_pm_notifier_lock);
	return status;
}

bool acpi_bus_can_wakeup(acpi_handle handle)
bool acpi_bus_can_wakeup(acpi_handle handle)
{
{
	struct acpi_device *device;
	struct acpi_device *device;
@@ -1023,3 +1024,4 @@ void acpi_dev_pm_remove_dependent(acpi_handle handle, struct device *depdev)
	mutex_unlock(&adev->physical_node_lock);
	mutex_unlock(&adev->physical_node_lock);
}
}
EXPORT_SYMBOL_GPL(acpi_dev_pm_remove_dependent);
EXPORT_SYMBOL_GPL(acpi_dev_pm_remove_dependent);
#endif /* CONFIG_PM */
+5 −35
Original line number Original line Diff line number Diff line
@@ -377,7 +377,6 @@ acpi_status acpi_bus_get_status_handle(acpi_handle handle,
				       unsigned long long *sta);
				       unsigned long long *sta);
int acpi_bus_get_status(struct acpi_device *device);
int acpi_bus_get_status(struct acpi_device *device);


#ifdef CONFIG_PM
int acpi_bus_set_power(acpi_handle handle, int state);
int acpi_bus_set_power(acpi_handle handle, int state);
const char *acpi_power_state_string(int state);
const char *acpi_power_state_string(int state);
int acpi_device_get_power(struct acpi_device *device, int *state);
int acpi_device_get_power(struct acpi_device *device, int *state);
@@ -385,41 +384,12 @@ int acpi_device_set_power(struct acpi_device *device, int state);
int acpi_bus_init_power(struct acpi_device *device);
int acpi_bus_init_power(struct acpi_device *device);
int acpi_bus_update_power(acpi_handle handle, int *state_p);
int acpi_bus_update_power(acpi_handle handle, int *state_p);
bool acpi_bus_power_manageable(acpi_handle handle);
bool acpi_bus_power_manageable(acpi_handle handle);

#ifdef CONFIG_PM
bool acpi_bus_can_wakeup(acpi_handle handle);
bool acpi_bus_can_wakeup(acpi_handle handle);
#else /* !CONFIG_PM */
#else
static inline int acpi_bus_set_power(acpi_handle handle, int state)
static inline bool acpi_bus_can_wakeup(acpi_handle handle) { return false; }
{
#endif
	return 0;
}
static inline const char *acpi_power_state_string(int state)
{
	return "D0";
}
static inline int acpi_device_get_power(struct acpi_device *device, int *state)
{
	return 0;
}
static inline int acpi_device_set_power(struct acpi_device *device, int state)
{
	return 0;
}
static inline int acpi_bus_init_power(struct acpi_device *device)
{
	return 0;
}
static inline int acpi_bus_update_power(acpi_handle handle, int *state_p)
{
	return 0;
}
static inline bool acpi_bus_power_manageable(acpi_handle handle)
{
	return false;
}
static inline bool acpi_bus_can_wakeup(acpi_handle handle)
{
	return false;
}
#endif /* !CONFIG_PM */


#ifdef CONFIG_ACPI_PROC_EVENT
#ifdef CONFIG_ACPI_PROC_EVENT
int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data);
int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data);