Commit ed206fac authored by Zhang Rui's avatar Zhang Rui Committed by Len Brown

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: default avatarZhang Rui <rui.zhang@intel.com>
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 49fdf678
...@@ -89,7 +89,7 @@ Description: ...@@ -89,7 +89,7 @@ Description:
error - an interrupt that can't be accounted for above. error - an interrupt that can't be accounted for above.
invalid: it's either a wakeup GPE or a GPE/Fixed Event that invalid: it's either a GPE or a Fixed Event that
doesn't have an event handler. doesn't have an event handler.
disable: the GPE/Fixed Event is valid but disabled. disable: the GPE/Fixed Event is valid but disabled.
...@@ -117,30 +117,30 @@ Description: ...@@ -117,30 +117,30 @@ Description:
and other user space applications so that the machine won't shutdown and other user space applications so that the machine won't shutdown
when pressing the power button. when pressing the power button.
# cat ff_pwr_btn # cat ff_pwr_btn
0 0 enabled
# press the power button for 3 times; # press the power button for 3 times;
# cat ff_pwr_btn # cat ff_pwr_btn
3 3 enabled
# echo disable > ff_pwr_btn # echo disable > ff_pwr_btn
# cat ff_pwr_btn # cat ff_pwr_btn
disable 3 disabled
# press the power button for 3 times; # press the power button for 3 times;
# cat ff_pwr_btn # cat ff_pwr_btn
disable 3 disabled
# echo enable > ff_pwr_btn # echo enable > ff_pwr_btn
# cat ff_pwr_btn # cat ff_pwr_btn
4 4 enabled
/* /*
* this is because the status bit is set even if the enable bit is cleared, * this is because the status bit is set even if the enable bit is cleared,
* and it triggers an ACPI fixed event when the enable bit is set again * and it triggers an ACPI fixed event when the enable bit is set again
*/ */
# press the power button for 3 times; # press the power button for 3 times;
# cat ff_pwr_btn # cat ff_pwr_btn
7 7 enabled
# echo disable > ff_pwr_btn # echo disable > ff_pwr_btn
# press the power button for 3 times; # press the power button for 3 times;
# echo clear > ff_pwr_btn /* clear the status bit */ # echo clear > ff_pwr_btn /* clear the status bit */
# echo disable > ff_pwr_btn # echo disable > ff_pwr_btn
# cat ff_pwr_btn # cat ff_pwr_btn
7 7 enabled
...@@ -521,6 +521,9 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) ...@@ -521,6 +521,9 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
if (value) if (value)
*event_status |= ACPI_EVENT_FLAG_SET; *event_status |= ACPI_EVENT_FLAG_SET;
if (acpi_gbl_fixed_event_handlers[event].handler)
*event_status |= ACPI_EVENT_FLAG_HANDLE;
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
...@@ -571,6 +574,9 @@ acpi_get_gpe_status(acpi_handle gpe_device, ...@@ -571,6 +574,9 @@ acpi_get_gpe_status(acpi_handle gpe_device,
status = acpi_hw_get_gpe_status(gpe_event_info, event_status); status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)
*event_status |= ACPI_EVENT_FLAG_HANDLE;
unlock_and_exit: unlock_and_exit:
if (flags & ACPI_NOT_ISR) { if (flags & ACPI_NOT_ISR) {
(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
......
...@@ -167,7 +167,6 @@ static int acpi_system_sysfs_init(void) ...@@ -167,7 +167,6 @@ static int acpi_system_sysfs_init(void)
#define COUNT_ERROR 2 /* other */ #define COUNT_ERROR 2 /* other */
#define NUM_COUNTERS_EXTRA 3 #define NUM_COUNTERS_EXTRA 3
#define ACPI_EVENT_VALID 0x01
struct event_counter { struct event_counter {
u32 count; u32 count;
u32 flags; u32 flags;
...@@ -312,12 +311,6 @@ static int get_status(u32 index, acpi_event_status *status, acpi_handle *handle) ...@@ -312,12 +311,6 @@ static int get_status(u32 index, acpi_event_status *status, acpi_handle *handle)
} else if (index < (num_gpes + ACPI_NUM_FIXED_EVENTS)) } else if (index < (num_gpes + ACPI_NUM_FIXED_EVENTS))
result = acpi_get_event_status(index - num_gpes, status); result = acpi_get_event_status(index - num_gpes, status);
/*
* sleep/power button GPE/Fixed Event is enabled after acpi_system_init,
* check the status at runtime and mark it as valid once it's enabled
*/
if (!result && (*status & ACPI_EVENT_FLAG_ENABLED))
all_counters[index].flags |= ACPI_EVENT_VALID;
end: end:
return result; return result;
} }
...@@ -346,12 +339,14 @@ static ssize_t counter_show(struct kobject *kobj, ...@@ -346,12 +339,14 @@ static ssize_t counter_show(struct kobject *kobj,
if (result) if (result)
goto end; goto end;
if (!(all_counters[index].flags & ACPI_EVENT_VALID)) if (!(status & ACPI_EVENT_FLAG_HANDLE))
size += sprintf(buf + size, " invalid"); size += sprintf(buf + size, " invalid");
else if (status & ACPI_EVENT_FLAG_ENABLED) else if (status & ACPI_EVENT_FLAG_ENABLED)
size += sprintf(buf + size, " enable"); size += sprintf(buf + size, " enabled");
else if (status & ACPI_EVENT_FLAG_WAKE_ENABLED)
size += sprintf(buf + size, " wake_enabled");
else else
size += sprintf(buf + size, " disable"); size += sprintf(buf + size, " disabled");
end: end:
size += sprintf(buf + size, "\n"); size += sprintf(buf + size, "\n");
...@@ -385,7 +380,7 @@ static ssize_t counter_set(struct kobject *kobj, ...@@ -385,7 +380,7 @@ static ssize_t counter_set(struct kobject *kobj,
if (result) if (result)
goto end; goto end;
if (!(all_counters[index].flags & ACPI_EVENT_VALID)) { if (!(status & ACPI_EVENT_FLAG_HANDLE)) {
printk(KERN_WARNING PREFIX printk(KERN_WARNING PREFIX
"Can not change Invalid GPE/Fixed Event status\n"); "Can not change Invalid GPE/Fixed Event status\n");
return -EINVAL; return -EINVAL;
......
...@@ -525,6 +525,7 @@ typedef u32 acpi_event_status; ...@@ -525,6 +525,7 @@ typedef u32 acpi_event_status;
#define ACPI_EVENT_FLAG_ENABLED (acpi_event_status) 0x01 #define ACPI_EVENT_FLAG_ENABLED (acpi_event_status) 0x01
#define ACPI_EVENT_FLAG_WAKE_ENABLED (acpi_event_status) 0x02 #define ACPI_EVENT_FLAG_WAKE_ENABLED (acpi_event_status) 0x02
#define ACPI_EVENT_FLAG_SET (acpi_event_status) 0x04 #define ACPI_EVENT_FLAG_SET (acpi_event_status) 0x04
#define ACPI_EVENT_FLAG_HANDLE (acpi_event_status) 0x08
/* /*
* General Purpose Events (GPE) * General Purpose Events (GPE)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment