@@ -669,6 +669,7 @@ static const struct acpi_device_id lps0_device_ids[] = {
669
669
670
670
#define ACPI_LPS0_DSM_UUID "c4eb40a0-6cd2-11e2-bcfd-0800200c9a66"
671
671
672
+ #define ACPI_LPS0_GET_DEVICE_CONSTRAINTS 1
672
673
#define ACPI_LPS0_SCREEN_OFF 3
673
674
#define ACPI_LPS0_SCREEN_ON 4
674
675
#define ACPI_LPS0_ENTRY 5
@@ -680,6 +681,166 @@ static acpi_handle lps0_device_handle;
680
681
static guid_t lps0_dsm_guid ;
681
682
static char lps0_dsm_func_mask ;
682
683
684
+ /* Device constraint entry structure */
685
+ struct lpi_device_info {
686
+ char * name ;
687
+ int enabled ;
688
+ union acpi_object * package ;
689
+ };
690
+
691
+ /* Constraint package structure */
692
+ struct lpi_device_constraint {
693
+ int uid ;
694
+ int min_dstate ;
695
+ int function_states ;
696
+ };
697
+
698
+ struct lpi_constraints {
699
+ acpi_handle handle ;
700
+ int min_dstate ;
701
+ };
702
+
703
+ static struct lpi_constraints * lpi_constraints_table ;
704
+ static int lpi_constraints_table_size ;
705
+
706
+ static 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
+
812
+ free_acpi_buffer :
813
+ ACPI_FREE (out_obj );
814
+ }
815
+
816
+ static 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
+
683
844
static void acpi_sleep_run_lps0_dsm (unsigned int func )
684
845
{
685
846
union acpi_object * out_obj ;
@@ -714,6 +875,12 @@ static int lps0_device_attach(struct acpi_device *adev,
714
875
if ((bitmask & ACPI_S2IDLE_FUNC_MASK ) == ACPI_S2IDLE_FUNC_MASK ) {
715
876
lps0_dsm_func_mask = bitmask ;
716
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
884
}
718
885
719
886
acpi_handle_debug (adev -> handle , "_DSM function mask: 0x%x\n" ,
@@ -723,6 +890,9 @@ static int lps0_device_attach(struct acpi_device *adev,
723
890
"_DSM function 0 evaluation failed\n" );
724
891
}
725
892
ACPI_FREE (out_obj );
893
+
894
+ lpi_device_get_constraints ();
895
+
726
896
return 0 ;
727
897
}
728
898
@@ -731,14 +901,14 @@ static struct acpi_scan_handler lps0_handler = {
731
901
.attach = lps0_device_attach ,
732
902
};
733
903
734
- static int acpi_freeze_begin (void )
904
+ static int acpi_s2idle_begin (void )
735
905
{
736
906
acpi_scan_lock_acquire ();
737
907
s2idle_in_progress = true;
738
908
return 0 ;
739
909
}
740
910
741
- static int acpi_freeze_prepare (void )
911
+ static int acpi_s2idle_prepare (void )
742
912
{
743
913
if (lps0_device_handle ) {
744
914
acpi_sleep_run_lps0_dsm (ACPI_LPS0_SCREEN_OFF );
@@ -758,8 +928,12 @@ static int acpi_freeze_prepare(void)
758
928
return 0 ;
759
929
}
760
930
761
- static void acpi_freeze_wake (void )
931
+ static void acpi_s2idle_wake (void )
762
932
{
933
+
934
+ if (pm_debug_messages_on )
935
+ lpi_check_constraints ();
936
+
763
937
/*
764
938
* If IRQD_WAKEUP_ARMED is not set for the SCI at this point, it means
765
939
* that the SCI has triggered while suspended, so cancel the wakeup in
@@ -772,7 +946,7 @@ static void acpi_freeze_wake(void)
772
946
}
773
947
}
774
948
775
- static void acpi_freeze_sync (void )
949
+ static void acpi_s2idle_sync (void )
776
950
{
777
951
/*
778
952
* Process all pending events in case there are any wakeup ones.
@@ -785,7 +959,7 @@ static void acpi_freeze_sync(void)
785
959
s2idle_wakeup = false;
786
960
}
787
961
788
- static void acpi_freeze_restore (void )
962
+ static void acpi_s2idle_restore (void )
789
963
{
790
964
if (acpi_sci_irq_valid ())
791
965
disable_irq_wake (acpi_sci_irq );
@@ -798,19 +972,19 @@ static void acpi_freeze_restore(void)
798
972
}
799
973
}
800
974
801
- static void acpi_freeze_end (void )
975
+ static void acpi_s2idle_end (void )
802
976
{
803
977
s2idle_in_progress = false;
804
978
acpi_scan_lock_release ();
805
979
}
806
980
807
- static 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 ,
981
+ static 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
988
};
815
989
816
990
static void acpi_sleep_suspend_setup (void )
@@ -825,7 +999,7 @@ static void acpi_sleep_suspend_setup(void)
825
999
& acpi_suspend_ops_old : & acpi_suspend_ops );
826
1000
827
1001
acpi_scan_add_handler (& lps0_handler );
828
- freeze_set_ops ( & acpi_freeze_ops );
1002
+ s2idle_set_ops ( & acpi_s2idle_ops );
829
1003
}
830
1004
831
1005
#else /* !CONFIG_SUSPEND */
0 commit comments