Commit | Line | Data |
---|---|---|
b7ecf663 HG |
1 | /* |
2 | * X86 ACPI Utility Functions | |
3 | * | |
4 | * Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com> | |
5 | * | |
6 | * Based on various non upstream patches to support the CHT Whiskey Cove PMIC: | |
7 | * Copyright (C) 2013-2015 Intel Corporation. All rights reserved. | |
8 | * | |
9 | * This program is free software; you can redistribute it and/or modify | |
10 | * it under the terms of the GNU General Public License version 2 as | |
11 | * published by the Free Software Foundation. | |
12 | */ | |
13 | ||
14 | #include <linux/acpi.h> | |
3b6a70be | 15 | #include <linux/dmi.h> |
b7ecf663 HG |
16 | #include <asm/cpu_device_id.h> |
17 | #include <asm/intel-family.h> | |
18 | #include "../internal.h" | |
19 | ||
20 | /* | |
21 | * Some ACPI devices are hidden (status == 0x0) in recent BIOS-es because | |
22 | * some recent Windows drivers bind to one device but poke at multiple | |
23 | * devices at the same time, so the others get hidden. | |
3b6a70be HG |
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 | * | |
b7ecf663 HG |
28 | * We work around this by always reporting ACPI_STA_DEFAULT for these |
29 | * devices. Note this MUST only be done for devices where this is safe. | |
30 | * | |
31 | * This forcing of devices to be present is limited to specific CPU (SoC) | |
32 | * models both to avoid potentially causing trouble on other models and | |
33 | * because some HIDs are re-used on different SoCs for completely | |
34 | * different devices. | |
35 | */ | |
36 | struct always_present_id { | |
37 | struct acpi_device_id hid[2]; | |
38 | struct x86_cpu_id cpu_ids[2]; | |
3b6a70be | 39 | struct dmi_system_id dmi_ids[2]; /* Optional */ |
b7ecf663 HG |
40 | const char *uid; |
41 | }; | |
42 | ||
43 | #define ICPU(model) { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, } | |
44 | ||
3b6a70be | 45 | #define ENTRY(hid, uid, cpu_models, dmi...) { \ |
b7ecf663 HG |
46 | { { hid, }, {} }, \ |
47 | { cpu_models, {} }, \ | |
3b6a70be | 48 | { { .matches = dmi }, {} }, \ |
b7ecf663 HG |
49 | uid, \ |
50 | } | |
51 | ||
52 | static const struct always_present_id always_present_ids[] = { | |
53 | /* | |
54 | * Bay / Cherry Trail PWM directly poked by GPU driver in win10, | |
55 | * but Linux uses a separate PWM driver, harmless if not used. | |
56 | */ | |
3b6a70be HG |
57 | ENTRY("80860F09", "1", ICPU(INTEL_FAM6_ATOM_SILVERMONT1), {}), |
58 | ENTRY("80862288", "1", ICPU(INTEL_FAM6_ATOM_AIRMONT), {}), | |
753a448c HG |
59 | /* |
60 | * The INT0002 device is necessary to clear wakeup interrupt sources | |
61 | * on Cherry Trail devices, without it we get nobody cared IRQ msgs. | |
62 | */ | |
3b6a70be | 63 | ENTRY("INT0002", "1", ICPU(INTEL_FAM6_ATOM_AIRMONT), {}), |
b5cc1699 | 64 | /* |
72a361a5 TC |
65 | * On the Dell Venue 11 Pro 7130 and 7139, the DSDT hides |
66 | * the touchscreen ACPI device until a certain time | |
67 | * after _SB.PCI0.GFX0.LCD.LCD1._ON gets called has passed | |
68 | * *and* _STA has been called at least 3 times since. | |
b5cc1699 HG |
69 | */ |
70 | ENTRY("SYNA7500", "1", ICPU(INTEL_FAM6_HASWELL_ULT), { | |
71 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | |
72 | DMI_MATCH(DMI_PRODUCT_NAME, "Venue 11 Pro 7130"), | |
73 | }), | |
72a361a5 TC |
74 | ENTRY("SYNA7500", "1", ICPU(INTEL_FAM6_HASWELL_ULT), { |
75 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | |
76 | DMI_MATCH(DMI_PRODUCT_NAME, "Venue 11 Pro 7139"), | |
77 | }), | |
78 | ||
906dc284 | 79 | /* |
1c3b44c0 | 80 | * The GPD win BIOS dated 20170221 has disabled the accelerometer, the |
906dc284 HG |
81 | * drivers sometimes cause crashes under Windows and this is how the |
82 | * manufacturer has solved this :| Note that the the DMI data is less | |
83 | * generic then it seems, a board_vendor of "AMI Corporation" is quite | |
84 | * rare and a board_name of "Default String" also is rare. | |
1c3b44c0 HG |
85 | * |
86 | * Unfortunately the GPD pocket also uses these strings and its BIOS | |
87 | * was copy-pasted from the GPD win, so it has a disabled KIOX000A | |
88 | * node which we should not enable, thus we also check the BIOS date. | |
906dc284 | 89 | */ |
1c3b44c0 HG |
90 | ENTRY("KIOX000A", "1", ICPU(INTEL_FAM6_ATOM_AIRMONT), { |
91 | DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), | |
92 | DMI_MATCH(DMI_BOARD_NAME, "Default string"), | |
93 | DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), | |
94 | DMI_MATCH(DMI_BIOS_DATE, "02/21/2017") | |
95 | }), | |
906dc284 HG |
96 | ENTRY("KIOX000A", "1", ICPU(INTEL_FAM6_ATOM_AIRMONT), { |
97 | DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), | |
98 | DMI_MATCH(DMI_BOARD_NAME, "Default string"), | |
99 | DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), | |
100 | DMI_MATCH(DMI_BIOS_DATE, "03/20/2017") | |
101 | }), | |
1c3b44c0 HG |
102 | ENTRY("KIOX000A", "1", ICPU(INTEL_FAM6_ATOM_AIRMONT), { |
103 | DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), | |
104 | DMI_MATCH(DMI_BOARD_NAME, "Default string"), | |
105 | DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), | |
106 | DMI_MATCH(DMI_BIOS_DATE, "05/25/2017") | |
107 | }), | |
b7ecf663 HG |
108 | }; |
109 | ||
110 | bool acpi_device_always_present(struct acpi_device *adev) | |
111 | { | |
b7ecf663 HG |
112 | bool ret = false; |
113 | unsigned int i; | |
114 | ||
b7ecf663 HG |
115 | for (i = 0; i < ARRAY_SIZE(always_present_ids); i++) { |
116 | if (acpi_match_device_ids(adev, always_present_ids[i].hid)) | |
117 | continue; | |
118 | ||
119 | if (!adev->pnp.unique_id || | |
120 | strcmp(adev->pnp.unique_id, always_present_ids[i].uid)) | |
121 | continue; | |
122 | ||
123 | if (!x86_match_cpu(always_present_ids[i].cpu_ids)) | |
124 | continue; | |
125 | ||
3b6a70be HG |
126 | if (always_present_ids[i].dmi_ids[0].matches[0].slot && |
127 | !dmi_check_system(always_present_ids[i].dmi_ids)) | |
128 | continue; | |
129 | ||
b7ecf663 HG |
130 | ret = true; |
131 | break; | |
132 | } | |
b7ecf663 HG |
133 | |
134 | return ret; | |
135 | } |