diff options
Diffstat (limited to 'drivers/acpi/acpica')
-rw-r--r-- | drivers/acpi/acpica/acevents.h | 7 | ||||
-rw-r--r-- | drivers/acpi/acpica/aclocal.h | 5 | ||||
-rw-r--r-- | drivers/acpi/acpica/evgpe.c | 153 | ||||
-rw-r--r-- | drivers/acpi/acpica/evgpeblk.c | 143 | ||||
-rw-r--r-- | drivers/acpi/acpica/evxface.c | 20 | ||||
-rw-r--r-- | drivers/acpi/acpica/evxfevnt.c | 191 | ||||
-rw-r--r-- | drivers/acpi/acpica/exoparg2.c | 27 |
7 files changed, 316 insertions, 230 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); | |||
85 | struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, | 85 | struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, |
86 | u32 gpe_number); | 86 | u32 gpe_number); |
87 | 87 | ||
88 | struct 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 | ||
119 | u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list); | 123 | u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list); |
120 | 124 | ||
121 | acpi_status | ||
122 | acpi_ev_check_for_wake_only_gpe(struct acpi_gpe_event_info *gpe_event_info); | ||
123 | |||
124 | acpi_status acpi_ev_gpe_initialize(void); | 125 | acpi_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 | |||
219 | struct 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 */ |
53 | static acpi_status | 53 | static acpi_status |
54 | acpi_ev_save_method_info(acpi_handle obj_handle, | 54 | acpi_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 | ||
57 | static acpi_status | 57 | static 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 | ||
252 | static acpi_status | 249 | static acpi_status |
253 | acpi_ev_save_method_info(acpi_handle obj_handle, | 250 | acpi_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 | |||
969 | acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, | 963 | acpi_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: | 742 | unlock_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 | ******************************************************************************/ |
216 | acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action) | 221 | acpi_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 | ******************************************************************************/ |
271 | acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type) | 278 | acpi_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 | ||
314 | unlock_and_exit: | 341 | unlock_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 | ******************************************************************************/ |
333 | acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type) | 363 | acpi_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 | ||
367 | unlock_and_exit: | 422 | unlock_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 | ******************************************************************************/ |
477 | acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) | 531 | acpi_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 | ******************************************************************************/ |
583 | acpi_status | 628 | acpi_status |
584 | acpi_get_gpe_status(acpi_handle gpe_device, | 629 | acpi_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 |