===================================================================
@@ -668,6 +668,8 @@ typedef u32 acpi_event_status;
#define ACPI_GPE_ENABLE 0
#define ACPI_GPE_DISABLE 1
#define ACPI_GPE_CHECK_AND_ENABLE 2
+#define ACPI_GPE_FORCE_ENABLE 3
+#define ACPI_GPE_FORCE_DISABLE 4
/* gpe_types for acpi_enable_gpe and acpi_disable_gpe */
@@ -677,13 +679,14 @@ typedef u32 acpi_event_status;
/*
* GPE info flags - Per GPE
- * +-------+---+-+-+
- * | 7:4 |3:2|1|0|
- * +-------+---+-+-+
- * | | | |
- * | | | +--- Interrupt type: edge or level triggered
- * | | +----- GPE can wake the system
- * | +-------- Type of dispatch:to method, handler, or none
+ * +-------+-+---+-+-+
+ * | 7:5 |4|3:2|1|0|
+ * +-------+-+---+-+-+
+ * | | | | |
+ * | | | | +--- Interrupt type: edge or level triggered
+ * | | | +----- GPE can wake the system
+ * | | +-------- Type of dispatch:to method, handler, or none
+ * | +----------- GPE has been forcibly disabled
* +-------------- <Reserved>
*/
#define ACPI_GPE_XRUPT_TYPE_MASK (u8) 0x01
@@ -697,6 +700,8 @@ typedef u32 acpi_event_status;
#define ACPI_GPE_DISPATCH_METHOD (u8) 0x08
#define ACPI_GPE_DISPATCH_NOT_USED (u8) 0x00
+#define ACPI_GPE_FORCE_DISABLED (u8) 0x10
+
/*
* Flags for GPE and Lock interfaces
*/
===================================================================
@@ -417,7 +417,10 @@ static void acpi_ev_asynch_enable_gpe(vo
}
/* Enable this GPE */
- (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_CHECK_AND_ENABLE);
+ if (!(gpe_event_info->flags & ACPI_GPE_FORCE_DISABLED)) {
+ (void)acpi_hw_low_set_gpe(gpe_event_info,
+ ACPI_GPE_CHECK_AND_ENABLE);
+ }
return_VOID;
}
===================================================================
@@ -281,10 +281,24 @@ acpi_status acpi_set_gpe(acpi_handle gpe
status = acpi_clear_and_enable_gpe(gpe_event_info);
break;
+ case ACPI_GPE_FORCE_ENABLE:
+ status = acpi_clear_and_enable_gpe(gpe_event_info);
+ if (ACPI_SUCCESS(status)) {
+ gpe_event_info->flags &= ~(ACPI_GPE_FORCE_DISABLED);
+ }
+ break;
+
case ACPI_GPE_DISABLE:
status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
break;
+ case ACPI_GPE_FORCE_DISABLE:
+ status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
+ if (ACPI_SUCCESS(status)) {
+ gpe_event_info->flags |= ACPI_GPE_FORCE_DISABLED;
+ }
+ break;
+
default:
status = AE_BAD_PARAMETER;
break;
@@ -337,6 +351,11 @@ acpi_status acpi_enable_gpe(acpi_handle
goto unlock_and_exit;
}
+ if (gpe_event_info->flags & ACPI_GPE_FORCE_DISABLED) {
+ status = AE_ERROR;
+ goto unlock_and_exit;
+ }
+
if (gpe_type & ACPI_GPE_TYPE_RUNTIME) {
if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) {
status = AE_LIMIT; /* Too many references */
@@ -426,6 +445,11 @@ acpi_status acpi_disable_gpe(acpi_handle
goto unlock_and_exit;
}
+ if (gpe_event_info->flags & ACPI_GPE_FORCE_DISABLED) {
+ status = AE_ERROR;
+ goto unlock_and_exit;
+ }
+
/* Hardware-disable a runtime GPE on removal of the last reference */
if (gpe_type & ACPI_GPE_TYPE_RUNTIME) {
===================================================================
@@ -388,10 +388,12 @@ static ssize_t counter_set(struct kobjec
if (index < num_gpes) {
if (!strcmp(buf, "disable\n") &&
(status & ACPI_EVENT_FLAG_ENABLED))
- result = acpi_set_gpe(handle, index, ACPI_GPE_DISABLE);
+ result = acpi_set_gpe(handle, index,
+ ACPI_GPE_FORCE_DISABLE);
else if (!strcmp(buf, "enable\n") &&
!(status & ACPI_EVENT_FLAG_ENABLED))
- result = acpi_set_gpe(handle, index, ACPI_GPE_ENABLE);
+ result = acpi_set_gpe(handle, index,
+ ACPI_GPE_FORCE_ENABLE);
else if (!strcmp(buf, "clear\n") &&
(status & ACPI_EVENT_FLAG_SET))
result = acpi_clear_gpe(handle, index);