aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/evregion.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica/evregion.c')
-rw-r--r--drivers/acpi/acpica/evregion.c81
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 @@
51ACPI_MODULE_NAME("evregion") 51ACPI_MODULE_NAME("evregion")
52 52
53/* Local prototypes */ 53/* Local prototypes */
54static u8
55acpi_ev_has_default_handler(struct acpi_namespace_node *node,
56 acpi_adr_space_type space_id);
57
54static acpi_status 58static acpi_status
55acpi_ev_reg_run(acpi_handle obj_handle, 59acpi_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
161static u8
162acpi_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}