forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/acpi/x86/utils.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * X86 ACPI Utility Functions
34 *
....@@ -5,10 +6,6 @@
56 *
67 * Based on various non upstream patches to support the CHT Whiskey Cove PMIC:
78 * 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.
129 */
1310
1411 #include <linux/acpi.h>
....@@ -25,53 +22,71 @@
2522 * Some BIOS-es (temporarily) hide specific APCI devices to work around Windows
2623 * driver bugs. We use DMI matching to match known cases of this.
2724 *
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.
25
+ * Likewise sometimes some not-actually present devices are sometimes
26
+ * reported as present, which may cause issues.
3027 *
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.
28
+ * We work around this by using the below quirk list to override the status
29
+ * reported by the _STA method with a fixed value (ACPI_STA_DEFAULT or 0).
30
+ * Note this MUST only be done for devices where this is safe.
31
+ *
32
+ * This status overriding is limited to specific CPU (SoC) models both to
33
+ * avoid potentially causing trouble on other models and because some HIDs
34
+ * are re-used on different SoCs for completely different devices.
3535 */
36
-struct always_present_id {
36
+struct override_status_id {
3737 struct acpi_device_id hid[2];
3838 struct x86_cpu_id cpu_ids[2];
3939 struct dmi_system_id dmi_ids[2]; /* Optional */
4040 const char *uid;
41
+ const char *path;
42
+ unsigned long long status;
4143 };
4244
43
-#define ICPU(model) { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, }
44
-
45
-#define ENTRY(hid, uid, cpu_models, dmi...) { \
45
+#define ENTRY(status, hid, uid, path, cpu_model, dmi...) { \
4646 { { hid, }, {} }, \
47
- { cpu_models, {} }, \
47
+ { X86_MATCH_INTEL_FAM6_MODEL(cpu_model, NULL), {} }, \
4848 { { .matches = dmi }, {} }, \
4949 uid, \
50
+ path, \
51
+ status, \
5052 }
5153
52
-static const struct always_present_id always_present_ids[] = {
54
+#define PRESENT_ENTRY_HID(hid, uid, cpu_model, dmi...) \
55
+ ENTRY(ACPI_STA_DEFAULT, hid, uid, NULL, cpu_model, dmi)
56
+
57
+#define NOT_PRESENT_ENTRY_HID(hid, uid, cpu_model, dmi...) \
58
+ ENTRY(0, hid, uid, NULL, cpu_model, dmi)
59
+
60
+#define PRESENT_ENTRY_PATH(path, cpu_model, dmi...) \
61
+ ENTRY(ACPI_STA_DEFAULT, "", NULL, path, cpu_model, dmi)
62
+
63
+#define NOT_PRESENT_ENTRY_PATH(path, cpu_model, dmi...) \
64
+ ENTRY(0, "", NULL, path, cpu_model, dmi)
65
+
66
+static const struct override_status_id override_status_ids[] = {
5367 /*
5468 * Bay / Cherry Trail PWM directly poked by GPU driver in win10,
5569 * but Linux uses a separate PWM driver, harmless if not used.
5670 */
57
- ENTRY("80860F09", "1", ICPU(INTEL_FAM6_ATOM_SILVERMONT), {}),
58
- ENTRY("80862288", "1", ICPU(INTEL_FAM6_ATOM_AIRMONT), {}),
71
+ PRESENT_ENTRY_HID("80860F09", "1", ATOM_SILVERMONT, {}),
72
+ PRESENT_ENTRY_HID("80862288", "1", ATOM_AIRMONT, {}),
73
+
5974 /*
6075 * The INT0002 device is necessary to clear wakeup interrupt sources
6176 * on Cherry Trail devices, without it we get nobody cared IRQ msgs.
6277 */
63
- ENTRY("INT0002", "1", ICPU(INTEL_FAM6_ATOM_AIRMONT), {}),
78
+ PRESENT_ENTRY_HID("INT0002", "1", ATOM_AIRMONT, {}),
6479 /*
6580 * On the Dell Venue 11 Pro 7130 and 7139, the DSDT hides
6681 * the touchscreen ACPI device until a certain time
6782 * after _SB.PCI0.GFX0.LCD.LCD1._ON gets called has passed
6883 * *and* _STA has been called at least 3 times since.
6984 */
70
- ENTRY("SYNA7500", "1", ICPU(INTEL_FAM6_HASWELL_ULT), {
85
+ PRESENT_ENTRY_HID("SYNA7500", "1", HASWELL_L, {
7186 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
7287 DMI_MATCH(DMI_PRODUCT_NAME, "Venue 11 Pro 7130"),
7388 }),
74
- ENTRY("SYNA7500", "1", ICPU(INTEL_FAM6_HASWELL_ULT), {
89
+ PRESENT_ENTRY_HID("SYNA7500", "1", HASWELL_L, {
7590 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
7691 DMI_MATCH(DMI_PRODUCT_NAME, "Venue 11 Pro 7139"),
7792 }),
....@@ -79,54 +94,83 @@
7994 /*
8095 * The GPD win BIOS dated 20170221 has disabled the accelerometer, the
8196 * 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.
97
+ * manufacturer has solved this :| The DMI match may not seem unique,
98
+ * but it is. In the 67000+ DMI decode dumps from linux-hardware.org
99
+ * only 116 have board_vendor set to "AMI Corporation" and of those 116
100
+ * only the GPD win and pocket entries' board_name is "Default string".
85101 *
86102 * Unfortunately the GPD pocket also uses these strings and its BIOS
87103 * was copy-pasted from the GPD win, so it has a disabled KIOX000A
88104 * node which we should not enable, thus we also check the BIOS date.
89105 */
90
- ENTRY("KIOX000A", "1", ICPU(INTEL_FAM6_ATOM_AIRMONT), {
106
+ PRESENT_ENTRY_HID("KIOX000A", "1", ATOM_AIRMONT, {
91107 DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
92108 DMI_MATCH(DMI_BOARD_NAME, "Default string"),
93109 DMI_MATCH(DMI_PRODUCT_NAME, "Default string"),
94110 DMI_MATCH(DMI_BIOS_DATE, "02/21/2017")
95111 }),
96
- ENTRY("KIOX000A", "1", ICPU(INTEL_FAM6_ATOM_AIRMONT), {
112
+ PRESENT_ENTRY_HID("KIOX000A", "1", ATOM_AIRMONT, {
97113 DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
98114 DMI_MATCH(DMI_BOARD_NAME, "Default string"),
99115 DMI_MATCH(DMI_PRODUCT_NAME, "Default string"),
100116 DMI_MATCH(DMI_BIOS_DATE, "03/20/2017")
101117 }),
102
- ENTRY("KIOX000A", "1", ICPU(INTEL_FAM6_ATOM_AIRMONT), {
118
+ PRESENT_ENTRY_HID("KIOX000A", "1", ATOM_AIRMONT, {
103119 DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
104120 DMI_MATCH(DMI_BOARD_NAME, "Default string"),
105121 DMI_MATCH(DMI_PRODUCT_NAME, "Default string"),
106122 DMI_MATCH(DMI_BIOS_DATE, "05/25/2017")
107123 }),
124
+
125
+ /*
126
+ * The GPD win/pocket have a PCI wifi card, but its DSDT has the SDIO
127
+ * mmc controller enabled and that has a child-device which _PS3
128
+ * method sets a GPIO causing the PCI wifi card to turn off.
129
+ * See above remark about uniqueness of the DMI match.
130
+ */
131
+ NOT_PRESENT_ENTRY_PATH("\\_SB_.PCI0.SDHB.BRC1", ATOM_AIRMONT, {
132
+ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
133
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
134
+ DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"),
135
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
136
+ }),
108137 };
109138
110
-bool acpi_device_always_present(struct acpi_device *adev)
139
+bool acpi_device_override_status(struct acpi_device *adev, unsigned long long *status)
111140 {
112141 bool ret = false;
113142 unsigned int i;
114143
115
- for (i = 0; i < ARRAY_SIZE(always_present_ids); i++) {
116
- if (acpi_match_device_ids(adev, always_present_ids[i].hid))
144
+ for (i = 0; i < ARRAY_SIZE(override_status_ids); i++) {
145
+ if (!x86_match_cpu(override_status_ids[i].cpu_ids))
117146 continue;
118147
119
- if (!adev->pnp.unique_id ||
120
- strcmp(adev->pnp.unique_id, always_present_ids[i].uid))
148
+ if (override_status_ids[i].dmi_ids[0].matches[0].slot &&
149
+ !dmi_check_system(override_status_ids[i].dmi_ids))
121150 continue;
122151
123
- if (!x86_match_cpu(always_present_ids[i].cpu_ids))
124
- continue;
152
+ if (override_status_ids[i].path) {
153
+ struct acpi_buffer path = { ACPI_ALLOCATE_BUFFER, NULL };
154
+ bool match;
125155
126
- if (always_present_ids[i].dmi_ids[0].matches[0].slot &&
127
- !dmi_check_system(always_present_ids[i].dmi_ids))
128
- continue;
156
+ if (acpi_get_name(adev->handle, ACPI_FULL_PATHNAME, &path))
157
+ continue;
129158
159
+ match = strcmp((char *)path.pointer, override_status_ids[i].path) == 0;
160
+ kfree(path.pointer);
161
+
162
+ if (!match)
163
+ continue;
164
+ } else {
165
+ if (acpi_match_device_ids(adev, override_status_ids[i].hid))
166
+ continue;
167
+
168
+ if (!adev->pnp.unique_id ||
169
+ strcmp(adev->pnp.unique_id, override_status_ids[i].uid))
170
+ continue;
171
+ }
172
+
173
+ *status = override_status_ids[i].status;
130174 ret = true;
131175 break;
132176 }