diff options
Diffstat (limited to 'drivers/acpi/acpica/evregion.c')
-rw-r--r-- | drivers/acpi/acpica/evregion.c | 81 |
1 files changed, 66 insertions, 15 deletions
diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index 98c7f9c62653..0bc807c33a56 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c | |||
@@ -51,6 +51,10 @@ | |||
51 | ACPI_MODULE_NAME("evregion") | 51 | ACPI_MODULE_NAME("evregion") |
52 | 52 | ||
53 | /* Local prototypes */ | 53 | /* Local prototypes */ |
54 | static u8 | ||
55 | acpi_ev_has_default_handler(struct acpi_namespace_node *node, | ||
56 | acpi_adr_space_type space_id); | ||
57 | |||
54 | static acpi_status | 58 | static acpi_status |
55 | acpi_ev_reg_run(acpi_handle obj_handle, | 59 | acpi_ev_reg_run(acpi_handle obj_handle, |
56 | u32 level, void *context, void **return_value); | 60 | u32 level, void *context, void **return_value); |
@@ -142,6 +146,50 @@ acpi_status acpi_ev_install_region_handlers(void) | |||
142 | 146 | ||
143 | /******************************************************************************* | 147 | /******************************************************************************* |
144 | * | 148 | * |
149 | * FUNCTION: acpi_ev_has_default_handler | ||
150 | * | ||
151 | * PARAMETERS: Node - Namespace node for the device | ||
152 | * space_id - The address space ID | ||
153 | * | ||
154 | * RETURN: TRUE if default handler is installed, FALSE otherwise | ||
155 | * | ||
156 | * DESCRIPTION: Check if the default handler is installed for the requested | ||
157 | * space ID. | ||
158 | * | ||
159 | ******************************************************************************/ | ||
160 | |||
161 | static u8 | ||
162 | acpi_ev_has_default_handler(struct acpi_namespace_node *node, | ||
163 | acpi_adr_space_type space_id) | ||
164 | { | ||
165 | union acpi_operand_object *obj_desc; | ||
166 | union acpi_operand_object *handler_obj; | ||
167 | |||
168 | /* Must have an existing internal object */ | ||
169 | |||
170 | obj_desc = acpi_ns_get_attached_object(node); | ||
171 | if (obj_desc) { | ||
172 | handler_obj = obj_desc->device.handler; | ||
173 | |||
174 | /* Walk the linked list of handlers for this object */ | ||
175 | |||
176 | while (handler_obj) { | ||
177 | if (handler_obj->address_space.space_id == space_id) { | ||
178 | if (handler_obj->address_space.handler_flags & | ||
179 | ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) { | ||
180 | return (TRUE); | ||
181 | } | ||
182 | } | ||
183 | |||
184 | handler_obj = handler_obj->address_space.next; | ||
185 | } | ||
186 | } | ||
187 | |||
188 | return (FALSE); | ||
189 | } | ||
190 | |||
191 | /******************************************************************************* | ||
192 | * | ||
145 | * FUNCTION: acpi_ev_initialize_op_regions | 193 | * FUNCTION: acpi_ev_initialize_op_regions |
146 | * | 194 | * |
147 | * PARAMETERS: None | 195 | * PARAMETERS: None |
@@ -169,12 +217,18 @@ acpi_status acpi_ev_initialize_op_regions(void) | |||
169 | 217 | ||
170 | for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) { | 218 | for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) { |
171 | /* | 219 | /* |
172 | * TBD: Make sure handler is the DEFAULT handler, otherwise | 220 | * Make sure the installed handler is the DEFAULT handler. If not the |
173 | * _REG will have already been run. | 221 | * default, the _REG methods will have already been run (when the |
222 | * handler was installed) | ||
174 | */ | 223 | */ |
175 | status = acpi_ev_execute_reg_methods(acpi_gbl_root_node, | 224 | if (acpi_ev_has_default_handler(acpi_gbl_root_node, |
176 | acpi_gbl_default_address_spaces | 225 | acpi_gbl_default_address_spaces |
177 | [i]); | 226 | [i])) { |
227 | status = | ||
228 | acpi_ev_execute_reg_methods(acpi_gbl_root_node, | ||
229 | acpi_gbl_default_address_spaces | ||
230 | [i]); | ||
231 | } | ||
178 | } | 232 | } |
179 | 233 | ||
180 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 234 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
@@ -235,23 +289,20 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) | |||
235 | * connection status 1 for connecting the handler, 0 for disconnecting | 289 | * connection status 1 for connecting the handler, 0 for disconnecting |
236 | * the handler (Passed as a parameter) | 290 | * the handler (Passed as a parameter) |
237 | */ | 291 | */ |
238 | args[0] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); | 292 | args[0] = |
293 | acpi_ut_create_integer_object((u64) region_obj->region.space_id); | ||
239 | if (!args[0]) { | 294 | if (!args[0]) { |
240 | status = AE_NO_MEMORY; | 295 | status = AE_NO_MEMORY; |
241 | goto cleanup1; | 296 | goto cleanup1; |
242 | } | 297 | } |
243 | 298 | ||
244 | args[1] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); | 299 | args[1] = acpi_ut_create_integer_object((u64) function); |
245 | if (!args[1]) { | 300 | if (!args[1]) { |
246 | status = AE_NO_MEMORY; | 301 | status = AE_NO_MEMORY; |
247 | goto cleanup2; | 302 | goto cleanup2; |
248 | } | 303 | } |
249 | 304 | ||
250 | /* Setup the parameter objects */ | 305 | args[2] = NULL; /* Terminate list */ |
251 | |||
252 | args[0]->integer.value = region_obj->region.space_id; | ||
253 | args[1]->integer.value = function; | ||
254 | args[2] = NULL; | ||
255 | 306 | ||
256 | /* Execute the method, no return value */ | 307 | /* Execute the method, no return value */ |
257 | 308 | ||
@@ -971,8 +1022,8 @@ acpi_ev_install_space_handler(struct acpi_namespace_node * node, | |||
971 | */ | 1022 | */ |
972 | status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX, | 1023 | status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX, |
973 | ACPI_NS_WALK_UNLOCK, | 1024 | ACPI_NS_WALK_UNLOCK, |
974 | acpi_ev_install_handler, handler_obj, | 1025 | acpi_ev_install_handler, NULL, |
975 | NULL); | 1026 | handler_obj, NULL); |
976 | 1027 | ||
977 | unlock_and_exit: | 1028 | unlock_and_exit: |
978 | return_ACPI_STATUS(status); | 1029 | return_ACPI_STATUS(status); |
@@ -1008,7 +1059,7 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node, | |||
1008 | */ | 1059 | */ |
1009 | status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX, | 1060 | status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX, |
1010 | ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run, | 1061 | ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run, |
1011 | &space_id, NULL); | 1062 | NULL, &space_id, NULL); |
1012 | 1063 | ||
1013 | return_ACPI_STATUS(status); | 1064 | return_ACPI_STATUS(status); |
1014 | } | 1065 | } |