Commit ed206fac87d65917280b6c3edd3f01125d4095c9
Committed by
Len Brown
1 parent
49fdf6785f
Exists in
master
and in
7 other branches
ACPI: bugfix reporting of event handler status
Introduce a new flag showing whether the event has an event handler/method. For all the GPEs and Fixed Events, 1. ACPI_EVENT_FLAG_HANDLE is cleared, it's an "invalid" ACPI event. 2. Both ACPI_EVENT_FLAG_HANDLE and ACPI_EVENT_FLAG_DISABLE are set, it's "disabled". 3. Both ACPI_EVENT_FLAG_HANDLE and ACPI_EVENT_FLAG_ENABLE are set, it's "enabled". 4. Both ACPI_EVENT_FLAG_HANDLE and ACPI_EVENT_FLAG_WAKE_ENABLE are set, it's "wake_enabled". Among other things, this prevents incorrect reporting of ACPI events as being "invalid" when it's really just (temporarily) "disabled". Signed-off-by: Zhang Rui <rui.zhang@intel.com> Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Len Brown <len.brown@intel.com>
Showing 4 changed files with 22 additions and 20 deletions Side-by-side Diff
Documentation/ABI/testing/sysfs-firmware-acpi
... | ... | @@ -89,7 +89,7 @@ |
89 | 89 | |
90 | 90 | error - an interrupt that can't be accounted for above. |
91 | 91 | |
92 | - invalid: it's either a wakeup GPE or a GPE/Fixed Event that | |
92 | + invalid: it's either a GPE or a Fixed Event that | |
93 | 93 | doesn't have an event handler. |
94 | 94 | |
95 | 95 | disable: the GPE/Fixed Event is valid but disabled. |
96 | 96 | |
97 | 97 | |
98 | 98 | |
99 | 99 | |
100 | 100 | |
101 | 101 | |
... | ... | @@ -117,30 +117,30 @@ |
117 | 117 | and other user space applications so that the machine won't shutdown |
118 | 118 | when pressing the power button. |
119 | 119 | # cat ff_pwr_btn |
120 | - 0 | |
120 | + 0 enabled | |
121 | 121 | # press the power button for 3 times; |
122 | 122 | # cat ff_pwr_btn |
123 | - 3 | |
123 | + 3 enabled | |
124 | 124 | # echo disable > ff_pwr_btn |
125 | 125 | # cat ff_pwr_btn |
126 | - disable | |
126 | + 3 disabled | |
127 | 127 | # press the power button for 3 times; |
128 | 128 | # cat ff_pwr_btn |
129 | - disable | |
129 | + 3 disabled | |
130 | 130 | # echo enable > ff_pwr_btn |
131 | 131 | # cat ff_pwr_btn |
132 | - 4 | |
132 | + 4 enabled | |
133 | 133 | /* |
134 | 134 | * this is because the status bit is set even if the enable bit is cleared, |
135 | 135 | * and it triggers an ACPI fixed event when the enable bit is set again |
136 | 136 | */ |
137 | 137 | # press the power button for 3 times; |
138 | 138 | # cat ff_pwr_btn |
139 | - 7 | |
139 | + 7 enabled | |
140 | 140 | # echo disable > ff_pwr_btn |
141 | 141 | # press the power button for 3 times; |
142 | 142 | # echo clear > ff_pwr_btn /* clear the status bit */ |
143 | 143 | # echo disable > ff_pwr_btn |
144 | 144 | # cat ff_pwr_btn |
145 | - 7 | |
145 | + 7 enabled |
drivers/acpi/events/evxfevnt.c
... | ... | @@ -521,6 +521,9 @@ |
521 | 521 | if (value) |
522 | 522 | *event_status |= ACPI_EVENT_FLAG_SET; |
523 | 523 | |
524 | + if (acpi_gbl_fixed_event_handlers[event].handler) | |
525 | + *event_status |= ACPI_EVENT_FLAG_HANDLE; | |
526 | + | |
524 | 527 | return_ACPI_STATUS(status); |
525 | 528 | } |
526 | 529 | |
... | ... | @@ -570,6 +573,9 @@ |
570 | 573 | /* Obtain status on the requested GPE number */ |
571 | 574 | |
572 | 575 | status = acpi_hw_get_gpe_status(gpe_event_info, event_status); |
576 | + | |
577 | + if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) | |
578 | + *event_status |= ACPI_EVENT_FLAG_HANDLE; | |
573 | 579 | |
574 | 580 | unlock_and_exit: |
575 | 581 | if (flags & ACPI_NOT_ISR) { |
drivers/acpi/system.c
... | ... | @@ -167,7 +167,6 @@ |
167 | 167 | #define COUNT_ERROR 2 /* other */ |
168 | 168 | #define NUM_COUNTERS_EXTRA 3 |
169 | 169 | |
170 | -#define ACPI_EVENT_VALID 0x01 | |
171 | 170 | struct event_counter { |
172 | 171 | u32 count; |
173 | 172 | u32 flags; |
... | ... | @@ -312,12 +311,6 @@ |
312 | 311 | } else if (index < (num_gpes + ACPI_NUM_FIXED_EVENTS)) |
313 | 312 | result = acpi_get_event_status(index - num_gpes, status); |
314 | 313 | |
315 | - /* | |
316 | - * sleep/power button GPE/Fixed Event is enabled after acpi_system_init, | |
317 | - * check the status at runtime and mark it as valid once it's enabled | |
318 | - */ | |
319 | - if (!result && (*status & ACPI_EVENT_FLAG_ENABLED)) | |
320 | - all_counters[index].flags |= ACPI_EVENT_VALID; | |
321 | 314 | end: |
322 | 315 | return result; |
323 | 316 | } |
324 | 317 | |
325 | 318 | |
... | ... | @@ -346,12 +339,14 @@ |
346 | 339 | if (result) |
347 | 340 | goto end; |
348 | 341 | |
349 | - if (!(all_counters[index].flags & ACPI_EVENT_VALID)) | |
350 | - size += sprintf(buf + size, " invalid"); | |
342 | + if (!(status & ACPI_EVENT_FLAG_HANDLE)) | |
343 | + size += sprintf(buf + size, " invalid"); | |
351 | 344 | else if (status & ACPI_EVENT_FLAG_ENABLED) |
352 | - size += sprintf(buf + size, " enable"); | |
345 | + size += sprintf(buf + size, " enabled"); | |
346 | + else if (status & ACPI_EVENT_FLAG_WAKE_ENABLED) | |
347 | + size += sprintf(buf + size, " wake_enabled"); | |
353 | 348 | else |
354 | - size += sprintf(buf + size, " disable"); | |
349 | + size += sprintf(buf + size, " disabled"); | |
355 | 350 | |
356 | 351 | end: |
357 | 352 | size += sprintf(buf + size, "\n"); |
... | ... | @@ -385,7 +380,7 @@ |
385 | 380 | if (result) |
386 | 381 | goto end; |
387 | 382 | |
388 | - if (!(all_counters[index].flags & ACPI_EVENT_VALID)) { | |
383 | + if (!(status & ACPI_EVENT_FLAG_HANDLE)) { | |
389 | 384 | printk(KERN_WARNING PREFIX |
390 | 385 | "Can not change Invalid GPE/Fixed Event status\n"); |
391 | 386 | return -EINVAL; |
include/acpi/actypes.h
... | ... | @@ -525,6 +525,7 @@ |
525 | 525 | #define ACPI_EVENT_FLAG_ENABLED (acpi_event_status) 0x01 |
526 | 526 | #define ACPI_EVENT_FLAG_WAKE_ENABLED (acpi_event_status) 0x02 |
527 | 527 | #define ACPI_EVENT_FLAG_SET (acpi_event_status) 0x04 |
528 | +#define ACPI_EVENT_FLAG_HANDLE (acpi_event_status) 0x08 | |
528 | 529 | |
529 | 530 | /* |
530 | 531 | * General Purpose Events (GPE) |