^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * X86 ACPI Utility Functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Based on various non upstream patches to support the CHT Whiskey Cove PMIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2013-2015 Intel Corporation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/dmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/cpu_device_id.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/intel-family.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "../internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Some ACPI devices are hidden (status == 0x0) in recent BIOS-es because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * some recent Windows drivers bind to one device but poke at multiple
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * devices at the same time, so the others get hidden.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * Some BIOS-es (temporarily) hide specific APCI devices to work around Windows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * driver bugs. We use DMI matching to match known cases of this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * Likewise sometimes some not-actually present devices are sometimes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * reported as present, which may cause issues.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * We work around this by using the below quirk list to override the status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * reported by the _STA method with a fixed value (ACPI_STA_DEFAULT or 0).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * Note this MUST only be done for devices where this is safe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * This status overriding is limited to specific CPU (SoC) models both to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * avoid potentially causing trouble on other models and because some HIDs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * are re-used on different SoCs for completely different devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct override_status_id {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct acpi_device_id hid[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct x86_cpu_id cpu_ids[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct dmi_system_id dmi_ids[2]; /* Optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) const char *uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) const char *path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) unsigned long long status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define ENTRY(status, hid, uid, path, cpu_model, dmi...) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) { { hid, }, {} }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) { X86_MATCH_INTEL_FAM6_MODEL(cpu_model, NULL), {} }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) { { .matches = dmi }, {} }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) uid, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) path, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) status, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define PRESENT_ENTRY_HID(hid, uid, cpu_model, dmi...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) ENTRY(ACPI_STA_DEFAULT, hid, uid, NULL, cpu_model, dmi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define NOT_PRESENT_ENTRY_HID(hid, uid, cpu_model, dmi...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) ENTRY(0, hid, uid, NULL, cpu_model, dmi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define PRESENT_ENTRY_PATH(path, cpu_model, dmi...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) ENTRY(ACPI_STA_DEFAULT, "", NULL, path, cpu_model, dmi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define NOT_PRESENT_ENTRY_PATH(path, cpu_model, dmi...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) ENTRY(0, "", NULL, path, cpu_model, dmi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static const struct override_status_id override_status_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * Bay / Cherry Trail PWM directly poked by GPU driver in win10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * but Linux uses a separate PWM driver, harmless if not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) PRESENT_ENTRY_HID("80860F09", "1", ATOM_SILVERMONT, {}),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) PRESENT_ENTRY_HID("80862288", "1", ATOM_AIRMONT, {}),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * The INT0002 device is necessary to clear wakeup interrupt sources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * on Cherry Trail devices, without it we get nobody cared IRQ msgs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) PRESENT_ENTRY_HID("INT0002", "1", ATOM_AIRMONT, {}),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * On the Dell Venue 11 Pro 7130 and 7139, the DSDT hides
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * the touchscreen ACPI device until a certain time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * after _SB.PCI0.GFX0.LCD.LCD1._ON gets called has passed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * *and* _STA has been called at least 3 times since.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) PRESENT_ENTRY_HID("SYNA7500", "1", HASWELL_L, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) DMI_MATCH(DMI_PRODUCT_NAME, "Venue 11 Pro 7130"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) PRESENT_ENTRY_HID("SYNA7500", "1", HASWELL_L, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) DMI_MATCH(DMI_PRODUCT_NAME, "Venue 11 Pro 7139"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * The GPD win BIOS dated 20170221 has disabled the accelerometer, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * drivers sometimes cause crashes under Windows and this is how the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * manufacturer has solved this :| The DMI match may not seem unique,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * but it is. In the 67000+ DMI decode dumps from linux-hardware.org
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * only 116 have board_vendor set to "AMI Corporation" and of those 116
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * only the GPD win and pocket entries' board_name is "Default string".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * Unfortunately the GPD pocket also uses these strings and its BIOS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * was copy-pasted from the GPD win, so it has a disabled KIOX000A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * node which we should not enable, thus we also check the BIOS date.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) PRESENT_ENTRY_HID("KIOX000A", "1", ATOM_AIRMONT, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) DMI_MATCH(DMI_BOARD_NAME, "Default string"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) DMI_MATCH(DMI_PRODUCT_NAME, "Default string"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) DMI_MATCH(DMI_BIOS_DATE, "02/21/2017")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) PRESENT_ENTRY_HID("KIOX000A", "1", ATOM_AIRMONT, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) DMI_MATCH(DMI_BOARD_NAME, "Default string"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) DMI_MATCH(DMI_PRODUCT_NAME, "Default string"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) DMI_MATCH(DMI_BIOS_DATE, "03/20/2017")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) PRESENT_ENTRY_HID("KIOX000A", "1", ATOM_AIRMONT, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) DMI_MATCH(DMI_BOARD_NAME, "Default string"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) DMI_MATCH(DMI_PRODUCT_NAME, "Default string"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) DMI_MATCH(DMI_BIOS_DATE, "05/25/2017")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * The GPD win/pocket have a PCI wifi card, but its DSDT has the SDIO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * mmc controller enabled and that has a child-device which _PS3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * method sets a GPIO causing the PCI wifi card to turn off.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * See above remark about uniqueness of the DMI match.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) NOT_PRESENT_ENTRY_PATH("\\_SB_.PCI0.SDHB.BRC1", ATOM_AIRMONT, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) bool acpi_device_override_status(struct acpi_device *adev, unsigned long long *status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) for (i = 0; i < ARRAY_SIZE(override_status_ids); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (!x86_match_cpu(override_status_ids[i].cpu_ids))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (override_status_ids[i].dmi_ids[0].matches[0].slot &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) !dmi_check_system(override_status_ids[i].dmi_ids))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (override_status_ids[i].path) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) struct acpi_buffer path = { ACPI_ALLOCATE_BUFFER, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) bool match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (acpi_get_name(adev->handle, ACPI_FULL_PATHNAME, &path))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) match = strcmp((char *)path.pointer, override_status_ids[i].path) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) kfree(path.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (!match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (acpi_match_device_ids(adev, override_status_ids[i].hid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (!adev->pnp.unique_id ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) strcmp(adev->pnp.unique_id, override_status_ids[i].uid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) *status = override_status_ids[i].status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }