1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2b7ecf663SHans de Goede /* 3b7ecf663SHans de Goede * X86 ACPI Utility Functions 4b7ecf663SHans de Goede * 5b7ecf663SHans de Goede * Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com> 6b7ecf663SHans de Goede * 7b7ecf663SHans de Goede * Based on various non upstream patches to support the CHT Whiskey Cove PMIC: 8b7ecf663SHans de Goede * Copyright (C) 2013-2015 Intel Corporation. All rights reserved. 9b7ecf663SHans de Goede */ 10b7ecf663SHans de Goede 11b7ecf663SHans de Goede #include <linux/acpi.h> 123b6a70beSHans de Goede #include <linux/dmi.h> 13*35f9e773SHans de Goede #include <linux/platform_device.h> 14b7ecf663SHans de Goede #include <asm/cpu_device_id.h> 15b7ecf663SHans de Goede #include <asm/intel-family.h> 16b7ecf663SHans de Goede #include "../internal.h" 17b7ecf663SHans de Goede 18b7ecf663SHans de Goede /* 19b7ecf663SHans de Goede * Some ACPI devices are hidden (status == 0x0) in recent BIOS-es because 20b7ecf663SHans de Goede * some recent Windows drivers bind to one device but poke at multiple 21b7ecf663SHans de Goede * devices at the same time, so the others get hidden. 223b6a70beSHans de Goede * 233b6a70beSHans de Goede * Some BIOS-es (temporarily) hide specific APCI devices to work around Windows 243b6a70beSHans de Goede * driver bugs. We use DMI matching to match known cases of this. 253b6a70beSHans de Goede * 26b7ecf663SHans de Goede * We work around this by always reporting ACPI_STA_DEFAULT for these 27b7ecf663SHans de Goede * devices. Note this MUST only be done for devices where this is safe. 28b7ecf663SHans de Goede * 29b7ecf663SHans de Goede * This forcing of devices to be present is limited to specific CPU (SoC) 30b7ecf663SHans de Goede * models both to avoid potentially causing trouble on other models and 31b7ecf663SHans de Goede * because some HIDs are re-used on different SoCs for completely 32b7ecf663SHans de Goede * different devices. 33b7ecf663SHans de Goede */ 34b7ecf663SHans de Goede struct always_present_id { 35b7ecf663SHans de Goede struct acpi_device_id hid[2]; 36b7ecf663SHans de Goede struct x86_cpu_id cpu_ids[2]; 373b6a70beSHans de Goede struct dmi_system_id dmi_ids[2]; /* Optional */ 38b7ecf663SHans de Goede const char *uid; 39b7ecf663SHans de Goede }; 40b7ecf663SHans de Goede 41e36cf2f7SThomas Gleixner #define X86_MATCH(model) X86_MATCH_INTEL_FAM6_MODEL(model, NULL) 42b7ecf663SHans de Goede 433b6a70beSHans de Goede #define ENTRY(hid, uid, cpu_models, dmi...) { \ 44b7ecf663SHans de Goede { { hid, }, {} }, \ 45b7ecf663SHans de Goede { cpu_models, {} }, \ 463b6a70beSHans de Goede { { .matches = dmi }, {} }, \ 47b7ecf663SHans de Goede uid, \ 48b7ecf663SHans de Goede } 49b7ecf663SHans de Goede 50b7ecf663SHans de Goede static const struct always_present_id always_present_ids[] = { 51b7ecf663SHans de Goede /* 52b7ecf663SHans de Goede * Bay / Cherry Trail PWM directly poked by GPU driver in win10, 53b7ecf663SHans de Goede * but Linux uses a separate PWM driver, harmless if not used. 54b7ecf663SHans de Goede */ 55e36cf2f7SThomas Gleixner ENTRY("80860F09", "1", X86_MATCH(ATOM_SILVERMONT), {}), 56e36cf2f7SThomas Gleixner ENTRY("80862288", "1", X86_MATCH(ATOM_AIRMONT), {}), 57ff6cdfd7SYauhen Kharuzhy 58ff6cdfd7SYauhen Kharuzhy /* Lenovo Yoga Book uses PWM2 for keyboard backlight control */ 59e36cf2f7SThomas Gleixner ENTRY("80862289", "2", X86_MATCH(ATOM_AIRMONT), { 60ff6cdfd7SYauhen Kharuzhy DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9"), 61ff6cdfd7SYauhen Kharuzhy }), 62753a448cSHans de Goede /* 63753a448cSHans de Goede * The INT0002 device is necessary to clear wakeup interrupt sources 64753a448cSHans de Goede * on Cherry Trail devices, without it we get nobody cared IRQ msgs. 65753a448cSHans de Goede */ 66e36cf2f7SThomas Gleixner ENTRY("INT0002", "1", X86_MATCH(ATOM_AIRMONT), {}), 67b5cc1699SHans de Goede /* 6872a361a5STristian Celestin * On the Dell Venue 11 Pro 7130 and 7139, the DSDT hides 6972a361a5STristian Celestin * the touchscreen ACPI device until a certain time 7072a361a5STristian Celestin * after _SB.PCI0.GFX0.LCD.LCD1._ON gets called has passed 7172a361a5STristian Celestin * *and* _STA has been called at least 3 times since. 72b5cc1699SHans de Goede */ 73e36cf2f7SThomas Gleixner ENTRY("SYNA7500", "1", X86_MATCH(HASWELL_L), { 74b5cc1699SHans de Goede DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 75b5cc1699SHans de Goede DMI_MATCH(DMI_PRODUCT_NAME, "Venue 11 Pro 7130"), 76b5cc1699SHans de Goede }), 77e36cf2f7SThomas Gleixner ENTRY("SYNA7500", "1", X86_MATCH(HASWELL_L), { 7872a361a5STristian Celestin DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 7972a361a5STristian Celestin DMI_MATCH(DMI_PRODUCT_NAME, "Venue 11 Pro 7139"), 8072a361a5STristian Celestin }), 8172a361a5STristian Celestin 82906dc284SHans de Goede /* 831c3b44c0SHans de Goede * The GPD win BIOS dated 20170221 has disabled the accelerometer, the 84906dc284SHans de Goede * drivers sometimes cause crashes under Windows and this is how the 85906dc284SHans de Goede * manufacturer has solved this :| Note that the the DMI data is less 86906dc284SHans de Goede * generic then it seems, a board_vendor of "AMI Corporation" is quite 87906dc284SHans de Goede * rare and a board_name of "Default String" also is rare. 881c3b44c0SHans de Goede * 891c3b44c0SHans de Goede * Unfortunately the GPD pocket also uses these strings and its BIOS 901c3b44c0SHans de Goede * was copy-pasted from the GPD win, so it has a disabled KIOX000A 911c3b44c0SHans de Goede * node which we should not enable, thus we also check the BIOS date. 92906dc284SHans de Goede */ 93e36cf2f7SThomas Gleixner ENTRY("KIOX000A", "1", X86_MATCH(ATOM_AIRMONT), { 94906dc284SHans de Goede DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), 95906dc284SHans de Goede DMI_MATCH(DMI_BOARD_NAME, "Default string"), 96906dc284SHans de Goede DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), 971c3b44c0SHans de Goede DMI_MATCH(DMI_BIOS_DATE, "02/21/2017") 981c3b44c0SHans de Goede }), 99e36cf2f7SThomas Gleixner ENTRY("KIOX000A", "1", X86_MATCH(ATOM_AIRMONT), { 1001c3b44c0SHans de Goede DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), 1011c3b44c0SHans de Goede DMI_MATCH(DMI_BOARD_NAME, "Default string"), 1021c3b44c0SHans de Goede DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), 103906dc284SHans de Goede DMI_MATCH(DMI_BIOS_DATE, "03/20/2017") 104906dc284SHans de Goede }), 105e36cf2f7SThomas Gleixner ENTRY("KIOX000A", "1", X86_MATCH(ATOM_AIRMONT), { 1061c3b44c0SHans de Goede DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), 1071c3b44c0SHans de Goede DMI_MATCH(DMI_BOARD_NAME, "Default string"), 1081c3b44c0SHans de Goede DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), 1091c3b44c0SHans de Goede DMI_MATCH(DMI_BIOS_DATE, "05/25/2017") 1101c3b44c0SHans de Goede }), 111b7ecf663SHans de Goede }; 112b7ecf663SHans de Goede 113b7ecf663SHans de Goede bool acpi_device_always_present(struct acpi_device *adev) 114b7ecf663SHans de Goede { 115b7ecf663SHans de Goede bool ret = false; 116b7ecf663SHans de Goede unsigned int i; 117b7ecf663SHans de Goede 118b7ecf663SHans de Goede for (i = 0; i < ARRAY_SIZE(always_present_ids); i++) { 119b7ecf663SHans de Goede if (acpi_match_device_ids(adev, always_present_ids[i].hid)) 120b7ecf663SHans de Goede continue; 121b7ecf663SHans de Goede 122b7ecf663SHans de Goede if (!adev->pnp.unique_id || 123b7ecf663SHans de Goede strcmp(adev->pnp.unique_id, always_present_ids[i].uid)) 124b7ecf663SHans de Goede continue; 125b7ecf663SHans de Goede 126b7ecf663SHans de Goede if (!x86_match_cpu(always_present_ids[i].cpu_ids)) 127b7ecf663SHans de Goede continue; 128b7ecf663SHans de Goede 1293b6a70beSHans de Goede if (always_present_ids[i].dmi_ids[0].matches[0].slot && 1303b6a70beSHans de Goede !dmi_check_system(always_present_ids[i].dmi_ids)) 1313b6a70beSHans de Goede continue; 1323b6a70beSHans de Goede 133b7ecf663SHans de Goede ret = true; 134b7ecf663SHans de Goede break; 135b7ecf663SHans de Goede } 136b7ecf663SHans de Goede 137b7ecf663SHans de Goede return ret; 138b7ecf663SHans de Goede } 1396485fc18SMario Limonciello 1406485fc18SMario Limonciello /* 1416485fc18SMario Limonciello * AMD systems from Renoir and Lucienne *require* that the NVME controller 1426485fc18SMario Limonciello * is put into D3 over a Modern Standby / suspend-to-idle cycle. 1436485fc18SMario Limonciello * 1446485fc18SMario Limonciello * This is "typically" accomplished using the `StorageD3Enable` 1456485fc18SMario Limonciello * property in the _DSD that is checked via the `acpi_storage_d3` function 1466485fc18SMario Limonciello * but this property was introduced after many of these systems launched 1476485fc18SMario Limonciello * and most OEM systems don't have it in their BIOS. 1486485fc18SMario Limonciello * 1496485fc18SMario Limonciello * The Microsoft documentation for StorageD3Enable mentioned that Windows has 1506485fc18SMario Limonciello * a hardcoded allowlist for D3 support, which was used for these platforms. 1516485fc18SMario Limonciello * 1526485fc18SMario Limonciello * This allows quirking on Linux in a similar fashion. 1536485fc18SMario Limonciello */ 1546485fc18SMario Limonciello static const struct x86_cpu_id storage_d3_cpu_ids[] = { 1556485fc18SMario Limonciello X86_MATCH_VENDOR_FAM_MODEL(AMD, 23, 96, NULL), /* Renoir */ 1566485fc18SMario Limonciello X86_MATCH_VENDOR_FAM_MODEL(AMD, 23, 104, NULL), /* Lucienne */ 1576485fc18SMario Limonciello {} 1586485fc18SMario Limonciello }; 1596485fc18SMario Limonciello 1606485fc18SMario Limonciello bool force_storage_d3(void) 1616485fc18SMario Limonciello { 1626485fc18SMario Limonciello return x86_match_cpu(storage_d3_cpu_ids); 1636485fc18SMario Limonciello } 164*35f9e773SHans de Goede 165*35f9e773SHans de Goede #if IS_ENABLED(CONFIG_X86_ANDROID_TABLETS) 166*35f9e773SHans de Goede /* 167*35f9e773SHans de Goede * x86 ACPI boards which ship with only Android as their factory image usually 168*35f9e773SHans de Goede * declare a whole bunch of bogus I2C devices in their ACPI tables and sometimes 169*35f9e773SHans de Goede * there are issues with serdev devices on these boards too, e.g. the resource 170*35f9e773SHans de Goede * points to the wrong serdev_controller. 171*35f9e773SHans de Goede * 172*35f9e773SHans de Goede * Instantiating I2C / serdev devs for these bogus devs causes various issues, 173*35f9e773SHans de Goede * e.g. GPIO/IRQ resource conflicts because sometimes drivers do bind to them. 174*35f9e773SHans de Goede * The Android x86 kernel fork shipped on these devices has some special code 175*35f9e773SHans de Goede * to remove the bogus I2C clients (and AFAICT serdevs are ignored completely). 176*35f9e773SHans de Goede * 177*35f9e773SHans de Goede * The acpi_quirk_skip_*_enumeration() functions below are used by the I2C or 178*35f9e773SHans de Goede * serdev code to skip instantiating any I2C or serdev devs on broken boards. 179*35f9e773SHans de Goede * 180*35f9e773SHans de Goede * In case of I2C an exception is made for HIDs on the i2c_acpi_known_good_ids 181*35f9e773SHans de Goede * list. These are known to always be correct (and in case of the audio-codecs 182*35f9e773SHans de Goede * the drivers heavily rely on the codec being enumerated through ACPI). 183*35f9e773SHans de Goede * 184*35f9e773SHans de Goede * Note these boards typically do actually have I2C and serdev devices, 185*35f9e773SHans de Goede * just different ones then the ones described in their DSDT. The devices 186*35f9e773SHans de Goede * which are actually present are manually instantiated by the 187*35f9e773SHans de Goede * drivers/platform/x86/x86-android-tablets.c kernel module. 188*35f9e773SHans de Goede */ 189*35f9e773SHans de Goede #define ACPI_QUIRK_SKIP_I2C_CLIENTS BIT(0) 190*35f9e773SHans de Goede #define ACPI_QUIRK_UART1_TTY_UART2_SKIP BIT(1) 191*35f9e773SHans de Goede 192*35f9e773SHans de Goede static const struct dmi_system_id acpi_skip_serial_bus_enumeration_ids[] = { 193*35f9e773SHans de Goede { 194*35f9e773SHans de Goede .matches = { 195*35f9e773SHans de Goede DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 196*35f9e773SHans de Goede DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ME176C"), 197*35f9e773SHans de Goede }, 198*35f9e773SHans de Goede .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS | 199*35f9e773SHans de Goede ACPI_QUIRK_UART1_TTY_UART2_SKIP), 200*35f9e773SHans de Goede }, 201*35f9e773SHans de Goede { 202*35f9e773SHans de Goede .matches = { 203*35f9e773SHans de Goede DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 204*35f9e773SHans de Goede DMI_MATCH(DMI_PRODUCT_NAME, "TF103C"), 205*35f9e773SHans de Goede }, 206*35f9e773SHans de Goede .driver_data = (void *)ACPI_QUIRK_SKIP_I2C_CLIENTS, 207*35f9e773SHans de Goede }, 208*35f9e773SHans de Goede { 209*35f9e773SHans de Goede /* Whitelabel (sold as various brands) TM800A550L */ 210*35f9e773SHans de Goede .matches = { 211*35f9e773SHans de Goede DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), 212*35f9e773SHans de Goede DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"), 213*35f9e773SHans de Goede /* Above strings are too generic, also match on BIOS version */ 214*35f9e773SHans de Goede DMI_MATCH(DMI_BIOS_VERSION, "ZY-8-BI-PX4S70VTR400-X423B-005-D"), 215*35f9e773SHans de Goede }, 216*35f9e773SHans de Goede .driver_data = (void *)ACPI_QUIRK_SKIP_I2C_CLIENTS, 217*35f9e773SHans de Goede }, 218*35f9e773SHans de Goede {} 219*35f9e773SHans de Goede }; 220*35f9e773SHans de Goede 221*35f9e773SHans de Goede static const struct acpi_device_id i2c_acpi_known_good_ids[] = { 222*35f9e773SHans de Goede { "10EC5640", 0 }, /* RealTek ALC5640 audio codec */ 223*35f9e773SHans de Goede { "INT33F4", 0 }, /* X-Powers AXP288 PMIC */ 224*35f9e773SHans de Goede { "INT33FD", 0 }, /* Intel Crystal Cove PMIC */ 225*35f9e773SHans de Goede { "NPCE69A", 0 }, /* Asus Transformer keyboard dock */ 226*35f9e773SHans de Goede {} 227*35f9e773SHans de Goede }; 228*35f9e773SHans de Goede 229*35f9e773SHans de Goede bool acpi_quirk_skip_i2c_client_enumeration(struct acpi_device *adev) 230*35f9e773SHans de Goede { 231*35f9e773SHans de Goede const struct dmi_system_id *dmi_id; 232*35f9e773SHans de Goede long quirks; 233*35f9e773SHans de Goede 234*35f9e773SHans de Goede dmi_id = dmi_first_match(acpi_skip_serial_bus_enumeration_ids); 235*35f9e773SHans de Goede if (!dmi_id) 236*35f9e773SHans de Goede return false; 237*35f9e773SHans de Goede 238*35f9e773SHans de Goede quirks = (unsigned long)dmi_id->driver_data; 239*35f9e773SHans de Goede if (!(quirks & ACPI_QUIRK_SKIP_I2C_CLIENTS)) 240*35f9e773SHans de Goede return false; 241*35f9e773SHans de Goede 242*35f9e773SHans de Goede return acpi_match_device_ids(adev, i2c_acpi_known_good_ids); 243*35f9e773SHans de Goede } 244*35f9e773SHans de Goede EXPORT_SYMBOL_GPL(acpi_quirk_skip_i2c_client_enumeration); 245*35f9e773SHans de Goede 246*35f9e773SHans de Goede int acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *skip) 247*35f9e773SHans de Goede { 248*35f9e773SHans de Goede struct acpi_device *adev = ACPI_COMPANION(controller_parent); 249*35f9e773SHans de Goede const struct dmi_system_id *dmi_id; 250*35f9e773SHans de Goede long quirks = 0; 251*35f9e773SHans de Goede 252*35f9e773SHans de Goede *skip = false; 253*35f9e773SHans de Goede 254*35f9e773SHans de Goede /* !dev_is_platform() to not match on PNP enumerated debug UARTs */ 255*35f9e773SHans de Goede if (!adev || !adev->pnp.unique_id || !dev_is_platform(controller_parent)) 256*35f9e773SHans de Goede return 0; 257*35f9e773SHans de Goede 258*35f9e773SHans de Goede dmi_id = dmi_first_match(acpi_skip_serial_bus_enumeration_ids); 259*35f9e773SHans de Goede if (dmi_id) 260*35f9e773SHans de Goede quirks = (unsigned long)dmi_id->driver_data; 261*35f9e773SHans de Goede 262*35f9e773SHans de Goede if (quirks & ACPI_QUIRK_UART1_TTY_UART2_SKIP) { 263*35f9e773SHans de Goede if (!strcmp(adev->pnp.unique_id, "1")) 264*35f9e773SHans de Goede return -ENODEV; /* Create tty cdev instead of serdev */ 265*35f9e773SHans de Goede 266*35f9e773SHans de Goede if (!strcmp(adev->pnp.unique_id, "2")) 267*35f9e773SHans de Goede *skip = true; 268*35f9e773SHans de Goede } 269*35f9e773SHans de Goede 270*35f9e773SHans de Goede return 0; 271*35f9e773SHans de Goede } 272*35f9e773SHans de Goede EXPORT_SYMBOL_GPL(acpi_quirk_skip_serdev_enumeration); 273*35f9e773SHans de Goede #endif 274