@@ -49,7 +49,7 @@ static const struct acpi_device_id lps0_device_ids[] = {
4949
5050static acpi_handle lps0_device_handle ;
5151static guid_t lps0_dsm_guid ;
52- static char lps0_dsm_func_mask ;
52+ static int lps0_dsm_func_mask ;
5353
5454/* Device constraint entry structure */
5555struct lpi_device_info {
@@ -70,15 +70,7 @@ struct lpi_constraints {
7070 int min_dstate ;
7171};
7272
73- /* AMD */
74- /* Device constraint entry structure */
75- struct lpi_device_info_amd {
76- int revision ;
77- int count ;
78- union acpi_object * package ;
79- };
80-
81- /* Constraint package structure */
73+ /* AMD Constraint package structure */
8274struct lpi_device_constraint_amd {
8375 char * name ;
8476 int enabled ;
@@ -99,12 +91,12 @@ static void lpi_device_get_constraints_amd(void)
9991 rev_id , ACPI_LPS0_GET_DEVICE_CONSTRAINTS ,
10092 NULL , ACPI_TYPE_PACKAGE );
10193
102- if (!out_obj )
103- return ;
104-
10594 acpi_handle_debug (lps0_device_handle , "_DSM function 1 eval %s\n" ,
10695 out_obj ? "successful" : "failed" );
10796
97+ if (!out_obj )
98+ return ;
99+
108100 for (i = 0 ; i < out_obj -> package .count ; i ++ ) {
109101 union acpi_object * package = & out_obj -> package .elements [i ];
110102
@@ -336,40 +328,51 @@ static bool acpi_s2idle_vendor_amd(void)
336328 return boot_cpu_data .x86_vendor == X86_VENDOR_AMD ;
337329}
338330
331+ static int validate_dsm (acpi_handle handle , const char * uuid , int rev , guid_t * dsm_guid )
332+ {
333+ union acpi_object * obj ;
334+ int ret = - EINVAL ;
335+
336+ guid_parse (uuid , dsm_guid );
337+ obj = acpi_evaluate_dsm (handle , dsm_guid , rev , 0 , NULL );
338+
339+ /* Check if the _DSM is present and as expected. */
340+ if (!obj || obj -> type != ACPI_TYPE_BUFFER || obj -> buffer .length == 0 ||
341+ obj -> buffer .length > sizeof (u32 )) {
342+ acpi_handle_debug (handle ,
343+ "_DSM UUID %s rev %d function 0 evaluation failed\n" , uuid , rev );
344+ goto out ;
345+ }
346+
347+ ret = * (int * )obj -> buffer .pointer ;
348+ acpi_handle_debug (handle , "_DSM UUID %s rev %d function mask: 0x%x\n" , uuid , rev , ret );
349+
350+ out :
351+ ACPI_FREE (obj );
352+ return ret ;
353+ }
354+
339355static int lps0_device_attach (struct acpi_device * adev ,
340356 const struct acpi_device_id * not_used )
341357{
342- union acpi_object * out_obj ;
343-
344358 if (lps0_device_handle )
345359 return 0 ;
346360
347361 if (!(acpi_gbl_FADT .flags & ACPI_FADT_LOW_POWER_S0 ))
348362 return 0 ;
349363
350364 if (acpi_s2idle_vendor_amd ()) {
351- guid_parse (ACPI_LPS0_DSM_UUID_AMD , & lps0_dsm_guid );
352- out_obj = acpi_evaluate_dsm (adev -> handle , & lps0_dsm_guid , 0 , 0 , NULL );
353365 rev_id = 0 ;
366+ lps0_dsm_func_mask = validate_dsm (adev -> handle ,
367+ ACPI_LPS0_DSM_UUID_AMD , rev_id , & lps0_dsm_guid );
354368 } else {
355- guid_parse (ACPI_LPS0_DSM_UUID , & lps0_dsm_guid );
356- out_obj = acpi_evaluate_dsm (adev -> handle , & lps0_dsm_guid , 1 , 0 , NULL );
357369 rev_id = 1 ;
370+ lps0_dsm_func_mask = validate_dsm (adev -> handle ,
371+ ACPI_LPS0_DSM_UUID , rev_id , & lps0_dsm_guid );
358372 }
359373
360- /* Check if the _DSM is present and as expected. */
361- if (!out_obj || out_obj -> type != ACPI_TYPE_BUFFER ) {
362- acpi_handle_debug (adev -> handle ,
363- "_DSM function 0 evaluation failed\n" );
364- return 0 ;
365- }
366-
367- lps0_dsm_func_mask = * (char * )out_obj -> buffer .pointer ;
368-
369- ACPI_FREE (out_obj );
370-
371- acpi_handle_debug (adev -> handle , "_DSM function mask: 0x%x\n" ,
372- lps0_dsm_func_mask );
374+ if (lps0_dsm_func_mask < 0 )
375+ return 0 ;//function eval failed
373376
374377 lps0_device_handle = adev -> handle ;
375378
0 commit comments