diff options
Diffstat (limited to 'drivers/xen/xen-acpi-processor.c')
-rw-r--r-- | drivers/xen/xen-acpi-processor.c | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c index 4ce10bcca18b..23e391d3ec01 100644 --- a/drivers/xen/xen-acpi-processor.c +++ b/drivers/xen/xen-acpi-processor.c | |||
@@ -27,10 +27,10 @@ | |||
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/types.h> | 29 | #include <linux/types.h> |
30 | #include <linux/syscore_ops.h> | ||
30 | #include <linux/acpi.h> | 31 | #include <linux/acpi.h> |
31 | #include <acpi/processor.h> | 32 | #include <acpi/processor.h> |
32 | #include <xen/xen.h> | 33 | #include <xen/xen.h> |
33 | #include <xen/xen-ops.h> | ||
34 | #include <xen/interface/platform.h> | 34 | #include <xen/interface/platform.h> |
35 | #include <asm/xen/hypercall.h> | 35 | #include <asm/xen/hypercall.h> |
36 | 36 | ||
@@ -408,7 +408,7 @@ static int check_acpi_ids(struct acpi_processor *pr_backup) | |||
408 | acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, | 408 | acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, |
409 | ACPI_UINT32_MAX, | 409 | ACPI_UINT32_MAX, |
410 | read_acpi_id, NULL, NULL, NULL); | 410 | read_acpi_id, NULL, NULL, NULL); |
411 | acpi_get_devices("ACPI0007", read_acpi_id, NULL, NULL); | 411 | acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID, read_acpi_id, NULL, NULL); |
412 | 412 | ||
413 | upload: | 413 | upload: |
414 | if (!bitmap_equal(acpi_id_present, acpi_ids_done, nr_acpi_bits)) { | 414 | if (!bitmap_equal(acpi_id_present, acpi_ids_done, nr_acpi_bits)) { |
@@ -466,15 +466,33 @@ static int xen_upload_processor_pm_data(void) | |||
466 | return rc; | 466 | return rc; |
467 | } | 467 | } |
468 | 468 | ||
469 | static int xen_acpi_processor_resume(struct notifier_block *nb, | 469 | static void xen_acpi_processor_resume_worker(struct work_struct *dummy) |
470 | unsigned long action, void *data) | ||
471 | { | 470 | { |
471 | int rc; | ||
472 | |||
472 | bitmap_zero(acpi_ids_done, nr_acpi_bits); | 473 | bitmap_zero(acpi_ids_done, nr_acpi_bits); |
473 | return xen_upload_processor_pm_data(); | 474 | |
475 | rc = xen_upload_processor_pm_data(); | ||
476 | if (rc != 0) | ||
477 | pr_info("ACPI data upload failed, error = %d\n", rc); | ||
478 | } | ||
479 | |||
480 | static void xen_acpi_processor_resume(void) | ||
481 | { | ||
482 | static DECLARE_WORK(wq, xen_acpi_processor_resume_worker); | ||
483 | |||
484 | /* | ||
485 | * xen_upload_processor_pm_data() calls non-atomic code. | ||
486 | * However, the context for xen_acpi_processor_resume is syscore | ||
487 | * with only the boot CPU online and in an atomic context. | ||
488 | * | ||
489 | * So defer the upload for some point safer. | ||
490 | */ | ||
491 | schedule_work(&wq); | ||
474 | } | 492 | } |
475 | 493 | ||
476 | struct notifier_block xen_acpi_processor_resume_nb = { | 494 | static struct syscore_ops xap_syscore_ops = { |
477 | .notifier_call = xen_acpi_processor_resume, | 495 | .resume = xen_acpi_processor_resume, |
478 | }; | 496 | }; |
479 | 497 | ||
480 | static int __init xen_acpi_processor_init(void) | 498 | static int __init xen_acpi_processor_init(void) |
@@ -527,7 +545,7 @@ static int __init xen_acpi_processor_init(void) | |||
527 | if (rc) | 545 | if (rc) |
528 | goto err_unregister; | 546 | goto err_unregister; |
529 | 547 | ||
530 | xen_resume_notifier_register(&xen_acpi_processor_resume_nb); | 548 | register_syscore_ops(&xap_syscore_ops); |
531 | 549 | ||
532 | return 0; | 550 | return 0; |
533 | err_unregister: | 551 | err_unregister: |
@@ -544,7 +562,7 @@ static void __exit xen_acpi_processor_exit(void) | |||
544 | { | 562 | { |
545 | int i; | 563 | int i; |
546 | 564 | ||
547 | xen_resume_notifier_unregister(&xen_acpi_processor_resume_nb); | 565 | unregister_syscore_ops(&xap_syscore_ops); |
548 | kfree(acpi_ids_done); | 566 | kfree(acpi_ids_done); |
549 | kfree(acpi_id_present); | 567 | kfree(acpi_id_present); |
550 | kfree(acpi_id_cst_present); | 568 | kfree(acpi_id_cst_present); |