aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/x86/utils.c
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2017-07-09 15:05:12 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2017-07-12 07:26:08 -0400
commit3b6a70be5ac81673af1ca8b4dae84743cb9fcc87 (patch)
treebf72bfd7f3793c116923bfd199723cfa5c300799 /drivers/acpi/x86/utils.c
parent6f7da290413ba713f0cdd9ff1a2a9bb129ef4f6c (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.c19
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 @@
31struct always_present_id { 36struct 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
59bool acpi_device_always_present(struct acpi_device *adev) 66bool 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",