Skip to content

Commit

Permalink
ACPI: x86: s2idle: Move _HID handling for AMD systems into structures
Browse files Browse the repository at this point in the history
Right now the information about which cases to use for what are in a
comment, but this is error prone.  Instead move all information into
a dedicated structure.

Tested-by: catalin@antebit.com
Reviewed-by: Philipp Zabel <philipp.zabel@gmail.com>
Tested-by: Philipp Zabel <philipp.zabel@gmail.com> # GA402RJ
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  • Loading branch information
superm1 authored and rafaeljw committed Sep 25, 2022
1 parent 0efe92b commit 100a573
Showing 1 changed file with 46 additions and 17 deletions.
63 changes: 46 additions & 17 deletions drivers/acpi/x86/s2idle.c
Original file line number Diff line number Diff line change
Expand Up @@ -363,38 +363,67 @@ static int validate_dsm(acpi_handle handle, const char *uuid, int rev, guid_t *d
return ret;
}

struct amd_lps0_hid_device_data {
const unsigned int rev_id;
const bool check_off_by_one;
const bool prefer_amd_guid;
};

static const struct amd_lps0_hid_device_data amd_picasso = {
.rev_id = 0,
.check_off_by_one = true,
.prefer_amd_guid = false,
};

static const struct amd_lps0_hid_device_data amd_cezanne = {
.rev_id = 0,
.check_off_by_one = false,
.prefer_amd_guid = false,
};

static const struct amd_lps0_hid_device_data amd_rembrandt = {
.rev_id = 2,
.check_off_by_one = false,
.prefer_amd_guid = true,
};

static const struct acpi_device_id amd_hid_ids[] = {
{"AMD0004", (kernel_ulong_t)&amd_picasso, },
{"AMD0005", (kernel_ulong_t)&amd_picasso, },
{"AMDI0005", (kernel_ulong_t)&amd_picasso, },
{"AMDI0006", (kernel_ulong_t)&amd_cezanne, },
{"AMDI0007", (kernel_ulong_t)&amd_rembrandt, },
{}
};

static int lps0_device_attach(struct acpi_device *adev,
const struct acpi_device_id *not_used)
{
if (lps0_device_handle)
return 0;

if (acpi_s2idle_vendor_amd()) {
/* AMD0004, AMD0005, AMDI0005:
* - Should use rev_id 0x0
* - function mask > 0x3: Should use AMD method, but has off by one bug
* - function mask = 0x3: Should use Microsoft method
* AMDI0006:
* - should use rev_id 0x0
* - function mask = 0x3: Should use Microsoft method
* AMDI0007:
* - Should use rev_id 0x2
* - Should only use AMD method
*/
const char *hid = acpi_device_hid(adev);
rev_id = strcmp(hid, "AMDI0007") ? 0 : 2;
static const struct acpi_device_id *dev_id;
const struct amd_lps0_hid_device_data *data;

for (dev_id = &amd_hid_ids[0]; dev_id->id[0]; dev_id++)
if (acpi_dev_hid_uid_match(adev, dev_id->id, NULL))
break;
if (dev_id)
data = (const struct amd_lps0_hid_device_data *) dev_id->driver_data;
else
return 0;
rev_id = data->rev_id;
lps0_dsm_func_mask = validate_dsm(adev->handle,
ACPI_LPS0_DSM_UUID_AMD, rev_id, &lps0_dsm_guid);
lps0_dsm_func_mask_microsoft = validate_dsm(adev->handle,
ACPI_LPS0_DSM_UUID_MICROSOFT, 0,
&lps0_dsm_guid_microsoft);
if (lps0_dsm_func_mask > 0x3 && (!strcmp(hid, "AMD0004") ||
!strcmp(hid, "AMD0005") ||
!strcmp(hid, "AMDI0005"))) {
if (lps0_dsm_func_mask > 0x3 && data->check_off_by_one) {
lps0_dsm_func_mask = (lps0_dsm_func_mask << 1) | 0x1;
acpi_handle_debug(adev->handle, "_DSM UUID %s: Adjusted function mask: 0x%x\n",
ACPI_LPS0_DSM_UUID_AMD, lps0_dsm_func_mask);
} else if (lps0_dsm_func_mask_microsoft > 0 &&
} else if (lps0_dsm_func_mask_microsoft > 0 && data->prefer_amd_guid &&
(!strcmp(hid, "AMDI0007") ||
!strcmp(hid, "AMDI0008"))) {
lps0_dsm_func_mask_microsoft = -EINVAL;
Expand Down

0 comments on commit 100a573

Please sign in to comment.