Commit ec4602a9588a196fa1a9af46bfdd37cbf5792db4

Authored by Rafael J. Wysocki
1 parent c7788792a5

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: Zhang Rui <rui.zhang@intel.com>
Reported-and-tested-by: Michel Lespinasse <walken@google.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: 3.9+ <stable@vger.kernel.org>

Showing 3 changed files with 70 additions and 98 deletions Side-by-side Diff

drivers/acpi/Makefile
... ... @@ -24,7 +24,7 @@
24 24 # Power management related files
25 25 acpi-y += wakeup.o
26 26 acpi-y += sleep.o
27   -acpi-$(CONFIG_PM) += device_pm.o
  27 +acpi-y += device_pm.o
28 28 acpi-$(CONFIG_ACPI_SLEEP) += proc.o
29 29  
30 30  
drivers/acpi/device_pm.c
... ... @@ -37,69 +37,7 @@
37 37 #define _COMPONENT ACPI_POWER_COMPONENT
38 38 ACPI_MODULE_NAME("device_pm");
39 39  
40   -static DEFINE_MUTEX(acpi_pm_notifier_lock);
41   -
42 40 /**
43   - * acpi_add_pm_notifier - Register PM notifier for given ACPI device.
44   - * @adev: ACPI device to add the notifier for.
45   - * @context: Context information to pass to the notifier routine.
46   - *
47   - * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of
48   - * PM wakeup events. For example, wakeup events may be generated for bridges
49   - * if one of the devices below the bridge is signaling wakeup, even if the
50   - * bridge itself doesn't have a wakeup GPE associated with it.
51   - */
52   -acpi_status acpi_add_pm_notifier(struct acpi_device *adev,
53   - acpi_notify_handler handler, void *context)
54   -{
55   - acpi_status status = AE_ALREADY_EXISTS;
56   -
57   - mutex_lock(&acpi_pm_notifier_lock);
58   -
59   - if (adev->wakeup.flags.notifier_present)
60   - goto out;
61   -
62   - status = acpi_install_notify_handler(adev->handle,
63   - ACPI_SYSTEM_NOTIFY,
64   - handler, context);
65   - if (ACPI_FAILURE(status))
66   - goto out;
67   -
68   - adev->wakeup.flags.notifier_present = true;
69   -
70   - out:
71   - mutex_unlock(&acpi_pm_notifier_lock);
72   - return status;
73   -}
74   -
75   -/**
76   - * acpi_remove_pm_notifier - Unregister PM notifier from given ACPI device.
77   - * @adev: ACPI device to remove the notifier from.
78   - */
79   -acpi_status acpi_remove_pm_notifier(struct acpi_device *adev,
80   - acpi_notify_handler handler)
81   -{
82   - acpi_status status = AE_BAD_PARAMETER;
83   -
84   - mutex_lock(&acpi_pm_notifier_lock);
85   -
86   - if (!adev->wakeup.flags.notifier_present)
87   - goto out;
88   -
89   - status = acpi_remove_notify_handler(adev->handle,
90   - ACPI_SYSTEM_NOTIFY,
91   - handler);
92   - if (ACPI_FAILURE(status))
93   - goto out;
94   -
95   - adev->wakeup.flags.notifier_present = false;
96   -
97   - out:
98   - mutex_unlock(&acpi_pm_notifier_lock);
99   - return status;
100   -}
101   -
102   -/**
103 41 * acpi_power_state_string - String representation of ACPI device power state.
104 42 * @state: ACPI device power state to return the string representation of.
105 43 */
... ... @@ -385,6 +323,69 @@
385 323 }
386 324 EXPORT_SYMBOL(acpi_bus_power_manageable);
387 325  
  326 +#ifdef CONFIG_PM
  327 +static DEFINE_MUTEX(acpi_pm_notifier_lock);
  328 +
  329 +/**
  330 + * acpi_add_pm_notifier - Register PM notifier for given ACPI device.
  331 + * @adev: ACPI device to add the notifier for.
  332 + * @context: Context information to pass to the notifier routine.
  333 + *
  334 + * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of
  335 + * PM wakeup events. For example, wakeup events may be generated for bridges
  336 + * if one of the devices below the bridge is signaling wakeup, even if the
  337 + * bridge itself doesn't have a wakeup GPE associated with it.
  338 + */
  339 +acpi_status acpi_add_pm_notifier(struct acpi_device *adev,
  340 + acpi_notify_handler handler, void *context)
  341 +{
  342 + acpi_status status = AE_ALREADY_EXISTS;
  343 +
  344 + mutex_lock(&acpi_pm_notifier_lock);
  345 +
  346 + if (adev->wakeup.flags.notifier_present)
  347 + goto out;
  348 +
  349 + status = acpi_install_notify_handler(adev->handle,
  350 + ACPI_SYSTEM_NOTIFY,
  351 + handler, context);
  352 + if (ACPI_FAILURE(status))
  353 + goto out;
  354 +
  355 + adev->wakeup.flags.notifier_present = true;
  356 +
  357 + out:
  358 + mutex_unlock(&acpi_pm_notifier_lock);
  359 + return status;
  360 +}
  361 +
  362 +/**
  363 + * acpi_remove_pm_notifier - Unregister PM notifier from given ACPI device.
  364 + * @adev: ACPI device to remove the notifier from.
  365 + */
  366 +acpi_status acpi_remove_pm_notifier(struct acpi_device *adev,
  367 + acpi_notify_handler handler)
  368 +{
  369 + acpi_status status = AE_BAD_PARAMETER;
  370 +
  371 + mutex_lock(&acpi_pm_notifier_lock);
  372 +
  373 + if (!adev->wakeup.flags.notifier_present)
  374 + goto out;
  375 +
  376 + status = acpi_remove_notify_handler(adev->handle,
  377 + ACPI_SYSTEM_NOTIFY,
  378 + handler);
  379 + if (ACPI_FAILURE(status))
  380 + goto out;
  381 +
  382 + adev->wakeup.flags.notifier_present = false;
  383 +
  384 + out:
  385 + mutex_unlock(&acpi_pm_notifier_lock);
  386 + return status;
  387 +}
  388 +
388 389 bool acpi_bus_can_wakeup(acpi_handle handle)
389 390 {
390 391 struct acpi_device *device;
... ... @@ -1023,4 +1024,5 @@
1023 1024 mutex_unlock(&adev->physical_node_lock);
1024 1025 }
1025 1026 EXPORT_SYMBOL_GPL(acpi_dev_pm_remove_dependent);
  1027 +#endif /* CONFIG_PM */
include/acpi/acpi_bus.h
... ... @@ -377,7 +377,6 @@
377 377 unsigned long long *sta);
378 378 int acpi_bus_get_status(struct acpi_device *device);
379 379  
380   -#ifdef CONFIG_PM
381 380 int acpi_bus_set_power(acpi_handle handle, int state);
382 381 const char *acpi_power_state_string(int state);
383 382 int acpi_device_get_power(struct acpi_device *device, int *state);
384 383  
... ... @@ -385,41 +384,12 @@
385 384 int acpi_bus_init_power(struct acpi_device *device);
386 385 int acpi_bus_update_power(acpi_handle handle, int *state_p);
387 386 bool acpi_bus_power_manageable(acpi_handle handle);
  387 +
  388 +#ifdef CONFIG_PM
388 389 bool acpi_bus_can_wakeup(acpi_handle handle);
389   -#else /* !CONFIG_PM */
390   -static inline int acpi_bus_set_power(acpi_handle handle, int state)
391   -{
392   - return 0;
393   -}
394   -static inline const char *acpi_power_state_string(int state)
395   -{
396   - return "D0";
397   -}
398   -static inline int acpi_device_get_power(struct acpi_device *device, int *state)
399   -{
400   - return 0;
401   -}
402   -static inline int acpi_device_set_power(struct acpi_device *device, int state)
403   -{
404   - return 0;
405   -}
406   -static inline int acpi_bus_init_power(struct acpi_device *device)
407   -{
408   - return 0;
409   -}
410   -static inline int acpi_bus_update_power(acpi_handle handle, int *state_p)
411   -{
412   - return 0;
413   -}
414   -static inline bool acpi_bus_power_manageable(acpi_handle handle)
415   -{
416   - return false;
417   -}
418   -static inline bool acpi_bus_can_wakeup(acpi_handle handle)
419   -{
420   - return false;
421   -}
422   -#endif /* !CONFIG_PM */
  390 +#else
  391 +static inline bool acpi_bus_can_wakeup(acpi_handle handle) { return false; }
  392 +#endif
423 393  
424 394 #ifdef CONFIG_ACPI_PROC_EVENT
425 395 int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data);