diff options
Diffstat (limited to 'drivers/acpi')
28 files changed, 1886 insertions, 139 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index b23fe37f67c0..8951cefb0a96 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -360,15 +360,14 @@ config ACPI_BGRT | |||
360 | config ACPI_REDUCED_HARDWARE_ONLY | 360 | config ACPI_REDUCED_HARDWARE_ONLY |
361 | bool "Hardware-reduced ACPI support only" if EXPERT | 361 | bool "Hardware-reduced ACPI support only" if EXPERT |
362 | def_bool n | 362 | def_bool n |
363 | depends on ACPI | ||
364 | help | 363 | help |
365 | This config item changes the way the ACPI code is built. When this | 364 | This config item changes the way the ACPI code is built. When this |
366 | option is selected, the kernel will use a specialized version of | 365 | option is selected, the kernel will use a specialized version of |
367 | ACPICA that ONLY supports the ACPI "reduced hardware" mode. The | 366 | ACPICA that ONLY supports the ACPI "reduced hardware" mode. The |
368 | resulting kernel will be smaller but it will also be restricted to | 367 | resulting kernel will be smaller but it will also be restricted to |
369 | running in ACPI reduced hardware mode ONLY. | 368 | running in ACPI reduced hardware mode ONLY. |
370 | 369 | ||
371 | If you are unsure what to do, do not enable this option. | 370 | If you are unsure what to do, do not enable this option. |
372 | 371 | ||
373 | source "drivers/acpi/apei/Kconfig" | 372 | source "drivers/acpi/apei/Kconfig" |
374 | 373 | ||
@@ -394,4 +393,27 @@ config ACPI_EXTLOG | |||
394 | driver adds support for that functionality with corresponding | 393 | driver adds support for that functionality with corresponding |
395 | tracepoint which carries that information to userspace. | 394 | tracepoint which carries that information to userspace. |
396 | 395 | ||
396 | menuconfig PMIC_OPREGION | ||
397 | bool "PMIC (Power Management Integrated Circuit) operation region support" | ||
398 | help | ||
399 | Select this option to enable support for ACPI operation | ||
400 | region of the PMIC chip. The operation region can be used | ||
401 | to control power rails and sensor reading/writing on the | ||
402 | PMIC chip. | ||
403 | |||
404 | if PMIC_OPREGION | ||
405 | config CRC_PMIC_OPREGION | ||
406 | bool "ACPI operation region support for CrystalCove PMIC" | ||
407 | depends on INTEL_SOC_PMIC | ||
408 | help | ||
409 | This config adds ACPI operation region support for CrystalCove PMIC. | ||
410 | |||
411 | config XPOWER_PMIC_OPREGION | ||
412 | bool "ACPI operation region support for XPower AXP288 PMIC" | ||
413 | depends on AXP288_ADC = y | ||
414 | help | ||
415 | This config adds ACPI operation region support for XPower AXP288 PMIC. | ||
416 | |||
417 | endif | ||
418 | |||
397 | endif # ACPI | 419 | endif # ACPI |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index c3b2fcb729f3..f74317cc1ca9 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -47,6 +47,7 @@ acpi-y += int340x_thermal.o | |||
47 | acpi-y += power.o | 47 | acpi-y += power.o |
48 | acpi-y += event.o | 48 | acpi-y += event.o |
49 | acpi-y += sysfs.o | 49 | acpi-y += sysfs.o |
50 | acpi-y += property.o | ||
50 | acpi-$(CONFIG_X86) += acpi_cmos_rtc.o | 51 | acpi-$(CONFIG_X86) += acpi_cmos_rtc.o |
51 | acpi-$(CONFIG_DEBUG_FS) += debugfs.o | 52 | acpi-$(CONFIG_DEBUG_FS) += debugfs.o |
52 | acpi-$(CONFIG_ACPI_NUMA) += numa.o | 53 | acpi-$(CONFIG_ACPI_NUMA) += numa.o |
@@ -87,3 +88,7 @@ obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o | |||
87 | obj-$(CONFIG_ACPI_APEI) += apei/ | 88 | obj-$(CONFIG_ACPI_APEI) += apei/ |
88 | 89 | ||
89 | obj-$(CONFIG_ACPI_EXTLOG) += acpi_extlog.o | 90 | obj-$(CONFIG_ACPI_EXTLOG) += acpi_extlog.o |
91 | |||
92 | obj-$(CONFIG_PMIC_OPREGION) += pmic/intel_pmic.o | ||
93 | obj-$(CONFIG_CRC_PMIC_OPREGION) += pmic/intel_pmic_crc.o | ||
94 | obj-$(CONFIG_XPOWER_PMIC_OPREGION) += pmic/intel_pmic_xpower.o | ||
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index 93d160661f4c..4f3febf8a589 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * ACPI support for Intel Lynxpoint LPSS. | 2 | * ACPI support for Intel Lynxpoint LPSS. |
3 | * | 3 | * |
4 | * Copyright (C) 2013, Intel Corporation | 4 | * Copyright (C) 2013, 2014, Intel Corporation |
5 | * Authors: Mika Westerberg <mika.westerberg@linux.intel.com> | 5 | * Authors: Mika Westerberg <mika.westerberg@linux.intel.com> |
6 | * Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 6 | * Rafael J. Wysocki <rafael.j.wysocki@intel.com> |
7 | * | 7 | * |
@@ -60,6 +60,8 @@ ACPI_MODULE_NAME("acpi_lpss"); | |||
60 | #define LPSS_CLK_DIVIDER BIT(2) | 60 | #define LPSS_CLK_DIVIDER BIT(2) |
61 | #define LPSS_LTR BIT(3) | 61 | #define LPSS_LTR BIT(3) |
62 | #define LPSS_SAVE_CTX BIT(4) | 62 | #define LPSS_SAVE_CTX BIT(4) |
63 | #define LPSS_DEV_PROXY BIT(5) | ||
64 | #define LPSS_PROXY_REQ BIT(6) | ||
63 | 65 | ||
64 | struct lpss_private_data; | 66 | struct lpss_private_data; |
65 | 67 | ||
@@ -70,8 +72,10 @@ struct lpss_device_desc { | |||
70 | void (*setup)(struct lpss_private_data *pdata); | 72 | void (*setup)(struct lpss_private_data *pdata); |
71 | }; | 73 | }; |
72 | 74 | ||
75 | static struct device *proxy_device; | ||
76 | |||
73 | static struct lpss_device_desc lpss_dma_desc = { | 77 | static struct lpss_device_desc lpss_dma_desc = { |
74 | .flags = LPSS_CLK, | 78 | .flags = LPSS_CLK | LPSS_PROXY_REQ, |
75 | }; | 79 | }; |
76 | 80 | ||
77 | struct lpss_private_data { | 81 | struct lpss_private_data { |
@@ -146,22 +150,24 @@ static struct lpss_device_desc byt_pwm_dev_desc = { | |||
146 | }; | 150 | }; |
147 | 151 | ||
148 | static struct lpss_device_desc byt_uart_dev_desc = { | 152 | static struct lpss_device_desc byt_uart_dev_desc = { |
149 | .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX, | 153 | .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX | |
154 | LPSS_DEV_PROXY, | ||
150 | .prv_offset = 0x800, | 155 | .prv_offset = 0x800, |
151 | .setup = lpss_uart_setup, | 156 | .setup = lpss_uart_setup, |
152 | }; | 157 | }; |
153 | 158 | ||
154 | static struct lpss_device_desc byt_spi_dev_desc = { | 159 | static struct lpss_device_desc byt_spi_dev_desc = { |
155 | .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX, | 160 | .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX | |
161 | LPSS_DEV_PROXY, | ||
156 | .prv_offset = 0x400, | 162 | .prv_offset = 0x400, |
157 | }; | 163 | }; |
158 | 164 | ||
159 | static struct lpss_device_desc byt_sdio_dev_desc = { | 165 | static struct lpss_device_desc byt_sdio_dev_desc = { |
160 | .flags = LPSS_CLK, | 166 | .flags = LPSS_CLK | LPSS_DEV_PROXY, |
161 | }; | 167 | }; |
162 | 168 | ||
163 | static struct lpss_device_desc byt_i2c_dev_desc = { | 169 | static struct lpss_device_desc byt_i2c_dev_desc = { |
164 | .flags = LPSS_CLK | LPSS_SAVE_CTX, | 170 | .flags = LPSS_CLK | LPSS_SAVE_CTX | LPSS_DEV_PROXY, |
165 | .prv_offset = 0x800, | 171 | .prv_offset = 0x800, |
166 | .setup = byt_i2c_setup, | 172 | .setup = byt_i2c_setup, |
167 | }; | 173 | }; |
@@ -368,6 +374,8 @@ static int acpi_lpss_create_device(struct acpi_device *adev, | |||
368 | adev->driver_data = pdata; | 374 | adev->driver_data = pdata; |
369 | pdev = acpi_create_platform_device(adev); | 375 | pdev = acpi_create_platform_device(adev); |
370 | if (!IS_ERR_OR_NULL(pdev)) { | 376 | if (!IS_ERR_OR_NULL(pdev)) { |
377 | if (!proxy_device && dev_desc->flags & LPSS_DEV_PROXY) | ||
378 | proxy_device = &pdev->dev; | ||
371 | return 1; | 379 | return 1; |
372 | } | 380 | } |
373 | 381 | ||
@@ -499,14 +507,15 @@ static void acpi_lpss_set_ltr(struct device *dev, s32 val) | |||
499 | /** | 507 | /** |
500 | * acpi_lpss_save_ctx() - Save the private registers of LPSS device | 508 | * acpi_lpss_save_ctx() - Save the private registers of LPSS device |
501 | * @dev: LPSS device | 509 | * @dev: LPSS device |
510 | * @pdata: pointer to the private data of the LPSS device | ||
502 | * | 511 | * |
503 | * Most LPSS devices have private registers which may loose their context when | 512 | * Most LPSS devices have private registers which may loose their context when |
504 | * the device is powered down. acpi_lpss_save_ctx() saves those registers into | 513 | * the device is powered down. acpi_lpss_save_ctx() saves those registers into |
505 | * prv_reg_ctx array. | 514 | * prv_reg_ctx array. |
506 | */ | 515 | */ |
507 | static void acpi_lpss_save_ctx(struct device *dev) | 516 | static void acpi_lpss_save_ctx(struct device *dev, |
517 | struct lpss_private_data *pdata) | ||
508 | { | 518 | { |
509 | struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); | ||
510 | unsigned int i; | 519 | unsigned int i; |
511 | 520 | ||
512 | for (i = 0; i < LPSS_PRV_REG_COUNT; i++) { | 521 | for (i = 0; i < LPSS_PRV_REG_COUNT; i++) { |
@@ -521,12 +530,13 @@ static void acpi_lpss_save_ctx(struct device *dev) | |||
521 | /** | 530 | /** |
522 | * acpi_lpss_restore_ctx() - Restore the private registers of LPSS device | 531 | * acpi_lpss_restore_ctx() - Restore the private registers of LPSS device |
523 | * @dev: LPSS device | 532 | * @dev: LPSS device |
533 | * @pdata: pointer to the private data of the LPSS device | ||
524 | * | 534 | * |
525 | * Restores the registers that were previously stored with acpi_lpss_save_ctx(). | 535 | * Restores the registers that were previously stored with acpi_lpss_save_ctx(). |
526 | */ | 536 | */ |
527 | static void acpi_lpss_restore_ctx(struct device *dev) | 537 | static void acpi_lpss_restore_ctx(struct device *dev, |
538 | struct lpss_private_data *pdata) | ||
528 | { | 539 | { |
529 | struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); | ||
530 | unsigned int i; | 540 | unsigned int i; |
531 | 541 | ||
532 | /* | 542 | /* |
@@ -549,54 +559,82 @@ static void acpi_lpss_restore_ctx(struct device *dev) | |||
549 | #ifdef CONFIG_PM_SLEEP | 559 | #ifdef CONFIG_PM_SLEEP |
550 | static int acpi_lpss_suspend_late(struct device *dev) | 560 | static int acpi_lpss_suspend_late(struct device *dev) |
551 | { | 561 | { |
552 | int ret = pm_generic_suspend_late(dev); | 562 | struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); |
563 | int ret; | ||
553 | 564 | ||
565 | ret = pm_generic_suspend_late(dev); | ||
554 | if (ret) | 566 | if (ret) |
555 | return ret; | 567 | return ret; |
556 | 568 | ||
557 | acpi_lpss_save_ctx(dev); | 569 | if (pdata->dev_desc->flags & LPSS_SAVE_CTX) |
570 | acpi_lpss_save_ctx(dev, pdata); | ||
571 | |||
558 | return acpi_dev_suspend_late(dev); | 572 | return acpi_dev_suspend_late(dev); |
559 | } | 573 | } |
560 | 574 | ||
561 | static int acpi_lpss_resume_early(struct device *dev) | 575 | static int acpi_lpss_resume_early(struct device *dev) |
562 | { | 576 | { |
563 | int ret = acpi_dev_resume_early(dev); | 577 | struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); |
578 | int ret; | ||
564 | 579 | ||
580 | ret = acpi_dev_resume_early(dev); | ||
565 | if (ret) | 581 | if (ret) |
566 | return ret; | 582 | return ret; |
567 | 583 | ||
568 | acpi_lpss_restore_ctx(dev); | 584 | if (pdata->dev_desc->flags & LPSS_SAVE_CTX) |
585 | acpi_lpss_restore_ctx(dev, pdata); | ||
586 | |||
569 | return pm_generic_resume_early(dev); | 587 | return pm_generic_resume_early(dev); |
570 | } | 588 | } |
571 | #endif /* CONFIG_PM_SLEEP */ | 589 | #endif /* CONFIG_PM_SLEEP */ |
572 | 590 | ||
573 | #ifdef CONFIG_PM_RUNTIME | ||
574 | static int acpi_lpss_runtime_suspend(struct device *dev) | 591 | static int acpi_lpss_runtime_suspend(struct device *dev) |
575 | { | 592 | { |
576 | int ret = pm_generic_runtime_suspend(dev); | 593 | struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); |
594 | int ret; | ||
595 | |||
596 | ret = pm_generic_runtime_suspend(dev); | ||
597 | if (ret) | ||
598 | return ret; | ||
577 | 599 | ||
600 | if (pdata->dev_desc->flags & LPSS_SAVE_CTX) | ||
601 | acpi_lpss_save_ctx(dev, pdata); | ||
602 | |||
603 | ret = acpi_dev_runtime_suspend(dev); | ||
578 | if (ret) | 604 | if (ret) |
579 | return ret; | 605 | return ret; |
580 | 606 | ||
581 | acpi_lpss_save_ctx(dev); | 607 | if (pdata->dev_desc->flags & LPSS_PROXY_REQ && proxy_device) |
582 | return acpi_dev_runtime_suspend(dev); | 608 | return pm_runtime_put_sync_suspend(proxy_device); |
609 | |||
610 | return 0; | ||
583 | } | 611 | } |
584 | 612 | ||
585 | static int acpi_lpss_runtime_resume(struct device *dev) | 613 | static int acpi_lpss_runtime_resume(struct device *dev) |
586 | { | 614 | { |
587 | int ret = acpi_dev_runtime_resume(dev); | 615 | struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); |
616 | int ret; | ||
617 | |||
618 | if (pdata->dev_desc->flags & LPSS_PROXY_REQ && proxy_device) { | ||
619 | ret = pm_runtime_get_sync(proxy_device); | ||
620 | if (ret) | ||
621 | return ret; | ||
622 | } | ||
588 | 623 | ||
624 | ret = acpi_dev_runtime_resume(dev); | ||
589 | if (ret) | 625 | if (ret) |
590 | return ret; | 626 | return ret; |
591 | 627 | ||
592 | acpi_lpss_restore_ctx(dev); | 628 | if (pdata->dev_desc->flags & LPSS_SAVE_CTX) |
629 | acpi_lpss_restore_ctx(dev, pdata); | ||
630 | |||
593 | return pm_generic_runtime_resume(dev); | 631 | return pm_generic_runtime_resume(dev); |
594 | } | 632 | } |
595 | #endif /* CONFIG_PM_RUNTIME */ | ||
596 | #endif /* CONFIG_PM */ | 633 | #endif /* CONFIG_PM */ |
597 | 634 | ||
598 | static struct dev_pm_domain acpi_lpss_pm_domain = { | 635 | static struct dev_pm_domain acpi_lpss_pm_domain = { |
599 | .ops = { | 636 | .ops = { |
637 | #ifdef CONFIG_PM | ||
600 | #ifdef CONFIG_PM_SLEEP | 638 | #ifdef CONFIG_PM_SLEEP |
601 | .prepare = acpi_subsys_prepare, | 639 | .prepare = acpi_subsys_prepare, |
602 | .complete = acpi_subsys_complete, | 640 | .complete = acpi_subsys_complete, |
@@ -608,7 +646,6 @@ static struct dev_pm_domain acpi_lpss_pm_domain = { | |||
608 | .poweroff_late = acpi_lpss_suspend_late, | 646 | .poweroff_late = acpi_lpss_suspend_late, |
609 | .restore_early = acpi_lpss_resume_early, | 647 | .restore_early = acpi_lpss_resume_early, |
610 | #endif | 648 | #endif |
611 | #ifdef CONFIG_PM_RUNTIME | ||
612 | .runtime_suspend = acpi_lpss_runtime_suspend, | 649 | .runtime_suspend = acpi_lpss_runtime_suspend, |
613 | .runtime_resume = acpi_lpss_runtime_resume, | 650 | .runtime_resume = acpi_lpss_runtime_resume, |
614 | #endif | 651 | #endif |
@@ -631,30 +668,27 @@ static int acpi_lpss_platform_notify(struct notifier_block *nb, | |||
631 | return 0; | 668 | return 0; |
632 | 669 | ||
633 | pdata = acpi_driver_data(adev); | 670 | pdata = acpi_driver_data(adev); |
634 | if (!pdata || !pdata->mmio_base) | 671 | if (!pdata) |
635 | return 0; | 672 | return 0; |
636 | 673 | ||
637 | if (pdata->mmio_size < pdata->dev_desc->prv_offset + LPSS_LTR_SIZE) { | 674 | if (pdata->mmio_base && |
675 | pdata->mmio_size < pdata->dev_desc->prv_offset + LPSS_LTR_SIZE) { | ||
638 | dev_err(&pdev->dev, "MMIO size insufficient to access LTR\n"); | 676 | dev_err(&pdev->dev, "MMIO size insufficient to access LTR\n"); |
639 | return 0; | 677 | return 0; |
640 | } | 678 | } |
641 | 679 | ||
642 | switch (action) { | 680 | switch (action) { |
643 | case BUS_NOTIFY_BOUND_DRIVER: | ||
644 | if (pdata->dev_desc->flags & LPSS_SAVE_CTX) | ||
645 | pdev->dev.pm_domain = &acpi_lpss_pm_domain; | ||
646 | break; | ||
647 | case BUS_NOTIFY_UNBOUND_DRIVER: | ||
648 | if (pdata->dev_desc->flags & LPSS_SAVE_CTX) | ||
649 | pdev->dev.pm_domain = NULL; | ||
650 | break; | ||
651 | case BUS_NOTIFY_ADD_DEVICE: | 681 | case BUS_NOTIFY_ADD_DEVICE: |
682 | pdev->dev.pm_domain = &acpi_lpss_pm_domain; | ||
652 | if (pdata->dev_desc->flags & LPSS_LTR) | 683 | if (pdata->dev_desc->flags & LPSS_LTR) |
653 | return sysfs_create_group(&pdev->dev.kobj, | 684 | return sysfs_create_group(&pdev->dev.kobj, |
654 | &lpss_attr_group); | 685 | &lpss_attr_group); |
686 | break; | ||
655 | case BUS_NOTIFY_DEL_DEVICE: | 687 | case BUS_NOTIFY_DEL_DEVICE: |
656 | if (pdata->dev_desc->flags & LPSS_LTR) | 688 | if (pdata->dev_desc->flags & LPSS_LTR) |
657 | sysfs_remove_group(&pdev->dev.kobj, &lpss_attr_group); | 689 | sysfs_remove_group(&pdev->dev.kobj, &lpss_attr_group); |
690 | pdev->dev.pm_domain = NULL; | ||
691 | break; | ||
658 | default: | 692 | default: |
659 | break; | 693 | break; |
660 | } | 694 | } |
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index ebf02cc10a43..7f60582d0c8c 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
@@ -305,6 +305,7 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_db_output_flags, ACPI_DB_CONSOLE_OUTPUT); | |||
305 | 305 | ||
306 | ACPI_INIT_GLOBAL(u8, acpi_gbl_no_resource_disassembly, FALSE); | 306 | ACPI_INIT_GLOBAL(u8, acpi_gbl_no_resource_disassembly, FALSE); |
307 | ACPI_INIT_GLOBAL(u8, acpi_gbl_ignore_noop_operator, FALSE); | 307 | ACPI_INIT_GLOBAL(u8, acpi_gbl_ignore_noop_operator, FALSE); |
308 | ACPI_INIT_GLOBAL(u8, acpi_gbl_cstyle_disassembly, TRUE); | ||
308 | 309 | ||
309 | ACPI_GLOBAL(u8, acpi_gbl_db_opt_disasm); | 310 | ACPI_GLOBAL(u8, acpi_gbl_db_opt_disasm); |
310 | ACPI_GLOBAL(u8, acpi_gbl_db_opt_verbose); | 311 | ACPI_GLOBAL(u8, acpi_gbl_db_opt_verbose); |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index c00e7e41ad75..680d23bbae7c 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
@@ -454,6 +454,7 @@ struct acpi_gpe_register_info { | |||
454 | u16 base_gpe_number; /* Base GPE number for this register */ | 454 | u16 base_gpe_number; /* Base GPE number for this register */ |
455 | u8 enable_for_wake; /* GPEs to keep enabled when sleeping */ | 455 | u8 enable_for_wake; /* GPEs to keep enabled when sleeping */ |
456 | u8 enable_for_run; /* GPEs to keep enabled when running */ | 456 | u8 enable_for_run; /* GPEs to keep enabled when running */ |
457 | u8 enable_mask; /* Current mask of enabled GPEs */ | ||
457 | }; | 458 | }; |
458 | 459 | ||
459 | /* | 460 | /* |
@@ -722,6 +723,7 @@ union acpi_parse_value { | |||
722 | ACPI_DISASM_ONLY_MEMBERS (\ | 723 | ACPI_DISASM_ONLY_MEMBERS (\ |
723 | u8 disasm_flags; /* Used during AML disassembly */\ | 724 | u8 disasm_flags; /* Used during AML disassembly */\ |
724 | u8 disasm_opcode; /* Subtype used for disassembly */\ | 725 | u8 disasm_opcode; /* Subtype used for disassembly */\ |
726 | char *operator_symbol;/* Used for C-style operator name strings */\ | ||
725 | char aml_op_name[16]) /* Op name (debug only) */ | 727 | char aml_op_name[16]) /* Op name (debug only) */ |
726 | 728 | ||
727 | /* Flags for disasm_flags field above */ | 729 | /* Flags for disasm_flags field above */ |
@@ -827,6 +829,8 @@ struct acpi_parse_state { | |||
827 | #define ACPI_PARSEOP_EMPTY_TERMLIST 0x04 | 829 | #define ACPI_PARSEOP_EMPTY_TERMLIST 0x04 |
828 | #define ACPI_PARSEOP_PREDEF_CHECKED 0x08 | 830 | #define ACPI_PARSEOP_PREDEF_CHECKED 0x08 |
829 | #define ACPI_PARSEOP_SPECIAL 0x10 | 831 | #define ACPI_PARSEOP_SPECIAL 0x10 |
832 | #define ACPI_PARSEOP_COMPOUND 0x20 | ||
833 | #define ACPI_PARSEOP_ASSIGNMENT 0x40 | ||
830 | 834 | ||
831 | /***************************************************************************** | 835 | /***************************************************************************** |
832 | * | 836 | * |
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 2095dfb72bcb..aa70154cf4fa 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c | |||
@@ -134,7 +134,7 @@ acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
134 | 134 | ||
135 | /* Enable the requested GPE */ | 135 | /* Enable the requested GPE */ |
136 | 136 | ||
137 | status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE); | 137 | status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE_SAVE); |
138 | return_ACPI_STATUS(status); | 138 | return_ACPI_STATUS(status); |
139 | } | 139 | } |
140 | 140 | ||
@@ -213,7 +213,7 @@ acpi_ev_remove_gpe_reference(struct acpi_gpe_event_info *gpe_event_info) | |||
213 | if (ACPI_SUCCESS(status)) { | 213 | if (ACPI_SUCCESS(status)) { |
214 | status = | 214 | status = |
215 | acpi_hw_low_set_gpe(gpe_event_info, | 215 | acpi_hw_low_set_gpe(gpe_event_info, |
216 | ACPI_GPE_DISABLE); | 216 | ACPI_GPE_DISABLE_SAVE); |
217 | } | 217 | } |
218 | 218 | ||
219 | if (ACPI_FAILURE(status)) { | 219 | if (ACPI_FAILURE(status)) { |
@@ -616,8 +616,11 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) | |||
616 | static void ACPI_SYSTEM_XFACE acpi_ev_asynch_enable_gpe(void *context) | 616 | static void ACPI_SYSTEM_XFACE acpi_ev_asynch_enable_gpe(void *context) |
617 | { | 617 | { |
618 | struct acpi_gpe_event_info *gpe_event_info = context; | 618 | struct acpi_gpe_event_info *gpe_event_info = context; |
619 | acpi_cpu_flags flags; | ||
619 | 620 | ||
621 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
620 | (void)acpi_ev_finish_gpe(gpe_event_info); | 622 | (void)acpi_ev_finish_gpe(gpe_event_info); |
623 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
621 | 624 | ||
622 | ACPI_FREE(gpe_event_info); | 625 | ACPI_FREE(gpe_event_info); |
623 | return; | 626 | return; |
@@ -655,7 +658,7 @@ acpi_status acpi_ev_finish_gpe(struct acpi_gpe_event_info * gpe_event_info) | |||
655 | 658 | ||
656 | /* | 659 | /* |
657 | * Enable this GPE, conditionally. This means that the GPE will | 660 | * Enable this GPE, conditionally. This means that the GPE will |
658 | * only be physically enabled if the enable_for_run bit is set | 661 | * only be physically enabled if the enable_mask bit is set |
659 | * in the event_info. | 662 | * in the event_info. |
660 | */ | 663 | */ |
661 | (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_CONDITIONAL_ENABLE); | 664 | (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_CONDITIONAL_ENABLE); |
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index 48ac7b7b59cd..494027f5c067 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c | |||
@@ -115,12 +115,12 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action) | |||
115 | /* Set or clear just the bit that corresponds to this GPE */ | 115 | /* Set or clear just the bit that corresponds to this GPE */ |
116 | 116 | ||
117 | register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info); | 117 | register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info); |
118 | switch (action) { | 118 | switch (action & ~ACPI_GPE_SAVE_MASK) { |
119 | case ACPI_GPE_CONDITIONAL_ENABLE: | 119 | case ACPI_GPE_CONDITIONAL_ENABLE: |
120 | 120 | ||
121 | /* Only enable if the enable_for_run bit is set */ | 121 | /* Only enable if the corresponding enable_mask bit is set */ |
122 | 122 | ||
123 | if (!(register_bit & gpe_register_info->enable_for_run)) { | 123 | if (!(register_bit & gpe_register_info->enable_mask)) { |
124 | return (AE_BAD_PARAMETER); | 124 | return (AE_BAD_PARAMETER); |
125 | } | 125 | } |
126 | 126 | ||
@@ -145,6 +145,9 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action) | |||
145 | /* Write the updated enable mask */ | 145 | /* Write the updated enable mask */ |
146 | 146 | ||
147 | status = acpi_hw_write(enable_mask, &gpe_register_info->enable_address); | 147 | status = acpi_hw_write(enable_mask, &gpe_register_info->enable_address); |
148 | if (ACPI_SUCCESS(status) && (action & ACPI_GPE_SAVE_MASK)) { | ||
149 | gpe_register_info->enable_mask = enable_mask; | ||
150 | } | ||
148 | return (status); | 151 | return (status); |
149 | } | 152 | } |
150 | 153 | ||
@@ -262,6 +265,32 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, | |||
262 | 265 | ||
263 | /****************************************************************************** | 266 | /****************************************************************************** |
264 | * | 267 | * |
268 | * FUNCTION: acpi_hw_gpe_enable_write | ||
269 | * | ||
270 | * PARAMETERS: enable_mask - Bit mask to write to the GPE register | ||
271 | * gpe_register_info - Gpe Register info | ||
272 | * | ||
273 | * RETURN: Status | ||
274 | * | ||
275 | * DESCRIPTION: Write the enable mask byte to the given GPE register. | ||
276 | * | ||
277 | ******************************************************************************/ | ||
278 | |||
279 | static acpi_status | ||
280 | acpi_hw_gpe_enable_write(u8 enable_mask, | ||
281 | struct acpi_gpe_register_info *gpe_register_info) | ||
282 | { | ||
283 | acpi_status status; | ||
284 | |||
285 | status = acpi_hw_write(enable_mask, &gpe_register_info->enable_address); | ||
286 | if (ACPI_SUCCESS(status)) { | ||
287 | gpe_register_info->enable_mask = enable_mask; | ||
288 | } | ||
289 | return (status); | ||
290 | } | ||
291 | |||
292 | /****************************************************************************** | ||
293 | * | ||
265 | * FUNCTION: acpi_hw_disable_gpe_block | 294 | * FUNCTION: acpi_hw_disable_gpe_block |
266 | * | 295 | * |
267 | * PARAMETERS: gpe_xrupt_info - GPE Interrupt info | 296 | * PARAMETERS: gpe_xrupt_info - GPE Interrupt info |
@@ -287,8 +316,8 @@ acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
287 | /* Disable all GPEs in this register */ | 316 | /* Disable all GPEs in this register */ |
288 | 317 | ||
289 | status = | 318 | status = |
290 | acpi_hw_write(0x00, | 319 | acpi_hw_gpe_enable_write(0x00, |
291 | &gpe_block->register_info[i].enable_address); | 320 | &gpe_block->register_info[i]); |
292 | if (ACPI_FAILURE(status)) { | 321 | if (ACPI_FAILURE(status)) { |
293 | return (status); | 322 | return (status); |
294 | } | 323 | } |
@@ -355,21 +384,23 @@ acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
355 | { | 384 | { |
356 | u32 i; | 385 | u32 i; |
357 | acpi_status status; | 386 | acpi_status status; |
387 | struct acpi_gpe_register_info *gpe_register_info; | ||
358 | 388 | ||
359 | /* NOTE: assumes that all GPEs are currently disabled */ | 389 | /* NOTE: assumes that all GPEs are currently disabled */ |
360 | 390 | ||
361 | /* Examine each GPE Register within the block */ | 391 | /* Examine each GPE Register within the block */ |
362 | 392 | ||
363 | for (i = 0; i < gpe_block->register_count; i++) { | 393 | for (i = 0; i < gpe_block->register_count; i++) { |
364 | if (!gpe_block->register_info[i].enable_for_run) { | 394 | gpe_register_info = &gpe_block->register_info[i]; |
395 | if (!gpe_register_info->enable_for_run) { | ||
365 | continue; | 396 | continue; |
366 | } | 397 | } |
367 | 398 | ||
368 | /* Enable all "runtime" GPEs in this register */ | 399 | /* Enable all "runtime" GPEs in this register */ |
369 | 400 | ||
370 | status = | 401 | status = |
371 | acpi_hw_write(gpe_block->register_info[i].enable_for_run, | 402 | acpi_hw_gpe_enable_write(gpe_register_info->enable_for_run, |
372 | &gpe_block->register_info[i].enable_address); | 403 | gpe_register_info); |
373 | if (ACPI_FAILURE(status)) { | 404 | if (ACPI_FAILURE(status)) { |
374 | return (status); | 405 | return (status); |
375 | } | 406 | } |
@@ -399,10 +430,12 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
399 | { | 430 | { |
400 | u32 i; | 431 | u32 i; |
401 | acpi_status status; | 432 | acpi_status status; |
433 | struct acpi_gpe_register_info *gpe_register_info; | ||
402 | 434 | ||
403 | /* Examine each GPE Register within the block */ | 435 | /* Examine each GPE Register within the block */ |
404 | 436 | ||
405 | for (i = 0; i < gpe_block->register_count; i++) { | 437 | for (i = 0; i < gpe_block->register_count; i++) { |
438 | gpe_register_info = &gpe_block->register_info[i]; | ||
406 | 439 | ||
407 | /* | 440 | /* |
408 | * Enable all "wake" GPEs in this register and disable the | 441 | * Enable all "wake" GPEs in this register and disable the |
@@ -410,8 +443,8 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
410 | */ | 443 | */ |
411 | 444 | ||
412 | status = | 445 | status = |
413 | acpi_hw_write(gpe_block->register_info[i].enable_for_wake, | 446 | acpi_hw_gpe_enable_write(gpe_register_info->enable_for_wake, |
414 | &gpe_block->register_info[i].enable_address); | 447 | gpe_register_info); |
415 | if (ACPI_FAILURE(status)) { | 448 | if (ACPI_FAILURE(status)) { |
416 | return (status); | 449 | return (status); |
417 | } | 450 | } |
diff --git a/drivers/acpi/acpica/utresrc.c b/drivers/acpi/acpica/utresrc.c index 5cd017c7ac0e..bc1ff820c7dd 100644 --- a/drivers/acpi/acpica/utresrc.c +++ b/drivers/acpi/acpica/utresrc.c | |||
@@ -263,7 +263,7 @@ const char *acpi_gbl_bpb_decode[] = { | |||
263 | /* UART serial bus stop bits */ | 263 | /* UART serial bus stop bits */ |
264 | 264 | ||
265 | const char *acpi_gbl_sb_decode[] = { | 265 | const char *acpi_gbl_sb_decode[] = { |
266 | "StopBitsNone", | 266 | "StopBitsZero", |
267 | "StopBitsOne", | 267 | "StopBitsOne", |
268 | "StopBitsOnePlusHalf", | 268 | "StopBitsOnePlusHalf", |
269 | "StopBitsTwo" | 269 | "StopBitsTwo" |
diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index 502a8492dc83..49c873c68756 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c | |||
@@ -531,7 +531,9 @@ acpi_decode_pld_buffer(u8 *in_buffer, | |||
531 | ACPI_MOVE_32_TO_32(&dword, &buffer[0]); | 531 | ACPI_MOVE_32_TO_32(&dword, &buffer[0]); |
532 | pld_info->revision = ACPI_PLD_GET_REVISION(&dword); | 532 | pld_info->revision = ACPI_PLD_GET_REVISION(&dword); |
533 | pld_info->ignore_color = ACPI_PLD_GET_IGNORE_COLOR(&dword); | 533 | pld_info->ignore_color = ACPI_PLD_GET_IGNORE_COLOR(&dword); |
534 | pld_info->color = ACPI_PLD_GET_COLOR(&dword); | 534 | pld_info->red = ACPI_PLD_GET_RED(&dword); |
535 | pld_info->green = ACPI_PLD_GET_GREEN(&dword); | ||
536 | pld_info->blue = ACPI_PLD_GET_BLUE(&dword); | ||
535 | 537 | ||
536 | /* Second 32-bit DWord */ | 538 | /* Second 32-bit DWord */ |
537 | 539 | ||
diff --git a/drivers/acpi/acpica/utxfinit.c b/drivers/acpi/acpica/utxfinit.c index 13380d818462..b1fd6886e439 100644 --- a/drivers/acpi/acpica/utxfinit.c +++ b/drivers/acpi/acpica/utxfinit.c | |||
@@ -53,6 +53,9 @@ | |||
53 | #define _COMPONENT ACPI_UTILITIES | 53 | #define _COMPONENT ACPI_UTILITIES |
54 | ACPI_MODULE_NAME("utxfinit") | 54 | ACPI_MODULE_NAME("utxfinit") |
55 | 55 | ||
56 | /* For acpi_exec only */ | ||
57 | void ae_do_object_overrides(void); | ||
58 | |||
56 | /******************************************************************************* | 59 | /******************************************************************************* |
57 | * | 60 | * |
58 | * FUNCTION: acpi_initialize_subsystem | 61 | * FUNCTION: acpi_initialize_subsystem |
@@ -65,6 +68,7 @@ ACPI_MODULE_NAME("utxfinit") | |||
65 | * called, so any early initialization belongs here. | 68 | * called, so any early initialization belongs here. |
66 | * | 69 | * |
67 | ******************************************************************************/ | 70 | ******************************************************************************/ |
71 | |||
68 | acpi_status __init acpi_initialize_subsystem(void) | 72 | acpi_status __init acpi_initialize_subsystem(void) |
69 | { | 73 | { |
70 | acpi_status status; | 74 | acpi_status status; |
@@ -275,6 +279,13 @@ acpi_status __init acpi_initialize_objects(u32 flags) | |||
275 | return_ACPI_STATUS(status); | 279 | return_ACPI_STATUS(status); |
276 | } | 280 | } |
277 | } | 281 | } |
282 | #ifdef ACPI_EXEC_APP | ||
283 | /* | ||
284 | * This call implements the "initialization file" option for acpi_exec. | ||
285 | * This is the precise point that we want to perform the overrides. | ||
286 | */ | ||
287 | ae_do_object_overrides(); | ||
288 | #endif | ||
278 | 289 | ||
279 | /* | 290 | /* |
280 | * Execute any module-level code that was detected during the table load | 291 | * Execute any module-level code that was detected during the table load |
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index fc5f780bb61d..1b6aa514848f 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c | |||
@@ -128,7 +128,7 @@ static DEFINE_SPINLOCK(ghes_ioremap_lock_irq); | |||
128 | static struct gen_pool *ghes_estatus_pool; | 128 | static struct gen_pool *ghes_estatus_pool; |
129 | static unsigned long ghes_estatus_pool_size_request; | 129 | static unsigned long ghes_estatus_pool_size_request; |
130 | 130 | ||
131 | struct ghes_estatus_cache *ghes_estatus_caches[GHES_ESTATUS_CACHES_SIZE]; | 131 | static struct ghes_estatus_cache *ghes_estatus_caches[GHES_ESTATUS_CACHES_SIZE]; |
132 | static atomic_t ghes_estatus_cache_alloced; | 132 | static atomic_t ghes_estatus_cache_alloced; |
133 | 133 | ||
134 | static int ghes_ioremap_init(void) | 134 | static int ghes_ioremap_init(void) |
@@ -738,20 +738,6 @@ static LIST_HEAD(ghes_nmi); | |||
738 | 738 | ||
739 | static int ghes_panic_timeout __read_mostly = 30; | 739 | static int ghes_panic_timeout __read_mostly = 30; |
740 | 740 | ||
741 | static struct llist_node *llist_nodes_reverse(struct llist_node *llnode) | ||
742 | { | ||
743 | struct llist_node *next, *tail = NULL; | ||
744 | |||
745 | while (llnode) { | ||
746 | next = llnode->next; | ||
747 | llnode->next = tail; | ||
748 | tail = llnode; | ||
749 | llnode = next; | ||
750 | } | ||
751 | |||
752 | return tail; | ||
753 | } | ||
754 | |||
755 | static void ghes_proc_in_irq(struct irq_work *irq_work) | 741 | static void ghes_proc_in_irq(struct irq_work *irq_work) |
756 | { | 742 | { |
757 | struct llist_node *llnode, *next; | 743 | struct llist_node *llnode, *next; |
@@ -765,7 +751,7 @@ static void ghes_proc_in_irq(struct irq_work *irq_work) | |||
765 | * Because the time order of estatus in list is reversed, | 751 | * Because the time order of estatus in list is reversed, |
766 | * revert it back to proper order. | 752 | * revert it back to proper order. |
767 | */ | 753 | */ |
768 | llnode = llist_nodes_reverse(llnode); | 754 | llnode = llist_reverse_order(llnode); |
769 | while (llnode) { | 755 | while (llnode) { |
770 | next = llnode->next; | 756 | next = llnode->next; |
771 | estatus_node = llist_entry(llnode, struct ghes_estatus_node, | 757 | estatus_node = llist_entry(llnode, struct ghes_estatus_node, |
@@ -798,7 +784,7 @@ static void ghes_print_queued_estatus(void) | |||
798 | * Because the time order of estatus in list is reversed, | 784 | * Because the time order of estatus in list is reversed, |
799 | * revert it back to proper order. | 785 | * revert it back to proper order. |
800 | */ | 786 | */ |
801 | llnode = llist_nodes_reverse(llnode); | 787 | llnode = llist_reverse_order(llnode); |
802 | while (llnode) { | 788 | while (llnode) { |
803 | estatus_node = llist_entry(llnode, struct ghes_estatus_node, | 789 | estatus_node = llist_entry(llnode, struct ghes_estatus_node, |
804 | llnode); | 790 | llnode); |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 8ec8a89a20ab..d98ba4355819 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -1180,6 +1180,10 @@ static int acpi_battery_add(struct acpi_device *device) | |||
1180 | 1180 | ||
1181 | if (!device) | 1181 | if (!device) |
1182 | return -EINVAL; | 1182 | return -EINVAL; |
1183 | |||
1184 | if (device->dep_unmet) | ||
1185 | return -EPROBE_DEFER; | ||
1186 | |||
1183 | battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL); | 1187 | battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL); |
1184 | if (!battery) | 1188 | if (!battery) |
1185 | return -ENOMEM; | 1189 | return -ENOMEM; |
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 7db193160766..c2daa85fc9f7 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c | |||
@@ -201,7 +201,7 @@ int acpi_device_set_power(struct acpi_device *device, int state) | |||
201 | * Transition Power | 201 | * Transition Power |
202 | * ---------------- | 202 | * ---------------- |
203 | * In accordance with the ACPI specification first apply power (via | 203 | * In accordance with the ACPI specification first apply power (via |
204 | * power resources) and then evalute _PSx. | 204 | * power resources) and then evaluate _PSx. |
205 | */ | 205 | */ |
206 | if (device->power.flags.power_resources) { | 206 | if (device->power.flags.power_resources) { |
207 | result = acpi_power_transition(device, state); | 207 | result = acpi_power_transition(device, state); |
@@ -680,19 +680,26 @@ static int acpi_device_wakeup(struct acpi_device *adev, u32 target_state, | |||
680 | if (error) | 680 | if (error) |
681 | return error; | 681 | return error; |
682 | 682 | ||
683 | if (adev->wakeup.flags.enabled) | ||
684 | return 0; | ||
685 | |||
683 | res = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number); | 686 | res = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number); |
684 | if (ACPI_FAILURE(res)) { | 687 | if (ACPI_SUCCESS(res)) { |
688 | adev->wakeup.flags.enabled = 1; | ||
689 | } else { | ||
685 | acpi_disable_wakeup_device_power(adev); | 690 | acpi_disable_wakeup_device_power(adev); |
686 | return -EIO; | 691 | return -EIO; |
687 | } | 692 | } |
688 | } else { | 693 | } else { |
689 | acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number); | 694 | if (adev->wakeup.flags.enabled) { |
695 | acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number); | ||
696 | adev->wakeup.flags.enabled = 0; | ||
697 | } | ||
690 | acpi_disable_wakeup_device_power(adev); | 698 | acpi_disable_wakeup_device_power(adev); |
691 | } | 699 | } |
692 | return 0; | 700 | return 0; |
693 | } | 701 | } |
694 | 702 | ||
695 | #ifdef CONFIG_PM_RUNTIME | ||
696 | /** | 703 | /** |
697 | * acpi_pm_device_run_wake - Enable/disable remote wakeup for given device. | 704 | * acpi_pm_device_run_wake - Enable/disable remote wakeup for given device. |
698 | * @dev: Device to enable/disable the platform to wake up. | 705 | * @dev: Device to enable/disable the platform to wake up. |
@@ -714,7 +721,6 @@ int acpi_pm_device_run_wake(struct device *phys_dev, bool enable) | |||
714 | return acpi_device_wakeup(adev, ACPI_STATE_S0, enable); | 721 | return acpi_device_wakeup(adev, ACPI_STATE_S0, enable); |
715 | } | 722 | } |
716 | EXPORT_SYMBOL(acpi_pm_device_run_wake); | 723 | EXPORT_SYMBOL(acpi_pm_device_run_wake); |
717 | #endif /* CONFIG_PM_RUNTIME */ | ||
718 | 724 | ||
719 | #ifdef CONFIG_PM_SLEEP | 725 | #ifdef CONFIG_PM_SLEEP |
720 | /** | 726 | /** |
@@ -773,7 +779,6 @@ static int acpi_dev_pm_full_power(struct acpi_device *adev) | |||
773 | acpi_device_set_power(adev, ACPI_STATE_D0) : 0; | 779 | acpi_device_set_power(adev, ACPI_STATE_D0) : 0; |
774 | } | 780 | } |
775 | 781 | ||
776 | #ifdef CONFIG_PM_RUNTIME | ||
777 | /** | 782 | /** |
778 | * acpi_dev_runtime_suspend - Put device into a low-power state using ACPI. | 783 | * acpi_dev_runtime_suspend - Put device into a low-power state using ACPI. |
779 | * @dev: Device to put into a low-power state. | 784 | * @dev: Device to put into a low-power state. |
@@ -855,7 +860,6 @@ int acpi_subsys_runtime_resume(struct device *dev) | |||
855 | return ret ? ret : pm_generic_runtime_resume(dev); | 860 | return ret ? ret : pm_generic_runtime_resume(dev); |
856 | } | 861 | } |
857 | EXPORT_SYMBOL_GPL(acpi_subsys_runtime_resume); | 862 | EXPORT_SYMBOL_GPL(acpi_subsys_runtime_resume); |
858 | #endif /* CONFIG_PM_RUNTIME */ | ||
859 | 863 | ||
860 | #ifdef CONFIG_PM_SLEEP | 864 | #ifdef CONFIG_PM_SLEEP |
861 | /** | 865 | /** |
@@ -1023,10 +1027,9 @@ EXPORT_SYMBOL_GPL(acpi_subsys_freeze); | |||
1023 | 1027 | ||
1024 | static struct dev_pm_domain acpi_general_pm_domain = { | 1028 | static struct dev_pm_domain acpi_general_pm_domain = { |
1025 | .ops = { | 1029 | .ops = { |
1026 | #ifdef CONFIG_PM_RUNTIME | 1030 | #ifdef CONFIG_PM |
1027 | .runtime_suspend = acpi_subsys_runtime_suspend, | 1031 | .runtime_suspend = acpi_subsys_runtime_suspend, |
1028 | .runtime_resume = acpi_subsys_runtime_resume, | 1032 | .runtime_resume = acpi_subsys_runtime_resume, |
1029 | #endif | ||
1030 | #ifdef CONFIG_PM_SLEEP | 1033 | #ifdef CONFIG_PM_SLEEP |
1031 | .prepare = acpi_subsys_prepare, | 1034 | .prepare = acpi_subsys_prepare, |
1032 | .complete = acpi_subsys_complete, | 1035 | .complete = acpi_subsys_complete, |
@@ -1038,6 +1041,7 @@ static struct dev_pm_domain acpi_general_pm_domain = { | |||
1038 | .poweroff_late = acpi_subsys_suspend_late, | 1041 | .poweroff_late = acpi_subsys_suspend_late, |
1039 | .restore_early = acpi_subsys_resume_early, | 1042 | .restore_early = acpi_subsys_resume_early, |
1040 | #endif | 1043 | #endif |
1044 | #endif | ||
1041 | }, | 1045 | }, |
1042 | }; | 1046 | }; |
1043 | 1047 | ||
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 5f9b74b9b71f..1b5853f384e2 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -844,6 +844,8 @@ static int ec_install_handlers(struct acpi_ec *ec) | |||
844 | 844 | ||
845 | static void ec_remove_handlers(struct acpi_ec *ec) | 845 | static void ec_remove_handlers(struct acpi_ec *ec) |
846 | { | 846 | { |
847 | if (!test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags)) | ||
848 | return; | ||
847 | acpi_disable_gpe(NULL, ec->gpe); | 849 | acpi_disable_gpe(NULL, ec->gpe); |
848 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, | 850 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, |
849 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) | 851 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) |
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index caf9b76b7ef8..7a36f02598a6 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -325,6 +325,7 @@ static int acpi_fan_probe(struct platform_device *pdev) | |||
325 | struct thermal_cooling_device *cdev; | 325 | struct thermal_cooling_device *cdev; |
326 | struct acpi_fan *fan; | 326 | struct acpi_fan *fan; |
327 | struct acpi_device *device = ACPI_COMPANION(&pdev->dev); | 327 | struct acpi_device *device = ACPI_COMPANION(&pdev->dev); |
328 | char *name; | ||
328 | 329 | ||
329 | fan = devm_kzalloc(&pdev->dev, sizeof(*fan), GFP_KERNEL); | 330 | fan = devm_kzalloc(&pdev->dev, sizeof(*fan), GFP_KERNEL); |
330 | if (!fan) { | 331 | if (!fan) { |
@@ -346,7 +347,12 @@ static int acpi_fan_probe(struct platform_device *pdev) | |||
346 | } | 347 | } |
347 | } | 348 | } |
348 | 349 | ||
349 | cdev = thermal_cooling_device_register("Fan", device, | 350 | if (!strncmp(pdev->name, "PNP0C0B", strlen("PNP0C0B"))) |
351 | name = "Fan"; | ||
352 | else | ||
353 | name = acpi_device_bid(device); | ||
354 | |||
355 | cdev = thermal_cooling_device_register(name, device, | ||
350 | &fan_cooling_ops); | 356 | &fan_cooling_ops); |
351 | if (IS_ERR(cdev)) { | 357 | if (IS_ERR(cdev)) { |
352 | result = PTR_ERR(cdev); | 358 | result = PTR_ERR(cdev); |
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 447f6d679b29..163e82f536fa 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
@@ -173,4 +173,10 @@ static inline void suspend_nvs_restore(void) {} | |||
173 | bool acpi_osi_is_win8(void); | 173 | bool acpi_osi_is_win8(void); |
174 | #endif | 174 | #endif |
175 | 175 | ||
176 | /*-------------------------------------------------------------------------- | ||
177 | Device properties | ||
178 | -------------------------------------------------------------------------- */ | ||
179 | void acpi_init_properties(struct acpi_device *adev); | ||
180 | void acpi_free_properties(struct acpi_device *adev); | ||
181 | |||
176 | #endif /* _ACPI_INTERNAL_H_ */ | 182 | #endif /* _ACPI_INTERNAL_H_ */ |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 9964f70be98d..f9eeae871593 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -436,7 +436,7 @@ static void acpi_os_drop_map_ref(struct acpi_ioremap *map) | |||
436 | static void acpi_os_map_cleanup(struct acpi_ioremap *map) | 436 | static void acpi_os_map_cleanup(struct acpi_ioremap *map) |
437 | { | 437 | { |
438 | if (!map->refcount) { | 438 | if (!map->refcount) { |
439 | synchronize_rcu(); | 439 | synchronize_rcu_expedited(); |
440 | acpi_unmap(map->phys, map->virt); | 440 | acpi_unmap(map->phys, map->virt); |
441 | kfree(map); | 441 | kfree(map); |
442 | } | 442 | } |
@@ -1188,6 +1188,12 @@ EXPORT_SYMBOL(acpi_os_execute); | |||
1188 | 1188 | ||
1189 | void acpi_os_wait_events_complete(void) | 1189 | void acpi_os_wait_events_complete(void) |
1190 | { | 1190 | { |
1191 | /* | ||
1192 | * Make sure the GPE handler or the fixed event handler is not used | ||
1193 | * on another CPU after removal. | ||
1194 | */ | ||
1195 | if (acpi_irq_handler) | ||
1196 | synchronize_hardirq(acpi_gbl_FADT.sci_interrupt); | ||
1191 | flush_workqueue(kacpid_wq); | 1197 | flush_workqueue(kacpid_wq); |
1192 | flush_workqueue(kacpi_notify_wq); | 1198 | flush_workqueue(kacpi_notify_wq); |
1193 | } | 1199 | } |
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 6e6b80eb0bba..7cc4e33179f9 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c | |||
@@ -484,7 +484,7 @@ void acpi_pci_irq_disable(struct pci_dev *dev) | |||
484 | /* Keep IOAPIC pin configuration when suspending */ | 484 | /* Keep IOAPIC pin configuration when suspending */ |
485 | if (dev->dev.power.is_prepared) | 485 | if (dev->dev.power.is_prepared) |
486 | return; | 486 | return; |
487 | #ifdef CONFIG_PM_RUNTIME | 487 | #ifdef CONFIG_PM |
488 | if (dev->dev.power.runtime_status == RPM_SUSPENDING) | 488 | if (dev->dev.power.runtime_status == RPM_SUSPENDING) |
489 | return; | 489 | return; |
490 | #endif | 490 | #endif |
diff --git a/drivers/acpi/pmic/intel_pmic.c b/drivers/acpi/pmic/intel_pmic.c new file mode 100644 index 000000000000..a732e5d7e322 --- /dev/null +++ b/drivers/acpi/pmic/intel_pmic.c | |||
@@ -0,0 +1,354 @@ | |||
1 | /* | ||
2 | * intel_pmic.c - Intel PMIC operation region driver | ||
3 | * | ||
4 | * Copyright (C) 2014 Intel Corporation. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License version | ||
8 | * 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/module.h> | ||
17 | #include <linux/acpi.h> | ||
18 | #include <linux/regmap.h> | ||
19 | #include "intel_pmic.h" | ||
20 | |||
21 | #define PMIC_POWER_OPREGION_ID 0x8d | ||
22 | #define PMIC_THERMAL_OPREGION_ID 0x8c | ||
23 | |||
24 | struct acpi_lpat { | ||
25 | int temp; | ||
26 | int raw; | ||
27 | }; | ||
28 | |||
29 | struct intel_pmic_opregion { | ||
30 | struct mutex lock; | ||
31 | struct acpi_lpat *lpat; | ||
32 | int lpat_count; | ||
33 | struct regmap *regmap; | ||
34 | struct intel_pmic_opregion_data *data; | ||
35 | }; | ||
36 | |||
37 | static int pmic_get_reg_bit(int address, struct pmic_table *table, | ||
38 | int count, int *reg, int *bit) | ||
39 | { | ||
40 | int i; | ||
41 | |||
42 | for (i = 0; i < count; i++) { | ||
43 | if (table[i].address == address) { | ||
44 | *reg = table[i].reg; | ||
45 | if (bit) | ||
46 | *bit = table[i].bit; | ||
47 | return 0; | ||
48 | } | ||
49 | } | ||
50 | return -ENOENT; | ||
51 | } | ||
52 | |||
53 | /** | ||
54 | * raw_to_temp(): Return temperature from raw value through LPAT table | ||
55 | * | ||
56 | * @lpat: the temperature_raw mapping table | ||
57 | * @count: the count of the above mapping table | ||
58 | * @raw: the raw value, used as a key to get the temerature from the | ||
59 | * above mapping table | ||
60 | * | ||
61 | * A positive value will be returned on success, a negative errno will | ||
62 | * be returned in error cases. | ||
63 | */ | ||
64 | static int raw_to_temp(struct acpi_lpat *lpat, int count, int raw) | ||
65 | { | ||
66 | int i, delta_temp, delta_raw, temp; | ||
67 | |||
68 | for (i = 0; i < count - 1; i++) { | ||
69 | if ((raw >= lpat[i].raw && raw <= lpat[i+1].raw) || | ||
70 | (raw <= lpat[i].raw && raw >= lpat[i+1].raw)) | ||
71 | break; | ||
72 | } | ||
73 | |||
74 | if (i == count - 1) | ||
75 | return -ENOENT; | ||
76 | |||
77 | delta_temp = lpat[i+1].temp - lpat[i].temp; | ||
78 | delta_raw = lpat[i+1].raw - lpat[i].raw; | ||
79 | temp = lpat[i].temp + (raw - lpat[i].raw) * delta_temp / delta_raw; | ||
80 | |||
81 | return temp; | ||
82 | } | ||
83 | |||
84 | /** | ||
85 | * temp_to_raw(): Return raw value from temperature through LPAT table | ||
86 | * | ||
87 | * @lpat: the temperature_raw mapping table | ||
88 | * @count: the count of the above mapping table | ||
89 | * @temp: the temperature, used as a key to get the raw value from the | ||
90 | * above mapping table | ||
91 | * | ||
92 | * A positive value will be returned on success, a negative errno will | ||
93 | * be returned in error cases. | ||
94 | */ | ||
95 | static int temp_to_raw(struct acpi_lpat *lpat, int count, int temp) | ||
96 | { | ||
97 | int i, delta_temp, delta_raw, raw; | ||
98 | |||
99 | for (i = 0; i < count - 1; i++) { | ||
100 | if (temp >= lpat[i].temp && temp <= lpat[i+1].temp) | ||
101 | break; | ||
102 | } | ||
103 | |||
104 | if (i == count - 1) | ||
105 | return -ENOENT; | ||
106 | |||
107 | delta_temp = lpat[i+1].temp - lpat[i].temp; | ||
108 | delta_raw = lpat[i+1].raw - lpat[i].raw; | ||
109 | raw = lpat[i].raw + (temp - lpat[i].temp) * delta_raw / delta_temp; | ||
110 | |||
111 | return raw; | ||
112 | } | ||
113 | |||
114 | static void pmic_thermal_lpat(struct intel_pmic_opregion *opregion, | ||
115 | acpi_handle handle, struct device *dev) | ||
116 | { | ||
117 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
118 | union acpi_object *obj_p, *obj_e; | ||
119 | int *lpat, i; | ||
120 | acpi_status status; | ||
121 | |||
122 | status = acpi_evaluate_object(handle, "LPAT", NULL, &buffer); | ||
123 | if (ACPI_FAILURE(status)) | ||
124 | return; | ||
125 | |||
126 | obj_p = (union acpi_object *)buffer.pointer; | ||
127 | if (!obj_p || (obj_p->type != ACPI_TYPE_PACKAGE) || | ||
128 | (obj_p->package.count % 2) || (obj_p->package.count < 4)) | ||
129 | goto out; | ||
130 | |||
131 | lpat = devm_kmalloc(dev, sizeof(int) * obj_p->package.count, | ||
132 | GFP_KERNEL); | ||
133 | if (!lpat) | ||
134 | goto out; | ||
135 | |||
136 | for (i = 0; i < obj_p->package.count; i++) { | ||
137 | obj_e = &obj_p->package.elements[i]; | ||
138 | if (obj_e->type != ACPI_TYPE_INTEGER) { | ||
139 | devm_kfree(dev, lpat); | ||
140 | goto out; | ||
141 | } | ||
142 | lpat[i] = (s64)obj_e->integer.value; | ||
143 | } | ||
144 | |||
145 | opregion->lpat = (struct acpi_lpat *)lpat; | ||
146 | opregion->lpat_count = obj_p->package.count / 2; | ||
147 | |||
148 | out: | ||
149 | kfree(buffer.pointer); | ||
150 | } | ||
151 | |||
152 | static acpi_status intel_pmic_power_handler(u32 function, | ||
153 | acpi_physical_address address, u32 bits, u64 *value64, | ||
154 | void *handler_context, void *region_context) | ||
155 | { | ||
156 | struct intel_pmic_opregion *opregion = region_context; | ||
157 | struct regmap *regmap = opregion->regmap; | ||
158 | struct intel_pmic_opregion_data *d = opregion->data; | ||
159 | int reg, bit, result; | ||
160 | |||
161 | if (bits != 32 || !value64) | ||
162 | return AE_BAD_PARAMETER; | ||
163 | |||
164 | if (function == ACPI_WRITE && !(*value64 == 0 || *value64 == 1)) | ||
165 | return AE_BAD_PARAMETER; | ||
166 | |||
167 | result = pmic_get_reg_bit(address, d->power_table, | ||
168 | d->power_table_count, ®, &bit); | ||
169 | if (result == -ENOENT) | ||
170 | return AE_BAD_PARAMETER; | ||
171 | |||
172 | mutex_lock(&opregion->lock); | ||
173 | |||
174 | result = function == ACPI_READ ? | ||
175 | d->get_power(regmap, reg, bit, value64) : | ||
176 | d->update_power(regmap, reg, bit, *value64 == 1); | ||
177 | |||
178 | mutex_unlock(&opregion->lock); | ||
179 | |||
180 | return result ? AE_ERROR : AE_OK; | ||
181 | } | ||
182 | |||
183 | static int pmic_read_temp(struct intel_pmic_opregion *opregion, | ||
184 | int reg, u64 *value) | ||
185 | { | ||
186 | int raw_temp, temp; | ||
187 | |||
188 | if (!opregion->data->get_raw_temp) | ||
189 | return -ENXIO; | ||
190 | |||
191 | raw_temp = opregion->data->get_raw_temp(opregion->regmap, reg); | ||
192 | if (raw_temp < 0) | ||
193 | return raw_temp; | ||
194 | |||
195 | if (!opregion->lpat) { | ||
196 | *value = raw_temp; | ||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | temp = raw_to_temp(opregion->lpat, opregion->lpat_count, raw_temp); | ||
201 | if (temp < 0) | ||
202 | return temp; | ||
203 | |||
204 | *value = temp; | ||
205 | return 0; | ||
206 | } | ||
207 | |||
208 | static int pmic_thermal_temp(struct intel_pmic_opregion *opregion, int reg, | ||
209 | u32 function, u64 *value) | ||
210 | { | ||
211 | return function == ACPI_READ ? | ||
212 | pmic_read_temp(opregion, reg, value) : -EINVAL; | ||
213 | } | ||
214 | |||
215 | static int pmic_thermal_aux(struct intel_pmic_opregion *opregion, int reg, | ||
216 | u32 function, u64 *value) | ||
217 | { | ||
218 | int raw_temp; | ||
219 | |||
220 | if (function == ACPI_READ) | ||
221 | return pmic_read_temp(opregion, reg, value); | ||
222 | |||
223 | if (!opregion->data->update_aux) | ||
224 | return -ENXIO; | ||
225 | |||
226 | if (opregion->lpat) { | ||
227 | raw_temp = temp_to_raw(opregion->lpat, opregion->lpat_count, | ||
228 | *value); | ||
229 | if (raw_temp < 0) | ||
230 | return raw_temp; | ||
231 | } else { | ||
232 | raw_temp = *value; | ||
233 | } | ||
234 | |||
235 | return opregion->data->update_aux(opregion->regmap, reg, raw_temp); | ||
236 | } | ||
237 | |||
238 | static int pmic_thermal_pen(struct intel_pmic_opregion *opregion, int reg, | ||
239 | u32 function, u64 *value) | ||
240 | { | ||
241 | struct intel_pmic_opregion_data *d = opregion->data; | ||
242 | struct regmap *regmap = opregion->regmap; | ||
243 | |||
244 | if (!d->get_policy || !d->update_policy) | ||
245 | return -ENXIO; | ||
246 | |||
247 | if (function == ACPI_READ) | ||
248 | return d->get_policy(regmap, reg, value); | ||
249 | |||
250 | if (*value != 0 && *value != 1) | ||
251 | return -EINVAL; | ||
252 | |||
253 | return d->update_policy(regmap, reg, *value); | ||
254 | } | ||
255 | |||
256 | static bool pmic_thermal_is_temp(int address) | ||
257 | { | ||
258 | return (address <= 0x3c) && !(address % 12); | ||
259 | } | ||
260 | |||
261 | static bool pmic_thermal_is_aux(int address) | ||
262 | { | ||
263 | return (address >= 4 && address <= 0x40 && !((address - 4) % 12)) || | ||
264 | (address >= 8 && address <= 0x44 && !((address - 8) % 12)); | ||
265 | } | ||
266 | |||
267 | static bool pmic_thermal_is_pen(int address) | ||
268 | { | ||
269 | return address >= 0x48 && address <= 0x5c; | ||
270 | } | ||
271 | |||
272 | static acpi_status intel_pmic_thermal_handler(u32 function, | ||
273 | acpi_physical_address address, u32 bits, u64 *value64, | ||
274 | void *handler_context, void *region_context) | ||
275 | { | ||
276 | struct intel_pmic_opregion *opregion = region_context; | ||
277 | struct intel_pmic_opregion_data *d = opregion->data; | ||
278 | int reg, result; | ||
279 | |||
280 | if (bits != 32 || !value64) | ||
281 | return AE_BAD_PARAMETER; | ||
282 | |||
283 | result = pmic_get_reg_bit(address, d->thermal_table, | ||
284 | d->thermal_table_count, ®, NULL); | ||
285 | if (result == -ENOENT) | ||
286 | return AE_BAD_PARAMETER; | ||
287 | |||
288 | mutex_lock(&opregion->lock); | ||
289 | |||
290 | if (pmic_thermal_is_temp(address)) | ||
291 | result = pmic_thermal_temp(opregion, reg, function, value64); | ||
292 | else if (pmic_thermal_is_aux(address)) | ||
293 | result = pmic_thermal_aux(opregion, reg, function, value64); | ||
294 | else if (pmic_thermal_is_pen(address)) | ||
295 | result = pmic_thermal_pen(opregion, reg, function, value64); | ||
296 | else | ||
297 | result = -EINVAL; | ||
298 | |||
299 | mutex_unlock(&opregion->lock); | ||
300 | |||
301 | if (result < 0) { | ||
302 | if (result == -EINVAL) | ||
303 | return AE_BAD_PARAMETER; | ||
304 | else | ||
305 | return AE_ERROR; | ||
306 | } | ||
307 | |||
308 | return AE_OK; | ||
309 | } | ||
310 | |||
311 | int intel_pmic_install_opregion_handler(struct device *dev, acpi_handle handle, | ||
312 | struct regmap *regmap, | ||
313 | struct intel_pmic_opregion_data *d) | ||
314 | { | ||
315 | acpi_status status; | ||
316 | struct intel_pmic_opregion *opregion; | ||
317 | |||
318 | if (!dev || !regmap || !d) | ||
319 | return -EINVAL; | ||
320 | |||
321 | if (!handle) | ||
322 | return -ENODEV; | ||
323 | |||
324 | opregion = devm_kzalloc(dev, sizeof(*opregion), GFP_KERNEL); | ||
325 | if (!opregion) | ||
326 | return -ENOMEM; | ||
327 | |||
328 | mutex_init(&opregion->lock); | ||
329 | opregion->regmap = regmap; | ||
330 | pmic_thermal_lpat(opregion, handle, dev); | ||
331 | |||
332 | status = acpi_install_address_space_handler(handle, | ||
333 | PMIC_POWER_OPREGION_ID, | ||
334 | intel_pmic_power_handler, | ||
335 | NULL, opregion); | ||
336 | if (ACPI_FAILURE(status)) | ||
337 | return -ENODEV; | ||
338 | |||
339 | status = acpi_install_address_space_handler(handle, | ||
340 | PMIC_THERMAL_OPREGION_ID, | ||
341 | intel_pmic_thermal_handler, | ||
342 | NULL, opregion); | ||
343 | if (ACPI_FAILURE(status)) { | ||
344 | acpi_remove_address_space_handler(handle, PMIC_POWER_OPREGION_ID, | ||
345 | intel_pmic_power_handler); | ||
346 | return -ENODEV; | ||
347 | } | ||
348 | |||
349 | opregion->data = d; | ||
350 | return 0; | ||
351 | } | ||
352 | EXPORT_SYMBOL_GPL(intel_pmic_install_opregion_handler); | ||
353 | |||
354 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/acpi/pmic/intel_pmic.h b/drivers/acpi/pmic/intel_pmic.h new file mode 100644 index 000000000000..d4e90af8f0dd --- /dev/null +++ b/drivers/acpi/pmic/intel_pmic.h | |||
@@ -0,0 +1,25 @@ | |||
1 | #ifndef __INTEL_PMIC_H | ||
2 | #define __INTEL_PMIC_H | ||
3 | |||
4 | struct pmic_table { | ||
5 | int address; /* operation region address */ | ||
6 | int reg; /* corresponding thermal register */ | ||
7 | int bit; /* control bit for power */ | ||
8 | }; | ||
9 | |||
10 | struct intel_pmic_opregion_data { | ||
11 | int (*get_power)(struct regmap *r, int reg, int bit, u64 *value); | ||
12 | int (*update_power)(struct regmap *r, int reg, int bit, bool on); | ||
13 | int (*get_raw_temp)(struct regmap *r, int reg); | ||
14 | int (*update_aux)(struct regmap *r, int reg, int raw_temp); | ||
15 | int (*get_policy)(struct regmap *r, int reg, u64 *value); | ||
16 | int (*update_policy)(struct regmap *r, int reg, int enable); | ||
17 | struct pmic_table *power_table; | ||
18 | int power_table_count; | ||
19 | struct pmic_table *thermal_table; | ||
20 | int thermal_table_count; | ||
21 | }; | ||
22 | |||
23 | int intel_pmic_install_opregion_handler(struct device *dev, acpi_handle handle, struct regmap *regmap, struct intel_pmic_opregion_data *d); | ||
24 | |||
25 | #endif | ||
diff --git a/drivers/acpi/pmic/intel_pmic_crc.c b/drivers/acpi/pmic/intel_pmic_crc.c new file mode 100644 index 000000000000..ef7d8ff95abe --- /dev/null +++ b/drivers/acpi/pmic/intel_pmic_crc.c | |||
@@ -0,0 +1,211 @@ | |||
1 | /* | ||
2 | * intel_pmic_crc.c - Intel CrystalCove PMIC operation region driver | ||
3 | * | ||
4 | * Copyright (C) 2014 Intel Corporation. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License version | ||
8 | * 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/module.h> | ||
17 | #include <linux/acpi.h> | ||
18 | #include <linux/mfd/intel_soc_pmic.h> | ||
19 | #include <linux/regmap.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include "intel_pmic.h" | ||
22 | |||
23 | #define PWR_SOURCE_SELECT BIT(1) | ||
24 | |||
25 | #define PMIC_A0LOCK_REG 0xc5 | ||
26 | |||
27 | static struct pmic_table power_table[] = { | ||
28 | { | ||
29 | .address = 0x24, | ||
30 | .reg = 0x66, | ||
31 | .bit = 0x00, | ||
32 | }, | ||
33 | { | ||
34 | .address = 0x48, | ||
35 | .reg = 0x5d, | ||
36 | .bit = 0x00, | ||
37 | }, | ||
38 | }; | ||
39 | |||
40 | static struct pmic_table thermal_table[] = { | ||
41 | { | ||
42 | .address = 0x00, | ||
43 | .reg = 0x75 | ||
44 | }, | ||
45 | { | ||
46 | .address = 0x04, | ||
47 | .reg = 0x95 | ||
48 | }, | ||
49 | { | ||
50 | .address = 0x08, | ||
51 | .reg = 0x97 | ||
52 | }, | ||
53 | { | ||
54 | .address = 0x0c, | ||
55 | .reg = 0x77 | ||
56 | }, | ||
57 | { | ||
58 | .address = 0x10, | ||
59 | .reg = 0x9a | ||
60 | }, | ||
61 | { | ||
62 | .address = 0x14, | ||
63 | .reg = 0x9c | ||
64 | }, | ||
65 | { | ||
66 | .address = 0x18, | ||
67 | .reg = 0x79 | ||
68 | }, | ||
69 | { | ||
70 | .address = 0x1c, | ||
71 | .reg = 0x9f | ||
72 | }, | ||
73 | { | ||
74 | .address = 0x20, | ||
75 | .reg = 0xa1 | ||
76 | }, | ||
77 | { | ||
78 | .address = 0x48, | ||
79 | .reg = 0x94 | ||
80 | }, | ||
81 | { | ||
82 | .address = 0x4c, | ||
83 | .reg = 0x99 | ||
84 | }, | ||
85 | { | ||
86 | .address = 0x50, | ||
87 | .reg = 0x9e | ||
88 | }, | ||
89 | }; | ||
90 | |||
91 | static int intel_crc_pmic_get_power(struct regmap *regmap, int reg, | ||
92 | int bit, u64 *value) | ||
93 | { | ||
94 | int data; | ||
95 | |||
96 | if (regmap_read(regmap, reg, &data)) | ||
97 | return -EIO; | ||
98 | |||
99 | *value = (data & PWR_SOURCE_SELECT) && (data & BIT(bit)) ? 1 : 0; | ||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | static int intel_crc_pmic_update_power(struct regmap *regmap, int reg, | ||
104 | int bit, bool on) | ||
105 | { | ||
106 | int data; | ||
107 | |||
108 | if (regmap_read(regmap, reg, &data)) | ||
109 | return -EIO; | ||
110 | |||
111 | if (on) { | ||
112 | data |= PWR_SOURCE_SELECT | BIT(bit); | ||
113 | } else { | ||
114 | data &= ~BIT(bit); | ||
115 | data |= PWR_SOURCE_SELECT; | ||
116 | } | ||
117 | |||
118 | if (regmap_write(regmap, reg, data)) | ||
119 | return -EIO; | ||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | static int intel_crc_pmic_get_raw_temp(struct regmap *regmap, int reg) | ||
124 | { | ||
125 | int temp_l, temp_h; | ||
126 | |||
127 | /* | ||
128 | * Raw temperature value is 10bits: 8bits in reg | ||
129 | * and 2bits in reg-1: bit0,1 | ||
130 | */ | ||
131 | if (regmap_read(regmap, reg, &temp_l) || | ||
132 | regmap_read(regmap, reg - 1, &temp_h)) | ||
133 | return -EIO; | ||
134 | |||
135 | return temp_l | (temp_h & 0x3) << 8; | ||
136 | } | ||
137 | |||
138 | static int intel_crc_pmic_update_aux(struct regmap *regmap, int reg, int raw) | ||
139 | { | ||
140 | return regmap_write(regmap, reg, raw) || | ||
141 | regmap_update_bits(regmap, reg - 1, 0x3, raw >> 8) ? -EIO : 0; | ||
142 | } | ||
143 | |||
144 | static int intel_crc_pmic_get_policy(struct regmap *regmap, int reg, u64 *value) | ||
145 | { | ||
146 | int pen; | ||
147 | |||
148 | if (regmap_read(regmap, reg, &pen)) | ||
149 | return -EIO; | ||
150 | *value = pen >> 7; | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | static int intel_crc_pmic_update_policy(struct regmap *regmap, | ||
155 | int reg, int enable) | ||
156 | { | ||
157 | int alert0; | ||
158 | |||
159 | /* Update to policy enable bit requires unlocking a0lock */ | ||
160 | if (regmap_read(regmap, PMIC_A0LOCK_REG, &alert0)) | ||
161 | return -EIO; | ||
162 | |||
163 | if (regmap_update_bits(regmap, PMIC_A0LOCK_REG, 0x01, 0)) | ||
164 | return -EIO; | ||
165 | |||
166 | if (regmap_update_bits(regmap, reg, 0x80, enable << 7)) | ||
167 | return -EIO; | ||
168 | |||
169 | /* restore alert0 */ | ||
170 | if (regmap_write(regmap, PMIC_A0LOCK_REG, alert0)) | ||
171 | return -EIO; | ||
172 | |||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | static struct intel_pmic_opregion_data intel_crc_pmic_opregion_data = { | ||
177 | .get_power = intel_crc_pmic_get_power, | ||
178 | .update_power = intel_crc_pmic_update_power, | ||
179 | .get_raw_temp = intel_crc_pmic_get_raw_temp, | ||
180 | .update_aux = intel_crc_pmic_update_aux, | ||
181 | .get_policy = intel_crc_pmic_get_policy, | ||
182 | .update_policy = intel_crc_pmic_update_policy, | ||
183 | .power_table = power_table, | ||
184 | .power_table_count= ARRAY_SIZE(power_table), | ||
185 | .thermal_table = thermal_table, | ||
186 | .thermal_table_count = ARRAY_SIZE(thermal_table), | ||
187 | }; | ||
188 | |||
189 | static int intel_crc_pmic_opregion_probe(struct platform_device *pdev) | ||
190 | { | ||
191 | struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent); | ||
192 | return intel_pmic_install_opregion_handler(&pdev->dev, | ||
193 | ACPI_HANDLE(pdev->dev.parent), pmic->regmap, | ||
194 | &intel_crc_pmic_opregion_data); | ||
195 | } | ||
196 | |||
197 | static struct platform_driver intel_crc_pmic_opregion_driver = { | ||
198 | .probe = intel_crc_pmic_opregion_probe, | ||
199 | .driver = { | ||
200 | .name = "crystal_cove_pmic", | ||
201 | }, | ||
202 | }; | ||
203 | |||
204 | static int __init intel_crc_pmic_opregion_driver_init(void) | ||
205 | { | ||
206 | return platform_driver_register(&intel_crc_pmic_opregion_driver); | ||
207 | } | ||
208 | module_init(intel_crc_pmic_opregion_driver_init); | ||
209 | |||
210 | MODULE_DESCRIPTION("CrystalCove ACPI opration region driver"); | ||
211 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/acpi/pmic/intel_pmic_xpower.c b/drivers/acpi/pmic/intel_pmic_xpower.c new file mode 100644 index 000000000000..6a082d4de12c --- /dev/null +++ b/drivers/acpi/pmic/intel_pmic_xpower.c | |||
@@ -0,0 +1,268 @@ | |||
1 | /* | ||
2 | * intel_pmic_xpower.c - XPower AXP288 PMIC operation region driver | ||
3 | * | ||
4 | * Copyright (C) 2014 Intel Corporation. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License version | ||
8 | * 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/module.h> | ||
17 | #include <linux/acpi.h> | ||
18 | #include <linux/mfd/axp20x.h> | ||
19 | #include <linux/regmap.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/iio/consumer.h> | ||
22 | #include "intel_pmic.h" | ||
23 | |||
24 | #define XPOWER_GPADC_LOW 0x5b | ||
25 | |||
26 | static struct pmic_table power_table[] = { | ||
27 | { | ||
28 | .address = 0x00, | ||
29 | .reg = 0x13, | ||
30 | .bit = 0x05, | ||
31 | }, | ||
32 | { | ||
33 | .address = 0x04, | ||
34 | .reg = 0x13, | ||
35 | .bit = 0x06, | ||
36 | }, | ||
37 | { | ||
38 | .address = 0x08, | ||
39 | .reg = 0x13, | ||
40 | .bit = 0x07, | ||
41 | }, | ||
42 | { | ||
43 | .address = 0x0c, | ||
44 | .reg = 0x12, | ||
45 | .bit = 0x03, | ||
46 | }, | ||
47 | { | ||
48 | .address = 0x10, | ||
49 | .reg = 0x12, | ||
50 | .bit = 0x04, | ||
51 | }, | ||
52 | { | ||
53 | .address = 0x14, | ||
54 | .reg = 0x12, | ||
55 | .bit = 0x05, | ||
56 | }, | ||
57 | { | ||
58 | .address = 0x18, | ||
59 | .reg = 0x12, | ||
60 | .bit = 0x06, | ||
61 | }, | ||
62 | { | ||
63 | .address = 0x1c, | ||
64 | .reg = 0x12, | ||
65 | .bit = 0x00, | ||
66 | }, | ||
67 | { | ||
68 | .address = 0x20, | ||
69 | .reg = 0x12, | ||
70 | .bit = 0x01, | ||
71 | }, | ||
72 | { | ||
73 | .address = 0x24, | ||
74 | .reg = 0x12, | ||
75 | .bit = 0x02, | ||
76 | }, | ||
77 | { | ||
78 | .address = 0x28, | ||
79 | .reg = 0x13, | ||
80 | .bit = 0x02, | ||
81 | }, | ||
82 | { | ||
83 | .address = 0x2c, | ||
84 | .reg = 0x13, | ||
85 | .bit = 0x03, | ||
86 | }, | ||
87 | { | ||
88 | .address = 0x30, | ||
89 | .reg = 0x13, | ||
90 | .bit = 0x04, | ||
91 | }, | ||
92 | { | ||
93 | .address = 0x38, | ||
94 | .reg = 0x10, | ||
95 | .bit = 0x03, | ||
96 | }, | ||
97 | { | ||
98 | .address = 0x3c, | ||
99 | .reg = 0x10, | ||
100 | .bit = 0x06, | ||
101 | }, | ||
102 | { | ||
103 | .address = 0x40, | ||
104 | .reg = 0x10, | ||
105 | .bit = 0x05, | ||
106 | }, | ||
107 | { | ||
108 | .address = 0x44, | ||
109 | .reg = 0x10, | ||
110 | .bit = 0x04, | ||
111 | }, | ||
112 | { | ||
113 | .address = 0x48, | ||
114 | .reg = 0x10, | ||
115 | .bit = 0x01, | ||
116 | }, | ||
117 | { | ||
118 | .address = 0x4c, | ||
119 | .reg = 0x10, | ||
120 | .bit = 0x00 | ||
121 | }, | ||
122 | }; | ||
123 | |||
124 | /* TMP0 - TMP5 are the same, all from GPADC */ | ||
125 | static struct pmic_table thermal_table[] = { | ||
126 | { | ||
127 | .address = 0x00, | ||
128 | .reg = XPOWER_GPADC_LOW | ||
129 | }, | ||
130 | { | ||
131 | .address = 0x0c, | ||
132 | .reg = XPOWER_GPADC_LOW | ||
133 | }, | ||
134 | { | ||
135 | .address = 0x18, | ||
136 | .reg = XPOWER_GPADC_LOW | ||
137 | }, | ||
138 | { | ||
139 | .address = 0x24, | ||
140 | .reg = XPOWER_GPADC_LOW | ||
141 | }, | ||
142 | { | ||
143 | .address = 0x30, | ||
144 | .reg = XPOWER_GPADC_LOW | ||
145 | }, | ||
146 | { | ||
147 | .address = 0x3c, | ||
148 | .reg = XPOWER_GPADC_LOW | ||
149 | }, | ||
150 | }; | ||
151 | |||
152 | static int intel_xpower_pmic_get_power(struct regmap *regmap, int reg, | ||
153 | int bit, u64 *value) | ||
154 | { | ||
155 | int data; | ||
156 | |||
157 | if (regmap_read(regmap, reg, &data)) | ||
158 | return -EIO; | ||
159 | |||
160 | *value = (data & BIT(bit)) ? 1 : 0; | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | static int intel_xpower_pmic_update_power(struct regmap *regmap, int reg, | ||
165 | int bit, bool on) | ||
166 | { | ||
167 | int data; | ||
168 | |||
169 | if (regmap_read(regmap, reg, &data)) | ||
170 | return -EIO; | ||
171 | |||
172 | if (on) | ||
173 | data |= BIT(bit); | ||
174 | else | ||
175 | data &= ~BIT(bit); | ||
176 | |||
177 | if (regmap_write(regmap, reg, data)) | ||
178 | return -EIO; | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | /** | ||
184 | * intel_xpower_pmic_get_raw_temp(): Get raw temperature reading from the PMIC | ||
185 | * | ||
186 | * @regmap: regmap of the PMIC device | ||
187 | * @reg: register to get the reading | ||
188 | * | ||
189 | * We could get the sensor value by manipulating the HW regs here, but since | ||
190 | * the axp288 IIO driver may also access the same regs at the same time, the | ||
191 | * APIs provided by IIO subsystem are used here instead to avoid problems. As | ||
192 | * a result, the two passed in params are of no actual use. | ||
193 | * | ||
194 | * Return a positive value on success, errno on failure. | ||
195 | */ | ||
196 | static int intel_xpower_pmic_get_raw_temp(struct regmap *regmap, int reg) | ||
197 | { | ||
198 | struct iio_channel *gpadc_chan; | ||
199 | int ret, val; | ||
200 | |||
201 | gpadc_chan = iio_channel_get(NULL, "axp288-system-temp"); | ||
202 | if (IS_ERR_OR_NULL(gpadc_chan)) | ||
203 | return -EACCES; | ||
204 | |||
205 | ret = iio_read_channel_raw(gpadc_chan, &val); | ||
206 | if (ret < 0) | ||
207 | val = ret; | ||
208 | |||
209 | iio_channel_release(gpadc_chan); | ||
210 | return val; | ||
211 | } | ||
212 | |||
213 | static struct intel_pmic_opregion_data intel_xpower_pmic_opregion_data = { | ||
214 | .get_power = intel_xpower_pmic_get_power, | ||
215 | .update_power = intel_xpower_pmic_update_power, | ||
216 | .get_raw_temp = intel_xpower_pmic_get_raw_temp, | ||
217 | .power_table = power_table, | ||
218 | .power_table_count = ARRAY_SIZE(power_table), | ||
219 | .thermal_table = thermal_table, | ||
220 | .thermal_table_count = ARRAY_SIZE(thermal_table), | ||
221 | }; | ||
222 | |||
223 | static acpi_status intel_xpower_pmic_gpio_handler(u32 function, | ||
224 | acpi_physical_address address, u32 bit_width, u64 *value, | ||
225 | void *handler_context, void *region_context) | ||
226 | { | ||
227 | return AE_OK; | ||
228 | } | ||
229 | |||
230 | static int intel_xpower_pmic_opregion_probe(struct platform_device *pdev) | ||
231 | { | ||
232 | struct device *parent = pdev->dev.parent; | ||
233 | struct axp20x_dev *axp20x = dev_get_drvdata(parent); | ||
234 | acpi_status status; | ||
235 | int result; | ||
236 | |||
237 | status = acpi_install_address_space_handler(ACPI_HANDLE(parent), | ||
238 | ACPI_ADR_SPACE_GPIO, intel_xpower_pmic_gpio_handler, | ||
239 | NULL, NULL); | ||
240 | if (ACPI_FAILURE(status)) | ||
241 | return -ENODEV; | ||
242 | |||
243 | result = intel_pmic_install_opregion_handler(&pdev->dev, | ||
244 | ACPI_HANDLE(parent), axp20x->regmap, | ||
245 | &intel_xpower_pmic_opregion_data); | ||
246 | if (result) | ||
247 | acpi_remove_address_space_handler(ACPI_HANDLE(parent), | ||
248 | ACPI_ADR_SPACE_GPIO, | ||
249 | intel_xpower_pmic_gpio_handler); | ||
250 | |||
251 | return result; | ||
252 | } | ||
253 | |||
254 | static struct platform_driver intel_xpower_pmic_opregion_driver = { | ||
255 | .probe = intel_xpower_pmic_opregion_probe, | ||
256 | .driver = { | ||
257 | .name = "axp288_pmic_acpi", | ||
258 | }, | ||
259 | }; | ||
260 | |||
261 | static int __init intel_xpower_pmic_opregion_driver_init(void) | ||
262 | { | ||
263 | return platform_driver_register(&intel_xpower_pmic_opregion_driver); | ||
264 | } | ||
265 | module_init(intel_xpower_pmic_opregion_driver_init); | ||
266 | |||
267 | MODULE_DESCRIPTION("XPower AXP288 ACPI operation region driver"); | ||
268 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 17f9ec501972..499536504698 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -334,10 +334,10 @@ static int acpi_processor_get_power_info_default(struct acpi_processor *pr) | |||
334 | 334 | ||
335 | static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) | 335 | static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) |
336 | { | 336 | { |
337 | acpi_status status = 0; | 337 | acpi_status status; |
338 | u64 count; | 338 | u64 count; |
339 | int current_count; | 339 | int current_count; |
340 | int i; | 340 | int i, ret = 0; |
341 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 341 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
342 | union acpi_object *cst; | 342 | union acpi_object *cst; |
343 | 343 | ||
@@ -358,7 +358,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) | |||
358 | /* There must be at least 2 elements */ | 358 | /* There must be at least 2 elements */ |
359 | if (!cst || (cst->type != ACPI_TYPE_PACKAGE) || cst->package.count < 2) { | 359 | if (!cst || (cst->type != ACPI_TYPE_PACKAGE) || cst->package.count < 2) { |
360 | printk(KERN_ERR PREFIX "not enough elements in _CST\n"); | 360 | printk(KERN_ERR PREFIX "not enough elements in _CST\n"); |
361 | status = -EFAULT; | 361 | ret = -EFAULT; |
362 | goto end; | 362 | goto end; |
363 | } | 363 | } |
364 | 364 | ||
@@ -367,7 +367,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) | |||
367 | /* Validate number of power states. */ | 367 | /* Validate number of power states. */ |
368 | if (count < 1 || count != cst->package.count - 1) { | 368 | if (count < 1 || count != cst->package.count - 1) { |
369 | printk(KERN_ERR PREFIX "count given by _CST is not valid\n"); | 369 | printk(KERN_ERR PREFIX "count given by _CST is not valid\n"); |
370 | status = -EFAULT; | 370 | ret = -EFAULT; |
371 | goto end; | 371 | goto end; |
372 | } | 372 | } |
373 | 373 | ||
@@ -489,12 +489,12 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) | |||
489 | 489 | ||
490 | /* Validate number of power states discovered */ | 490 | /* Validate number of power states discovered */ |
491 | if (current_count < 2) | 491 | if (current_count < 2) |
492 | status = -EFAULT; | 492 | ret = -EFAULT; |
493 | 493 | ||
494 | end: | 494 | end: |
495 | kfree(buffer.pointer); | 495 | kfree(buffer.pointer); |
496 | 496 | ||
497 | return status; | 497 | return ret; |
498 | } | 498 | } |
499 | 499 | ||
500 | static void acpi_processor_power_verify_c3(struct acpi_processor *pr, | 500 | static void acpi_processor_power_verify_c3(struct acpi_processor *pr, |
@@ -985,8 +985,8 @@ static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr) | |||
985 | state->flags = 0; | 985 | state->flags = 0; |
986 | switch (cx->type) { | 986 | switch (cx->type) { |
987 | case ACPI_STATE_C1: | 987 | case ACPI_STATE_C1: |
988 | if (cx->entry_method == ACPI_CSTATE_FFH) | 988 | if (cx->entry_method != ACPI_CSTATE_FFH) |
989 | state->flags |= CPUIDLE_FLAG_TIME_VALID; | 989 | state->flags |= CPUIDLE_FLAG_TIME_INVALID; |
990 | 990 | ||
991 | state->enter = acpi_idle_enter_c1; | 991 | state->enter = acpi_idle_enter_c1; |
992 | state->enter_dead = acpi_idle_play_dead; | 992 | state->enter_dead = acpi_idle_play_dead; |
@@ -994,14 +994,12 @@ static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr) | |||
994 | break; | 994 | break; |
995 | 995 | ||
996 | case ACPI_STATE_C2: | 996 | case ACPI_STATE_C2: |
997 | state->flags |= CPUIDLE_FLAG_TIME_VALID; | ||
998 | state->enter = acpi_idle_enter_simple; | 997 | state->enter = acpi_idle_enter_simple; |
999 | state->enter_dead = acpi_idle_play_dead; | 998 | state->enter_dead = acpi_idle_play_dead; |
1000 | drv->safe_state_index = count; | 999 | drv->safe_state_index = count; |
1001 | break; | 1000 | break; |
1002 | 1001 | ||
1003 | case ACPI_STATE_C3: | 1002 | case ACPI_STATE_C3: |
1004 | state->flags |= CPUIDLE_FLAG_TIME_VALID; | ||
1005 | state->enter = pr->flags.bm_check ? | 1003 | state->enter = pr->flags.bm_check ? |
1006 | acpi_idle_enter_bm : | 1004 | acpi_idle_enter_bm : |
1007 | acpi_idle_enter_simple; | 1005 | acpi_idle_enter_simple; |
@@ -1111,7 +1109,7 @@ static int acpi_processor_registered; | |||
1111 | 1109 | ||
1112 | int acpi_processor_power_init(struct acpi_processor *pr) | 1110 | int acpi_processor_power_init(struct acpi_processor *pr) |
1113 | { | 1111 | { |
1114 | acpi_status status = 0; | 1112 | acpi_status status; |
1115 | int retval; | 1113 | int retval; |
1116 | struct cpuidle_device *dev; | 1114 | struct cpuidle_device *dev; |
1117 | static int first_run; | 1115 | static int first_run; |
diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c new file mode 100644 index 000000000000..0d083736e25b --- /dev/null +++ b/drivers/acpi/property.c | |||
@@ -0,0 +1,551 @@ | |||
1 | /* | ||
2 | * ACPI device specific properties support. | ||
3 | * | ||
4 | * Copyright (C) 2014, Intel Corporation | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Authors: Mika Westerberg <mika.westerberg@linux.intel.com> | ||
8 | * Darren Hart <dvhart@linux.intel.com> | ||
9 | * Rafael J. Wysocki <rafael.j.wysocki@intel.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #include <linux/acpi.h> | ||
17 | #include <linux/device.h> | ||
18 | #include <linux/export.h> | ||
19 | |||
20 | #include "internal.h" | ||
21 | |||
22 | /* ACPI _DSD device properties UUID: daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */ | ||
23 | static const u8 prp_uuid[16] = { | ||
24 | 0x14, 0xd8, 0xff, 0xda, 0xba, 0x6e, 0x8c, 0x4d, | ||
25 | 0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01 | ||
26 | }; | ||
27 | |||
28 | static bool acpi_property_value_ok(const union acpi_object *value) | ||
29 | { | ||
30 | int j; | ||
31 | |||
32 | /* | ||
33 | * The value must be an integer, a string, a reference, or a package | ||
34 | * whose every element must be an integer, a string, or a reference. | ||
35 | */ | ||
36 | switch (value->type) { | ||
37 | case ACPI_TYPE_INTEGER: | ||
38 | case ACPI_TYPE_STRING: | ||
39 | case ACPI_TYPE_LOCAL_REFERENCE: | ||
40 | return true; | ||
41 | |||
42 | case ACPI_TYPE_PACKAGE: | ||
43 | for (j = 0; j < value->package.count; j++) | ||
44 | switch (value->package.elements[j].type) { | ||
45 | case ACPI_TYPE_INTEGER: | ||
46 | case ACPI_TYPE_STRING: | ||
47 | case ACPI_TYPE_LOCAL_REFERENCE: | ||
48 | continue; | ||
49 | |||
50 | default: | ||
51 | return false; | ||
52 | } | ||
53 | |||
54 | return true; | ||
55 | } | ||
56 | return false; | ||
57 | } | ||
58 | |||
59 | static bool acpi_properties_format_valid(const union acpi_object *properties) | ||
60 | { | ||
61 | int i; | ||
62 | |||
63 | for (i = 0; i < properties->package.count; i++) { | ||
64 | const union acpi_object *property; | ||
65 | |||
66 | property = &properties->package.elements[i]; | ||
67 | /* | ||
68 | * Only two elements allowed, the first one must be a string and | ||
69 | * the second one has to satisfy certain conditions. | ||
70 | */ | ||
71 | if (property->package.count != 2 | ||
72 | || property->package.elements[0].type != ACPI_TYPE_STRING | ||
73 | || !acpi_property_value_ok(&property->package.elements[1])) | ||
74 | return false; | ||
75 | } | ||
76 | return true; | ||
77 | } | ||
78 | |||
79 | static void acpi_init_of_compatible(struct acpi_device *adev) | ||
80 | { | ||
81 | const union acpi_object *of_compatible; | ||
82 | struct acpi_hardware_id *hwid; | ||
83 | bool acpi_of = false; | ||
84 | int ret; | ||
85 | |||
86 | /* | ||
87 | * Check if the special PRP0001 ACPI ID is present and in that | ||
88 | * case we fill in Device Tree compatible properties for this | ||
89 | * device. | ||
90 | */ | ||
91 | list_for_each_entry(hwid, &adev->pnp.ids, list) { | ||
92 | if (!strcmp(hwid->id, "PRP0001")) { | ||
93 | acpi_of = true; | ||
94 | break; | ||
95 | } | ||
96 | } | ||
97 | |||
98 | if (!acpi_of) | ||
99 | return; | ||
100 | |||
101 | ret = acpi_dev_get_property_array(adev, "compatible", ACPI_TYPE_STRING, | ||
102 | &of_compatible); | ||
103 | if (ret) { | ||
104 | ret = acpi_dev_get_property(adev, "compatible", | ||
105 | ACPI_TYPE_STRING, &of_compatible); | ||
106 | if (ret) { | ||
107 | acpi_handle_warn(adev->handle, | ||
108 | "PRP0001 requires compatible property\n"); | ||
109 | return; | ||
110 | } | ||
111 | } | ||
112 | adev->data.of_compatible = of_compatible; | ||
113 | } | ||
114 | |||
115 | void acpi_init_properties(struct acpi_device *adev) | ||
116 | { | ||
117 | struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER }; | ||
118 | const union acpi_object *desc; | ||
119 | acpi_status status; | ||
120 | int i; | ||
121 | |||
122 | status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL, &buf, | ||
123 | ACPI_TYPE_PACKAGE); | ||
124 | if (ACPI_FAILURE(status)) | ||
125 | return; | ||
126 | |||
127 | desc = buf.pointer; | ||
128 | if (desc->package.count % 2) | ||
129 | goto fail; | ||
130 | |||
131 | /* Look for the device properties UUID. */ | ||
132 | for (i = 0; i < desc->package.count; i += 2) { | ||
133 | const union acpi_object *uuid, *properties; | ||
134 | |||
135 | uuid = &desc->package.elements[i]; | ||
136 | properties = &desc->package.elements[i + 1]; | ||
137 | |||
138 | /* | ||
139 | * The first element must be a UUID and the second one must be | ||
140 | * a package. | ||
141 | */ | ||
142 | if (uuid->type != ACPI_TYPE_BUFFER || uuid->buffer.length != 16 | ||
143 | || properties->type != ACPI_TYPE_PACKAGE) | ||
144 | break; | ||
145 | |||
146 | if (memcmp(uuid->buffer.pointer, prp_uuid, sizeof(prp_uuid))) | ||
147 | continue; | ||
148 | |||
149 | /* | ||
150 | * We found the matching UUID. Now validate the format of the | ||
151 | * package immediately following it. | ||
152 | */ | ||
153 | if (!acpi_properties_format_valid(properties)) | ||
154 | break; | ||
155 | |||
156 | adev->data.pointer = buf.pointer; | ||
157 | adev->data.properties = properties; | ||
158 | |||
159 | acpi_init_of_compatible(adev); | ||
160 | return; | ||
161 | } | ||
162 | |||
163 | fail: | ||
164 | dev_warn(&adev->dev, "Returned _DSD data is not valid, skipping\n"); | ||
165 | ACPI_FREE(buf.pointer); | ||
166 | } | ||
167 | |||
168 | void acpi_free_properties(struct acpi_device *adev) | ||
169 | { | ||
170 | ACPI_FREE((void *)adev->data.pointer); | ||
171 | adev->data.of_compatible = NULL; | ||
172 | adev->data.pointer = NULL; | ||
173 | adev->data.properties = NULL; | ||
174 | } | ||
175 | |||
176 | /** | ||
177 | * acpi_dev_get_property - return an ACPI property with given name | ||
178 | * @adev: ACPI device to get property | ||
179 | * @name: Name of the property | ||
180 | * @type: Expected property type | ||
181 | * @obj: Location to store the property value (if not %NULL) | ||
182 | * | ||
183 | * Look up a property with @name and store a pointer to the resulting ACPI | ||
184 | * object at the location pointed to by @obj if found. | ||
185 | * | ||
186 | * Callers must not attempt to free the returned objects. These objects will be | ||
187 | * freed by the ACPI core automatically during the removal of @adev. | ||
188 | * | ||
189 | * Return: %0 if property with @name has been found (success), | ||
190 | * %-EINVAL if the arguments are invalid, | ||
191 | * %-ENODATA if the property doesn't exist, | ||
192 | * %-EPROTO if the property value type doesn't match @type. | ||
193 | */ | ||
194 | int acpi_dev_get_property(struct acpi_device *adev, const char *name, | ||
195 | acpi_object_type type, const union acpi_object **obj) | ||
196 | { | ||
197 | const union acpi_object *properties; | ||
198 | int i; | ||
199 | |||
200 | if (!adev || !name) | ||
201 | return -EINVAL; | ||
202 | |||
203 | if (!adev->data.pointer || !adev->data.properties) | ||
204 | return -ENODATA; | ||
205 | |||
206 | properties = adev->data.properties; | ||
207 | for (i = 0; i < properties->package.count; i++) { | ||
208 | const union acpi_object *propname, *propvalue; | ||
209 | const union acpi_object *property; | ||
210 | |||
211 | property = &properties->package.elements[i]; | ||
212 | |||
213 | propname = &property->package.elements[0]; | ||
214 | propvalue = &property->package.elements[1]; | ||
215 | |||
216 | if (!strcmp(name, propname->string.pointer)) { | ||
217 | if (type != ACPI_TYPE_ANY && propvalue->type != type) | ||
218 | return -EPROTO; | ||
219 | else if (obj) | ||
220 | *obj = propvalue; | ||
221 | |||
222 | return 0; | ||
223 | } | ||
224 | } | ||
225 | return -ENODATA; | ||
226 | } | ||
227 | EXPORT_SYMBOL_GPL(acpi_dev_get_property); | ||
228 | |||
229 | /** | ||
230 | * acpi_dev_get_property_array - return an ACPI array property with given name | ||
231 | * @adev: ACPI device to get property | ||
232 | * @name: Name of the property | ||
233 | * @type: Expected type of array elements | ||
234 | * @obj: Location to store a pointer to the property value (if not NULL) | ||
235 | * | ||
236 | * Look up an array property with @name and store a pointer to the resulting | ||
237 | * ACPI object at the location pointed to by @obj if found. | ||
238 | * | ||
239 | * Callers must not attempt to free the returned objects. Those objects will be | ||
240 | * freed by the ACPI core automatically during the removal of @adev. | ||
241 | * | ||
242 | * Return: %0 if array property (package) with @name has been found (success), | ||
243 | * %-EINVAL if the arguments are invalid, | ||
244 | * %-ENODATA if the property doesn't exist, | ||
245 | * %-EPROTO if the property is not a package or the type of its elements | ||
246 | * doesn't match @type. | ||
247 | */ | ||
248 | int acpi_dev_get_property_array(struct acpi_device *adev, const char *name, | ||
249 | acpi_object_type type, | ||
250 | const union acpi_object **obj) | ||
251 | { | ||
252 | const union acpi_object *prop; | ||
253 | int ret, i; | ||
254 | |||
255 | ret = acpi_dev_get_property(adev, name, ACPI_TYPE_PACKAGE, &prop); | ||
256 | if (ret) | ||
257 | return ret; | ||
258 | |||
259 | if (type != ACPI_TYPE_ANY) { | ||
260 | /* Check that all elements are of correct type. */ | ||
261 | for (i = 0; i < prop->package.count; i++) | ||
262 | if (prop->package.elements[i].type != type) | ||
263 | return -EPROTO; | ||
264 | } | ||
265 | if (obj) | ||
266 | *obj = prop; | ||
267 | |||
268 | return 0; | ||
269 | } | ||
270 | EXPORT_SYMBOL_GPL(acpi_dev_get_property_array); | ||
271 | |||
272 | /** | ||
273 | * acpi_dev_get_property_reference - returns handle to the referenced object | ||
274 | * @adev: ACPI device to get property | ||
275 | * @name: Name of the property | ||
276 | * @index: Index of the reference to return | ||
277 | * @args: Location to store the returned reference with optional arguments | ||
278 | * | ||
279 | * Find property with @name, verifify that it is a package containing at least | ||
280 | * one object reference and if so, store the ACPI device object pointer to the | ||
281 | * target object in @args->adev. If the reference includes arguments, store | ||
282 | * them in the @args->args[] array. | ||
283 | * | ||
284 | * If there's more than one reference in the property value package, @index is | ||
285 | * used to select the one to return. | ||
286 | * | ||
287 | * Return: %0 on success, negative error code on failure. | ||
288 | */ | ||
289 | int acpi_dev_get_property_reference(struct acpi_device *adev, | ||
290 | const char *name, size_t index, | ||
291 | struct acpi_reference_args *args) | ||
292 | { | ||
293 | const union acpi_object *element, *end; | ||
294 | const union acpi_object *obj; | ||
295 | struct acpi_device *device; | ||
296 | int ret, idx = 0; | ||
297 | |||
298 | ret = acpi_dev_get_property(adev, name, ACPI_TYPE_ANY, &obj); | ||
299 | if (ret) | ||
300 | return ret; | ||
301 | |||
302 | /* | ||
303 | * The simplest case is when the value is a single reference. Just | ||
304 | * return that reference then. | ||
305 | */ | ||
306 | if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) { | ||
307 | if (index) | ||
308 | return -EINVAL; | ||
309 | |||
310 | ret = acpi_bus_get_device(obj->reference.handle, &device); | ||
311 | if (ret) | ||
312 | return ret; | ||
313 | |||
314 | args->adev = device; | ||
315 | args->nargs = 0; | ||
316 | return 0; | ||
317 | } | ||
318 | |||
319 | /* | ||
320 | * If it is not a single reference, then it is a package of | ||
321 | * references followed by number of ints as follows: | ||
322 | * | ||
323 | * Package () { REF, INT, REF, INT, INT } | ||
324 | * | ||
325 | * The index argument is then used to determine which reference | ||
326 | * the caller wants (along with the arguments). | ||
327 | */ | ||
328 | if (obj->type != ACPI_TYPE_PACKAGE || index >= obj->package.count) | ||
329 | return -EPROTO; | ||
330 | |||
331 | element = obj->package.elements; | ||
332 | end = element + obj->package.count; | ||
333 | |||
334 | while (element < end) { | ||
335 | u32 nargs, i; | ||
336 | |||
337 | if (element->type != ACPI_TYPE_LOCAL_REFERENCE) | ||
338 | return -EPROTO; | ||
339 | |||
340 | ret = acpi_bus_get_device(element->reference.handle, &device); | ||
341 | if (ret) | ||
342 | return -ENODEV; | ||
343 | |||
344 | element++; | ||
345 | nargs = 0; | ||
346 | |||
347 | /* assume following integer elements are all args */ | ||
348 | for (i = 0; element + i < end; i++) { | ||
349 | int type = element[i].type; | ||
350 | |||
351 | if (type == ACPI_TYPE_INTEGER) | ||
352 | nargs++; | ||
353 | else if (type == ACPI_TYPE_LOCAL_REFERENCE) | ||
354 | break; | ||
355 | else | ||
356 | return -EPROTO; | ||
357 | } | ||
358 | |||
359 | if (idx++ == index) { | ||
360 | args->adev = device; | ||
361 | args->nargs = nargs; | ||
362 | for (i = 0; i < nargs; i++) | ||
363 | args->args[i] = element[i].integer.value; | ||
364 | |||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | element += nargs; | ||
369 | } | ||
370 | |||
371 | return -EPROTO; | ||
372 | } | ||
373 | EXPORT_SYMBOL_GPL(acpi_dev_get_property_reference); | ||
374 | |||
375 | int acpi_dev_prop_get(struct acpi_device *adev, const char *propname, | ||
376 | void **valptr) | ||
377 | { | ||
378 | return acpi_dev_get_property(adev, propname, ACPI_TYPE_ANY, | ||
379 | (const union acpi_object **)valptr); | ||
380 | } | ||
381 | |||
382 | int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname, | ||
383 | enum dev_prop_type proptype, void *val) | ||
384 | { | ||
385 | const union acpi_object *obj; | ||
386 | int ret; | ||
387 | |||
388 | if (!val) | ||
389 | return -EINVAL; | ||
390 | |||
391 | if (proptype >= DEV_PROP_U8 && proptype <= DEV_PROP_U64) { | ||
392 | ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_INTEGER, &obj); | ||
393 | if (ret) | ||
394 | return ret; | ||
395 | |||
396 | switch (proptype) { | ||
397 | case DEV_PROP_U8: | ||
398 | if (obj->integer.value > U8_MAX) | ||
399 | return -EOVERFLOW; | ||
400 | *(u8 *)val = obj->integer.value; | ||
401 | break; | ||
402 | case DEV_PROP_U16: | ||
403 | if (obj->integer.value > U16_MAX) | ||
404 | return -EOVERFLOW; | ||
405 | *(u16 *)val = obj->integer.value; | ||
406 | break; | ||
407 | case DEV_PROP_U32: | ||
408 | if (obj->integer.value > U32_MAX) | ||
409 | return -EOVERFLOW; | ||
410 | *(u32 *)val = obj->integer.value; | ||
411 | break; | ||
412 | default: | ||
413 | *(u64 *)val = obj->integer.value; | ||
414 | break; | ||
415 | } | ||
416 | } else if (proptype == DEV_PROP_STRING) { | ||
417 | ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_STRING, &obj); | ||
418 | if (ret) | ||
419 | return ret; | ||
420 | |||
421 | *(char **)val = obj->string.pointer; | ||
422 | } else { | ||
423 | ret = -EINVAL; | ||
424 | } | ||
425 | return ret; | ||
426 | } | ||
427 | |||
428 | static int acpi_copy_property_array_u8(const union acpi_object *items, u8 *val, | ||
429 | size_t nval) | ||
430 | { | ||
431 | int i; | ||
432 | |||
433 | for (i = 0; i < nval; i++) { | ||
434 | if (items[i].type != ACPI_TYPE_INTEGER) | ||
435 | return -EPROTO; | ||
436 | if (items[i].integer.value > U8_MAX) | ||
437 | return -EOVERFLOW; | ||
438 | |||
439 | val[i] = items[i].integer.value; | ||
440 | } | ||
441 | return 0; | ||
442 | } | ||
443 | |||
444 | static int acpi_copy_property_array_u16(const union acpi_object *items, | ||
445 | u16 *val, size_t nval) | ||
446 | { | ||
447 | int i; | ||
448 | |||
449 | for (i = 0; i < nval; i++) { | ||
450 | if (items[i].type != ACPI_TYPE_INTEGER) | ||
451 | return -EPROTO; | ||
452 | if (items[i].integer.value > U16_MAX) | ||
453 | return -EOVERFLOW; | ||
454 | |||
455 | val[i] = items[i].integer.value; | ||
456 | } | ||
457 | return 0; | ||
458 | } | ||
459 | |||
460 | static int acpi_copy_property_array_u32(const union acpi_object *items, | ||
461 | u32 *val, size_t nval) | ||
462 | { | ||
463 | int i; | ||
464 | |||
465 | for (i = 0; i < nval; i++) { | ||
466 | if (items[i].type != ACPI_TYPE_INTEGER) | ||
467 | return -EPROTO; | ||
468 | if (items[i].integer.value > U32_MAX) | ||
469 | return -EOVERFLOW; | ||
470 | |||
471 | val[i] = items[i].integer.value; | ||
472 | } | ||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | static int acpi_copy_property_array_u64(const union acpi_object *items, | ||
477 | u64 *val, size_t nval) | ||
478 | { | ||
479 | int i; | ||
480 | |||
481 | for (i = 0; i < nval; i++) { | ||
482 | if (items[i].type != ACPI_TYPE_INTEGER) | ||
483 | return -EPROTO; | ||
484 | |||
485 | val[i] = items[i].integer.value; | ||
486 | } | ||
487 | return 0; | ||
488 | } | ||
489 | |||
490 | static int acpi_copy_property_array_string(const union acpi_object *items, | ||
491 | char **val, size_t nval) | ||
492 | { | ||
493 | int i; | ||
494 | |||
495 | for (i = 0; i < nval; i++) { | ||
496 | if (items[i].type != ACPI_TYPE_STRING) | ||
497 | return -EPROTO; | ||
498 | |||
499 | val[i] = items[i].string.pointer; | ||
500 | } | ||
501 | return 0; | ||
502 | } | ||
503 | |||
504 | int acpi_dev_prop_read(struct acpi_device *adev, const char *propname, | ||
505 | enum dev_prop_type proptype, void *val, size_t nval) | ||
506 | { | ||
507 | const union acpi_object *obj; | ||
508 | const union acpi_object *items; | ||
509 | int ret; | ||
510 | |||
511 | if (val && nval == 1) { | ||
512 | ret = acpi_dev_prop_read_single(adev, propname, proptype, val); | ||
513 | if (!ret) | ||
514 | return ret; | ||
515 | } | ||
516 | |||
517 | ret = acpi_dev_get_property_array(adev, propname, ACPI_TYPE_ANY, &obj); | ||
518 | if (ret) | ||
519 | return ret; | ||
520 | |||
521 | if (!val) | ||
522 | return obj->package.count; | ||
523 | else if (nval <= 0) | ||
524 | return -EINVAL; | ||
525 | |||
526 | if (nval > obj->package.count) | ||
527 | return -EOVERFLOW; | ||
528 | |||
529 | items = obj->package.elements; | ||
530 | switch (proptype) { | ||
531 | case DEV_PROP_U8: | ||
532 | ret = acpi_copy_property_array_u8(items, (u8 *)val, nval); | ||
533 | break; | ||
534 | case DEV_PROP_U16: | ||
535 | ret = acpi_copy_property_array_u16(items, (u16 *)val, nval); | ||
536 | break; | ||
537 | case DEV_PROP_U32: | ||
538 | ret = acpi_copy_property_array_u32(items, (u32 *)val, nval); | ||
539 | break; | ||
540 | case DEV_PROP_U64: | ||
541 | ret = acpi_copy_property_array_u64(items, (u64 *)val, nval); | ||
542 | break; | ||
543 | case DEV_PROP_STRING: | ||
544 | ret = acpi_copy_property_array_string(items, (char **)val, nval); | ||
545 | break; | ||
546 | default: | ||
547 | ret = -EINVAL; | ||
548 | break; | ||
549 | } | ||
550 | return ret; | ||
551 | } | ||
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 0476e90b2091..16914cc30882 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -36,6 +36,8 @@ bool acpi_force_hot_remove; | |||
36 | 36 | ||
37 | static const char *dummy_hid = "device"; | 37 | static const char *dummy_hid = "device"; |
38 | 38 | ||
39 | static LIST_HEAD(acpi_dep_list); | ||
40 | static DEFINE_MUTEX(acpi_dep_list_lock); | ||
39 | static LIST_HEAD(acpi_bus_id_list); | 41 | static LIST_HEAD(acpi_bus_id_list); |
40 | static DEFINE_MUTEX(acpi_scan_lock); | 42 | static DEFINE_MUTEX(acpi_scan_lock); |
41 | static LIST_HEAD(acpi_scan_handlers_list); | 43 | static LIST_HEAD(acpi_scan_handlers_list); |
@@ -43,6 +45,12 @@ DEFINE_MUTEX(acpi_device_lock); | |||
43 | LIST_HEAD(acpi_wakeup_device_list); | 45 | LIST_HEAD(acpi_wakeup_device_list); |
44 | static DEFINE_MUTEX(acpi_hp_context_lock); | 46 | static DEFINE_MUTEX(acpi_hp_context_lock); |
45 | 47 | ||
48 | struct acpi_dep_data { | ||
49 | struct list_head node; | ||
50 | acpi_handle master; | ||
51 | acpi_handle slave; | ||
52 | }; | ||
53 | |||
46 | struct acpi_device_bus_id{ | 54 | struct acpi_device_bus_id{ |
47 | char bus_id[15]; | 55 | char bus_id[15]; |
48 | unsigned int instance_no; | 56 | unsigned int instance_no; |
@@ -124,17 +132,56 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias, | |||
124 | if (list_empty(&acpi_dev->pnp.ids)) | 132 | if (list_empty(&acpi_dev->pnp.ids)) |
125 | return 0; | 133 | return 0; |
126 | 134 | ||
127 | len = snprintf(modalias, size, "acpi:"); | 135 | /* |
128 | size -= len; | 136 | * If the device has PRP0001 we expose DT compatible modalias |
129 | 137 | * instead in form of of:NnameTCcompatible. | |
130 | list_for_each_entry(id, &acpi_dev->pnp.ids, list) { | 138 | */ |
131 | count = snprintf(&modalias[len], size, "%s:", id->id); | 139 | if (acpi_dev->data.of_compatible) { |
132 | if (count < 0) | 140 | struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER }; |
133 | return -EINVAL; | 141 | const union acpi_object *of_compatible, *obj; |
134 | if (count >= size) | 142 | int i, nval; |
135 | return -ENOMEM; | 143 | char *c; |
136 | len += count; | 144 | |
137 | size -= count; | 145 | acpi_get_name(acpi_dev->handle, ACPI_SINGLE_NAME, &buf); |
146 | /* DT strings are all in lower case */ | ||
147 | for (c = buf.pointer; *c != '\0'; c++) | ||
148 | *c = tolower(*c); | ||
149 | |||
150 | len = snprintf(modalias, size, "of:N%sT", (char *)buf.pointer); | ||
151 | ACPI_FREE(buf.pointer); | ||
152 | |||
153 | of_compatible = acpi_dev->data.of_compatible; | ||
154 | if (of_compatible->type == ACPI_TYPE_PACKAGE) { | ||
155 | nval = of_compatible->package.count; | ||
156 | obj = of_compatible->package.elements; | ||
157 | } else { /* Must be ACPI_TYPE_STRING. */ | ||
158 | nval = 1; | ||
159 | obj = of_compatible; | ||
160 | } | ||
161 | for (i = 0; i < nval; i++, obj++) { | ||
162 | count = snprintf(&modalias[len], size, "C%s", | ||
163 | obj->string.pointer); | ||
164 | if (count < 0) | ||
165 | return -EINVAL; | ||
166 | if (count >= size) | ||
167 | return -ENOMEM; | ||
168 | |||
169 | len += count; | ||
170 | size -= count; | ||
171 | } | ||
172 | } else { | ||
173 | len = snprintf(modalias, size, "acpi:"); | ||
174 | size -= len; | ||
175 | |||
176 | list_for_each_entry(id, &acpi_dev->pnp.ids, list) { | ||
177 | count = snprintf(&modalias[len], size, "%s:", id->id); | ||
178 | if (count < 0) | ||
179 | return -EINVAL; | ||
180 | if (count >= size) | ||
181 | return -ENOMEM; | ||
182 | len += count; | ||
183 | size -= count; | ||
184 | } | ||
138 | } | 185 | } |
139 | 186 | ||
140 | modalias[len] = '\0'; | 187 | modalias[len] = '\0'; |
@@ -902,6 +949,51 @@ int acpi_match_device_ids(struct acpi_device *device, | |||
902 | } | 949 | } |
903 | EXPORT_SYMBOL(acpi_match_device_ids); | 950 | EXPORT_SYMBOL(acpi_match_device_ids); |
904 | 951 | ||
952 | /* Performs match against special "PRP0001" shoehorn ACPI ID */ | ||
953 | static bool acpi_of_driver_match_device(struct device *dev, | ||
954 | const struct device_driver *drv) | ||
955 | { | ||
956 | const union acpi_object *of_compatible, *obj; | ||
957 | struct acpi_device *adev; | ||
958 | int i, nval; | ||
959 | |||
960 | adev = ACPI_COMPANION(dev); | ||
961 | if (!adev) | ||
962 | return false; | ||
963 | |||
964 | of_compatible = adev->data.of_compatible; | ||
965 | if (!drv->of_match_table || !of_compatible) | ||
966 | return false; | ||
967 | |||
968 | if (of_compatible->type == ACPI_TYPE_PACKAGE) { | ||
969 | nval = of_compatible->package.count; | ||
970 | obj = of_compatible->package.elements; | ||
971 | } else { /* Must be ACPI_TYPE_STRING. */ | ||
972 | nval = 1; | ||
973 | obj = of_compatible; | ||
974 | } | ||
975 | /* Now we can look for the driver DT compatible strings */ | ||
976 | for (i = 0; i < nval; i++, obj++) { | ||
977 | const struct of_device_id *id; | ||
978 | |||
979 | for (id = drv->of_match_table; id->compatible[0]; id++) | ||
980 | if (!strcasecmp(obj->string.pointer, id->compatible)) | ||
981 | return true; | ||
982 | } | ||
983 | |||
984 | return false; | ||
985 | } | ||
986 | |||
987 | bool acpi_driver_match_device(struct device *dev, | ||
988 | const struct device_driver *drv) | ||
989 | { | ||
990 | if (!drv->acpi_match_table) | ||
991 | return acpi_of_driver_match_device(dev, drv); | ||
992 | |||
993 | return !!acpi_match_device(drv->acpi_match_table, dev); | ||
994 | } | ||
995 | EXPORT_SYMBOL_GPL(acpi_driver_match_device); | ||
996 | |||
905 | static void acpi_free_power_resources_lists(struct acpi_device *device) | 997 | static void acpi_free_power_resources_lists(struct acpi_device *device) |
906 | { | 998 | { |
907 | int i; | 999 | int i; |
@@ -922,6 +1014,7 @@ static void acpi_device_release(struct device *dev) | |||
922 | { | 1014 | { |
923 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 1015 | struct acpi_device *acpi_dev = to_acpi_device(dev); |
924 | 1016 | ||
1017 | acpi_free_properties(acpi_dev); | ||
925 | acpi_free_pnp_ids(&acpi_dev->pnp); | 1018 | acpi_free_pnp_ids(&acpi_dev->pnp); |
926 | acpi_free_power_resources_lists(acpi_dev); | 1019 | acpi_free_power_resources_lists(acpi_dev); |
927 | kfree(acpi_dev); | 1020 | kfree(acpi_dev); |
@@ -1304,6 +1397,26 @@ int acpi_device_add(struct acpi_device *device, | |||
1304 | return result; | 1397 | return result; |
1305 | } | 1398 | } |
1306 | 1399 | ||
1400 | struct acpi_device *acpi_get_next_child(struct device *dev, | ||
1401 | struct acpi_device *child) | ||
1402 | { | ||
1403 | struct acpi_device *adev = ACPI_COMPANION(dev); | ||
1404 | struct list_head *head, *next; | ||
1405 | |||
1406 | if (!adev) | ||
1407 | return NULL; | ||
1408 | |||
1409 | head = &adev->children; | ||
1410 | if (list_empty(head)) | ||
1411 | return NULL; | ||
1412 | |||
1413 | if (!child) | ||
1414 | return list_first_entry(head, struct acpi_device, node); | ||
1415 | |||
1416 | next = child->node.next; | ||
1417 | return next == head ? NULL : list_entry(next, struct acpi_device, node); | ||
1418 | } | ||
1419 | |||
1307 | /* -------------------------------------------------------------------------- | 1420 | /* -------------------------------------------------------------------------- |
1308 | Driver Management | 1421 | Driver Management |
1309 | -------------------------------------------------------------------------- */ | 1422 | -------------------------------------------------------------------------- */ |
@@ -1923,9 +2036,11 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, | |||
1923 | device->device_type = type; | 2036 | device->device_type = type; |
1924 | device->handle = handle; | 2037 | device->handle = handle; |
1925 | device->parent = acpi_bus_get_parent(handle); | 2038 | device->parent = acpi_bus_get_parent(handle); |
2039 | device->fwnode.type = FWNODE_ACPI; | ||
1926 | acpi_set_device_status(device, sta); | 2040 | acpi_set_device_status(device, sta); |
1927 | acpi_device_get_busid(device); | 2041 | acpi_device_get_busid(device); |
1928 | acpi_set_pnp_ids(handle, &device->pnp, type); | 2042 | acpi_set_pnp_ids(handle, &device->pnp, type); |
2043 | acpi_init_properties(device); | ||
1929 | acpi_bus_get_flags(device); | 2044 | acpi_bus_get_flags(device); |
1930 | device->flags.match_driver = false; | 2045 | device->flags.match_driver = false; |
1931 | device->flags.initialized = true; | 2046 | device->flags.initialized = true; |
@@ -2086,6 +2201,59 @@ static void acpi_scan_init_hotplug(struct acpi_device *adev) | |||
2086 | } | 2201 | } |
2087 | } | 2202 | } |
2088 | 2203 | ||
2204 | static void acpi_device_dep_initialize(struct acpi_device *adev) | ||
2205 | { | ||
2206 | struct acpi_dep_data *dep; | ||
2207 | struct acpi_handle_list dep_devices; | ||
2208 | acpi_status status; | ||
2209 | int i; | ||
2210 | |||
2211 | if (!acpi_has_method(adev->handle, "_DEP")) | ||
2212 | return; | ||
2213 | |||
2214 | status = acpi_evaluate_reference(adev->handle, "_DEP", NULL, | ||
2215 | &dep_devices); | ||
2216 | if (ACPI_FAILURE(status)) { | ||
2217 | dev_dbg(&adev->dev, "Failed to evaluate _DEP.\n"); | ||
2218 | return; | ||
2219 | } | ||
2220 | |||
2221 | for (i = 0; i < dep_devices.count; i++) { | ||
2222 | struct acpi_device_info *info; | ||
2223 | int skip; | ||
2224 | |||
2225 | status = acpi_get_object_info(dep_devices.handles[i], &info); | ||
2226 | if (ACPI_FAILURE(status)) { | ||
2227 | dev_dbg(&adev->dev, "Error reading _DEP device info\n"); | ||
2228 | continue; | ||
2229 | } | ||
2230 | |||
2231 | /* | ||
2232 | * Skip the dependency of Windows System Power | ||
2233 | * Management Controller | ||
2234 | */ | ||
2235 | skip = info->valid & ACPI_VALID_HID && | ||
2236 | !strcmp(info->hardware_id.string, "INT3396"); | ||
2237 | |||
2238 | kfree(info); | ||
2239 | |||
2240 | if (skip) | ||
2241 | continue; | ||
2242 | |||
2243 | dep = kzalloc(sizeof(struct acpi_dep_data), GFP_KERNEL); | ||
2244 | if (!dep) | ||
2245 | return; | ||
2246 | |||
2247 | dep->master = dep_devices.handles[i]; | ||
2248 | dep->slave = adev->handle; | ||
2249 | adev->dep_unmet++; | ||
2250 | |||
2251 | mutex_lock(&acpi_dep_list_lock); | ||
2252 | list_add_tail(&dep->node , &acpi_dep_list); | ||
2253 | mutex_unlock(&acpi_dep_list_lock); | ||
2254 | } | ||
2255 | } | ||
2256 | |||
2089 | static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, | 2257 | static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, |
2090 | void *not_used, void **return_value) | 2258 | void *not_used, void **return_value) |
2091 | { | 2259 | { |
@@ -2112,6 +2280,7 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, | |||
2112 | return AE_CTRL_DEPTH; | 2280 | return AE_CTRL_DEPTH; |
2113 | 2281 | ||
2114 | acpi_scan_init_hotplug(device); | 2282 | acpi_scan_init_hotplug(device); |
2283 | acpi_device_dep_initialize(device); | ||
2115 | 2284 | ||
2116 | out: | 2285 | out: |
2117 | if (!*return_value) | 2286 | if (!*return_value) |
@@ -2232,6 +2401,29 @@ static void acpi_bus_attach(struct acpi_device *device) | |||
2232 | device->handler->hotplug.notify_online(device); | 2401 | device->handler->hotplug.notify_online(device); |
2233 | } | 2402 | } |
2234 | 2403 | ||
2404 | void acpi_walk_dep_device_list(acpi_handle handle) | ||
2405 | { | ||
2406 | struct acpi_dep_data *dep, *tmp; | ||
2407 | struct acpi_device *adev; | ||
2408 | |||
2409 | mutex_lock(&acpi_dep_list_lock); | ||
2410 | list_for_each_entry_safe(dep, tmp, &acpi_dep_list, node) { | ||
2411 | if (dep->master == handle) { | ||
2412 | acpi_bus_get_device(dep->slave, &adev); | ||
2413 | if (!adev) | ||
2414 | continue; | ||
2415 | |||
2416 | adev->dep_unmet--; | ||
2417 | if (!adev->dep_unmet) | ||
2418 | acpi_bus_attach(adev); | ||
2419 | list_del(&dep->node); | ||
2420 | kfree(dep); | ||
2421 | } | ||
2422 | } | ||
2423 | mutex_unlock(&acpi_dep_list_lock); | ||
2424 | } | ||
2425 | EXPORT_SYMBOL_GPL(acpi_walk_dep_device_list); | ||
2426 | |||
2235 | /** | 2427 | /** |
2236 | * acpi_bus_scan - Add ACPI device node objects in a given namespace scope. | 2428 | * acpi_bus_scan - Add ACPI device node objects in a given namespace scope. |
2237 | * @handle: Root of the namespace scope to scan. | 2429 | * @handle: Root of the namespace scope to scan. |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 05a31b573fc3..8aa9254a387f 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -630,6 +630,7 @@ static int acpi_freeze_begin(void) | |||
630 | static int acpi_freeze_prepare(void) | 630 | static int acpi_freeze_prepare(void) |
631 | { | 631 | { |
632 | acpi_enable_all_wakeup_gpes(); | 632 | acpi_enable_all_wakeup_gpes(); |
633 | acpi_os_wait_events_complete(); | ||
633 | enable_irq_wake(acpi_gbl_FADT.sci_interrupt); | 634 | enable_irq_wake(acpi_gbl_FADT.sci_interrupt); |
634 | return 0; | 635 | return 0; |
635 | } | 636 | } |
@@ -825,6 +826,7 @@ static void acpi_power_off_prepare(void) | |||
825 | /* Prepare to power off the system */ | 826 | /* Prepare to power off the system */ |
826 | acpi_sleep_prepare(ACPI_STATE_S5); | 827 | acpi_sleep_prepare(ACPI_STATE_S5); |
827 | acpi_disable_all_gpes(); | 828 | acpi_disable_all_gpes(); |
829 | acpi_os_wait_events_complete(); | ||
828 | } | 830 | } |
829 | 831 | ||
830 | static void acpi_power_off(void) | 832 | static void acpi_power_off(void) |
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 6d5a6cda0734..93b81523a2fe 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c | |||
@@ -190,30 +190,24 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) | |||
190 | } | 190 | } |
191 | } | 191 | } |
192 | 192 | ||
193 | |||
194 | int __init | 193 | int __init |
195 | acpi_table_parse_entries(char *id, | 194 | acpi_parse_entries(char *id, unsigned long table_size, |
196 | unsigned long table_size, | 195 | acpi_tbl_entry_handler handler, |
197 | int entry_id, | 196 | struct acpi_table_header *table_header, |
198 | acpi_tbl_entry_handler handler, | 197 | int entry_id, unsigned int max_entries) |
199 | unsigned int max_entries) | ||
200 | { | 198 | { |
201 | struct acpi_table_header *table_header = NULL; | ||
202 | struct acpi_subtable_header *entry; | 199 | struct acpi_subtable_header *entry; |
203 | unsigned int count = 0; | 200 | int count = 0; |
204 | unsigned long table_end; | 201 | unsigned long table_end; |
205 | acpi_size tbl_size; | ||
206 | 202 | ||
207 | if (acpi_disabled) | 203 | if (acpi_disabled) |
208 | return -ENODEV; | 204 | return -ENODEV; |
209 | 205 | ||
210 | if (!handler) | 206 | if (!id || !handler) |
211 | return -EINVAL; | 207 | return -EINVAL; |
212 | 208 | ||
213 | if (strncmp(id, ACPI_SIG_MADT, 4) == 0) | 209 | if (!table_size) |
214 | acpi_get_table_with_size(id, acpi_apic_instance, &table_header, &tbl_size); | 210 | return -EINVAL; |
215 | else | ||
216 | acpi_get_table_with_size(id, 0, &table_header, &tbl_size); | ||
217 | 211 | ||
218 | if (!table_header) { | 212 | if (!table_header) { |
219 | pr_warn("%4.4s not present\n", id); | 213 | pr_warn("%4.4s not present\n", id); |
@@ -230,9 +224,12 @@ acpi_table_parse_entries(char *id, | |||
230 | while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) < | 224 | while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) < |
231 | table_end) { | 225 | table_end) { |
232 | if (entry->type == entry_id | 226 | if (entry->type == entry_id |
233 | && (!max_entries || count++ < max_entries)) | 227 | && (!max_entries || count < max_entries)) { |
234 | if (handler(entry, table_end)) | 228 | if (handler(entry, table_end)) |
235 | goto err; | 229 | return -EINVAL; |
230 | |||
231 | count++; | ||
232 | } | ||
236 | 233 | ||
237 | /* | 234 | /* |
238 | * If entry->length is 0, break from this loop to avoid | 235 | * If entry->length is 0, break from this loop to avoid |
@@ -240,22 +237,53 @@ acpi_table_parse_entries(char *id, | |||
240 | */ | 237 | */ |
241 | if (entry->length == 0) { | 238 | if (entry->length == 0) { |
242 | pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, entry_id); | 239 | pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, entry_id); |
243 | goto err; | 240 | return -EINVAL; |
244 | } | 241 | } |
245 | 242 | ||
246 | entry = (struct acpi_subtable_header *) | 243 | entry = (struct acpi_subtable_header *) |
247 | ((unsigned long)entry + entry->length); | 244 | ((unsigned long)entry + entry->length); |
248 | } | 245 | } |
246 | |||
249 | if (max_entries && count > max_entries) { | 247 | if (max_entries && count > max_entries) { |
250 | pr_warn("[%4.4s:0x%02x] ignored %i entries of %i found\n", | 248 | pr_warn("[%4.4s:0x%02x] ignored %i entries of %i found\n", |
251 | id, entry_id, count - max_entries, count); | 249 | id, entry_id, count - max_entries, count); |
252 | } | 250 | } |
253 | 251 | ||
254 | early_acpi_os_unmap_memory((char *)table_header, tbl_size); | ||
255 | return count; | 252 | return count; |
256 | err: | 253 | } |
254 | |||
255 | int __init | ||
256 | acpi_table_parse_entries(char *id, | ||
257 | unsigned long table_size, | ||
258 | int entry_id, | ||
259 | acpi_tbl_entry_handler handler, | ||
260 | unsigned int max_entries) | ||
261 | { | ||
262 | struct acpi_table_header *table_header = NULL; | ||
263 | acpi_size tbl_size; | ||
264 | int count; | ||
265 | u32 instance = 0; | ||
266 | |||
267 | if (acpi_disabled) | ||
268 | return -ENODEV; | ||
269 | |||
270 | if (!id || !handler) | ||
271 | return -EINVAL; | ||
272 | |||
273 | if (!strncmp(id, ACPI_SIG_MADT, 4)) | ||
274 | instance = acpi_apic_instance; | ||
275 | |||
276 | acpi_get_table_with_size(id, instance, &table_header, &tbl_size); | ||
277 | if (!table_header) { | ||
278 | pr_warn("%4.4s not present\n", id); | ||
279 | return -ENODEV; | ||
280 | } | ||
281 | |||
282 | count = acpi_parse_entries(id, table_size, handler, table_header, | ||
283 | entry_id, max_entries); | ||
284 | |||
257 | early_acpi_os_unmap_memory((char *)table_header, tbl_size); | 285 | early_acpi_os_unmap_memory((char *)table_header, tbl_size); |
258 | return -EINVAL; | 286 | return count; |
259 | } | 287 | } |
260 | 288 | ||
261 | int __init | 289 | int __init |
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 371ac12d25b1..cd49a3982b6a 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c | |||
@@ -136,8 +136,7 @@ acpi_extract_package(union acpi_object *package, | |||
136 | break; | 136 | break; |
137 | case 'B': | 137 | case 'B': |
138 | size_required += | 138 | size_required += |
139 | sizeof(u8 *) + | 139 | sizeof(u8 *) + element->buffer.length; |
140 | (element->buffer.length * sizeof(u8)); | ||
141 | tail_offset += sizeof(u8 *); | 140 | tail_offset += sizeof(u8 *); |
142 | break; | 141 | break; |
143 | default: | 142 | default: |
@@ -255,7 +254,7 @@ acpi_extract_package(union acpi_object *package, | |||
255 | memcpy(tail, element->buffer.pointer, | 254 | memcpy(tail, element->buffer.pointer, |
256 | element->buffer.length); | 255 | element->buffer.length); |
257 | head += sizeof(u8 *); | 256 | head += sizeof(u8 *); |
258 | tail += element->buffer.length * sizeof(u8); | 257 | tail += element->buffer.length; |
259 | break; | 258 | break; |
260 | default: | 259 | default: |
261 | /* Should never get here */ | 260 | /* Should never get here */ |
@@ -347,22 +346,16 @@ acpi_evaluate_reference(acpi_handle handle, | |||
347 | package = buffer.pointer; | 346 | package = buffer.pointer; |
348 | 347 | ||
349 | if ((buffer.length == 0) || !package) { | 348 | if ((buffer.length == 0) || !package) { |
350 | printk(KERN_ERR PREFIX "No return object (len %X ptr %p)\n", | ||
351 | (unsigned)buffer.length, package); | ||
352 | status = AE_BAD_DATA; | 349 | status = AE_BAD_DATA; |
353 | acpi_util_eval_error(handle, pathname, status); | 350 | acpi_util_eval_error(handle, pathname, status); |
354 | goto end; | 351 | goto end; |
355 | } | 352 | } |
356 | if (package->type != ACPI_TYPE_PACKAGE) { | 353 | if (package->type != ACPI_TYPE_PACKAGE) { |
357 | printk(KERN_ERR PREFIX "Expecting a [Package], found type %X\n", | ||
358 | package->type); | ||
359 | status = AE_BAD_DATA; | 354 | status = AE_BAD_DATA; |
360 | acpi_util_eval_error(handle, pathname, status); | 355 | acpi_util_eval_error(handle, pathname, status); |
361 | goto end; | 356 | goto end; |
362 | } | 357 | } |
363 | if (!package->package.count) { | 358 | if (!package->package.count) { |
364 | printk(KERN_ERR PREFIX "[Package] has zero elements (%p)\n", | ||
365 | package); | ||
366 | status = AE_BAD_DATA; | 359 | status = AE_BAD_DATA; |
367 | acpi_util_eval_error(handle, pathname, status); | 360 | acpi_util_eval_error(handle, pathname, status); |
368 | goto end; | 361 | goto end; |
@@ -381,17 +374,13 @@ acpi_evaluate_reference(acpi_handle handle, | |||
381 | 374 | ||
382 | if (element->type != ACPI_TYPE_LOCAL_REFERENCE) { | 375 | if (element->type != ACPI_TYPE_LOCAL_REFERENCE) { |
383 | status = AE_BAD_DATA; | 376 | status = AE_BAD_DATA; |
384 | printk(KERN_ERR PREFIX | ||
385 | "Expecting a [Reference] package element, found type %X\n", | ||
386 | element->type); | ||
387 | acpi_util_eval_error(handle, pathname, status); | 377 | acpi_util_eval_error(handle, pathname, status); |
388 | break; | 378 | break; |
389 | } | 379 | } |
390 | 380 | ||
391 | if (!element->reference.handle) { | 381 | if (!element->reference.handle) { |
392 | printk(KERN_WARNING PREFIX "Invalid reference in" | ||
393 | " package %s\n", pathname); | ||
394 | status = AE_NULL_ENTRY; | 382 | status = AE_NULL_ENTRY; |
383 | acpi_util_eval_error(handle, pathname, status); | ||
395 | break; | 384 | break; |
396 | } | 385 | } |
397 | /* Get the acpi_handle. */ | 386 | /* Get the acpi_handle. */ |