aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/dispatcher/dsopcode.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c
index 69fae5905bb8..5cd406676c2c 100644
--- a/drivers/acpi/dispatcher/dsopcode.c
+++ b/drivers/acpi/dispatcher/dsopcode.c
@@ -1140,10 +1140,29 @@ acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state,
1140 op->common.aml_opcode, walk_state)); 1140 op->common.aml_opcode, walk_state));
1141 1141
1142 switch (op->common.aml_opcode) { 1142 switch (op->common.aml_opcode) {
1143 case AML_IF_OP:
1144 case AML_WHILE_OP: 1143 case AML_WHILE_OP:
1145 1144
1146 /* 1145 /*
1146 * If this is an additional iteration of a while loop, continue.
1147 * There is no need to allocate a new control state.
1148 */
1149 if (walk_state->control_state) {
1150 if (walk_state->control_state->control.aml_predicate_start
1151 == (walk_state->parser_state.aml - 1)) {
1152
1153 /* Reset the state to start-of-loop */
1154
1155 walk_state->control_state->common.state =
1156 ACPI_CONTROL_CONDITIONAL_EXECUTING;
1157 break;
1158 }
1159 }
1160
1161 /*lint -fallthrough */
1162
1163 case AML_IF_OP:
1164
1165 /*
1147 * IF/WHILE: Create a new control state to manage these 1166 * IF/WHILE: Create a new control state to manage these
1148 * constructs. We need to manage these as a stack, in order 1167 * constructs. We need to manage these as a stack, in order
1149 * to handle nesting. 1168 * to handle nesting.
@@ -1248,8 +1267,13 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state,
1248 /* Predicate was true, go back and evaluate it again! */ 1267 /* Predicate was true, go back and evaluate it again! */
1249 1268
1250 status = AE_CTRL_PENDING; 1269 status = AE_CTRL_PENDING;
1270 walk_state->aml_last_while =
1271 walk_state->control_state->control.aml_predicate_start;
1272 break;
1251 } 1273 }
1252 1274
1275 /* Predicate was false, terminate this while loop */
1276
1253 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, 1277 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
1254 "[WHILE_OP] termination! Op=%p\n", op)); 1278 "[WHILE_OP] termination! Op=%p\n", op));
1255 1279
@@ -1257,9 +1281,6 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state,
1257 1281
1258 control_state = 1282 control_state =
1259 acpi_ut_pop_generic_state(&walk_state->control_state); 1283 acpi_ut_pop_generic_state(&walk_state->control_state);
1260
1261 walk_state->aml_last_while =
1262 control_state->control.aml_predicate_start;
1263 acpi_ut_delete_generic_state(control_state); 1284 acpi_ut_delete_generic_state(control_state);
1264 break; 1285 break;
1265 1286