sleep.c (2257e268b1154966c5b0141b23695db1043ff39d) | sleep.c (726fb6b4f2a82a14a906f39bdabac4863b87c01a) |
---|---|
1/* 2 * sleep.c - ACPI sleep support. 3 * 4 * Copyright (c) 2005 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> 5 * Copyright (c) 2004 David Shaohua Li <shaohua.li@intel.com> 6 * Copyright (c) 2000-2003 Patrick Mochel 7 * Copyright (c) 2003 Open Source Development Lab 8 * --- 655 unchanged lines hidden (view full) --- 664 */ 665static const struct acpi_device_id lps0_device_ids[] = { 666 {"PNP0D80", }, 667 {"", }, 668}; 669 670#define ACPI_LPS0_DSM_UUID "c4eb40a0-6cd2-11e2-bcfd-0800200c9a66" 671 | 1/* 2 * sleep.c - ACPI sleep support. 3 * 4 * Copyright (c) 2005 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> 5 * Copyright (c) 2004 David Shaohua Li <shaohua.li@intel.com> 6 * Copyright (c) 2000-2003 Patrick Mochel 7 * Copyright (c) 2003 Open Source Development Lab 8 * --- 655 unchanged lines hidden (view full) --- 664 */ 665static const struct acpi_device_id lps0_device_ids[] = { 666 {"PNP0D80", }, 667 {"", }, 668}; 669 670#define ACPI_LPS0_DSM_UUID "c4eb40a0-6cd2-11e2-bcfd-0800200c9a66" 671 |
672#define ACPI_LPS0_GET_DEVICE_CONSTRAINTS 1 |
|
672#define ACPI_LPS0_SCREEN_OFF 3 673#define ACPI_LPS0_SCREEN_ON 4 674#define ACPI_LPS0_ENTRY 5 675#define ACPI_LPS0_EXIT 6 676 677#define ACPI_S2IDLE_FUNC_MASK ((1 << ACPI_LPS0_ENTRY) | (1 << ACPI_LPS0_EXIT)) 678 679static acpi_handle lps0_device_handle; 680static guid_t lps0_dsm_guid; 681static char lps0_dsm_func_mask; 682 | 673#define ACPI_LPS0_SCREEN_OFF 3 674#define ACPI_LPS0_SCREEN_ON 4 675#define ACPI_LPS0_ENTRY 5 676#define ACPI_LPS0_EXIT 6 677 678#define ACPI_S2IDLE_FUNC_MASK ((1 << ACPI_LPS0_ENTRY) | (1 << ACPI_LPS0_EXIT)) 679 680static acpi_handle lps0_device_handle; 681static guid_t lps0_dsm_guid; 682static char lps0_dsm_func_mask; 683 |
684/* Device constraint entry structure */ 685struct lpi_device_info { 686 char *name; 687 int enabled; 688 union acpi_object *package; 689}; 690 691/* Constraint package structure */ 692struct lpi_device_constraint { 693 int uid; 694 int min_dstate; 695 int function_states; 696}; 697 698struct lpi_constraints { 699 acpi_handle handle; 700 int min_dstate; 701}; 702 703static struct lpi_constraints *lpi_constraints_table; 704static int lpi_constraints_table_size; 705 706static void lpi_device_get_constraints(void) 707{ 708 union acpi_object *out_obj; 709 int i; 710 711 out_obj = acpi_evaluate_dsm_typed(lps0_device_handle, &lps0_dsm_guid, 712 1, ACPI_LPS0_GET_DEVICE_CONSTRAINTS, 713 NULL, ACPI_TYPE_PACKAGE); 714 715 acpi_handle_debug(lps0_device_handle, "_DSM function 1 eval %s\n", 716 out_obj ? "successful" : "failed"); 717 718 if (!out_obj) 719 return; 720 721 lpi_constraints_table = kcalloc(out_obj->package.count, 722 sizeof(*lpi_constraints_table), 723 GFP_KERNEL); 724 if (!lpi_constraints_table) 725 goto free_acpi_buffer; 726 727 acpi_handle_debug(lps0_device_handle, "LPI: constraints list begin:\n"); 728 729 for (i = 0; i < out_obj->package.count; i++) { 730 struct lpi_constraints *constraint; 731 acpi_status status; 732 union acpi_object *package = &out_obj->package.elements[i]; 733 struct lpi_device_info info = { }; 734 int package_count = 0, j; 735 736 if (!package) 737 continue; 738 739 for (j = 0; j < package->package.count; ++j) { 740 union acpi_object *element = 741 &(package->package.elements[j]); 742 743 switch (element->type) { 744 case ACPI_TYPE_INTEGER: 745 info.enabled = element->integer.value; 746 break; 747 case ACPI_TYPE_STRING: 748 info.name = element->string.pointer; 749 break; 750 case ACPI_TYPE_PACKAGE: 751 package_count = element->package.count; 752 info.package = element->package.elements; 753 break; 754 } 755 } 756 757 if (!info.enabled || !info.package || !info.name) 758 continue; 759 760 constraint = &lpi_constraints_table[lpi_constraints_table_size]; 761 762 status = acpi_get_handle(NULL, info.name, &constraint->handle); 763 if (ACPI_FAILURE(status)) 764 continue; 765 766 acpi_handle_debug(lps0_device_handle, 767 "index:%d Name:%s\n", i, info.name); 768 769 constraint->min_dstate = -1; 770 771 for (j = 0; j < package_count; ++j) { 772 union acpi_object *info_obj = &info.package[j]; 773 union acpi_object *cnstr_pkg; 774 union acpi_object *obj; 775 struct lpi_device_constraint dev_info; 776 777 switch (info_obj->type) { 778 case ACPI_TYPE_INTEGER: 779 /* version */ 780 break; 781 case ACPI_TYPE_PACKAGE: 782 if (info_obj->package.count < 2) 783 break; 784 785 cnstr_pkg = info_obj->package.elements; 786 obj = &cnstr_pkg[0]; 787 dev_info.uid = obj->integer.value; 788 obj = &cnstr_pkg[1]; 789 dev_info.min_dstate = obj->integer.value; 790 791 acpi_handle_debug(lps0_device_handle, 792 "uid:%d min_dstate:%s\n", 793 dev_info.uid, 794 acpi_power_state_string(dev_info.min_dstate)); 795 796 constraint->min_dstate = dev_info.min_dstate; 797 break; 798 } 799 } 800 801 if (constraint->min_dstate < 0) { 802 acpi_handle_debug(lps0_device_handle, 803 "Incomplete constraint defined\n"); 804 continue; 805 } 806 807 lpi_constraints_table_size++; 808 } 809 810 acpi_handle_debug(lps0_device_handle, "LPI: constraints list end\n"); 811 812free_acpi_buffer: 813 ACPI_FREE(out_obj); 814} 815 816static void lpi_check_constraints(void) 817{ 818 int i; 819 820 for (i = 0; i < lpi_constraints_table_size; ++i) { 821 struct acpi_device *adev; 822 823 if (acpi_bus_get_device(lpi_constraints_table[i].handle, &adev)) 824 continue; 825 826 acpi_handle_debug(adev->handle, 827 "LPI: required min power state:%s current power state:%s\n", 828 acpi_power_state_string(lpi_constraints_table[i].min_dstate), 829 acpi_power_state_string(adev->power.state)); 830 831 if (!adev->flags.power_manageable) { 832 acpi_handle_info(adev->handle, "LPI: Device not power manageble\n"); 833 continue; 834 } 835 836 if (adev->power.state < lpi_constraints_table[i].min_dstate) 837 acpi_handle_info(adev->handle, 838 "LPI: Constraint not met; min power state:%s current power state:%s\n", 839 acpi_power_state_string(lpi_constraints_table[i].min_dstate), 840 acpi_power_state_string(adev->power.state)); 841 } 842} 843 |
|
683static void acpi_sleep_run_lps0_dsm(unsigned int func) 684{ 685 union acpi_object *out_obj; 686 687 if (!(lps0_dsm_func_mask & (1 << func))) 688 return; 689 690 out_obj = acpi_evaluate_dsm(lps0_device_handle, &lps0_dsm_guid, 1, func, NULL); --- 18 unchanged lines hidden (view full) --- 709 /* Check if the _DSM is present and as expected. */ 710 out_obj = acpi_evaluate_dsm(adev->handle, &lps0_dsm_guid, 1, 0, NULL); 711 if (out_obj && out_obj->type == ACPI_TYPE_BUFFER) { 712 char bitmask = *(char *)out_obj->buffer.pointer; 713 714 if ((bitmask & ACPI_S2IDLE_FUNC_MASK) == ACPI_S2IDLE_FUNC_MASK) { 715 lps0_dsm_func_mask = bitmask; 716 lps0_device_handle = adev->handle; | 844static void acpi_sleep_run_lps0_dsm(unsigned int func) 845{ 846 union acpi_object *out_obj; 847 848 if (!(lps0_dsm_func_mask & (1 << func))) 849 return; 850 851 out_obj = acpi_evaluate_dsm(lps0_device_handle, &lps0_dsm_guid, 1, func, NULL); --- 18 unchanged lines hidden (view full) --- 870 /* Check if the _DSM is present and as expected. */ 871 out_obj = acpi_evaluate_dsm(adev->handle, &lps0_dsm_guid, 1, 0, NULL); 872 if (out_obj && out_obj->type == ACPI_TYPE_BUFFER) { 873 char bitmask = *(char *)out_obj->buffer.pointer; 874 875 if ((bitmask & ACPI_S2IDLE_FUNC_MASK) == ACPI_S2IDLE_FUNC_MASK) { 876 lps0_dsm_func_mask = bitmask; 877 lps0_device_handle = adev->handle; |
878 /* 879 * Use suspend-to-idle by default if the default 880 * suspend mode was not set from the command line. 881 */ 882 if (mem_sleep_default > PM_SUSPEND_MEM) 883 mem_sleep_current = PM_SUSPEND_TO_IDLE; |
|
717 } 718 719 acpi_handle_debug(adev->handle, "_DSM function mask: 0x%x\n", 720 bitmask); 721 } else { 722 acpi_handle_debug(adev->handle, 723 "_DSM function 0 evaluation failed\n"); 724 } 725 ACPI_FREE(out_obj); | 884 } 885 886 acpi_handle_debug(adev->handle, "_DSM function mask: 0x%x\n", 887 bitmask); 888 } else { 889 acpi_handle_debug(adev->handle, 890 "_DSM function 0 evaluation failed\n"); 891 } 892 ACPI_FREE(out_obj); |
893 894 lpi_device_get_constraints(); 895 |
|
726 return 0; 727} 728 729static struct acpi_scan_handler lps0_handler = { 730 .ids = lps0_device_ids, 731 .attach = lps0_device_attach, 732}; 733 | 896 return 0; 897} 898 899static struct acpi_scan_handler lps0_handler = { 900 .ids = lps0_device_ids, 901 .attach = lps0_device_attach, 902}; 903 |
734static int acpi_freeze_begin(void) | 904static int acpi_s2idle_begin(void) |
735{ 736 acpi_scan_lock_acquire(); 737 s2idle_in_progress = true; 738 return 0; 739} 740 | 905{ 906 acpi_scan_lock_acquire(); 907 s2idle_in_progress = true; 908 return 0; 909} 910 |
741static int acpi_freeze_prepare(void) | 911static int acpi_s2idle_prepare(void) |
742{ 743 if (lps0_device_handle) { 744 acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF); 745 acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY); 746 } else { 747 /* 748 * The configuration of GPEs is changed here to avoid spurious 749 * wakeups, but that should not be necessary if this is a 750 * "low-power S0" platform and the low-power S0 _DSM is present. 751 */ 752 acpi_enable_all_wakeup_gpes(); 753 acpi_os_wait_events_complete(); 754 } 755 if (acpi_sci_irq_valid()) 756 enable_irq_wake(acpi_sci_irq); 757 758 return 0; 759} 760 | 912{ 913 if (lps0_device_handle) { 914 acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF); 915 acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY); 916 } else { 917 /* 918 * The configuration of GPEs is changed here to avoid spurious 919 * wakeups, but that should not be necessary if this is a 920 * "low-power S0" platform and the low-power S0 _DSM is present. 921 */ 922 acpi_enable_all_wakeup_gpes(); 923 acpi_os_wait_events_complete(); 924 } 925 if (acpi_sci_irq_valid()) 926 enable_irq_wake(acpi_sci_irq); 927 928 return 0; 929} 930 |
761static void acpi_freeze_wake(void) | 931static void acpi_s2idle_wake(void) |
762{ | 932{ |
933 934 if (pm_debug_messages_on) 935 lpi_check_constraints(); 936 |
|
763 /* 764 * If IRQD_WAKEUP_ARMED is not set for the SCI at this point, it means 765 * that the SCI has triggered while suspended, so cancel the wakeup in 766 * case it has not been a wakeup event (the GPEs will be checked later). 767 */ 768 if (acpi_sci_irq_valid() && 769 !irqd_is_wakeup_armed(irq_get_irq_data(acpi_sci_irq))) { 770 pm_system_cancel_wakeup(); 771 s2idle_wakeup = true; 772 } 773} 774 | 937 /* 938 * If IRQD_WAKEUP_ARMED is not set for the SCI at this point, it means 939 * that the SCI has triggered while suspended, so cancel the wakeup in 940 * case it has not been a wakeup event (the GPEs will be checked later). 941 */ 942 if (acpi_sci_irq_valid() && 943 !irqd_is_wakeup_armed(irq_get_irq_data(acpi_sci_irq))) { 944 pm_system_cancel_wakeup(); 945 s2idle_wakeup = true; 946 } 947} 948 |
775static void acpi_freeze_sync(void) | 949static void acpi_s2idle_sync(void) |
776{ 777 /* 778 * Process all pending events in case there are any wakeup ones. 779 * | 950{ 951 /* 952 * Process all pending events in case there are any wakeup ones. 953 * |
780 * The EC driver uses the system workqueue and an additional special 781 * one, so those need to be flushed too. | 954 * The EC driver uses the system workqueue, so that one needs to be 955 * flushed too. |
782 */ | 956 */ |
783 acpi_ec_flush_work(); | |
784 acpi_os_wait_events_complete(); | 957 acpi_os_wait_events_complete(); |
958 flush_scheduled_work(); |
|
785 s2idle_wakeup = false; 786} 787 | 959 s2idle_wakeup = false; 960} 961 |
788static void acpi_freeze_restore(void) | 962static void acpi_s2idle_restore(void) |
789{ 790 if (acpi_sci_irq_valid()) 791 disable_irq_wake(acpi_sci_irq); 792 793 if (lps0_device_handle) { 794 acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT); 795 acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON); 796 } else { 797 acpi_enable_all_runtime_gpes(); 798 } 799} 800 | 963{ 964 if (acpi_sci_irq_valid()) 965 disable_irq_wake(acpi_sci_irq); 966 967 if (lps0_device_handle) { 968 acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT); 969 acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON); 970 } else { 971 acpi_enable_all_runtime_gpes(); 972 } 973} 974 |
801static void acpi_freeze_end(void) | 975static void acpi_s2idle_end(void) |
802{ 803 s2idle_in_progress = false; 804 acpi_scan_lock_release(); 805} 806 | 976{ 977 s2idle_in_progress = false; 978 acpi_scan_lock_release(); 979} 980 |
807static const struct platform_freeze_ops acpi_freeze_ops = { 808 .begin = acpi_freeze_begin, 809 .prepare = acpi_freeze_prepare, 810 .wake = acpi_freeze_wake, 811 .sync = acpi_freeze_sync, 812 .restore = acpi_freeze_restore, 813 .end = acpi_freeze_end, | 981static const struct platform_s2idle_ops acpi_s2idle_ops = { 982 .begin = acpi_s2idle_begin, 983 .prepare = acpi_s2idle_prepare, 984 .wake = acpi_s2idle_wake, 985 .sync = acpi_s2idle_sync, 986 .restore = acpi_s2idle_restore, 987 .end = acpi_s2idle_end, |
814}; 815 816static void acpi_sleep_suspend_setup(void) 817{ 818 int i; 819 820 for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++) 821 if (acpi_sleep_state_supported(i)) 822 sleep_states[i] = 1; 823 824 suspend_set_ops(old_suspend_ordering ? 825 &acpi_suspend_ops_old : &acpi_suspend_ops); 826 827 acpi_scan_add_handler(&lps0_handler); | 988}; 989 990static void acpi_sleep_suspend_setup(void) 991{ 992 int i; 993 994 for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++) 995 if (acpi_sleep_state_supported(i)) 996 sleep_states[i] = 1; 997 998 suspend_set_ops(old_suspend_ordering ? 999 &acpi_suspend_ops_old : &acpi_suspend_ops); 1000 1001 acpi_scan_add_handler(&lps0_handler); |
828 freeze_set_ops(&acpi_freeze_ops); | 1002 s2idle_set_ops(&acpi_s2idle_ops); |
829} 830 831#else /* !CONFIG_SUSPEND */ 832#define s2idle_in_progress (false) 833#define s2idle_wakeup (false) 834#define lps0_device_handle (NULL) 835static inline void acpi_sleep_suspend_setup(void) {} 836#endif /* !CONFIG_SUSPEND */ --- 233 unchanged lines hidden --- | 1003} 1004 1005#else /* !CONFIG_SUSPEND */ 1006#define s2idle_in_progress (false) 1007#define s2idle_wakeup (false) 1008#define lps0_device_handle (NULL) 1009static inline void acpi_sleep_suspend_setup(void) {} 1010#endif /* !CONFIG_SUSPEND */ --- 233 unchanged lines hidden --- |