wakeup.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*
  2. * wakeup.c - support wakeup devices
  3. * Copyright (C) 2004 Li Shaohua <shaohua.li@intel.com>
  4. */
  5. #include <linux/init.h>
  6. #include <linux/acpi.h>
  7. #include <acpi/acpi_drivers.h>
  8. #include <linux/kernel.h>
  9. #include <linux/types.h>
  10. #include "internal.h"
  11. #include "sleep.h"
  12. /*
  13. * We didn't lock acpi_device_lock in the file, because it invokes oops in
  14. * suspend/resume and isn't really required as this is called in S-state. At
  15. * that time, there is no device hotplug
  16. **/
  17. #define _COMPONENT ACPI_SYSTEM_COMPONENT
  18. ACPI_MODULE_NAME("wakeup_devices")
  19. /**
  20. * acpi_enable_wakeup_device_prep - prepare wakeup devices
  21. * @sleep_state: ACPI state
  22. * Enable all wakup devices power if the devices' wakeup level
  23. * is higher than requested sleep level
  24. */
  25. void acpi_enable_wakeup_device_prep(u8 sleep_state)
  26. {
  27. struct list_head *node, *next;
  28. list_for_each_safe(node, next, &acpi_wakeup_device_list) {
  29. struct acpi_device *dev = container_of(node,
  30. struct acpi_device,
  31. wakeup_list);
  32. if (!dev->wakeup.flags.valid ||
  33. !dev->wakeup.state.enabled ||
  34. (sleep_state > (u32) dev->wakeup.sleep_state))
  35. continue;
  36. acpi_enable_wakeup_device_power(dev, sleep_state);
  37. }
  38. }
  39. /**
  40. * acpi_enable_wakeup_device - enable wakeup devices
  41. * @sleep_state: ACPI state
  42. * Enable all wakup devices's GPE
  43. */
  44. void acpi_enable_wakeup_device(u8 sleep_state)
  45. {
  46. struct list_head *node, *next;
  47. /*
  48. * Caution: this routine must be invoked when interrupt is disabled
  49. * Refer ACPI2.0: P212
  50. */
  51. list_for_each_safe(node, next, &acpi_wakeup_device_list) {
  52. struct acpi_device *dev =
  53. container_of(node, struct acpi_device, wakeup_list);
  54. if (!dev->wakeup.flags.valid)
  55. continue;
  56. /* If users want to disable run-wake GPE,
  57. * we only disable it for wake and leave it for runtime
  58. */
  59. if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared)
  60. || sleep_state > (u32) dev->wakeup.sleep_state) {
  61. if (dev->wakeup.flags.run_wake) {
  62. /* set_gpe_type will disable GPE, leave it like that */
  63. acpi_set_gpe_type(dev->wakeup.gpe_device,
  64. dev->wakeup.gpe_number,
  65. ACPI_GPE_TYPE_RUNTIME);
  66. }
  67. continue;
  68. }
  69. if (!dev->wakeup.flags.run_wake)
  70. acpi_enable_gpe(dev->wakeup.gpe_device,
  71. dev->wakeup.gpe_number);
  72. }
  73. }
  74. /**
  75. * acpi_disable_wakeup_device - disable devices' wakeup capability
  76. * @sleep_state: ACPI state
  77. * Disable all wakup devices's GPE and wakeup capability
  78. */
  79. void acpi_disable_wakeup_device(u8 sleep_state)
  80. {
  81. struct list_head *node, *next;
  82. list_for_each_safe(node, next, &acpi_wakeup_device_list) {
  83. struct acpi_device *dev =
  84. container_of(node, struct acpi_device, wakeup_list);
  85. if (!dev->wakeup.flags.valid)
  86. continue;
  87. if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared)
  88. || sleep_state > (u32) dev->wakeup.sleep_state) {
  89. if (dev->wakeup.flags.run_wake) {
  90. acpi_set_gpe_type(dev->wakeup.gpe_device,
  91. dev->wakeup.gpe_number,
  92. ACPI_GPE_TYPE_WAKE_RUN);
  93. /* Re-enable it, since set_gpe_type will disable it */
  94. acpi_enable_gpe(dev->wakeup.gpe_device,
  95. dev->wakeup.gpe_number);
  96. }
  97. continue;
  98. }
  99. acpi_disable_wakeup_device_power(dev);
  100. /* Never disable run-wake GPE */
  101. if (!dev->wakeup.flags.run_wake) {
  102. acpi_disable_gpe(dev->wakeup.gpe_device,
  103. dev->wakeup.gpe_number);
  104. acpi_clear_gpe(dev->wakeup.gpe_device,
  105. dev->wakeup.gpe_number, ACPI_NOT_ISR);
  106. }
  107. }
  108. }
  109. int __init acpi_wakeup_device_init(void)
  110. {
  111. struct list_head *node, *next;
  112. mutex_lock(&acpi_device_lock);
  113. list_for_each_safe(node, next, &acpi_wakeup_device_list) {
  114. struct acpi_device *dev = container_of(node,
  115. struct acpi_device,
  116. wakeup_list);
  117. /* In case user doesn't load button driver */
  118. if (!dev->wakeup.flags.run_wake || dev->wakeup.state.enabled)
  119. continue;
  120. acpi_set_gpe_type(dev->wakeup.gpe_device,
  121. dev->wakeup.gpe_number,
  122. ACPI_GPE_TYPE_WAKE_RUN);
  123. acpi_enable_gpe(dev->wakeup.gpe_device,
  124. dev->wakeup.gpe_number);
  125. dev->wakeup.state.enabled = 1;
  126. }
  127. mutex_unlock(&acpi_device_lock);
  128. return 0;
  129. }