wakeup.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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 "sleep.h"
  11. #define _COMPONENT ACPI_SYSTEM_COMPONENT
  12. ACPI_MODULE_NAME("wakeup_devices")
  13. extern struct list_head acpi_wakeup_device_list;
  14. extern spinlock_t acpi_device_lock;
  15. /**
  16. * acpi_enable_wakeup_device_prep - prepare wakeup devices
  17. * @sleep_state: ACPI state
  18. * Enable all wakup devices power if the devices' wakeup level
  19. * is higher than requested sleep level
  20. */
  21. void acpi_enable_wakeup_device_prep(u8 sleep_state)
  22. {
  23. struct list_head *node, *next;
  24. spin_lock(&acpi_device_lock);
  25. list_for_each_safe(node, next, &acpi_wakeup_device_list) {
  26. struct acpi_device *dev = container_of(node,
  27. struct acpi_device,
  28. wakeup_list);
  29. if (!dev->wakeup.flags.valid ||
  30. !dev->wakeup.state.enabled ||
  31. (sleep_state > (u32) dev->wakeup.sleep_state))
  32. continue;
  33. spin_unlock(&acpi_device_lock);
  34. acpi_enable_wakeup_device_power(dev, sleep_state);
  35. spin_lock(&acpi_device_lock);
  36. }
  37. spin_unlock(&acpi_device_lock);
  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. spin_lock(&acpi_device_lock);
  52. list_for_each_safe(node, next, &acpi_wakeup_device_list) {
  53. struct acpi_device *dev =
  54. container_of(node, struct acpi_device, wakeup_list);
  55. if (!dev->wakeup.flags.valid)
  56. continue;
  57. /* If users want to disable run-wake GPE,
  58. * we only disable it for wake and leave it for runtime
  59. */
  60. if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared)
  61. || sleep_state > (u32) dev->wakeup.sleep_state) {
  62. if (dev->wakeup.flags.run_wake) {
  63. spin_unlock(&acpi_device_lock);
  64. /* set_gpe_type will disable GPE, leave it like that */
  65. acpi_set_gpe_type(dev->wakeup.gpe_device,
  66. dev->wakeup.gpe_number,
  67. ACPI_GPE_TYPE_RUNTIME);
  68. spin_lock(&acpi_device_lock);
  69. }
  70. continue;
  71. }
  72. spin_unlock(&acpi_device_lock);
  73. if (!dev->wakeup.flags.run_wake)
  74. acpi_enable_gpe(dev->wakeup.gpe_device,
  75. dev->wakeup.gpe_number);
  76. spin_lock(&acpi_device_lock);
  77. }
  78. spin_unlock(&acpi_device_lock);
  79. }
  80. /**
  81. * acpi_disable_wakeup_device - disable devices' wakeup capability
  82. * @sleep_state: ACPI state
  83. * Disable all wakup devices's GPE and wakeup capability
  84. */
  85. void acpi_disable_wakeup_device(u8 sleep_state)
  86. {
  87. struct list_head *node, *next;
  88. spin_lock(&acpi_device_lock);
  89. list_for_each_safe(node, next, &acpi_wakeup_device_list) {
  90. struct acpi_device *dev =
  91. container_of(node, struct acpi_device, wakeup_list);
  92. if (!dev->wakeup.flags.valid)
  93. continue;
  94. if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared)
  95. || sleep_state > (u32) dev->wakeup.sleep_state) {
  96. if (dev->wakeup.flags.run_wake) {
  97. spin_unlock(&acpi_device_lock);
  98. acpi_set_gpe_type(dev->wakeup.gpe_device,
  99. dev->wakeup.gpe_number,
  100. ACPI_GPE_TYPE_WAKE_RUN);
  101. /* Re-enable it, since set_gpe_type will disable it */
  102. acpi_enable_gpe(dev->wakeup.gpe_device,
  103. dev->wakeup.gpe_number);
  104. spin_lock(&acpi_device_lock);
  105. }
  106. continue;
  107. }
  108. spin_unlock(&acpi_device_lock);
  109. acpi_disable_wakeup_device_power(dev);
  110. /* Never disable run-wake GPE */
  111. if (!dev->wakeup.flags.run_wake) {
  112. acpi_disable_gpe(dev->wakeup.gpe_device,
  113. dev->wakeup.gpe_number);
  114. acpi_clear_gpe(dev->wakeup.gpe_device,
  115. dev->wakeup.gpe_number, ACPI_NOT_ISR);
  116. }
  117. spin_lock(&acpi_device_lock);
  118. }
  119. spin_unlock(&acpi_device_lock);
  120. }
  121. static int __init acpi_wakeup_device_init(void)
  122. {
  123. struct list_head *node, *next;
  124. if (acpi_disabled)
  125. return 0;
  126. spin_lock(&acpi_device_lock);
  127. list_for_each_safe(node, next, &acpi_wakeup_device_list) {
  128. struct acpi_device *dev = container_of(node,
  129. struct acpi_device,
  130. wakeup_list);
  131. /* In case user doesn't load button driver */
  132. if (!dev->wakeup.flags.run_wake || dev->wakeup.state.enabled)
  133. continue;
  134. spin_unlock(&acpi_device_lock);
  135. acpi_set_gpe_type(dev->wakeup.gpe_device,
  136. dev->wakeup.gpe_number,
  137. ACPI_GPE_TYPE_WAKE_RUN);
  138. acpi_enable_gpe(dev->wakeup.gpe_device,
  139. dev->wakeup.gpe_number);
  140. dev->wakeup.state.enabled = 1;
  141. spin_lock(&acpi_device_lock);
  142. }
  143. spin_unlock(&acpi_device_lock);
  144. return 0;
  145. }
  146. late_initcall(acpi_wakeup_device_init);