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 @@  #include <linux/init.h>  #include <linux/module.h>  #include <linux/types.h> +#include <linux/syscore_ops.h>  #include <linux/acpi.h>  #include <acpi/processor.h>  #include <xen/xen.h> -#include <xen/xen-ops.h>  #include <xen/interface/platform.h>  #include <asm/xen/hypercall.h> @@ -408,7 +408,7 @@ static int check_acpi_ids(struct acpi_processor *pr_backup)  	acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,  			    ACPI_UINT32_MAX,  			    read_acpi_id, NULL, NULL, NULL); -	acpi_get_devices("ACPI0007", read_acpi_id, NULL, NULL); +	acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID, read_acpi_id, NULL, NULL);  upload:  	if (!bitmap_equal(acpi_id_present, acpi_ids_done, nr_acpi_bits)) { @@ -466,15 +466,33 @@ static int xen_upload_processor_pm_data(void)  	return rc;  } -static int xen_acpi_processor_resume(struct notifier_block *nb, -				     unsigned long action, void *data) +static void xen_acpi_processor_resume_worker(struct work_struct *dummy)  { +	int rc; +  	bitmap_zero(acpi_ids_done, nr_acpi_bits); -	return xen_upload_processor_pm_data(); + +	rc = xen_upload_processor_pm_data(); +	if (rc != 0) +		pr_info("ACPI data upload failed, error = %d\n", rc); +} + +static void xen_acpi_processor_resume(void) +{ +	static DECLARE_WORK(wq, xen_acpi_processor_resume_worker); + +	/* +	 * xen_upload_processor_pm_data() calls non-atomic code. +	 * However, the context for xen_acpi_processor_resume is syscore +	 * with only the boot CPU online and in an atomic context. +	 * +	 * So defer the upload for some point safer. +	 */ +	schedule_work(&wq);  } -struct notifier_block xen_acpi_processor_resume_nb = { -	.notifier_call = xen_acpi_processor_resume, +static struct syscore_ops xap_syscore_ops = { +	.resume	= xen_acpi_processor_resume,  };  static int __init xen_acpi_processor_init(void) @@ -527,7 +545,7 @@ static int __init xen_acpi_processor_init(void)  	if (rc)  		goto err_unregister; -	xen_resume_notifier_register(&xen_acpi_processor_resume_nb); +	register_syscore_ops(&xap_syscore_ops);  	return 0;  err_unregister: @@ -544,7 +562,7 @@ static void __exit xen_acpi_processor_exit(void)  {  	int i; -	xen_resume_notifier_unregister(&xen_acpi_processor_resume_nb); +	unregister_syscore_ops(&xap_syscore_ops);  	kfree(acpi_ids_done);  	kfree(acpi_id_present);  	kfree(acpi_id_cst_present);  | 
