@@ -363,38 +363,67 @@ static int validate_dsm(acpi_handle handle, const char *uuid, int rev, guid_t *d
363363 return ret ;
364364}
365365
366+ struct amd_lps0_hid_device_data {
367+ const unsigned int rev_id ;
368+ const bool check_off_by_one ;
369+ const bool prefer_amd_guid ;
370+ };
371+
372+ static const struct amd_lps0_hid_device_data amd_picasso = {
373+ .rev_id = 0 ,
374+ .check_off_by_one = true,
375+ .prefer_amd_guid = false,
376+ };
377+
378+ static const struct amd_lps0_hid_device_data amd_cezanne = {
379+ .rev_id = 0 ,
380+ .check_off_by_one = false,
381+ .prefer_amd_guid = false,
382+ };
383+
384+ static const struct amd_lps0_hid_device_data amd_rembrandt = {
385+ .rev_id = 2 ,
386+ .check_off_by_one = false,
387+ .prefer_amd_guid = true,
388+ };
389+
390+ static const struct acpi_device_id amd_hid_ids [] = {
391+ {"AMD0004" , (kernel_ulong_t )& amd_picasso , },
392+ {"AMD0005" , (kernel_ulong_t )& amd_picasso , },
393+ {"AMDI0005" , (kernel_ulong_t )& amd_picasso , },
394+ {"AMDI0006" , (kernel_ulong_t )& amd_cezanne , },
395+ {"AMDI0007" , (kernel_ulong_t )& amd_rembrandt , },
396+ {}
397+ };
398+
366399static int lps0_device_attach (struct acpi_device * adev ,
367400 const struct acpi_device_id * not_used )
368401{
369402 if (lps0_device_handle )
370403 return 0 ;
371404
372405 if (acpi_s2idle_vendor_amd ()) {
373- /* AMD0004, AMD0005, AMDI0005:
374- * - Should use rev_id 0x0
375- * - function mask > 0x3: Should use AMD method, but has off by one bug
376- * - function mask = 0x3: Should use Microsoft method
377- * AMDI0006:
378- * - should use rev_id 0x0
379- * - function mask = 0x3: Should use Microsoft method
380- * AMDI0007:
381- * - Should use rev_id 0x2
382- * - Should only use AMD method
383- */
384- const char * hid = acpi_device_hid (adev );
385- rev_id = strcmp (hid , "AMDI0007" ) ? 0 : 2 ;
406+ static const struct acpi_device_id * dev_id ;
407+ const struct amd_lps0_hid_device_data * data ;
408+
409+ for (dev_id = & amd_hid_ids [0 ]; dev_id -> id [0 ]; dev_id ++ )
410+ if (acpi_dev_hid_uid_match (adev , dev_id -> id , NULL ))
411+ break ;
412+ if (dev_id )
413+ data = (const struct amd_lps0_hid_device_data * ) dev_id -> driver_data ;
414+ else
415+ return 0 ;
416+ rev_id = data -> rev_id ;
386417 lps0_dsm_func_mask = validate_dsm (adev -> handle ,
387418 ACPI_LPS0_DSM_UUID_AMD , rev_id , & lps0_dsm_guid );
388419 lps0_dsm_func_mask_microsoft = validate_dsm (adev -> handle ,
389420 ACPI_LPS0_DSM_UUID_MICROSOFT , 0 ,
390421 & lps0_dsm_guid_microsoft );
391- if (lps0_dsm_func_mask > 0x3 && (!strcmp (hid , "AMD0004" ) ||
392- !strcmp (hid , "AMD0005" ) ||
393- !strcmp (hid , "AMDI0005" ))) {
422+ if (lps0_dsm_func_mask > 0x3 && data -> check_off_by_one ) {
394423 lps0_dsm_func_mask = (lps0_dsm_func_mask << 1 ) | 0x1 ;
395424 acpi_handle_debug (adev -> handle , "_DSM UUID %s: Adjusted function mask: 0x%x\n" ,
396425 ACPI_LPS0_DSM_UUID_AMD , lps0_dsm_func_mask );
397- } else if (lps0_dsm_func_mask_microsoft > 0 &&
426+ } else if (lps0_dsm_func_mask_microsoft > 0 && data -> prefer_amd_guid &&
398427 (!strcmp (hid , "AMDI0007" ) ||
399428 !strcmp (hid , "AMDI0008" ))) {
400429 lps0_dsm_func_mask_microsoft = - EINVAL ;
0 commit comments