diff options
author | Hans de Goede <hdegoede@redhat.com> | 2017-07-09 15:05:12 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2017-07-12 07:26:08 -0400 |
commit | 3b6a70be5ac81673af1ca8b4dae84743cb9fcc87 (patch) | |
tree | bf72bfd7f3793c116923bfd199723cfa5c300799 /drivers/acpi/x86/utils.c | |
parent | 6f7da290413ba713f0cdd9ff1a2a9bb129ef4f6c (diff) |
ACPI / x86: Allow matching always_present_id array entries by DMI
On some x86 systems the DSDT hides APCI devices to work around Windows
driver bugs. On one such system the device is even hidden until a certain
time after _SB.PCI0.GFX0.LCD.LCD1._ON gets called has passed *and*
_STA has been called at least 3 times since. TL;DR: it is a mess.
Until now the always_present_id matching was used to force status
for a whole class of devices, e.g. always enable PWM1 on CHerry Trail
devices.
This commit extends the always_present_id matching code to optionally
also check for a DMI match so that we can also add system specific
quirks to the always_present_id array.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi/x86/utils.c')
-rw-r--r-- | drivers/acpi/x86/utils.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c index bd86b809c848..b0e16516adfd 100644 --- a/drivers/acpi/x86/utils.c +++ b/drivers/acpi/x86/utils.c | |||
@@ -12,6 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/acpi.h> | 14 | #include <linux/acpi.h> |
15 | #include <linux/dmi.h> | ||
15 | #include <asm/cpu_device_id.h> | 16 | #include <asm/cpu_device_id.h> |
16 | #include <asm/intel-family.h> | 17 | #include <asm/intel-family.h> |
17 | #include "../internal.h" | 18 | #include "../internal.h" |
@@ -20,6 +21,10 @@ | |||
20 | * Some ACPI devices are hidden (status == 0x0) in recent BIOS-es because | 21 | * Some ACPI devices are hidden (status == 0x0) in recent BIOS-es because |
21 | * some recent Windows drivers bind to one device but poke at multiple | 22 | * some recent Windows drivers bind to one device but poke at multiple |
22 | * devices at the same time, so the others get hidden. | 23 | * devices at the same time, so the others get hidden. |
24 | * | ||
25 | * Some BIOS-es (temporarily) hide specific APCI devices to work around Windows | ||
26 | * driver bugs. We use DMI matching to match known cases of this. | ||
27 | * | ||
23 | * We work around this by always reporting ACPI_STA_DEFAULT for these | 28 | * We work around this by always reporting ACPI_STA_DEFAULT for these |
24 | * devices. Note this MUST only be done for devices where this is safe. | 29 | * devices. Note this MUST only be done for devices where this is safe. |
25 | * | 30 | * |
@@ -31,14 +36,16 @@ | |||
31 | struct always_present_id { | 36 | struct always_present_id { |
32 | struct acpi_device_id hid[2]; | 37 | struct acpi_device_id hid[2]; |
33 | struct x86_cpu_id cpu_ids[2]; | 38 | struct x86_cpu_id cpu_ids[2]; |
39 | struct dmi_system_id dmi_ids[2]; /* Optional */ | ||
34 | const char *uid; | 40 | const char *uid; |
35 | }; | 41 | }; |
36 | 42 | ||
37 | #define ICPU(model) { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, } | 43 | #define ICPU(model) { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, } |
38 | 44 | ||
39 | #define ENTRY(hid, uid, cpu_models) { \ | 45 | #define ENTRY(hid, uid, cpu_models, dmi...) { \ |
40 | { { hid, }, {} }, \ | 46 | { { hid, }, {} }, \ |
41 | { cpu_models, {} }, \ | 47 | { cpu_models, {} }, \ |
48 | { { .matches = dmi }, {} }, \ | ||
42 | uid, \ | 49 | uid, \ |
43 | } | 50 | } |
44 | 51 | ||
@@ -47,13 +54,13 @@ static const struct always_present_id always_present_ids[] = { | |||
47 | * Bay / Cherry Trail PWM directly poked by GPU driver in win10, | 54 | * Bay / Cherry Trail PWM directly poked by GPU driver in win10, |
48 | * but Linux uses a separate PWM driver, harmless if not used. | 55 | * but Linux uses a separate PWM driver, harmless if not used. |
49 | */ | 56 | */ |
50 | ENTRY("80860F09", "1", ICPU(INTEL_FAM6_ATOM_SILVERMONT1)), | 57 | ENTRY("80860F09", "1", ICPU(INTEL_FAM6_ATOM_SILVERMONT1), {}), |
51 | ENTRY("80862288", "1", ICPU(INTEL_FAM6_ATOM_AIRMONT)), | 58 | ENTRY("80862288", "1", ICPU(INTEL_FAM6_ATOM_AIRMONT), {}), |
52 | /* | 59 | /* |
53 | * The INT0002 device is necessary to clear wakeup interrupt sources | 60 | * The INT0002 device is necessary to clear wakeup interrupt sources |
54 | * on Cherry Trail devices, without it we get nobody cared IRQ msgs. | 61 | * on Cherry Trail devices, without it we get nobody cared IRQ msgs. |
55 | */ | 62 | */ |
56 | ENTRY("INT0002", "1", ICPU(INTEL_FAM6_ATOM_AIRMONT)), | 63 | ENTRY("INT0002", "1", ICPU(INTEL_FAM6_ATOM_AIRMONT), {}), |
57 | }; | 64 | }; |
58 | 65 | ||
59 | bool acpi_device_always_present(struct acpi_device *adev) | 66 | bool acpi_device_always_present(struct acpi_device *adev) |
@@ -76,6 +83,10 @@ bool acpi_device_always_present(struct acpi_device *adev) | |||
76 | if (!x86_match_cpu(always_present_ids[i].cpu_ids)) | 83 | if (!x86_match_cpu(always_present_ids[i].cpu_ids)) |
77 | continue; | 84 | continue; |
78 | 85 | ||
86 | if (always_present_ids[i].dmi_ids[0].matches[0].slot && | ||
87 | !dmi_check_system(always_present_ids[i].dmi_ids)) | ||
88 | continue; | ||
89 | |||
79 | if (old_status != ACPI_STA_DEFAULT) /* Log only once */ | 90 | if (old_status != ACPI_STA_DEFAULT) /* Log only once */ |
80 | dev_info(&adev->dev, | 91 | dev_info(&adev->dev, |
81 | "Device [%s] is in always present list\n", | 92 | "Device [%s] is in always present list\n", |