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