aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/acpica/acevents.h7
-rw-r--r--drivers/acpi/acpica/aclocal.h5
-rw-r--r--drivers/acpi/acpica/evgpe.c153
-rw-r--r--drivers/acpi/acpica/evgpeblk.c143
-rw-r--r--drivers/acpi/acpica/evxface.c20
-rw-r--r--drivers/acpi/acpica/evxfevnt.c191
-rw-r--r--drivers/acpi/acpica/exoparg2.c27
-rw-r--r--drivers/acpi/scan.c2
-rw-r--r--drivers/acpi/system.c5
-rw-r--r--include/acpi/acexcep.h2
-rw-r--r--include/acpi/acpixf.h11
-rw-r--r--include/acpi/actypes.h42
12 files changed, 346 insertions, 262 deletions
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h
index 3e6ba99e4053..5e094a28cf54 100644
--- a/drivers/acpi/acpica/acevents.h
+++ b/drivers/acpi/acpica/acevents.h
@@ -85,6 +85,10 @@ acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info);
85struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, 85struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device,
86 u32 gpe_number); 86 u32 gpe_number);
87 87
88struct acpi_gpe_event_info *acpi_ev_low_get_gpe_info(u32 gpe_number,
89 struct acpi_gpe_block_info
90 *gpe_block);
91
88/* 92/*
89 * evgpeblk 93 * evgpeblk
90 */ 94 */
@@ -118,9 +122,6 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info,
118 122
119u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list); 123u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list);
120 124
121acpi_status
122acpi_ev_check_for_wake_only_gpe(struct acpi_gpe_event_info *gpe_event_info);
123
124acpi_status acpi_ev_gpe_initialize(void); 125acpi_status acpi_ev_gpe_initialize(void);
125 126
126/* 127/*
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index 24b8faa5c395..5a6203a40c3e 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -427,8 +427,8 @@ struct acpi_gpe_event_info {
427 struct acpi_gpe_register_info *register_info; /* Backpointer to register info */ 427 struct acpi_gpe_register_info *register_info; /* Backpointer to register info */
428 u8 flags; /* Misc info about this GPE */ 428 u8 flags; /* Misc info about this GPE */
429 u8 gpe_number; /* This GPE */ 429 u8 gpe_number; /* This GPE */
430 u8 runtime_count; 430 u8 runtime_count; /* References to a run GPE */
431 u8 wakeup_count; 431 u8 wakeup_count; /* References to a wake GPE */
432}; 432};
433 433
434/* Information about a GPE register pair, one per each status/enable pair in an array */ 434/* Information about a GPE register pair, one per each status/enable pair in an array */
@@ -454,6 +454,7 @@ struct acpi_gpe_block_info {
454 struct acpi_gpe_event_info *event_info; /* One for each GPE */ 454 struct acpi_gpe_event_info *event_info; /* One for each GPE */
455 struct acpi_generic_address block_address; /* Base address of the block */ 455 struct acpi_generic_address block_address; /* Base address of the block */
456 u32 register_count; /* Number of register pairs in block */ 456 u32 register_count; /* Number of register pairs in block */
457 u16 gpe_count; /* Number of individual GPEs in block */
457 u8 block_base_number; /* Base GPE number for this block */ 458 u8 block_base_number; /* Base GPE number for this block */
458}; 459};
459 460
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c
index b9d50ef9f3ec..deb26f4c6623 100644
--- a/drivers/acpi/acpica/evgpe.c
+++ b/drivers/acpi/acpica/evgpe.c
@@ -60,7 +60,8 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context);
60 * 60 *
61 * RETURN: Status 61 * RETURN: Status
62 * 62 *
63 * DESCRIPTION: Updates GPE register enable masks based on the GPE type 63 * DESCRIPTION: Updates GPE register enable masks based upon whether there are
64 * references (either wake or run) to this GPE
64 * 65 *
65 ******************************************************************************/ 66 ******************************************************************************/
66 67
@@ -81,14 +82,20 @@ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info)
81 (1 << 82 (1 <<
82 (gpe_event_info->gpe_number - gpe_register_info->base_gpe_number)); 83 (gpe_event_info->gpe_number - gpe_register_info->base_gpe_number));
83 84
85 /* Clear the wake/run bits up front */
86
84 ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake, register_bit); 87 ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake, register_bit);
85 ACPI_CLEAR_BIT(gpe_register_info->enable_for_run, register_bit); 88 ACPI_CLEAR_BIT(gpe_register_info->enable_for_run, register_bit);
86 89
87 if (gpe_event_info->runtime_count) 90 /* Set the mask bits only if there are references to this GPE */
91
92 if (gpe_event_info->runtime_count) {
88 ACPI_SET_BIT(gpe_register_info->enable_for_run, register_bit); 93 ACPI_SET_BIT(gpe_register_info->enable_for_run, register_bit);
94 }
89 95
90 if (gpe_event_info->wakeup_count) 96 if (gpe_event_info->wakeup_count) {
91 ACPI_SET_BIT(gpe_register_info->enable_for_wake, register_bit); 97 ACPI_SET_BIT(gpe_register_info->enable_for_wake, register_bit);
98 }
92 99
93 return_ACPI_STATUS(AE_OK); 100 return_ACPI_STATUS(AE_OK);
94} 101}
@@ -101,7 +108,10 @@ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info)
101 * 108 *
102 * RETURN: Status 109 * RETURN: Status
103 * 110 *
104 * DESCRIPTION: Enable a GPE based on the GPE type 111 * DESCRIPTION: Hardware-enable a GPE. Always enables the GPE, regardless
112 * of type or number of references.
113 *
114 * Note: The GPE lock should be already acquired when this function is called.
105 * 115 *
106 ******************************************************************************/ 116 ******************************************************************************/
107 117
@@ -109,20 +119,36 @@ acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
109{ 119{
110 acpi_status status; 120 acpi_status status;
111 121
122
112 ACPI_FUNCTION_TRACE(ev_enable_gpe); 123 ACPI_FUNCTION_TRACE(ev_enable_gpe);
113 124
114 /* Make sure HW enable masks are updated */ 125
126 /*
127 * We will only allow a GPE to be enabled if it has either an
128 * associated method (_Lxx/_Exx) or a handler. Otherwise, the
129 * GPE will be immediately disabled by acpi_ev_gpe_dispatch the
130 * first time it fires.
131 */
132 if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)) {
133 return_ACPI_STATUS(AE_NO_HANDLER);
134 }
135
136 /* Ensure the HW enable masks are current */
115 137
116 status = acpi_ev_update_gpe_enable_masks(gpe_event_info); 138 status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
117 if (ACPI_FAILURE(status)) 139 if (ACPI_FAILURE(status)) {
118 return_ACPI_STATUS(status); 140 return_ACPI_STATUS(status);
141 }
142
143 /* Clear the GPE (of stale events) */
119 144
120 /* Clear the GPE (of stale events), then enable it */
121 status = acpi_hw_clear_gpe(gpe_event_info); 145 status = acpi_hw_clear_gpe(gpe_event_info);
122 if (ACPI_FAILURE(status)) 146 if (ACPI_FAILURE(status)) {
123 return_ACPI_STATUS(status); 147 return_ACPI_STATUS(status);
148 }
124 149
125 /* Enable the requested GPE */ 150 /* Enable the requested GPE */
151
126 status = acpi_hw_write_gpe_enable_reg(gpe_event_info); 152 status = acpi_hw_write_gpe_enable_reg(gpe_event_info);
127 return_ACPI_STATUS(status); 153 return_ACPI_STATUS(status);
128} 154}
@@ -135,7 +161,10 @@ acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
135 * 161 *
136 * RETURN: Status 162 * RETURN: Status
137 * 163 *
138 * DESCRIPTION: Disable a GPE based on the GPE type 164 * DESCRIPTION: Hardware-disable a GPE. Always disables the requested GPE,
165 * regardless of the type or number of references.
166 *
167 * Note: The GPE lock should be already acquired when this function is called.
139 * 168 *
140 ******************************************************************************/ 169 ******************************************************************************/
141 170
@@ -145,24 +174,71 @@ acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info)
145 174
146 ACPI_FUNCTION_TRACE(ev_disable_gpe); 175 ACPI_FUNCTION_TRACE(ev_disable_gpe);
147 176
148 /* Make sure HW enable masks are updated */ 177
178 /*
179 * Note: Always disable the GPE, even if we think that that it is already
180 * disabled. It is possible that the AML or some other code has enabled
181 * the GPE behind our back.
182 */
183
184 /* Ensure the HW enable masks are current */
149 185
150 status = acpi_ev_update_gpe_enable_masks(gpe_event_info); 186 status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
151 if (ACPI_FAILURE(status)) 187 if (ACPI_FAILURE(status)) {
152 return_ACPI_STATUS(status); 188 return_ACPI_STATUS(status);
189 }
153 190
154 /* 191 /*
155 * Even if we don't know the GPE type, make sure that we always 192 * Always H/W disable this GPE, even if we don't know the GPE type.
156 * disable it. low_disable_gpe will just clear the enable bit for this 193 * Simply clear the enable bit for this particular GPE, but do not
157 * GPE and write it. It will not write out the current GPE enable mask, 194 * write out the current GPE enable mask since this may inadvertently
158 * since this may inadvertently enable GPEs too early, if a rogue GPE has 195 * enable GPEs too early. An example is a rogue GPE that has arrived
159 * come in during ACPICA initialization - possibly as a result of AML or 196 * during ACPICA initialization - possibly because AML or other code
160 * other code that has enabled the GPE. 197 * has enabled the GPE.
161 */ 198 */
162 status = acpi_hw_low_disable_gpe(gpe_event_info); 199 status = acpi_hw_low_disable_gpe(gpe_event_info);
163 return_ACPI_STATUS(status); 200 return_ACPI_STATUS(status);
164} 201}
165 202
203
204/*******************************************************************************
205 *
206 * FUNCTION: acpi_ev_low_get_gpe_info
207 *
208 * PARAMETERS: gpe_number - Raw GPE number
209 * gpe_block - A GPE info block
210 *
211 * RETURN: A GPE event_info struct. NULL if not a valid GPE (The gpe_number
212 * is not within the specified GPE block)
213 *
214 * DESCRIPTION: Returns the event_info struct associated with this GPE. This is
215 * the low-level implementation of ev_get_gpe_event_info.
216 *
217 ******************************************************************************/
218
219struct acpi_gpe_event_info *acpi_ev_low_get_gpe_info(u32 gpe_number,
220 struct acpi_gpe_block_info
221 *gpe_block)
222{
223 u32 gpe_index;
224
225 /*
226 * Validate that the gpe_number is within the specified gpe_block.
227 * (Two steps)
228 */
229 if (!gpe_block || (gpe_number < gpe_block->block_base_number)) {
230 return (NULL);
231 }
232
233 gpe_index = gpe_number - gpe_block->block_base_number;
234 if (gpe_index >= gpe_block->gpe_count) {
235 return (NULL);
236 }
237
238 return (&gpe_block->event_info[gpe_index]);
239}
240
241
166/******************************************************************************* 242/*******************************************************************************
167 * 243 *
168 * FUNCTION: acpi_ev_get_gpe_event_info 244 * FUNCTION: acpi_ev_get_gpe_event_info
@@ -184,7 +260,7 @@ struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device,
184 u32 gpe_number) 260 u32 gpe_number)
185{ 261{
186 union acpi_operand_object *obj_desc; 262 union acpi_operand_object *obj_desc;
187 struct acpi_gpe_block_info *gpe_block; 263 struct acpi_gpe_event_info *gpe_info;
188 u32 i; 264 u32 i;
189 265
190 ACPI_FUNCTION_ENTRY(); 266 ACPI_FUNCTION_ENTRY();
@@ -196,17 +272,11 @@ struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device,
196 /* Examine GPE Block 0 and 1 (These blocks are permanent) */ 272 /* Examine GPE Block 0 and 1 (These blocks are permanent) */
197 273
198 for (i = 0; i < ACPI_MAX_GPE_BLOCKS; i++) { 274 for (i = 0; i < ACPI_MAX_GPE_BLOCKS; i++) {
199 gpe_block = acpi_gbl_gpe_fadt_blocks[i]; 275 gpe_info = acpi_ev_low_get_gpe_info(gpe_number,
200 if (gpe_block) { 276 acpi_gbl_gpe_fadt_blocks
201 if ((gpe_number >= gpe_block->block_base_number) 277 [i]);
202 && (gpe_number < 278 if (gpe_info) {
203 gpe_block->block_base_number + 279 return (gpe_info);
204 (gpe_block->register_count * 8))) {
205 return (&gpe_block->
206 event_info[gpe_number -
207 gpe_block->
208 block_base_number]);
209 }
210 } 280 }
211 } 281 }
212 282
@@ -223,16 +293,8 @@ struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device,
223 return (NULL); 293 return (NULL);
224 } 294 }
225 295
226 gpe_block = obj_desc->device.gpe_block; 296 return (acpi_ev_low_get_gpe_info
227 297 (gpe_number, obj_desc->device.gpe_block));
228 if ((gpe_number >= gpe_block->block_base_number) &&
229 (gpe_number <
230 gpe_block->block_base_number + (gpe_block->register_count * 8))) {
231 return (&gpe_block->
232 event_info[gpe_number - gpe_block->block_base_number]);
233 }
234
235 return (NULL);
236} 298}
237 299
238/******************************************************************************* 300/*******************************************************************************
@@ -389,7 +451,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
389 return_VOID; 451 return_VOID;
390 } 452 }
391 453
392 /* Set the GPE flags for return to enabled state */ 454 /* Update the GPE register masks for return to enabled state */
393 455
394 (void)acpi_ev_update_gpe_enable_masks(gpe_event_info); 456 (void)acpi_ev_update_gpe_enable_masks(gpe_event_info);
395 457
@@ -569,15 +631,18 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
569 631
570 default: 632 default:
571 633
572 /* No handler or method to run! */ 634 /*
573 635 * No handler or method to run!
636 * 03/2010: This case should no longer be possible. We will not allow
637 * a GPE to be enabled if it has no handler or method.
638 */
574 ACPI_ERROR((AE_INFO, 639 ACPI_ERROR((AE_INFO,
575 "No handler or method for GPE[0x%2X], disabling event", 640 "No handler or method for GPE[0x%2X], disabling event",
576 gpe_number)); 641 gpe_number));
577 642
578 /* 643 /*
579 * Disable the GPE. The GPE will remain disabled until the ACPICA 644 * Disable the GPE. The GPE will remain disabled a handler
580 * Core Subsystem is restarted, or a handler is installed. 645 * is installed or ACPICA is restarted.
581 */ 646 */
582 status = acpi_ev_disable_gpe(gpe_event_info); 647 status = acpi_ev_disable_gpe(gpe_event_info);
583 if (ACPI_FAILURE(status)) { 648 if (ACPI_FAILURE(status)) {
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c
index fa47e3522abe..85ded1f2540d 100644
--- a/drivers/acpi/acpica/evgpeblk.c
+++ b/drivers/acpi/acpica/evgpeblk.c
@@ -51,7 +51,7 @@ ACPI_MODULE_NAME("evgpeblk")
51 51
52/* Local prototypes */ 52/* Local prototypes */
53static acpi_status 53static acpi_status
54acpi_ev_save_method_info(acpi_handle obj_handle, 54acpi_ev_match_gpe_method(acpi_handle obj_handle,
55 u32 level, void *obj_desc, void **return_value); 55 u32 level, void *obj_desc, void **return_value);
56 56
57static acpi_status 57static acpi_status
@@ -104,9 +104,7 @@ u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info)
104 104
105 while (gpe_block) { 105 while (gpe_block) {
106 if ((&gpe_block->event_info[0] <= gpe_event_info) && 106 if ((&gpe_block->event_info[0] <= gpe_event_info) &&
107 (&gpe_block->event_info[((acpi_size) 107 (&gpe_block->event_info[gpe_block->gpe_count] >
108 gpe_block->
109 register_count) * 8] >
110 gpe_event_info)) { 108 gpe_event_info)) {
111 return (TRUE); 109 return (TRUE);
112 } 110 }
@@ -229,7 +227,7 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
229 227
230/******************************************************************************* 228/*******************************************************************************
231 * 229 *
232 * FUNCTION: acpi_ev_save_method_info 230 * FUNCTION: acpi_ev_match_gpe_method
233 * 231 *
234 * PARAMETERS: Callback from walk_namespace 232 * PARAMETERS: Callback from walk_namespace
235 * 233 *
@@ -241,8 +239,7 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
241 * information for quick lookup during GPE dispatch 239 * information for quick lookup during GPE dispatch
242 * 240 *
243 * The name of each GPE control method is of the form: 241 * The name of each GPE control method is of the form:
244 * "_Lxx" or "_Exx" 242 * "_Lxx" or "_Exx", where:
245 * Where:
246 * L - means that the GPE is level triggered 243 * L - means that the GPE is level triggered
247 * E - means that the GPE is edge triggered 244 * E - means that the GPE is edge triggered
248 * xx - is the GPE number [in HEX] 245 * xx - is the GPE number [in HEX]
@@ -250,9 +247,11 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
250 ******************************************************************************/ 247 ******************************************************************************/
251 248
252static acpi_status 249static acpi_status
253acpi_ev_save_method_info(acpi_handle obj_handle, 250acpi_ev_match_gpe_method(acpi_handle obj_handle,
254 u32 level, void *obj_desc, void **return_value) 251 u32 level, void *obj_desc, void **return_value)
255{ 252{
253 struct acpi_namespace_node *method_node =
254 ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
256 struct acpi_gpe_block_info *gpe_block = (void *)obj_desc; 255 struct acpi_gpe_block_info *gpe_block = (void *)obj_desc;
257 struct acpi_gpe_event_info *gpe_event_info; 256 struct acpi_gpe_event_info *gpe_event_info;
258 u32 gpe_number; 257 u32 gpe_number;
@@ -262,21 +261,25 @@ acpi_ev_save_method_info(acpi_handle obj_handle,
262 ACPI_FUNCTION_TRACE(ev_save_method_info); 261 ACPI_FUNCTION_TRACE(ev_save_method_info);
263 262
264 /* 263 /*
265 * _Lxx and _Exx GPE method support 264 * Match and decode the _Lxx and _Exx GPE method names
266 * 265 *
267 * 1) Extract the name from the object and convert to a string 266 * 1) Extract the method name and null terminate it
268 */ 267 */
269 ACPI_MOVE_32_TO_32(name, 268 ACPI_MOVE_32_TO_32(name, &method_node->name.integer);
270 &((struct acpi_namespace_node *)obj_handle)->name.
271 integer);
272 name[ACPI_NAME_SIZE] = 0; 269 name[ACPI_NAME_SIZE] = 0;
273 270
271 /* 2) Name must begin with an underscore */
272
273 if (name[0] != '_') {
274 return_ACPI_STATUS(AE_OK); /* Ignore this method */
275 }
276
274 /* 277 /*
275 * 2) Edge/Level determination is based on the 2nd character 278 * 3) Edge/Level determination is based on the 2nd character
276 * of the method name 279 * of the method name
277 * 280 *
278 * NOTE: Default GPE type is RUNTIME. May be changed later to WAKE 281 * NOTE: Default GPE type is RUNTIME only. Later, if a _PRW object is
279 * if a _PRW object is found that points to this GPE. 282 * found that points to this GPE, the ACPI_GPE_CAN_WAKE flag is set.
280 */ 283 */
281 switch (name[1]) { 284 switch (name[1]) {
282 case 'L': 285 case 'L':
@@ -288,7 +291,7 @@ acpi_ev_save_method_info(acpi_handle obj_handle,
288 break; 291 break;
289 292
290 default: 293 default:
291 /* Unknown method type, just ignore it! */ 294 /* Unknown method type, just ignore it */
292 295
293 ACPI_DEBUG_PRINT((ACPI_DB_LOAD, 296 ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
294 "Ignoring unknown GPE method type: %s " 297 "Ignoring unknown GPE method type: %s "
@@ -296,7 +299,7 @@ acpi_ev_save_method_info(acpi_handle obj_handle,
296 return_ACPI_STATUS(AE_OK); 299 return_ACPI_STATUS(AE_OK);
297 } 300 }
298 301
299 /* Convert the last two characters of the name to the GPE Number */ 302 /* 4) The last two characters of the name are the hex GPE Number */
300 303
301 gpe_number = ACPI_STRTOUL(&name[2], NULL, 16); 304 gpe_number = ACPI_STRTOUL(&name[2], NULL, 16);
302 if (gpe_number == ACPI_UINT32_MAX) { 305 if (gpe_number == ACPI_UINT32_MAX) {
@@ -311,28 +314,22 @@ acpi_ev_save_method_info(acpi_handle obj_handle,
311 314
312 /* Ensure that we have a valid GPE number for this GPE block */ 315 /* Ensure that we have a valid GPE number for this GPE block */
313 316
314 if ((gpe_number < gpe_block->block_base_number) || 317 gpe_event_info = acpi_ev_low_get_gpe_info(gpe_number, gpe_block);
315 (gpe_number >= (gpe_block->block_base_number + 318 if (!gpe_event_info) {
316 (gpe_block->register_count * 8)))) {
317 /* 319 /*
318 * Not valid for this GPE block, just ignore it. However, it may be 320 * This gpe_number is not valid for this GPE block, just ignore it.
319 * valid for a different GPE block, since GPE0 and GPE1 methods both 321 * However, it may be valid for a different GPE block, since GPE0
320 * appear under \_GPE. 322 * and GPE1 methods both appear under \_GPE.
321 */ 323 */
322 return_ACPI_STATUS(AE_OK); 324 return_ACPI_STATUS(AE_OK);
323 } 325 }
324 326
325 /* 327 /*
326 * Now we can add this information to the gpe_event_info block for use 328 * Add the GPE information from above to the gpe_event_info block for
327 * during dispatch of this GPE. 329 * use during dispatch of this GPE.
328 */ 330 */
329 gpe_event_info = 331 gpe_event_info->flags = (u8)(type | ACPI_GPE_DISPATCH_METHOD);
330 &gpe_block->event_info[gpe_number - gpe_block->block_base_number]; 332 gpe_event_info->dispatch.method_node = method_node;
331
332 gpe_event_info->flags = (u8) (type | ACPI_GPE_DISPATCH_METHOD);
333
334 gpe_event_info->dispatch.method_node =
335 (struct acpi_namespace_node *)obj_handle;
336 333
337 ACPI_DEBUG_PRINT((ACPI_DB_LOAD, 334 ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
338 "Registered GPE method %s as GPE number 0x%.2X\n", 335 "Registered GPE method %s as GPE number 0x%.2X\n",
@@ -351,7 +348,7 @@ acpi_ev_save_method_info(acpi_handle obj_handle,
351 * 348 *
352 * DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a 349 * DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a
353 * Device. Run the _PRW method. If present, extract the GPE 350 * Device. Run the _PRW method. If present, extract the GPE
354 * number and mark the GPE as a WAKE GPE. 351 * number and mark the GPE as a CAN_WAKE GPE.
355 * 352 *
356 ******************************************************************************/ 353 ******************************************************************************/
357 354
@@ -377,7 +374,7 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle,
377 ACPI_BTYPE_PACKAGE, &pkg_desc); 374 ACPI_BTYPE_PACKAGE, &pkg_desc);
378 if (ACPI_FAILURE(status)) { 375 if (ACPI_FAILURE(status)) {
379 376
380 /* Ignore all errors from _PRW, we don't want to abort the subsystem */ 377 /* Ignore all errors from _PRW, we don't want to abort the walk */
381 378
382 return_ACPI_STATUS(AE_OK); 379 return_ACPI_STATUS(AE_OK);
383 } 380 }
@@ -439,13 +436,13 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle,
439 * 2) The GPE index(number) is within the range of the Gpe Block 436 * 2) The GPE index(number) is within the range of the Gpe Block
440 * associated with the GPE device. 437 * associated with the GPE device.
441 */ 438 */
442 if ((gpe_device == target_gpe_device) && 439 if (gpe_device != target_gpe_device) {
443 (gpe_number >= gpe_block->block_base_number) && 440 goto cleanup;
444 (gpe_number < gpe_block->block_base_number + 441 }
445 (gpe_block->register_count * 8))) { 442
446 gpe_event_info = &gpe_block->event_info[gpe_number - 443 gpe_event_info = acpi_ev_low_get_gpe_info(gpe_number, gpe_block);
447 gpe_block-> 444 if (gpe_event_info) {
448 block_base_number]; 445 /* This GPE can wake the system */
449 446
450 gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; 447 gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
451 } 448 }
@@ -705,8 +702,7 @@ acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block)
705 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 702 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
706 } 703 }
707 704
708 acpi_current_gpe_count -= 705 acpi_current_gpe_count -= gpe_block->gpe_count;
709 gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH;
710 706
711 /* Free the gpe_block */ 707 /* Free the gpe_block */
712 708
@@ -760,9 +756,7 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block)
760 * Allocate the GPE event_info block. There are eight distinct GPEs 756 * Allocate the GPE event_info block. There are eight distinct GPEs
761 * per register. Initialization to zeros is sufficient. 757 * per register. Initialization to zeros is sufficient.
762 */ 758 */
763 gpe_event_info = ACPI_ALLOCATE_ZEROED(((acpi_size) gpe_block-> 759 gpe_event_info = ACPI_ALLOCATE_ZEROED((acpi_size) gpe_block->gpe_count *
764 register_count *
765 ACPI_GPE_REGISTER_WIDTH) *
766 sizeof(struct 760 sizeof(struct
767 acpi_gpe_event_info)); 761 acpi_gpe_event_info));
768 if (!gpe_event_info) { 762 if (!gpe_event_info) {
@@ -897,6 +891,7 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
897 /* Initialize the new GPE block */ 891 /* Initialize the new GPE block */
898 892
899 gpe_block->node = gpe_device; 893 gpe_block->node = gpe_device;
894 gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH);
900 gpe_block->register_count = register_count; 895 gpe_block->register_count = register_count;
901 gpe_block->block_base_number = gpe_block_base_number; 896 gpe_block->block_base_number = gpe_block_base_number;
902 897
@@ -925,7 +920,7 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
925 920
926 status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device, 921 status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device,
927 ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, 922 ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
928 acpi_ev_save_method_info, NULL, 923 acpi_ev_match_gpe_method, NULL,
929 gpe_block, NULL); 924 gpe_block, NULL);
930 925
931 /* Return the new block */ 926 /* Return the new block */
@@ -938,14 +933,13 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
938 "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n", 933 "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n",
939 (u32) gpe_block->block_base_number, 934 (u32) gpe_block->block_base_number,
940 (u32) (gpe_block->block_base_number + 935 (u32) (gpe_block->block_base_number +
941 ((gpe_block->register_count * 936 (gpe_block->gpe_count - 1)),
942 ACPI_GPE_REGISTER_WIDTH) - 1)),
943 gpe_device->name.ascii, gpe_block->register_count, 937 gpe_device->name.ascii, gpe_block->register_count,
944 interrupt_number)); 938 interrupt_number));
945 939
946 /* Update global count of currently available GPEs */ 940 /* Update global count of currently available GPEs */
947 941
948 acpi_current_gpe_count += register_count * ACPI_GPE_REGISTER_WIDTH; 942 acpi_current_gpe_count += gpe_block->gpe_count;
949 return_ACPI_STATUS(AE_OK); 943 return_ACPI_STATUS(AE_OK);
950} 944}
951 945
@@ -969,10 +963,13 @@ acpi_status
969acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, 963acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
970 struct acpi_gpe_block_info *gpe_block) 964 struct acpi_gpe_block_info *gpe_block)
971{ 965{
966 acpi_status status;
972 struct acpi_gpe_event_info *gpe_event_info; 967 struct acpi_gpe_event_info *gpe_event_info;
973 struct acpi_gpe_walk_info gpe_info; 968 struct acpi_gpe_walk_info gpe_info;
974 u32 wake_gpe_count; 969 u32 wake_gpe_count;
975 u32 gpe_enabled_count; 970 u32 gpe_enabled_count;
971 u32 gpe_index;
972 u32 gpe_number;
976 u32 i; 973 u32 i;
977 u32 j; 974 u32 j;
978 975
@@ -998,50 +995,62 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
998 gpe_info.gpe_block = gpe_block; 995 gpe_info.gpe_block = gpe_block;
999 gpe_info.gpe_device = gpe_device; 996 gpe_info.gpe_device = gpe_device;
1000 997
1001 acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 998 status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
1002 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, 999 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
1003 acpi_ev_match_prw_and_gpe, NULL, 1000 acpi_ev_match_prw_and_gpe, NULL,
1004 &gpe_info, NULL); 1001 &gpe_info, NULL);
1002 if (ACPI_FAILURE(status)) {
1003 ACPI_EXCEPTION((AE_INFO, status,
1004 "While executing _PRW methods"));
1005 }
1005 } 1006 }
1006 1007
1007 /* 1008 /*
1008 * Enable all GPEs that have a corresponding method and aren't 1009 * Enable all GPEs that have a corresponding method and are not
1009 * capable of generating wakeups. Any other GPEs within this block 1010 * capable of generating wakeups. Any other GPEs within this block
1010 * must be enabled via the acpi_enable_gpe() interface. 1011 * must be enabled via the acpi_enable_gpe interface.
1011 */ 1012 */
1012 wake_gpe_count = 0; 1013 wake_gpe_count = 0;
1013 gpe_enabled_count = 0; 1014 gpe_enabled_count = 0;
1014 if (gpe_device == acpi_gbl_fadt_gpe_device) 1015
1016 if (gpe_device == acpi_gbl_fadt_gpe_device) {
1015 gpe_device = NULL; 1017 gpe_device = NULL;
1018 }
1016 1019
1017 for (i = 0; i < gpe_block->register_count; i++) { 1020 for (i = 0; i < gpe_block->register_count; i++) {
1018 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { 1021 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
1019 acpi_status status;
1020 acpi_size gpe_index;
1021 int gpe_number;
1022 1022
1023 /* Get the info block for this particular GPE */ 1023 /* Get the info block for this particular GPE */
1024 gpe_index = (acpi_size)i * ACPI_GPE_REGISTER_WIDTH + j; 1024
1025 gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j;
1025 gpe_event_info = &gpe_block->event_info[gpe_index]; 1026 gpe_event_info = &gpe_block->event_info[gpe_index];
1026 1027
1027 if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) { 1028 if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) {
1028 wake_gpe_count++; 1029 wake_gpe_count++;
1029 if (acpi_gbl_leave_wake_gpes_disabled) 1030 if (acpi_gbl_leave_wake_gpes_disabled) {
1030 continue; 1031 continue;
1032 }
1031 } 1033 }
1032 1034
1033 if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD)) 1035 /* Ignore GPEs that have no corresponding _Lxx/_Exx method */
1036
1037 if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD)) {
1034 continue; 1038 continue;
1039 }
1040
1041 /* Enable this GPE */
1035 1042
1036 gpe_number = gpe_index + gpe_block->block_base_number; 1043 gpe_number = gpe_index + gpe_block->block_base_number;
1037 status = acpi_enable_gpe(gpe_device, gpe_number, 1044 status = acpi_enable_gpe(gpe_device, gpe_number,
1038 ACPI_GPE_TYPE_RUNTIME); 1045 ACPI_GPE_TYPE_RUNTIME);
1039 if (ACPI_FAILURE(status)) 1046 if (ACPI_FAILURE(status)) {
1040 ACPI_ERROR((AE_INFO, 1047 ACPI_EXCEPTION((AE_INFO, status,
1041 "Failed to enable GPE %02X\n", 1048 "Could not enable GPE 0x%02X",
1042 gpe_number)); 1049 gpe_number));
1043 else 1050 continue;
1044 gpe_enabled_count++; 1051 }
1052
1053 gpe_enabled_count++;
1045 } 1054 }
1046 } 1055 }
1047 1056
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c
index ca048233d8d3..cc825023012a 100644
--- a/drivers/acpi/acpica/evxface.c
+++ b/drivers/acpi/acpica/evxface.c
@@ -682,14 +682,13 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
682 682
683 /* Parameter validation */ 683 /* Parameter validation */
684 684
685 if ((!address) || (type > ACPI_GPE_XRUPT_TYPE_MASK)) { 685 if ((!address) || (type & ~ACPI_GPE_XRUPT_TYPE_MASK)) {
686 status = AE_BAD_PARAMETER; 686 return_ACPI_STATUS(AE_BAD_PARAMETER);
687 goto exit;
688 } 687 }
689 688
690 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); 689 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
691 if (ACPI_FAILURE(status)) { 690 if (ACPI_FAILURE(status)) {
692 goto exit; 691 return_ACPI_STATUS(status);
693 } 692 }
694 693
695 /* Ensure that we have a valid GPE number */ 694 /* Ensure that we have a valid GPE number */
@@ -720,6 +719,13 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
720 handler->context = context; 719 handler->context = context;
721 handler->method_node = gpe_event_info->dispatch.method_node; 720 handler->method_node = gpe_event_info->dispatch.method_node;
722 721
722 /* Disable the GPE before installing the handler */
723
724 status = acpi_ev_disable_gpe(gpe_event_info);
725 if (ACPI_FAILURE (status)) {
726 goto unlock_and_exit;
727 }
728
723 /* Install the handler */ 729 /* Install the handler */
724 730
725 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 731 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
@@ -733,12 +739,8 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
733 739
734 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 740 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
735 741
736 unlock_and_exit: 742unlock_and_exit:
737 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); 743 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
738 exit:
739 if (ACPI_FAILURE(status))
740 ACPI_EXCEPTION((AE_INFO, status,
741 "Installing notify handler failed"));
742 return_ACPI_STATUS(status); 744 return_ACPI_STATUS(status);
743} 745}
744 746
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c
index 5ff32c78ea2d..7c7bbb4d402c 100644
--- a/drivers/acpi/acpica/evxfevnt.c
+++ b/drivers/acpi/acpica/evxfevnt.c
@@ -203,21 +203,26 @@ ACPI_EXPORT_SYMBOL(acpi_enable_event)
203 * 203 *
204 * FUNCTION: acpi_set_gpe 204 * FUNCTION: acpi_set_gpe
205 * 205 *
206 * PARAMETERS: gpe_device - Parent GPE Device 206 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
207 * gpe_number - GPE level within the GPE block 207 * gpe_number - GPE level within the GPE block
208 * action - Enable or disable 208 * action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
209 * Called from ISR or not
210 * 209 *
211 * RETURN: Status 210 * RETURN: Status
212 * 211 *
213 * DESCRIPTION: Enable or disable an ACPI event (general purpose) 212 * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
213 * the reference count mechanism used in the acpi_enable_gpe and
214 * acpi_disable_gpe interfaces -- and should be used with care.
215 *
216 * Note: Typically used to disable a runtime GPE for short period of time,
217 * then re-enable it, without disturbing the existing reference counts. This
218 * is useful, for example, in the Embedded Controller (EC) driver.
214 * 219 *
215 ******************************************************************************/ 220 ******************************************************************************/
216acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action) 221acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action)
217{ 222{
218 acpi_status status = AE_OK;
219 acpi_cpu_flags flags;
220 struct acpi_gpe_event_info *gpe_event_info; 223 struct acpi_gpe_event_info *gpe_event_info;
224 acpi_status status;
225 acpi_cpu_flags flags;
221 226
222 ACPI_FUNCTION_TRACE(acpi_set_gpe); 227 ACPI_FUNCTION_TRACE(acpi_set_gpe);
223 228
@@ -243,7 +248,6 @@ acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action)
243 break; 248 break;
244 249
245 default: 250 default:
246 ACPI_ERROR((AE_INFO, "Invalid action\n"));
247 status = AE_BAD_PARAMETER; 251 status = AE_BAD_PARAMETER;
248 break; 252 break;
249 } 253 }
@@ -259,25 +263,31 @@ ACPI_EXPORT_SYMBOL(acpi_set_gpe)
259 * 263 *
260 * FUNCTION: acpi_enable_gpe 264 * FUNCTION: acpi_enable_gpe
261 * 265 *
262 * PARAMETERS: gpe_device - Parent GPE Device 266 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
263 * gpe_number - GPE level within the GPE block 267 * gpe_number - GPE level within the GPE block
264 * type - Purpose the GPE will be used for 268 * gpe_type - ACPI_GPE_TYPE_RUNTIME or ACPI_GPE_TYPE_WAKE
269 * or both
265 * 270 *
266 * RETURN: Status 271 * RETURN: Status
267 * 272 *
268 * DESCRIPTION: Take a reference to a GPE and enable it if necessary 273 * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
274 * hardware-enabled (for runtime GPEs), or the GPE register mask
275 * is updated (for wake GPEs).
269 * 276 *
270 ******************************************************************************/ 277 ******************************************************************************/
271acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type) 278acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type)
272{ 279{
273 acpi_status status = AE_OK; 280 acpi_status status = AE_OK;
274 acpi_cpu_flags flags;
275 struct acpi_gpe_event_info *gpe_event_info; 281 struct acpi_gpe_event_info *gpe_event_info;
282 acpi_cpu_flags flags;
276 283
277 ACPI_FUNCTION_TRACE(acpi_enable_gpe); 284 ACPI_FUNCTION_TRACE(acpi_enable_gpe);
278 285
279 if (type & ~ACPI_GPE_TYPE_WAKE_RUN) 286 /* Parameter validation */
287
288 if (!gpe_type || (gpe_type & ~ACPI_GPE_TYPE_WAKE_RUN)) {
280 return_ACPI_STATUS(AE_BAD_PARAMETER); 289 return_ACPI_STATUS(AE_BAD_PARAMETER);
290 }
281 291
282 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 292 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
283 293
@@ -289,26 +299,43 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type)
289 goto unlock_and_exit; 299 goto unlock_and_exit;
290 } 300 }
291 301
292 if (type & ACPI_GPE_TYPE_RUNTIME) { 302 if (gpe_type & ACPI_GPE_TYPE_RUNTIME) {
293 if (++gpe_event_info->runtime_count == 1) { 303 if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) {
304 status = AE_LIMIT; /* Too many references */
305 goto unlock_and_exit;
306 }
307
308 gpe_event_info->runtime_count++;
309 if (gpe_event_info->runtime_count == 1) {
294 status = acpi_ev_enable_gpe(gpe_event_info); 310 status = acpi_ev_enable_gpe(gpe_event_info);
295 if (ACPI_FAILURE(status)) 311 if (ACPI_FAILURE(status)) {
296 gpe_event_info->runtime_count--; 312 gpe_event_info->runtime_count--;
313 goto unlock_and_exit;
314 }
297 } 315 }
298 } 316 }
299 317
300 if (type & ACPI_GPE_TYPE_WAKE) { 318 if (gpe_type & ACPI_GPE_TYPE_WAKE) {
319 /* The GPE must have the ability to wake the system */
320
301 if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { 321 if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
302 status = AE_BAD_PARAMETER; 322 status = AE_TYPE;
323 goto unlock_and_exit;
324 }
325
326 if (gpe_event_info->wakeup_count == ACPI_UINT8_MAX) {
327 status = AE_LIMIT; /* Too many references */
303 goto unlock_and_exit; 328 goto unlock_and_exit;
304 } 329 }
305 330
306 /* 331 /*
307 * Wake-up GPEs are only enabled right prior to putting the 332 * Update the enable mask on the first wakeup reference. Wake GPEs
308 * system into a sleep state. 333 * are only hardware-enabled just before sleeping.
309 */ 334 */
310 if (++gpe_event_info->wakeup_count == 1) 335 gpe_event_info->wakeup_count++;
311 acpi_ev_update_gpe_enable_masks(gpe_event_info); 336 if (gpe_event_info->wakeup_count == 1) {
337 (void)acpi_ev_update_gpe_enable_masks(gpe_event_info);
338 }
312 } 339 }
313 340
314unlock_and_exit: 341unlock_and_exit:
@@ -321,27 +348,34 @@ ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
321 * 348 *
322 * FUNCTION: acpi_disable_gpe 349 * FUNCTION: acpi_disable_gpe
323 * 350 *
324 * PARAMETERS: gpe_device - Parent GPE Device 351 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
325 * gpe_number - GPE level within the GPE block 352 * gpe_number - GPE level within the GPE block
326 * type - Purpose the GPE won't be used for any more 353 * gpe_type - ACPI_GPE_TYPE_RUNTIME or ACPI_GPE_TYPE_WAKE
354 * or both
327 * 355 *
328 * RETURN: Status 356 * RETURN: Status
329 * 357 *
330 * DESCRIPTION: Release a reference to a GPE and disable it if necessary 358 * DESCRIPTION: Remove a reference to a GPE. When the last reference is
359 * removed, only then is the GPE disabled (for runtime GPEs), or
360 * the GPE mask bit disabled (for wake GPEs)
331 * 361 *
332 ******************************************************************************/ 362 ******************************************************************************/
333acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type) 363acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type)
334{ 364{
335 acpi_status status = AE_OK; 365 acpi_status status = AE_OK;
336 acpi_cpu_flags flags;
337 struct acpi_gpe_event_info *gpe_event_info; 366 struct acpi_gpe_event_info *gpe_event_info;
367 acpi_cpu_flags flags;
338 368
339 ACPI_FUNCTION_TRACE(acpi_disable_gpe); 369 ACPI_FUNCTION_TRACE(acpi_disable_gpe);
340 370
341 if (type & ~ACPI_GPE_TYPE_WAKE_RUN) 371 /* Parameter validation */
372
373 if (!gpe_type || (gpe_type & ~ACPI_GPE_TYPE_WAKE_RUN)) {
342 return_ACPI_STATUS(AE_BAD_PARAMETER); 374 return_ACPI_STATUS(AE_BAD_PARAMETER);
375 }
343 376
344 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 377 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
378
345 /* Ensure that we have a valid GPE number */ 379 /* Ensure that we have a valid GPE number */
346 380
347 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 381 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
@@ -350,18 +384,39 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type)
350 goto unlock_and_exit; 384 goto unlock_and_exit;
351 } 385 }
352 386
353 if ((type & ACPI_GPE_TYPE_RUNTIME) && gpe_event_info->runtime_count) { 387 /* Hardware-disable a runtime GPE on removal of the last reference */
354 if (--gpe_event_info->runtime_count == 0) 388
389 if (gpe_type & ACPI_GPE_TYPE_RUNTIME) {
390 if (!gpe_event_info->runtime_count) {
391 status = AE_LIMIT; /* There are no references to remove */
392 goto unlock_and_exit;
393 }
394
395 gpe_event_info->runtime_count--;
396 if (!gpe_event_info->runtime_count) {
355 status = acpi_ev_disable_gpe(gpe_event_info); 397 status = acpi_ev_disable_gpe(gpe_event_info);
398 if (ACPI_FAILURE(status)) {
399 gpe_event_info->runtime_count++;
400 goto unlock_and_exit;
401 }
402 }
356 } 403 }
357 404
358 if ((type & ACPI_GPE_TYPE_WAKE) && gpe_event_info->wakeup_count) { 405 /*
359 /* 406 * Update masks for wake GPE on removal of the last reference.
360 * Wake-up GPEs are not enabled after leaving system sleep 407 * No need to hardware-disable wake GPEs here, they are not currently
361 * states, so we don't need to disable them here. 408 * enabled.
362 */ 409 */
363 if (--gpe_event_info->wakeup_count == 0) 410 if (gpe_type & ACPI_GPE_TYPE_WAKE) {
364 acpi_ev_update_gpe_enable_masks(gpe_event_info); 411 if (!gpe_event_info->wakeup_count) {
412 status = AE_LIMIT; /* There are no references to remove */
413 goto unlock_and_exit;
414 }
415
416 gpe_event_info->wakeup_count--;
417 if (!gpe_event_info->wakeup_count) {
418 (void)acpi_ev_update_gpe_enable_masks(gpe_event_info);
419 }
365 } 420 }
366 421
367unlock_and_exit: 422unlock_and_exit:
@@ -465,30 +520,23 @@ ACPI_EXPORT_SYMBOL(acpi_clear_event)
465 * 520 *
466 * FUNCTION: acpi_clear_gpe 521 * FUNCTION: acpi_clear_gpe
467 * 522 *
468 * PARAMETERS: gpe_device - Parent GPE Device 523 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
469 * gpe_number - GPE level within the GPE block 524 * gpe_number - GPE level within the GPE block
470 * Flags - Called from an ISR or not
471 * 525 *
472 * RETURN: Status 526 * RETURN: Status
473 * 527 *
474 * DESCRIPTION: Clear an ACPI event (general purpose) 528 * DESCRIPTION: Clear an ACPI event (general purpose)
475 * 529 *
476 ******************************************************************************/ 530 ******************************************************************************/
477acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) 531acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number)
478{ 532{
479 acpi_status status = AE_OK; 533 acpi_status status = AE_OK;
480 struct acpi_gpe_event_info *gpe_event_info; 534 struct acpi_gpe_event_info *gpe_event_info;
535 acpi_cpu_flags flags;
481 536
482 ACPI_FUNCTION_TRACE(acpi_clear_gpe); 537 ACPI_FUNCTION_TRACE(acpi_clear_gpe);
483 538
484 /* Use semaphore lock if not executing at interrupt level */ 539 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
485
486 if (flags & ACPI_NOT_ISR) {
487 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
488 if (ACPI_FAILURE(status)) {
489 return_ACPI_STATUS(status);
490 }
491 }
492 540
493 /* Ensure that we have a valid GPE number */ 541 /* Ensure that we have a valid GPE number */
494 542
@@ -501,9 +549,7 @@ acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
501 status = acpi_hw_clear_gpe(gpe_event_info); 549 status = acpi_hw_clear_gpe(gpe_event_info);
502 550
503 unlock_and_exit: 551 unlock_and_exit:
504 if (flags & ACPI_NOT_ISR) { 552 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
505 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
506 }
507 return_ACPI_STATUS(status); 553 return_ACPI_STATUS(status);
508} 554}
509 555
@@ -569,9 +615,8 @@ ACPI_EXPORT_SYMBOL(acpi_get_event_status)
569 * 615 *
570 * FUNCTION: acpi_get_gpe_status 616 * FUNCTION: acpi_get_gpe_status
571 * 617 *
572 * PARAMETERS: gpe_device - Parent GPE Device 618 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
573 * gpe_number - GPE level within the GPE block 619 * gpe_number - GPE level within the GPE block
574 * Flags - Called from an ISR or not
575 * event_status - Where the current status of the event will 620 * event_status - Where the current status of the event will
576 * be returned 621 * be returned
577 * 622 *
@@ -582,21 +627,15 @@ ACPI_EXPORT_SYMBOL(acpi_get_event_status)
582 ******************************************************************************/ 627 ******************************************************************************/
583acpi_status 628acpi_status
584acpi_get_gpe_status(acpi_handle gpe_device, 629acpi_get_gpe_status(acpi_handle gpe_device,
585 u32 gpe_number, u32 flags, acpi_event_status * event_status) 630 u32 gpe_number, acpi_event_status *event_status)
586{ 631{
587 acpi_status status = AE_OK; 632 acpi_status status = AE_OK;
588 struct acpi_gpe_event_info *gpe_event_info; 633 struct acpi_gpe_event_info *gpe_event_info;
634 acpi_cpu_flags flags;
589 635
590 ACPI_FUNCTION_TRACE(acpi_get_gpe_status); 636 ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
591 637
592 /* Use semaphore lock if not executing at interrupt level */ 638 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
593
594 if (flags & ACPI_NOT_ISR) {
595 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
596 if (ACPI_FAILURE(status)) {
597 return_ACPI_STATUS(status);
598 }
599 }
600 639
601 /* Ensure that we have a valid GPE number */ 640 /* Ensure that we have a valid GPE number */
602 641
@@ -614,9 +653,7 @@ acpi_get_gpe_status(acpi_handle gpe_device,
614 *event_status |= ACPI_EVENT_FLAG_HANDLE; 653 *event_status |= ACPI_EVENT_FLAG_HANDLE;
615 654
616 unlock_and_exit: 655 unlock_and_exit:
617 if (flags & ACPI_NOT_ISR) { 656 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
618 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
619 }
620 return_ACPI_STATUS(status); 657 return_ACPI_STATUS(status);
621} 658}
622 659
@@ -673,20 +710,15 @@ acpi_install_gpe_block(acpi_handle gpe_device,
673 goto unlock_and_exit; 710 goto unlock_and_exit;
674 } 711 }
675 712
676 /* Run the _PRW methods and enable the GPEs */ 713 /* Install block in the device_object attached to the node */
677
678 status = acpi_ev_initialize_gpe_block(node, gpe_block);
679 if (ACPI_FAILURE(status)) {
680 goto unlock_and_exit;
681 }
682
683 /* Get the device_object attached to the node */
684 714
685 obj_desc = acpi_ns_get_attached_object(node); 715 obj_desc = acpi_ns_get_attached_object(node);
686 if (!obj_desc) { 716 if (!obj_desc) {
687 717
688 /* No object, create a new one */ 718 /*
689 719 * No object, create a new one (Device nodes do not always have
720 * an attached object)
721 */
690 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE); 722 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
691 if (!obj_desc) { 723 if (!obj_desc) {
692 status = AE_NO_MEMORY; 724 status = AE_NO_MEMORY;
@@ -705,10 +737,14 @@ acpi_install_gpe_block(acpi_handle gpe_device,
705 } 737 }
706 } 738 }
707 739
708 /* Install the GPE block in the device_object */ 740 /* Now install the GPE block in the device_object */
709 741
710 obj_desc->device.gpe_block = gpe_block; 742 obj_desc->device.gpe_block = gpe_block;
711 743
744 /* Run the _PRW methods and enable the runtime GPEs in the new block */
745
746 status = acpi_ev_initialize_gpe_block(node, gpe_block);
747
712 unlock_and_exit: 748 unlock_and_exit:
713 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 749 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
714 return_ACPI_STATUS(status); 750 return_ACPI_STATUS(status);
@@ -839,8 +875,7 @@ acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
839 875
840 /* Increment Index by the number of GPEs in this block */ 876 /* Increment Index by the number of GPEs in this block */
841 877
842 info->next_block_base_index += 878 info->next_block_base_index += gpe_block->gpe_count;
843 (gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH);
844 879
845 if (info->index < info->next_block_base_index) { 880 if (info->index < info->next_block_base_index) {
846 /* 881 /*
diff --git a/drivers/acpi/acpica/exoparg2.c b/drivers/acpi/acpica/exoparg2.c
index 3f3f48bb2dc8..10e104cf0fb9 100644
--- a/drivers/acpi/acpica/exoparg2.c
+++ b/drivers/acpi/acpica/exoparg2.c
@@ -119,33 +119,6 @@ acpi_status acpi_ex_opcode_2A_0T_0R(struct acpi_walk_state *walk_state)
119 status = AE_AML_OPERAND_TYPE; 119 status = AE_AML_OPERAND_TYPE;
120 break; 120 break;
121 } 121 }
122#ifdef ACPI_GPE_NOTIFY_CHECK
123 /*
124 * GPE method wake/notify check. Here, we want to ensure that we
125 * don't receive any "DeviceWake" Notifies from a GPE _Lxx or _Exx
126 * GPE method during system runtime. If we do, the GPE is marked
127 * as "wake-only" and disabled.
128 *
129 * 1) Is the Notify() value == device_wake?
130 * 2) Is this a GPE deferred method? (An _Lxx or _Exx method)
131 * 3) Did the original GPE happen at system runtime?
132 * (versus during wake)
133 *
134 * If all three cases are true, this is a wake-only GPE that should
135 * be disabled at runtime.
136 */
137 if (value == 2) { /* device_wake */
138 status =
139 acpi_ev_check_for_wake_only_gpe(walk_state->
140 gpe_event_info);
141 if (ACPI_FAILURE(status)) {
142
143 /* AE_WAKE_ONLY_GPE only error, means ignore this notify */
144
145 return_ACPI_STATUS(AE_OK)
146 }
147 }
148#endif
149 122
150 /* 123 /*
151 * Dispatch the notify to the appropriate handler 124 * Dispatch the notify to the appropriate handler
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 0338f513a010..7f2e051ed4f1 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -765,7 +765,7 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
765 } 765 }
766 766
767 status = acpi_get_gpe_status(NULL, device->wakeup.gpe_number, 767 status = acpi_get_gpe_status(NULL, device->wakeup.gpe_number,
768 ACPI_NOT_ISR, &event_status); 768 &event_status);
769 if (status == AE_OK) 769 if (status == AE_OK)
770 device->wakeup.flags.run_wake = 770 device->wakeup.flags.run_wake =
771 !!(event_status & ACPI_EVENT_FLAG_HANDLE); 771 !!(event_status & ACPI_EVENT_FLAG_HANDLE);
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index 4aaf24976138..e35525b39f6b 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -303,8 +303,7 @@ static int get_status(u32 index, acpi_event_status *status, acpi_handle *handle)
303 "Invalid GPE 0x%x\n", index)); 303 "Invalid GPE 0x%x\n", index));
304 goto end; 304 goto end;
305 } 305 }
306 result = acpi_get_gpe_status(*handle, index, 306 result = acpi_get_gpe_status(*handle, index, status);
307 ACPI_NOT_ISR, status);
308 } else if (index < (num_gpes + ACPI_NUM_FIXED_EVENTS)) 307 } else if (index < (num_gpes + ACPI_NUM_FIXED_EVENTS))
309 result = acpi_get_event_status(index - num_gpes, status); 308 result = acpi_get_event_status(index - num_gpes, status);
310 309
@@ -395,7 +394,7 @@ static ssize_t counter_set(struct kobject *kobj,
395 result = acpi_set_gpe(handle, index, ACPI_GPE_ENABLE); 394 result = acpi_set_gpe(handle, index, ACPI_GPE_ENABLE);
396 else if (!strcmp(buf, "clear\n") && 395 else if (!strcmp(buf, "clear\n") &&
397 (status & ACPI_EVENT_FLAG_SET)) 396 (status & ACPI_EVENT_FLAG_SET))
398 result = acpi_clear_gpe(handle, index, ACPI_NOT_ISR); 397 result = acpi_clear_gpe(handle, index);
399 else 398 else
400 all_counters[index].count = strtoul(buf, NULL, 0); 399 all_counters[index].count = strtoul(buf, NULL, 0);
401 } else if (index < num_gpes + ACPI_NUM_FIXED_EVENTS) { 400 } else if (index < num_gpes + ACPI_NUM_FIXED_EVENTS) {
diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h
index 5b2e5e80ecb0..5958d7845bd5 100644
--- a/include/acpi/acexcep.h
+++ b/include/acpi/acexcep.h
@@ -87,7 +87,7 @@
87#define AE_NO_GLOBAL_LOCK (acpi_status) (0x0017 | AE_CODE_ENVIRONMENTAL) 87#define AE_NO_GLOBAL_LOCK (acpi_status) (0x0017 | AE_CODE_ENVIRONMENTAL)
88#define AE_ABORT_METHOD (acpi_status) (0x0018 | AE_CODE_ENVIRONMENTAL) 88#define AE_ABORT_METHOD (acpi_status) (0x0018 | AE_CODE_ENVIRONMENTAL)
89#define AE_SAME_HANDLER (acpi_status) (0x0019 | AE_CODE_ENVIRONMENTAL) 89#define AE_SAME_HANDLER (acpi_status) (0x0019 | AE_CODE_ENVIRONMENTAL)
90#define AE_WAKE_ONLY_GPE (acpi_status) (0x001A | AE_CODE_ENVIRONMENTAL) 90#define AE_NO_HANDLER (acpi_status) (0x001A | AE_CODE_ENVIRONMENTAL)
91#define AE_OWNER_ID_LIMIT (acpi_status) (0x001B | AE_CODE_ENVIRONMENTAL) 91#define AE_OWNER_ID_LIMIT (acpi_status) (0x001B | AE_CODE_ENVIRONMENTAL)
92 92
93#define AE_CODE_ENV_MAX 0x001B 93#define AE_CODE_ENV_MAX 0x001B
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index fd815f605426..be16f976c531 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -285,16 +285,17 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status);
285 */ 285 */
286acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action); 286acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action);
287 287
288acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type); 288acpi_status
289acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type);
289 290
290acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type); 291acpi_status
292acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type);
291 293
292acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags); 294acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number);
293 295
294acpi_status 296acpi_status
295acpi_get_gpe_status(acpi_handle gpe_device, 297acpi_get_gpe_status(acpi_handle gpe_device,
296 u32 gpe_number, 298 u32 gpe_number, acpi_event_status *event_status);
297 u32 flags, acpi_event_status * event_status);
298 299
299acpi_status acpi_disable_all_gpes(void); 300acpi_status acpi_disable_all_gpes(void);
300 301
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
index 3f08e64962f8..de5e99a99530 100644
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -663,44 +663,42 @@ typedef u32 acpi_event_status;
663#define ACPI_GPE_MAX 0xFF 663#define ACPI_GPE_MAX 0xFF
664#define ACPI_NUM_GPE 256 664#define ACPI_NUM_GPE 256
665 665
666/* Actions for acpi_set_gpe */
667
666#define ACPI_GPE_ENABLE 0 668#define ACPI_GPE_ENABLE 0
667#define ACPI_GPE_DISABLE 1 669#define ACPI_GPE_DISABLE 1
668 670
671/* gpe_types for acpi_enable_gpe and acpi_disable_gpe */
672
673#define ACPI_GPE_TYPE_WAKE (u8) 0x01
674#define ACPI_GPE_TYPE_RUNTIME (u8) 0x02
675#define ACPI_GPE_TYPE_WAKE_RUN (u8) 0x03
676
669/* 677/*
670 * GPE info flags - Per GPE 678 * GPE info flags - Per GPE
671 * +-+-+-+---+-+-+-+ 679 * +-------+---+-+-+
672 * |7|6|5|4:3|2|1|0| 680 * | 7:4 |3:2|1|0|
673 * +-+-+-+---+-+-+-+ 681 * +-------+---+-+-+
674 * | | | | | | | 682 * | | | |
675 * | | | | | | +--- Interrupt type: Edge or Level Triggered 683 * | | | +--- Interrupt type: edge or level triggered
676 * | | | | | +--- GPE can wake the system 684 * | | +----- GPE can wake the system
677 * | | | | +--- Unused 685 * | +-------- Type of dispatch:to method, handler, or none
678 * | | | +--- Type of dispatch -- to method, handler, or none 686 * +-------------- <Reserved>
679 * | | +--- Unused
680 * | +--- Unused
681 * +--- Unused
682 */ 687 */
683#define ACPI_GPE_XRUPT_TYPE_MASK (u8) 0x01 688#define ACPI_GPE_XRUPT_TYPE_MASK (u8) 0x01
684#define ACPI_GPE_LEVEL_TRIGGERED (u8) 0x01 689#define ACPI_GPE_LEVEL_TRIGGERED (u8) 0x01
685#define ACPI_GPE_EDGE_TRIGGERED (u8) 0x00 690#define ACPI_GPE_EDGE_TRIGGERED (u8) 0x00
686 691
687#define ACPI_GPE_TYPE_MASK (u8) 0x06
688#define ACPI_GPE_TYPE_WAKE_RUN (u8) 0x06
689#define ACPI_GPE_TYPE_WAKE (u8) 0x02
690#define ACPI_GPE_TYPE_RUNTIME (u8) 0x04 /* Default */
691#define ACPI_GPE_CAN_WAKE (u8) 0x02 692#define ACPI_GPE_CAN_WAKE (u8) 0x02
692 693
693#define ACPI_GPE_DISPATCH_MASK (u8) 0x18 694#define ACPI_GPE_DISPATCH_MASK (u8) 0x0C
694#define ACPI_GPE_DISPATCH_HANDLER (u8) 0x08 695#define ACPI_GPE_DISPATCH_HANDLER (u8) 0x04
695#define ACPI_GPE_DISPATCH_METHOD (u8) 0x10 696#define ACPI_GPE_DISPATCH_METHOD (u8) 0x08
696#define ACPI_GPE_DISPATCH_NOT_USED (u8) 0x00 /* Default */ 697#define ACPI_GPE_DISPATCH_NOT_USED (u8) 0x00
697 698
698/* 699/*
699 * Flags for GPE and Lock interfaces 700 * Flags for GPE and Lock interfaces
700 */ 701 */
701#define ACPI_EVENT_WAKE_ENABLE 0x2 /* acpi_gpe_enable */
702#define ACPI_EVENT_WAKE_DISABLE 0x2 /* acpi_gpe_disable */
703
704#define ACPI_NOT_ISR 0x1 702#define ACPI_NOT_ISR 0x1
705#define ACPI_ISR 0x0 703#define ACPI_ISR 0x0
706 704