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>
This commit is contained in:
Zhang Rui 2008-10-27 14:01:02 -07:00 коммит произвёл Len Brown
Родитель 49fdf6785f
Коммит ed206fac87
4 изменённых файлов: 22 добавлений и 20 удалений

Просмотреть файл

@ -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:
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)
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,
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)
#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)
} 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,
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,
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;
#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)