Skip to content

Commit 4c2fe64

Browse files
author
Herton R. Krzesinski
committed
Merge: Use MFST GUID instead of AMD GUID
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/1839 The MFST GUID turns out to be a better choice as its used by Windows as well. Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2158310 Tested: To be performed by partner Signed-off-by: David Arcari <darcari@redhat.com> Approved-by: Mark Langsdorf <mlangsdo@redhat.com> Approved-by: Prarit Bhargava <prarit@redhat.com> Signed-off-by: Herton R. Krzesinski <herton@redhat.com>
2 parents 456fdee + a327676 commit 4c2fe64

File tree

5 files changed

+81
-23
lines changed

5 files changed

+81
-23
lines changed

drivers/acpi/sleep.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ static inline acpi_status acpi_set_waking_vector(u32 wakeup_address)
1818
extern int acpi_s2idle_begin(void);
1919
extern int acpi_s2idle_prepare(void);
2020
extern int acpi_s2idle_prepare_late(void);
21+
extern void acpi_s2idle_check(void);
2122
extern bool acpi_s2idle_wake(void);
2223
extern void acpi_s2idle_restore_early(void);
2324
extern void acpi_s2idle_restore(void);

drivers/acpi/x86/s2idle.c

Lines changed: 75 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include <linux/acpi.h>
1919
#include <linux/device.h>
20+
#include <linux/dmi.h>
2021
#include <linux/suspend.h>
2122

2223
#include "../sleep.h"
@@ -363,40 +364,76 @@ static int validate_dsm(acpi_handle handle, const char *uuid, int rev, guid_t *d
363364
return ret;
364365
}
365366

367+
struct amd_lps0_hid_device_data {
368+
const bool check_off_by_one;
369+
};
370+
371+
static const struct amd_lps0_hid_device_data amd_picasso = {
372+
.check_off_by_one = true,
373+
};
374+
375+
static const struct amd_lps0_hid_device_data amd_cezanne = {
376+
.check_off_by_one = false,
377+
};
378+
379+
static const struct acpi_device_id amd_hid_ids[] = {
380+
{"AMD0004", (kernel_ulong_t)&amd_picasso, },
381+
{"AMD0005", (kernel_ulong_t)&amd_picasso, },
382+
{"AMDI0005", (kernel_ulong_t)&amd_picasso, },
383+
{"AMDI0006", (kernel_ulong_t)&amd_cezanne, },
384+
{}
385+
};
386+
387+
static int lps0_prefer_amd(const struct dmi_system_id *id)
388+
{
389+
pr_debug("Using AMD GUID w/ _REV 2.\n");
390+
rev_id = 2;
391+
return 0;
392+
}
393+
static const struct dmi_system_id s2idle_dmi_table[] __initconst = {
394+
{
395+
/*
396+
* AMD Rembrandt based HP EliteBook 835/845/865 G9
397+
* Contains specialized AML in AMD/_REV 2 path to avoid
398+
* triggering a bug in Qualcomm WLAN firmware. This may be
399+
* removed in the future if that firmware is fixed.
400+
*/
401+
.callback = lps0_prefer_amd,
402+
.matches = {
403+
DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
404+
DMI_MATCH(DMI_BOARD_NAME, "8990"),
405+
},
406+
},
407+
{}
408+
};
409+
366410
static int lps0_device_attach(struct acpi_device *adev,
367411
const struct acpi_device_id *not_used)
368412
{
369413
if (lps0_device_handle)
370414
return 0;
371415

416+
lps0_dsm_func_mask_microsoft = validate_dsm(adev->handle,
417+
ACPI_LPS0_DSM_UUID_MICROSOFT, 0,
418+
&lps0_dsm_guid_microsoft);
372419
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;
420+
static const struct acpi_device_id *dev_id;
421+
const struct amd_lps0_hid_device_data *data;
422+
423+
for (dev_id = &amd_hid_ids[0]; dev_id->id[0]; dev_id++)
424+
if (acpi_dev_hid_uid_match(adev, dev_id->id, NULL))
425+
break;
426+
if (dev_id->id[0])
427+
data = (const struct amd_lps0_hid_device_data *) dev_id->driver_data;
428+
else
429+
data = &amd_cezanne;
386430
lps0_dsm_func_mask = validate_dsm(adev->handle,
387431
ACPI_LPS0_DSM_UUID_AMD, rev_id, &lps0_dsm_guid);
388-
lps0_dsm_func_mask_microsoft = validate_dsm(adev->handle,
389-
ACPI_LPS0_DSM_UUID_MICROSOFT, 0,
390-
&lps0_dsm_guid_microsoft);
391-
if (lps0_dsm_func_mask > 0x3 && (!strcmp(hid, "AMD0004") ||
392-
!strcmp(hid, "AMD0005") ||
393-
!strcmp(hid, "AMDI0005"))) {
432+
if (lps0_dsm_func_mask > 0x3 && data->check_off_by_one) {
394433
lps0_dsm_func_mask = (lps0_dsm_func_mask << 1) | 0x1;
395434
acpi_handle_debug(adev->handle, "_DSM UUID %s: Adjusted function mask: 0x%x\n",
396435
ACPI_LPS0_DSM_UUID_AMD, lps0_dsm_func_mask);
397-
} else if (lps0_dsm_func_mask_microsoft > 0 &&
398-
(!strcmp(hid, "AMDI0007") ||
399-
!strcmp(hid, "AMDI0008"))) {
436+
} else if (lps0_dsm_func_mask_microsoft > 0 && rev_id) {
400437
lps0_dsm_func_mask_microsoft = -EINVAL;
401438
acpi_handle_debug(adev->handle, "_DSM Using AMD method\n");
402439
}
@@ -486,6 +523,19 @@ int acpi_s2idle_prepare_late(void)
486523
return 0;
487524
}
488525

526+
void acpi_s2idle_check(void)
527+
{
528+
struct acpi_s2idle_dev_ops *handler;
529+
530+
if (!lps0_device_handle || sleep_no_lps0)
531+
return;
532+
533+
list_for_each_entry(handler, &lps0_s2idle_devops_head, list_node) {
534+
if (handler->check)
535+
handler->check();
536+
}
537+
}
538+
489539
void acpi_s2idle_restore_early(void)
490540
{
491541
struct acpi_s2idle_dev_ops *handler;
@@ -527,14 +577,16 @@ static const struct platform_s2idle_ops acpi_s2idle_ops_lps0 = {
527577
.begin = acpi_s2idle_begin,
528578
.prepare = acpi_s2idle_prepare,
529579
.prepare_late = acpi_s2idle_prepare_late,
580+
.check = acpi_s2idle_check,
530581
.wake = acpi_s2idle_wake,
531582
.restore_early = acpi_s2idle_restore_early,
532583
.restore = acpi_s2idle_restore,
533584
.end = acpi_s2idle_end,
534585
};
535586

536-
void acpi_s2idle_setup(void)
587+
void __init acpi_s2idle_setup(void)
537588
{
589+
dmi_check_system(s2idle_dmi_table);
538590
acpi_scan_add_handler(&lps0_handler);
539591
s2idle_set_ops(&acpi_s2idle_ops_lps0);
540592
}

include/linux/acpi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,7 @@ acpi_status acpi_os_prepare_extended_sleep(u8 sleep_state,
10651065
struct acpi_s2idle_dev_ops {
10661066
struct list_head list_node;
10671067
void (*prepare)(void);
1068+
void (*check)(void);
10681069
void (*restore)(void);
10691070
};
10701071
int acpi_register_lps0_dev(struct acpi_s2idle_dev_ops *arg);

include/linux/suspend.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ struct platform_s2idle_ops {
191191
int (*begin)(void);
192192
int (*prepare)(void);
193193
int (*prepare_late)(void);
194+
void (*check)(void);
194195
bool (*wake)(void);
195196
void (*restore_early)(void);
196197
void (*restore)(void);

kernel/power/suspend.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@ static void s2idle_loop(void)
136136
break;
137137
}
138138

139+
if (s2idle_ops && s2idle_ops->check)
140+
s2idle_ops->check();
141+
139142
s2idle_enter();
140143
}
141144

0 commit comments

Comments
 (0)