diff options
Diffstat (limited to 'drivers/acpi/wmi.c')
-rw-r--r-- | drivers/acpi/wmi.c | 49 |
1 files changed, 42 insertions, 7 deletions
diff --git a/drivers/acpi/wmi.c b/drivers/acpi/wmi.c index cfe2c833474d..47cd7baf9b1b 100644 --- a/drivers/acpi/wmi.c +++ b/drivers/acpi/wmi.c | |||
@@ -217,6 +217,35 @@ static bool find_guid(const char *guid_string, struct wmi_block **out) | |||
217 | return 0; | 217 | return 0; |
218 | } | 218 | } |
219 | 219 | ||
220 | static acpi_status wmi_method_enable(struct wmi_block *wblock, int enable) | ||
221 | { | ||
222 | struct guid_block *block = NULL; | ||
223 | char method[5]; | ||
224 | struct acpi_object_list input; | ||
225 | union acpi_object params[1]; | ||
226 | acpi_status status; | ||
227 | acpi_handle handle; | ||
228 | |||
229 | block = &wblock->gblock; | ||
230 | handle = wblock->handle; | ||
231 | |||
232 | if (!block) | ||
233 | return AE_NOT_EXIST; | ||
234 | |||
235 | input.count = 1; | ||
236 | input.pointer = params; | ||
237 | params[0].type = ACPI_TYPE_INTEGER; | ||
238 | params[0].integer.value = enable; | ||
239 | |||
240 | snprintf(method, 5, "WE%02X", block->notify_id); | ||
241 | status = acpi_evaluate_object(handle, method, &input, NULL); | ||
242 | |||
243 | if (status != AE_OK && status != AE_NOT_FOUND) | ||
244 | return status; | ||
245 | else | ||
246 | return AE_OK; | ||
247 | } | ||
248 | |||
220 | /* | 249 | /* |
221 | * Exported WMI functions | 250 | * Exported WMI functions |
222 | */ | 251 | */ |
@@ -242,7 +271,7 @@ u32 method_id, const struct acpi_buffer *in, struct acpi_buffer *out) | |||
242 | char method[4] = "WM"; | 271 | char method[4] = "WM"; |
243 | 272 | ||
244 | if (!find_guid(guid_string, &wblock)) | 273 | if (!find_guid(guid_string, &wblock)) |
245 | return AE_BAD_ADDRESS; | 274 | return AE_ERROR; |
246 | 275 | ||
247 | block = &wblock->gblock; | 276 | block = &wblock->gblock; |
248 | handle = wblock->handle; | 277 | handle = wblock->handle; |
@@ -304,7 +333,7 @@ struct acpi_buffer *out) | |||
304 | return AE_BAD_PARAMETER; | 333 | return AE_BAD_PARAMETER; |
305 | 334 | ||
306 | if (!find_guid(guid_string, &wblock)) | 335 | if (!find_guid(guid_string, &wblock)) |
307 | return AE_BAD_ADDRESS; | 336 | return AE_ERROR; |
308 | 337 | ||
309 | block = &wblock->gblock; | 338 | block = &wblock->gblock; |
310 | handle = wblock->handle; | 339 | handle = wblock->handle; |
@@ -314,7 +343,7 @@ struct acpi_buffer *out) | |||
314 | 343 | ||
315 | /* Check GUID is a data block */ | 344 | /* Check GUID is a data block */ |
316 | if (block->flags & (ACPI_WMI_EVENT | ACPI_WMI_METHOD)) | 345 | if (block->flags & (ACPI_WMI_EVENT | ACPI_WMI_METHOD)) |
317 | return AE_BAD_ADDRESS; | 346 | return AE_ERROR; |
318 | 347 | ||
319 | input.count = 1; | 348 | input.count = 1; |
320 | input.pointer = wq_params; | 349 | input.pointer = wq_params; |
@@ -385,7 +414,7 @@ const struct acpi_buffer *in) | |||
385 | return AE_BAD_DATA; | 414 | return AE_BAD_DATA; |
386 | 415 | ||
387 | if (!find_guid(guid_string, &wblock)) | 416 | if (!find_guid(guid_string, &wblock)) |
388 | return AE_BAD_ADDRESS; | 417 | return AE_ERROR; |
389 | 418 | ||
390 | block = &wblock->gblock; | 419 | block = &wblock->gblock; |
391 | handle = wblock->handle; | 420 | handle = wblock->handle; |
@@ -395,7 +424,7 @@ const struct acpi_buffer *in) | |||
395 | 424 | ||
396 | /* Check GUID is a data block */ | 425 | /* Check GUID is a data block */ |
397 | if (block->flags & (ACPI_WMI_EVENT | ACPI_WMI_METHOD)) | 426 | if (block->flags & (ACPI_WMI_EVENT | ACPI_WMI_METHOD)) |
398 | return AE_BAD_ADDRESS; | 427 | return AE_ERROR; |
399 | 428 | ||
400 | input.count = 2; | 429 | input.count = 2; |
401 | input.pointer = params; | 430 | input.pointer = params; |
@@ -427,6 +456,7 @@ acpi_status wmi_install_notify_handler(const char *guid, | |||
427 | wmi_notify_handler handler, void *data) | 456 | wmi_notify_handler handler, void *data) |
428 | { | 457 | { |
429 | struct wmi_block *block; | 458 | struct wmi_block *block; |
459 | acpi_status status; | ||
430 | 460 | ||
431 | if (!guid || !handler) | 461 | if (!guid || !handler) |
432 | return AE_BAD_PARAMETER; | 462 | return AE_BAD_PARAMETER; |
@@ -441,7 +471,9 @@ wmi_notify_handler handler, void *data) | |||
441 | block->handler = handler; | 471 | block->handler = handler; |
442 | block->handler_data = data; | 472 | block->handler_data = data; |
443 | 473 | ||
444 | return AE_OK; | 474 | status = wmi_method_enable(block, 1); |
475 | |||
476 | return status; | ||
445 | } | 477 | } |
446 | EXPORT_SYMBOL_GPL(wmi_install_notify_handler); | 478 | EXPORT_SYMBOL_GPL(wmi_install_notify_handler); |
447 | 479 | ||
@@ -453,6 +485,7 @@ EXPORT_SYMBOL_GPL(wmi_install_notify_handler); | |||
453 | acpi_status wmi_remove_notify_handler(const char *guid) | 485 | acpi_status wmi_remove_notify_handler(const char *guid) |
454 | { | 486 | { |
455 | struct wmi_block *block; | 487 | struct wmi_block *block; |
488 | acpi_status status; | ||
456 | 489 | ||
457 | if (!guid) | 490 | if (!guid) |
458 | return AE_BAD_PARAMETER; | 491 | return AE_BAD_PARAMETER; |
@@ -464,10 +497,12 @@ acpi_status wmi_remove_notify_handler(const char *guid) | |||
464 | if (!block->handler) | 497 | if (!block->handler) |
465 | return AE_NULL_ENTRY; | 498 | return AE_NULL_ENTRY; |
466 | 499 | ||
500 | status = wmi_method_enable(block, 0); | ||
501 | |||
467 | block->handler = NULL; | 502 | block->handler = NULL; |
468 | block->handler_data = NULL; | 503 | block->handler_data = NULL; |
469 | 504 | ||
470 | return AE_OK; | 505 | return status; |
471 | } | 506 | } |
472 | EXPORT_SYMBOL_GPL(wmi_remove_notify_handler); | 507 | EXPORT_SYMBOL_GPL(wmi_remove_notify_handler); |
473 | 508 | ||