aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica')
-rw-r--r--drivers/acpi/acpica/acconfig.h4
-rw-r--r--drivers/acpi/acpica/acevents.h4
-rw-r--r--drivers/acpi/acpica/acglobal.h8
-rw-r--r--drivers/acpi/acpica/achware.h6
-rw-r--r--drivers/acpi/acpica/evgpe.c115
-rw-r--r--drivers/acpi/acpica/evgpeblk.c14
-rw-r--r--drivers/acpi/acpica/evxface.c7
-rw-r--r--drivers/acpi/acpica/evxfevnt.c78
-rw-r--r--drivers/acpi/acpica/exsystem.c8
-rw-r--r--drivers/acpi/acpica/hwgpe.c94
-rw-r--r--drivers/acpi/acpica/hwvalid.c12
-rw-r--r--drivers/acpi/acpica/nsinit.c9
12 files changed, 193 insertions, 166 deletions
diff --git a/drivers/acpi/acpica/acconfig.h b/drivers/acpi/acpica/acconfig.h
index 33181ad350d5..b17d8de9f6ff 100644
--- a/drivers/acpi/acpica/acconfig.h
+++ b/drivers/acpi/acpica/acconfig.h
@@ -119,6 +119,10 @@
119 119
120#define ACPI_MAX_LOOP_ITERATIONS 0xFFFF 120#define ACPI_MAX_LOOP_ITERATIONS 0xFFFF
121 121
122/* Maximum sleep allowed via Sleep() operator */
123
124#define ACPI_MAX_SLEEP 20000 /* Two seconds */
125
122/****************************************************************************** 126/******************************************************************************
123 * 127 *
124 * ACPI Specification constants (Do not change unless the specification changes) 128 * ACPI Specification constants (Do not change unless the specification changes)
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h
index 64d1e5c2d4ae..c3f43daa8be3 100644
--- a/drivers/acpi/acpica/acevents.h
+++ b/drivers/acpi/acpica/acevents.h
@@ -80,10 +80,6 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list);
80acpi_status 80acpi_status
81acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info); 81acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info);
82 82
83acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info);
84
85acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info);
86
87struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, 83struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device,
88 u32 gpe_number); 84 u32 gpe_number);
89 85
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index 9070f1fe8f17..899d68afc3c5 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -125,6 +125,14 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_enable_aml_debug_object, FALSE);
125 */ 125 */
126u8 ACPI_INIT_GLOBAL(acpi_gbl_copy_dsdt_locally, FALSE); 126u8 ACPI_INIT_GLOBAL(acpi_gbl_copy_dsdt_locally, FALSE);
127 127
128/*
129 * Optionally truncate I/O addresses to 16 bits. Provides compatibility
130 * with other ACPI implementations. NOTE: During ACPICA initialization,
131 * this value is set to TRUE if any Windows OSI strings have been
132 * requested by the BIOS.
133 */
134u8 ACPI_INIT_GLOBAL(acpi_gbl_truncate_io_addresses, FALSE);
135
128/* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */ 136/* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */
129 137
130struct acpi_table_fadt acpi_gbl_FADT; 138struct acpi_table_fadt acpi_gbl_FADT;
diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h
index 5900f135dc6d..32391588e163 100644
--- a/drivers/acpi/acpica/achware.h
+++ b/drivers/acpi/acpica/achware.h
@@ -90,7 +90,11 @@ acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width);
90/* 90/*
91 * hwgpe - GPE support 91 * hwgpe - GPE support
92 */ 92 */
93acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info); 93u32 acpi_hw_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info,
94 struct acpi_gpe_register_info *gpe_register_info);
95
96acpi_status
97acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action);
94 98
95acpi_status 99acpi_status
96acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info *gpe_event_info); 100acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info *gpe_event_info);
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c
index a221ad404167..7c2c336006a1 100644
--- a/drivers/acpi/acpica/evgpe.c
+++ b/drivers/acpi/acpica/evgpe.c
@@ -69,7 +69,7 @@ acpi_status
69acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info) 69acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info)
70{ 70{
71 struct acpi_gpe_register_info *gpe_register_info; 71 struct acpi_gpe_register_info *gpe_register_info;
72 u8 register_bit; 72 u32 register_bit;
73 73
74 ACPI_FUNCTION_TRACE(ev_update_gpe_enable_masks); 74 ACPI_FUNCTION_TRACE(ev_update_gpe_enable_masks);
75 75
@@ -78,9 +78,8 @@ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info)
78 return_ACPI_STATUS(AE_NOT_EXIST); 78 return_ACPI_STATUS(AE_NOT_EXIST);
79 } 79 }
80 80
81 register_bit = (u8) 81 register_bit = acpi_hw_gpe_register_bit(gpe_event_info,
82 (1 << 82 gpe_register_info);
83 (gpe_event_info->gpe_number - gpe_register_info->base_gpe_number));
84 83
85 /* Clear the wake/run bits up front */ 84 /* Clear the wake/run bits up front */
86 85
@@ -100,106 +99,6 @@ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info)
100 return_ACPI_STATUS(AE_OK); 99 return_ACPI_STATUS(AE_OK);
101} 100}
102 101
103/*******************************************************************************
104 *
105 * FUNCTION: acpi_ev_enable_gpe
106 *
107 * PARAMETERS: gpe_event_info - GPE to enable
108 *
109 * RETURN: Status
110 *
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.
115 *
116 ******************************************************************************/
117
118acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
119{
120 acpi_status status;
121
122
123 ACPI_FUNCTION_TRACE(ev_enable_gpe);
124
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 */
137
138 status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
139 if (ACPI_FAILURE(status)) {
140 return_ACPI_STATUS(status);
141 }
142
143 /* Clear the GPE (of stale events) */
144
145 status = acpi_hw_clear_gpe(gpe_event_info);
146 if (ACPI_FAILURE(status)) {
147 return_ACPI_STATUS(status);
148 }
149
150 /* Enable the requested GPE */
151
152 status = acpi_hw_write_gpe_enable_reg(gpe_event_info);
153 return_ACPI_STATUS(status);
154}
155
156/*******************************************************************************
157 *
158 * FUNCTION: acpi_ev_disable_gpe
159 *
160 * PARAMETERS: gpe_event_info - GPE to disable
161 *
162 * RETURN: Status
163 *
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.
168 *
169 ******************************************************************************/
170
171acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info)
172{
173 acpi_status status;
174
175 ACPI_FUNCTION_TRACE(ev_disable_gpe);
176
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 */
185
186 status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
187 if (ACPI_FAILURE(status)) {
188 return_ACPI_STATUS(status);
189 }
190
191 /*
192 * Always H/W disable this GPE, even if we don't know the GPE type.
193 * Simply clear the enable bit for this particular GPE, but do not
194 * write out the current GPE enable mask since this may inadvertently
195 * enable GPEs too early. An example is a rogue GPE that has arrived
196 * during ACPICA initialization - possibly because AML or other code
197 * has enabled the GPE.
198 */
199 status = acpi_hw_low_disable_gpe(gpe_event_info);
200 return_ACPI_STATUS(status);
201}
202
203 102
204/******************************************************************************* 103/*******************************************************************************
205 * 104 *
@@ -451,10 +350,6 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
451 return_VOID; 350 return_VOID;
452 } 351 }
453 352
454 /* Update the GPE register masks for return to enabled state */
455
456 (void)acpi_ev_update_gpe_enable_masks(gpe_event_info);
457
458 /* 353 /*
459 * Take a snapshot of the GPE info for this level - we copy the info to 354 * Take a snapshot of the GPE info for this level - we copy the info to
460 * prevent a race condition with remove_handler/remove_block. 355 * prevent a race condition with remove_handler/remove_block.
@@ -607,7 +502,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
607 * Disable the GPE, so it doesn't keep firing before the method has a 502 * Disable the GPE, so it doesn't keep firing before the method has a
608 * chance to run (it runs asynchronously with interrupts enabled). 503 * chance to run (it runs asynchronously with interrupts enabled).
609 */ 504 */
610 status = acpi_ev_disable_gpe(gpe_event_info); 505 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
611 if (ACPI_FAILURE(status)) { 506 if (ACPI_FAILURE(status)) {
612 ACPI_EXCEPTION((AE_INFO, status, 507 ACPI_EXCEPTION((AE_INFO, status,
613 "Unable to disable GPE[0x%2X]", 508 "Unable to disable GPE[0x%2X]",
@@ -644,7 +539,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
644 * Disable the GPE. The GPE will remain disabled a handler 539 * Disable the GPE. The GPE will remain disabled a handler
645 * is installed or ACPICA is restarted. 540 * is installed or ACPICA is restarted.
646 */ 541 */
647 status = acpi_ev_disable_gpe(gpe_event_info); 542 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
648 if (ACPI_FAILURE(status)) { 543 if (ACPI_FAILURE(status)) {
649 ACPI_EXCEPTION((AE_INFO, status, 544 ACPI_EXCEPTION((AE_INFO, status,
650 "Unable to disable GPE[0x%2X]", 545 "Unable to disable GPE[0x%2X]",
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c
index 7c28f2d9fd35..341a38ce8aa6 100644
--- a/drivers/acpi/acpica/evgpeblk.c
+++ b/drivers/acpi/acpica/evgpeblk.c
@@ -500,6 +500,19 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
500 500
501 gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j; 501 gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j;
502 gpe_event_info = &gpe_block->event_info[gpe_index]; 502 gpe_event_info = &gpe_block->event_info[gpe_index];
503 gpe_number = gpe_index + gpe_block->block_base_number;
504
505 /*
506 * If the GPE has already been enabled for runtime
507 * signaling, make sure it remains enabled, but do not
508 * increment its reference counter.
509 */
510 if (gpe_event_info->runtime_count) {
511 acpi_set_gpe(gpe_device, gpe_number,
512 ACPI_GPE_ENABLE);
513 gpe_enabled_count++;
514 continue;
515 }
503 516
504 if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) { 517 if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) {
505 wake_gpe_count++; 518 wake_gpe_count++;
@@ -516,7 +529,6 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
516 529
517 /* Enable this GPE */ 530 /* Enable this GPE */
518 531
519 gpe_number = gpe_index + gpe_block->block_base_number;
520 status = acpi_enable_gpe(gpe_device, gpe_number, 532 status = acpi_enable_gpe(gpe_device, gpe_number,
521 ACPI_GPE_TYPE_RUNTIME); 533 ACPI_GPE_TYPE_RUNTIME);
522 if (ACPI_FAILURE(status)) { 534 if (ACPI_FAILURE(status)) {
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c
index cc825023012a..4a531cdf7942 100644
--- a/drivers/acpi/acpica/evxface.c
+++ b/drivers/acpi/acpica/evxface.c
@@ -719,13 +719,6 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
719 handler->context = context; 719 handler->context = context;
720 handler->method_node = gpe_event_info->dispatch.method_node; 720 handler->method_node = gpe_event_info->dispatch.method_node;
721 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
729 /* Install the handler */ 722 /* Install the handler */
730 723
731 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 724 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c
index d5a5efc043bf..18b3f1468b7d 100644
--- a/drivers/acpi/acpica/evxfevnt.c
+++ b/drivers/acpi/acpica/evxfevnt.c
@@ -70,6 +70,7 @@ acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
70acpi_status acpi_enable(void) 70acpi_status acpi_enable(void)
71{ 71{
72 acpi_status status; 72 acpi_status status;
73 int retry;
73 74
74 ACPI_FUNCTION_TRACE(acpi_enable); 75 ACPI_FUNCTION_TRACE(acpi_enable);
75 76
@@ -98,16 +99,18 @@ acpi_status acpi_enable(void)
98 99
99 /* Sanity check that transition succeeded */ 100 /* Sanity check that transition succeeded */
100 101
101 if (acpi_hw_get_mode() != ACPI_SYS_MODE_ACPI) { 102 for (retry = 0; retry < 30000; ++retry) {
102 ACPI_ERROR((AE_INFO, 103 if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
103 "Hardware did not enter ACPI mode")); 104 if (retry != 0)
104 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); 105 ACPI_WARNING((AE_INFO,
106 "Platform took > %d00 usec to enter ACPI mode", retry));
107 return_ACPI_STATUS(AE_OK);
108 }
109 acpi_os_stall(100); /* 100 usec */
105 } 110 }
106 111
107 ACPI_DEBUG_PRINT((ACPI_DB_INIT, 112 ACPI_ERROR((AE_INFO, "Hardware did not enter ACPI mode"));
108 "Transition to ACPI mode successful\n")); 113 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
109
110 return_ACPI_STATUS(AE_OK);
111} 114}
112 115
113ACPI_EXPORT_SYMBOL(acpi_enable) 116ACPI_EXPORT_SYMBOL(acpi_enable)
@@ -210,6 +213,44 @@ ACPI_EXPORT_SYMBOL(acpi_enable_event)
210 213
211/******************************************************************************* 214/*******************************************************************************
212 * 215 *
216 * FUNCTION: acpi_clear_and_enable_gpe
217 *
218 * PARAMETERS: gpe_event_info - GPE to enable
219 *
220 * RETURN: Status
221 *
222 * DESCRIPTION: Clear the given GPE from stale events and enable it.
223 *
224 ******************************************************************************/
225static acpi_status
226acpi_clear_and_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
227{
228 acpi_status status;
229
230 /*
231 * We will only allow a GPE to be enabled if it has either an
232 * associated method (_Lxx/_Exx) or a handler. Otherwise, the
233 * GPE will be immediately disabled by acpi_ev_gpe_dispatch the
234 * first time it fires.
235 */
236 if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)) {
237 return_ACPI_STATUS(AE_NO_HANDLER);
238 }
239
240 /* Clear the GPE (of stale events) */
241 status = acpi_hw_clear_gpe(gpe_event_info);
242 if (ACPI_FAILURE(status)) {
243 return_ACPI_STATUS(status);
244 }
245
246 /* Enable the requested GPE */
247 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE);
248
249 return_ACPI_STATUS(status);
250}
251
252/*******************************************************************************
253 *
213 * FUNCTION: acpi_set_gpe 254 * FUNCTION: acpi_set_gpe
214 * 255 *
215 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 256 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
@@ -249,11 +290,11 @@ acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action)
249 290
250 switch (action) { 291 switch (action) {
251 case ACPI_GPE_ENABLE: 292 case ACPI_GPE_ENABLE:
252 status = acpi_ev_enable_gpe(gpe_event_info); 293 status = acpi_clear_and_enable_gpe(gpe_event_info);
253 break; 294 break;
254 295
255 case ACPI_GPE_DISABLE: 296 case ACPI_GPE_DISABLE:
256 status = acpi_ev_disable_gpe(gpe_event_info); 297 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
257 break; 298 break;
258 299
259 default: 300 default:
@@ -316,7 +357,11 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type)
316 357
317 gpe_event_info->runtime_count++; 358 gpe_event_info->runtime_count++;
318 if (gpe_event_info->runtime_count == 1) { 359 if (gpe_event_info->runtime_count == 1) {
319 status = acpi_ev_enable_gpe(gpe_event_info); 360 status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
361 if (ACPI_SUCCESS(status)) {
362 status = acpi_clear_and_enable_gpe(gpe_event_info);
363 }
364
320 if (ACPI_FAILURE(status)) { 365 if (ACPI_FAILURE(status)) {
321 gpe_event_info->runtime_count--; 366 gpe_event_info->runtime_count--;
322 goto unlock_and_exit; 367 goto unlock_and_exit;
@@ -343,7 +388,7 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type)
343 */ 388 */
344 gpe_event_info->wakeup_count++; 389 gpe_event_info->wakeup_count++;
345 if (gpe_event_info->wakeup_count == 1) { 390 if (gpe_event_info->wakeup_count == 1) {
346 (void)acpi_ev_update_gpe_enable_masks(gpe_event_info); 391 status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
347 } 392 }
348 } 393 }
349 394
@@ -403,7 +448,12 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type
403 448
404 gpe_event_info->runtime_count--; 449 gpe_event_info->runtime_count--;
405 if (!gpe_event_info->runtime_count) { 450 if (!gpe_event_info->runtime_count) {
406 status = acpi_ev_disable_gpe(gpe_event_info); 451 status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
452 if (ACPI_SUCCESS(status)) {
453 status = acpi_hw_low_set_gpe(gpe_event_info,
454 ACPI_GPE_DISABLE);
455 }
456
407 if (ACPI_FAILURE(status)) { 457 if (ACPI_FAILURE(status)) {
408 gpe_event_info->runtime_count++; 458 gpe_event_info->runtime_count++;
409 goto unlock_and_exit; 459 goto unlock_and_exit;
@@ -424,7 +474,7 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type
424 474
425 gpe_event_info->wakeup_count--; 475 gpe_event_info->wakeup_count--;
426 if (!gpe_event_info->wakeup_count) { 476 if (!gpe_event_info->wakeup_count) {
427 (void)acpi_ev_update_gpe_enable_masks(gpe_event_info); 477 status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
428 } 478 }
429 } 479 }
430 480
diff --git a/drivers/acpi/acpica/exsystem.c b/drivers/acpi/acpica/exsystem.c
index 6d32e09327f1..675aaa91a770 100644
--- a/drivers/acpi/acpica/exsystem.c
+++ b/drivers/acpi/acpica/exsystem.c
@@ -201,6 +201,14 @@ acpi_status acpi_ex_system_do_sleep(u64 how_long)
201 201
202 acpi_ex_relinquish_interpreter(); 202 acpi_ex_relinquish_interpreter();
203 203
204 /*
205 * For compatibility with other ACPI implementations and to prevent
206 * accidental deep sleeps, limit the sleep time to something reasonable.
207 */
208 if (how_long > ACPI_MAX_SLEEP) {
209 how_long = ACPI_MAX_SLEEP;
210 }
211
204 acpi_os_sleep(how_long); 212 acpi_os_sleep(how_long);
205 213
206 /* And now we must get the interpreter again */ 214 /* And now we must get the interpreter again */
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c
index bd72319a38f0..3450309c2786 100644
--- a/drivers/acpi/acpica/hwgpe.c
+++ b/drivers/acpi/acpica/hwgpe.c
@@ -57,21 +57,47 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
57 57
58/****************************************************************************** 58/******************************************************************************
59 * 59 *
60 * FUNCTION: acpi_hw_low_disable_gpe 60 * FUNCTION: acpi_hw_gpe_register_bit
61 *
62 * PARAMETERS: gpe_event_info - Info block for the GPE
63 * gpe_register_info - Info block for the GPE register
64 *
65 * RETURN: Status
66 *
67 * DESCRIPTION: Compute GPE enable mask with one bit corresponding to the given
68 * GPE set.
69 *
70 ******************************************************************************/
71
72u32 acpi_hw_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info,
73 struct acpi_gpe_register_info *gpe_register_info)
74{
75 return (u32)1 << (gpe_event_info->gpe_number -
76 gpe_register_info->base_gpe_number);
77}
78
79/******************************************************************************
80 *
81 * FUNCTION: acpi_hw_low_set_gpe
61 * 82 *
62 * PARAMETERS: gpe_event_info - Info block for the GPE to be disabled 83 * PARAMETERS: gpe_event_info - Info block for the GPE to be disabled
84 * action - Enable or disable
63 * 85 *
64 * RETURN: Status 86 * RETURN: Status
65 * 87 *
66 * DESCRIPTION: Disable a single GPE in the enable register. 88 * DESCRIPTION: Enable or disable a single GPE in its enable register.
67 * 89 *
68 ******************************************************************************/ 90 ******************************************************************************/
69 91
70acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) 92acpi_status
93acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action)
71{ 94{
72 struct acpi_gpe_register_info *gpe_register_info; 95 struct acpi_gpe_register_info *gpe_register_info;
73 acpi_status status; 96 acpi_status status;
74 u32 enable_mask; 97 u32 enable_mask;
98 u32 register_bit;
99
100 ACPI_FUNCTION_ENTRY();
75 101
76 /* Get the info block for the entire GPE register */ 102 /* Get the info block for the entire GPE register */
77 103
@@ -87,11 +113,27 @@ acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info)
87 return (status); 113 return (status);
88 } 114 }
89 115
90 /* Clear just the bit that corresponds to this GPE */ 116 /* Set ot clear just the bit that corresponds to this GPE */
91 117
92 ACPI_CLEAR_BIT(enable_mask, ((u32)1 << 118 register_bit = acpi_hw_gpe_register_bit(gpe_event_info,
93 (gpe_event_info->gpe_number - 119 gpe_register_info);
94 gpe_register_info->base_gpe_number))); 120 switch (action) {
121 case ACPI_GPE_COND_ENABLE:
122 if (!(register_bit & gpe_register_info->enable_for_run))
123 return (AE_BAD_PARAMETER);
124
125 case ACPI_GPE_ENABLE:
126 ACPI_SET_BIT(enable_mask, register_bit);
127 break;
128
129 case ACPI_GPE_DISABLE:
130 ACPI_CLEAR_BIT(enable_mask, register_bit);
131 break;
132
133 default:
134 ACPI_ERROR((AE_INFO, "Invalid action\n"));
135 return (AE_BAD_PARAMETER);
136 }
95 137
96 /* Write the updated enable mask */ 138 /* Write the updated enable mask */
97 139
@@ -116,23 +158,11 @@ acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info)
116acpi_status 158acpi_status
117acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info * gpe_event_info) 159acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info * gpe_event_info)
118{ 160{
119 struct acpi_gpe_register_info *gpe_register_info;
120 acpi_status status; 161 acpi_status status;
121 162
122 ACPI_FUNCTION_ENTRY(); 163 ACPI_FUNCTION_ENTRY();
123 164
124 /* Get the info block for the entire GPE register */ 165 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_COND_ENABLE);
125
126 gpe_register_info = gpe_event_info->register_info;
127 if (!gpe_register_info) {
128 return (AE_NOT_EXIST);
129 }
130
131 /* Write the entire GPE (runtime) enable register */
132
133 status = acpi_hw_write(gpe_register_info->enable_for_run,
134 &gpe_register_info->enable_address);
135
136 return (status); 166 return (status);
137} 167}
138 168
@@ -150,21 +180,28 @@ acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info * gpe_event_info)
150 180
151acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info) 181acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info)
152{ 182{
183 struct acpi_gpe_register_info *gpe_register_info;
153 acpi_status status; 184 acpi_status status;
154 u8 register_bit; 185 u32 register_bit;
155 186
156 ACPI_FUNCTION_ENTRY(); 187 ACPI_FUNCTION_ENTRY();
157 188
158 register_bit = (u8)(1 << 189 /* Get the info block for the entire GPE register */
159 (gpe_event_info->gpe_number - 190
160 gpe_event_info->register_info->base_gpe_number)); 191 gpe_register_info = gpe_event_info->register_info;
192 if (!gpe_register_info) {
193 return (AE_NOT_EXIST);
194 }
195
196 register_bit = acpi_hw_gpe_register_bit(gpe_event_info,
197 gpe_register_info);
161 198
162 /* 199 /*
163 * Write a one to the appropriate bit in the status register to 200 * Write a one to the appropriate bit in the status register to
164 * clear this GPE. 201 * clear this GPE.
165 */ 202 */
166 status = acpi_hw_write(register_bit, 203 status = acpi_hw_write(register_bit,
167 &gpe_event_info->register_info->status_address); 204 &gpe_register_info->status_address);
168 205
169 return (status); 206 return (status);
170} 207}
@@ -187,7 +224,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info,
187 acpi_event_status * event_status) 224 acpi_event_status * event_status)
188{ 225{
189 u32 in_byte; 226 u32 in_byte;
190 u8 register_bit; 227 u32 register_bit;
191 struct acpi_gpe_register_info *gpe_register_info; 228 struct acpi_gpe_register_info *gpe_register_info;
192 acpi_status status; 229 acpi_status status;
193 acpi_event_status local_event_status = 0; 230 acpi_event_status local_event_status = 0;
@@ -204,9 +241,8 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info,
204 241
205 /* Get the register bitmask for this GPE */ 242 /* Get the register bitmask for this GPE */
206 243
207 register_bit = (u8)(1 << 244 register_bit = acpi_hw_gpe_register_bit(gpe_event_info,
208 (gpe_event_info->gpe_number - 245 gpe_register_info);
209 gpe_event_info->register_info->base_gpe_number));
210 246
211 /* GPE currently enabled? (enabled for runtime?) */ 247 /* GPE currently enabled? (enabled for runtime?) */
212 248
diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c
index c10d587c1641..e1d9c777b213 100644
--- a/drivers/acpi/acpica/hwvalid.c
+++ b/drivers/acpi/acpica/hwvalid.c
@@ -222,6 +222,12 @@ acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width)
222 u32 one_byte; 222 u32 one_byte;
223 u32 i; 223 u32 i;
224 224
225 /* Truncate address to 16 bits if requested */
226
227 if (acpi_gbl_truncate_io_addresses) {
228 address &= ACPI_UINT16_MAX;
229 }
230
225 /* Validate the entire request and perform the I/O */ 231 /* Validate the entire request and perform the I/O */
226 232
227 status = acpi_hw_validate_io_request(address, width); 233 status = acpi_hw_validate_io_request(address, width);
@@ -279,6 +285,12 @@ acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width)
279 acpi_status status; 285 acpi_status status;
280 u32 i; 286 u32 i;
281 287
288 /* Truncate address to 16 bits if requested */
289
290 if (acpi_gbl_truncate_io_addresses) {
291 address &= ACPI_UINT16_MAX;
292 }
293
282 /* Validate the entire request and perform the I/O */ 294 /* Validate the entire request and perform the I/O */
283 295
284 status = acpi_hw_validate_io_request(address, width); 296 status = acpi_hw_validate_io_request(address, width);
diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c
index 9bd6f050f299..4e5272c313e0 100644
--- a/drivers/acpi/acpica/nsinit.c
+++ b/drivers/acpi/acpica/nsinit.c
@@ -193,6 +193,15 @@ acpi_status acpi_ns_initialize_devices(void)
193 acpi_ns_init_one_device, NULL, &info, 193 acpi_ns_init_one_device, NULL, &info,
194 NULL); 194 NULL);
195 195
196 /*
197 * Any _OSI requests should be completed by now. If the BIOS has
198 * requested any Windows OSI strings, we will always truncate
199 * I/O addresses to 16 bits -- for Windows compatibility.
200 */
201 if (acpi_gbl_osi_data >= ACPI_OSI_WIN_2000) {
202 acpi_gbl_truncate_io_addresses = TRUE;
203 }
204
196 ACPI_FREE(info.evaluate_info); 205 ACPI_FREE(info.evaluate_info);
197 if (ACPI_FAILURE(status)) { 206 if (ACPI_FAILURE(status)) {
198 goto error_exit; 207 goto error_exit;