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 ---