18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * osi.c - _OSI implementation 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2016 Intel Corporation 68c2ecf20Sopenharmony_ci * Author: Lv Zheng <lv.zheng@intel.com> 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci/* Uncomment next line to get verbose printout */ 108c2ecf20Sopenharmony_ci/* #define DEBUG */ 118c2ecf20Sopenharmony_ci#define pr_fmt(fmt) "ACPI: " fmt 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <linux/module.h> 148c2ecf20Sopenharmony_ci#include <linux/kernel.h> 158c2ecf20Sopenharmony_ci#include <linux/acpi.h> 168c2ecf20Sopenharmony_ci#include <linux/dmi.h> 178c2ecf20Sopenharmony_ci#include <linux/platform_data/x86/apple.h> 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#include "internal.h" 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#define OSI_STRING_LENGTH_MAX 64 238c2ecf20Sopenharmony_ci#define OSI_STRING_ENTRIES_MAX 16 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_cistruct acpi_osi_entry { 268c2ecf20Sopenharmony_ci char string[OSI_STRING_LENGTH_MAX]; 278c2ecf20Sopenharmony_ci bool enable; 288c2ecf20Sopenharmony_ci}; 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_cistatic struct acpi_osi_config { 318c2ecf20Sopenharmony_ci u8 default_disabling; 328c2ecf20Sopenharmony_ci unsigned int linux_enable:1; 338c2ecf20Sopenharmony_ci unsigned int linux_dmi:1; 348c2ecf20Sopenharmony_ci unsigned int linux_cmdline:1; 358c2ecf20Sopenharmony_ci unsigned int darwin_enable:1; 368c2ecf20Sopenharmony_ci unsigned int darwin_dmi:1; 378c2ecf20Sopenharmony_ci unsigned int darwin_cmdline:1; 388c2ecf20Sopenharmony_ci} osi_config; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_cistatic struct acpi_osi_config osi_config; 418c2ecf20Sopenharmony_cistatic struct acpi_osi_entry 428c2ecf20Sopenharmony_ciosi_setup_entries[OSI_STRING_ENTRIES_MAX] __initdata = { 438c2ecf20Sopenharmony_ci {"Module Device", true}, 448c2ecf20Sopenharmony_ci {"Processor Device", true}, 458c2ecf20Sopenharmony_ci {"3.0 _SCP Extensions", true}, 468c2ecf20Sopenharmony_ci {"Processor Aggregator Device", true}, 478c2ecf20Sopenharmony_ci /* 488c2ecf20Sopenharmony_ci * Linux-Dell-Video is used by BIOS to disable RTD3 for NVidia graphics 498c2ecf20Sopenharmony_ci * cards as RTD3 is not supported by drivers now. Systems with NVidia 508c2ecf20Sopenharmony_ci * cards will hang without RTD3 disabled. 518c2ecf20Sopenharmony_ci * 528c2ecf20Sopenharmony_ci * Once NVidia drivers officially support RTD3, this _OSI strings can 538c2ecf20Sopenharmony_ci * be removed if both new and old graphics cards are supported. 548c2ecf20Sopenharmony_ci */ 558c2ecf20Sopenharmony_ci {"Linux-Dell-Video", true}, 568c2ecf20Sopenharmony_ci /* 578c2ecf20Sopenharmony_ci * Linux-Lenovo-NV-HDMI-Audio is used by BIOS to power on NVidia's HDMI 588c2ecf20Sopenharmony_ci * audio device which is turned off for power-saving in Windows OS. 598c2ecf20Sopenharmony_ci * This power management feature observed on some Lenovo Thinkpad 608c2ecf20Sopenharmony_ci * systems which will not be able to output audio via HDMI without 618c2ecf20Sopenharmony_ci * a BIOS workaround. 628c2ecf20Sopenharmony_ci */ 638c2ecf20Sopenharmony_ci {"Linux-Lenovo-NV-HDMI-Audio", true}, 648c2ecf20Sopenharmony_ci /* 658c2ecf20Sopenharmony_ci * Linux-HPI-Hybrid-Graphics is used by BIOS to enable dGPU to 668c2ecf20Sopenharmony_ci * output video directly to external monitors on HP Inc. mobile 678c2ecf20Sopenharmony_ci * workstations as Nvidia and AMD VGA drivers provide limited 688c2ecf20Sopenharmony_ci * hybrid graphics supports. 698c2ecf20Sopenharmony_ci */ 708c2ecf20Sopenharmony_ci {"Linux-HPI-Hybrid-Graphics", true}, 718c2ecf20Sopenharmony_ci}; 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_cistatic u32 acpi_osi_handler(acpi_string interface, u32 supported) 748c2ecf20Sopenharmony_ci{ 758c2ecf20Sopenharmony_ci if (!strcmp("Linux", interface)) { 768c2ecf20Sopenharmony_ci pr_notice_once(FW_BUG 778c2ecf20Sopenharmony_ci "BIOS _OSI(Linux) query %s%s\n", 788c2ecf20Sopenharmony_ci osi_config.linux_enable ? "honored" : "ignored", 798c2ecf20Sopenharmony_ci osi_config.linux_cmdline ? " via cmdline" : 808c2ecf20Sopenharmony_ci osi_config.linux_dmi ? " via DMI" : ""); 818c2ecf20Sopenharmony_ci } 828c2ecf20Sopenharmony_ci if (!strcmp("Darwin", interface)) { 838c2ecf20Sopenharmony_ci pr_notice_once( 848c2ecf20Sopenharmony_ci "BIOS _OSI(Darwin) query %s%s\n", 858c2ecf20Sopenharmony_ci osi_config.darwin_enable ? "honored" : "ignored", 868c2ecf20Sopenharmony_ci osi_config.darwin_cmdline ? " via cmdline" : 878c2ecf20Sopenharmony_ci osi_config.darwin_dmi ? " via DMI" : ""); 888c2ecf20Sopenharmony_ci } 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci return supported; 918c2ecf20Sopenharmony_ci} 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_civoid __init acpi_osi_setup(char *str) 948c2ecf20Sopenharmony_ci{ 958c2ecf20Sopenharmony_ci struct acpi_osi_entry *osi; 968c2ecf20Sopenharmony_ci bool enable = true; 978c2ecf20Sopenharmony_ci int i; 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci if (!acpi_gbl_create_osi_method) 1008c2ecf20Sopenharmony_ci return; 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci if (str == NULL || *str == '\0') { 1038c2ecf20Sopenharmony_ci pr_info("_OSI method disabled\n"); 1048c2ecf20Sopenharmony_ci acpi_gbl_create_osi_method = FALSE; 1058c2ecf20Sopenharmony_ci return; 1068c2ecf20Sopenharmony_ci } 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci if (*str == '!') { 1098c2ecf20Sopenharmony_ci str++; 1108c2ecf20Sopenharmony_ci if (*str == '\0') { 1118c2ecf20Sopenharmony_ci /* Do not override acpi_osi=!* */ 1128c2ecf20Sopenharmony_ci if (!osi_config.default_disabling) 1138c2ecf20Sopenharmony_ci osi_config.default_disabling = 1148c2ecf20Sopenharmony_ci ACPI_DISABLE_ALL_VENDOR_STRINGS; 1158c2ecf20Sopenharmony_ci return; 1168c2ecf20Sopenharmony_ci } else if (*str == '*') { 1178c2ecf20Sopenharmony_ci osi_config.default_disabling = ACPI_DISABLE_ALL_STRINGS; 1188c2ecf20Sopenharmony_ci for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { 1198c2ecf20Sopenharmony_ci osi = &osi_setup_entries[i]; 1208c2ecf20Sopenharmony_ci osi->enable = false; 1218c2ecf20Sopenharmony_ci } 1228c2ecf20Sopenharmony_ci return; 1238c2ecf20Sopenharmony_ci } else if (*str == '!') { 1248c2ecf20Sopenharmony_ci osi_config.default_disabling = 0; 1258c2ecf20Sopenharmony_ci return; 1268c2ecf20Sopenharmony_ci } 1278c2ecf20Sopenharmony_ci enable = false; 1288c2ecf20Sopenharmony_ci } 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { 1318c2ecf20Sopenharmony_ci osi = &osi_setup_entries[i]; 1328c2ecf20Sopenharmony_ci if (!strcmp(osi->string, str)) { 1338c2ecf20Sopenharmony_ci osi->enable = enable; 1348c2ecf20Sopenharmony_ci break; 1358c2ecf20Sopenharmony_ci } else if (osi->string[0] == '\0') { 1368c2ecf20Sopenharmony_ci osi->enable = enable; 1378c2ecf20Sopenharmony_ci strncpy(osi->string, str, OSI_STRING_LENGTH_MAX); 1388c2ecf20Sopenharmony_ci break; 1398c2ecf20Sopenharmony_ci } 1408c2ecf20Sopenharmony_ci } 1418c2ecf20Sopenharmony_ci} 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_cistatic void __init __acpi_osi_setup_darwin(bool enable) 1448c2ecf20Sopenharmony_ci{ 1458c2ecf20Sopenharmony_ci osi_config.darwin_enable = !!enable; 1468c2ecf20Sopenharmony_ci if (enable) { 1478c2ecf20Sopenharmony_ci acpi_osi_setup("!"); 1488c2ecf20Sopenharmony_ci acpi_osi_setup("Darwin"); 1498c2ecf20Sopenharmony_ci } else { 1508c2ecf20Sopenharmony_ci acpi_osi_setup("!!"); 1518c2ecf20Sopenharmony_ci acpi_osi_setup("!Darwin"); 1528c2ecf20Sopenharmony_ci } 1538c2ecf20Sopenharmony_ci} 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_cistatic void __init acpi_osi_setup_darwin(bool enable) 1568c2ecf20Sopenharmony_ci{ 1578c2ecf20Sopenharmony_ci /* Override acpi_osi_dmi_blacklisted() */ 1588c2ecf20Sopenharmony_ci osi_config.darwin_dmi = 0; 1598c2ecf20Sopenharmony_ci osi_config.darwin_cmdline = 1; 1608c2ecf20Sopenharmony_ci __acpi_osi_setup_darwin(enable); 1618c2ecf20Sopenharmony_ci} 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci/* 1648c2ecf20Sopenharmony_ci * The story of _OSI(Linux) 1658c2ecf20Sopenharmony_ci * 1668c2ecf20Sopenharmony_ci * From pre-history through Linux-2.6.22, Linux responded TRUE upon a BIOS 1678c2ecf20Sopenharmony_ci * OSI(Linux) query. 1688c2ecf20Sopenharmony_ci * 1698c2ecf20Sopenharmony_ci * Unfortunately, reference BIOS writers got wind of this and put 1708c2ecf20Sopenharmony_ci * OSI(Linux) in their example code, quickly exposing this string as 1718c2ecf20Sopenharmony_ci * ill-conceived and opening the door to an un-bounded number of BIOS 1728c2ecf20Sopenharmony_ci * incompatibilities. 1738c2ecf20Sopenharmony_ci * 1748c2ecf20Sopenharmony_ci * For example, OSI(Linux) was used on resume to re-POST a video card on 1758c2ecf20Sopenharmony_ci * one system, because Linux at that time could not do a speedy restore in 1768c2ecf20Sopenharmony_ci * its native driver. But then upon gaining quick native restore 1778c2ecf20Sopenharmony_ci * capability, Linux has no way to tell the BIOS to skip the time-consuming 1788c2ecf20Sopenharmony_ci * POST -- putting Linux at a permanent performance disadvantage. On 1798c2ecf20Sopenharmony_ci * another system, the BIOS writer used OSI(Linux) to infer native OS 1808c2ecf20Sopenharmony_ci * support for IPMI! On other systems, OSI(Linux) simply got in the way of 1818c2ecf20Sopenharmony_ci * Linux claiming to be compatible with other operating systems, exposing 1828c2ecf20Sopenharmony_ci * BIOS issues such as skipped device initialization. 1838c2ecf20Sopenharmony_ci * 1848c2ecf20Sopenharmony_ci * So "Linux" turned out to be a really poor chose of OSI string, and from 1858c2ecf20Sopenharmony_ci * Linux-2.6.23 onward we respond FALSE. 1868c2ecf20Sopenharmony_ci * 1878c2ecf20Sopenharmony_ci * BIOS writers should NOT query _OSI(Linux) on future systems. Linux will 1888c2ecf20Sopenharmony_ci * complain on the console when it sees it, and return FALSE. To get Linux 1898c2ecf20Sopenharmony_ci * to return TRUE for your system will require a kernel source update to 1908c2ecf20Sopenharmony_ci * add a DMI entry, or boot with "acpi_osi=Linux" 1918c2ecf20Sopenharmony_ci */ 1928c2ecf20Sopenharmony_cistatic void __init __acpi_osi_setup_linux(bool enable) 1938c2ecf20Sopenharmony_ci{ 1948c2ecf20Sopenharmony_ci osi_config.linux_enable = !!enable; 1958c2ecf20Sopenharmony_ci if (enable) 1968c2ecf20Sopenharmony_ci acpi_osi_setup("Linux"); 1978c2ecf20Sopenharmony_ci else 1988c2ecf20Sopenharmony_ci acpi_osi_setup("!Linux"); 1998c2ecf20Sopenharmony_ci} 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_cistatic void __init acpi_osi_setup_linux(bool enable) 2028c2ecf20Sopenharmony_ci{ 2038c2ecf20Sopenharmony_ci /* Override acpi_osi_dmi_blacklisted() */ 2048c2ecf20Sopenharmony_ci osi_config.linux_dmi = 0; 2058c2ecf20Sopenharmony_ci osi_config.linux_cmdline = 1; 2068c2ecf20Sopenharmony_ci __acpi_osi_setup_linux(enable); 2078c2ecf20Sopenharmony_ci} 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci/* 2108c2ecf20Sopenharmony_ci * Modify the list of "OS Interfaces" reported to BIOS via _OSI 2118c2ecf20Sopenharmony_ci * 2128c2ecf20Sopenharmony_ci * empty string disables _OSI 2138c2ecf20Sopenharmony_ci * string starting with '!' disables that string 2148c2ecf20Sopenharmony_ci * otherwise string is added to list, augmenting built-in strings 2158c2ecf20Sopenharmony_ci */ 2168c2ecf20Sopenharmony_cistatic void __init acpi_osi_setup_late(void) 2178c2ecf20Sopenharmony_ci{ 2188c2ecf20Sopenharmony_ci struct acpi_osi_entry *osi; 2198c2ecf20Sopenharmony_ci char *str; 2208c2ecf20Sopenharmony_ci int i; 2218c2ecf20Sopenharmony_ci acpi_status status; 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci if (osi_config.default_disabling) { 2248c2ecf20Sopenharmony_ci status = acpi_update_interfaces(osi_config.default_disabling); 2258c2ecf20Sopenharmony_ci if (ACPI_SUCCESS(status)) 2268c2ecf20Sopenharmony_ci pr_info("Disabled all _OSI OS vendors%s\n", 2278c2ecf20Sopenharmony_ci osi_config.default_disabling == 2288c2ecf20Sopenharmony_ci ACPI_DISABLE_ALL_STRINGS ? 2298c2ecf20Sopenharmony_ci " and feature groups" : ""); 2308c2ecf20Sopenharmony_ci } 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { 2338c2ecf20Sopenharmony_ci osi = &osi_setup_entries[i]; 2348c2ecf20Sopenharmony_ci str = osi->string; 2358c2ecf20Sopenharmony_ci if (*str == '\0') 2368c2ecf20Sopenharmony_ci break; 2378c2ecf20Sopenharmony_ci if (osi->enable) { 2388c2ecf20Sopenharmony_ci status = acpi_install_interface(str); 2398c2ecf20Sopenharmony_ci if (ACPI_SUCCESS(status)) 2408c2ecf20Sopenharmony_ci pr_info("Added _OSI(%s)\n", str); 2418c2ecf20Sopenharmony_ci } else { 2428c2ecf20Sopenharmony_ci status = acpi_remove_interface(str); 2438c2ecf20Sopenharmony_ci if (ACPI_SUCCESS(status)) 2448c2ecf20Sopenharmony_ci pr_info("Deleted _OSI(%s)\n", str); 2458c2ecf20Sopenharmony_ci } 2468c2ecf20Sopenharmony_ci } 2478c2ecf20Sopenharmony_ci} 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_cistatic int __init osi_setup(char *str) 2508c2ecf20Sopenharmony_ci{ 2518c2ecf20Sopenharmony_ci if (str && !strcmp("Linux", str)) 2528c2ecf20Sopenharmony_ci acpi_osi_setup_linux(true); 2538c2ecf20Sopenharmony_ci else if (str && !strcmp("!Linux", str)) 2548c2ecf20Sopenharmony_ci acpi_osi_setup_linux(false); 2558c2ecf20Sopenharmony_ci else if (str && !strcmp("Darwin", str)) 2568c2ecf20Sopenharmony_ci acpi_osi_setup_darwin(true); 2578c2ecf20Sopenharmony_ci else if (str && !strcmp("!Darwin", str)) 2588c2ecf20Sopenharmony_ci acpi_osi_setup_darwin(false); 2598c2ecf20Sopenharmony_ci else 2608c2ecf20Sopenharmony_ci acpi_osi_setup(str); 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci return 1; 2638c2ecf20Sopenharmony_ci} 2648c2ecf20Sopenharmony_ci__setup("acpi_osi=", osi_setup); 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_cibool acpi_osi_is_win8(void) 2678c2ecf20Sopenharmony_ci{ 2688c2ecf20Sopenharmony_ci return acpi_gbl_osi_data >= ACPI_OSI_WIN_8; 2698c2ecf20Sopenharmony_ci} 2708c2ecf20Sopenharmony_ciEXPORT_SYMBOL(acpi_osi_is_win8); 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_cistatic void __init acpi_osi_dmi_darwin(void) 2738c2ecf20Sopenharmony_ci{ 2748c2ecf20Sopenharmony_ci pr_notice("DMI detected to setup _OSI(\"Darwin\"): Apple hardware\n"); 2758c2ecf20Sopenharmony_ci osi_config.darwin_dmi = 1; 2768c2ecf20Sopenharmony_ci __acpi_osi_setup_darwin(true); 2778c2ecf20Sopenharmony_ci} 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_cistatic void __init acpi_osi_dmi_linux(bool enable, 2808c2ecf20Sopenharmony_ci const struct dmi_system_id *d) 2818c2ecf20Sopenharmony_ci{ 2828c2ecf20Sopenharmony_ci pr_notice("DMI detected to setup _OSI(\"Linux\"): %s\n", d->ident); 2838c2ecf20Sopenharmony_ci osi_config.linux_dmi = 1; 2848c2ecf20Sopenharmony_ci __acpi_osi_setup_linux(enable); 2858c2ecf20Sopenharmony_ci} 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_cistatic int __init dmi_enable_osi_linux(const struct dmi_system_id *d) 2888c2ecf20Sopenharmony_ci{ 2898c2ecf20Sopenharmony_ci acpi_osi_dmi_linux(true, d); 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci return 0; 2928c2ecf20Sopenharmony_ci} 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_cistatic int __init dmi_disable_osi_vista(const struct dmi_system_id *d) 2958c2ecf20Sopenharmony_ci{ 2968c2ecf20Sopenharmony_ci pr_notice("DMI detected: %s\n", d->ident); 2978c2ecf20Sopenharmony_ci acpi_osi_setup("!Windows 2006"); 2988c2ecf20Sopenharmony_ci acpi_osi_setup("!Windows 2006 SP1"); 2998c2ecf20Sopenharmony_ci acpi_osi_setup("!Windows 2006 SP2"); 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci return 0; 3028c2ecf20Sopenharmony_ci} 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_cistatic int __init dmi_disable_osi_win7(const struct dmi_system_id *d) 3058c2ecf20Sopenharmony_ci{ 3068c2ecf20Sopenharmony_ci pr_notice("DMI detected: %s\n", d->ident); 3078c2ecf20Sopenharmony_ci acpi_osi_setup("!Windows 2009"); 3088c2ecf20Sopenharmony_ci 3098c2ecf20Sopenharmony_ci return 0; 3108c2ecf20Sopenharmony_ci} 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_cistatic int __init dmi_disable_osi_win8(const struct dmi_system_id *d) 3138c2ecf20Sopenharmony_ci{ 3148c2ecf20Sopenharmony_ci pr_notice("DMI detected: %s\n", d->ident); 3158c2ecf20Sopenharmony_ci acpi_osi_setup("!Windows 2012"); 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci return 0; 3188c2ecf20Sopenharmony_ci} 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci/* 3218c2ecf20Sopenharmony_ci * Linux default _OSI response behavior is determined by this DMI table. 3228c2ecf20Sopenharmony_ci * 3238c2ecf20Sopenharmony_ci * Note that _OSI("Linux")/_OSI("Darwin") determined here can be overridden 3248c2ecf20Sopenharmony_ci * by acpi_osi=!Linux/acpi_osi=!Darwin command line options. 3258c2ecf20Sopenharmony_ci */ 3268c2ecf20Sopenharmony_cistatic const struct dmi_system_id acpi_osi_dmi_table[] __initconst = { 3278c2ecf20Sopenharmony_ci { 3288c2ecf20Sopenharmony_ci .callback = dmi_disable_osi_vista, 3298c2ecf20Sopenharmony_ci .ident = "Fujitsu Siemens", 3308c2ecf20Sopenharmony_ci .matches = { 3318c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 3328c2ecf20Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"), 3338c2ecf20Sopenharmony_ci }, 3348c2ecf20Sopenharmony_ci }, 3358c2ecf20Sopenharmony_ci { 3368c2ecf20Sopenharmony_ci /* 3378c2ecf20Sopenharmony_ci * There have a NVIF method in MSI GX723 DSDT need call by Nvidia 3388c2ecf20Sopenharmony_ci * driver (e.g. nouveau) when user press brightness hotkey. 3398c2ecf20Sopenharmony_ci * Currently, nouveau driver didn't do the job and it causes there 3408c2ecf20Sopenharmony_ci * have a infinite while loop in DSDT when user press hotkey. 3418c2ecf20Sopenharmony_ci * We add MSI GX723's dmi information to this table for workaround 3428c2ecf20Sopenharmony_ci * this issue. 3438c2ecf20Sopenharmony_ci * Will remove MSI GX723 from the table after nouveau grows support. 3448c2ecf20Sopenharmony_ci */ 3458c2ecf20Sopenharmony_ci .callback = dmi_disable_osi_vista, 3468c2ecf20Sopenharmony_ci .ident = "MSI GX723", 3478c2ecf20Sopenharmony_ci .matches = { 3488c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), 3498c2ecf20Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "GX723"), 3508c2ecf20Sopenharmony_ci }, 3518c2ecf20Sopenharmony_ci }, 3528c2ecf20Sopenharmony_ci { 3538c2ecf20Sopenharmony_ci .callback = dmi_disable_osi_vista, 3548c2ecf20Sopenharmony_ci .ident = "Sony VGN-NS10J_S", 3558c2ecf20Sopenharmony_ci .matches = { 3568c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 3578c2ecf20Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS10J_S"), 3588c2ecf20Sopenharmony_ci }, 3598c2ecf20Sopenharmony_ci }, 3608c2ecf20Sopenharmony_ci { 3618c2ecf20Sopenharmony_ci .callback = dmi_disable_osi_vista, 3628c2ecf20Sopenharmony_ci .ident = "Sony VGN-SR290J", 3638c2ecf20Sopenharmony_ci .matches = { 3648c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 3658c2ecf20Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR290J"), 3668c2ecf20Sopenharmony_ci }, 3678c2ecf20Sopenharmony_ci }, 3688c2ecf20Sopenharmony_ci { 3698c2ecf20Sopenharmony_ci .callback = dmi_disable_osi_vista, 3708c2ecf20Sopenharmony_ci .ident = "VGN-NS50B_L", 3718c2ecf20Sopenharmony_ci .matches = { 3728c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 3738c2ecf20Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS50B_L"), 3748c2ecf20Sopenharmony_ci }, 3758c2ecf20Sopenharmony_ci }, 3768c2ecf20Sopenharmony_ci { 3778c2ecf20Sopenharmony_ci .callback = dmi_disable_osi_vista, 3788c2ecf20Sopenharmony_ci .ident = "VGN-SR19XN", 3798c2ecf20Sopenharmony_ci .matches = { 3808c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 3818c2ecf20Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR19XN"), 3828c2ecf20Sopenharmony_ci }, 3838c2ecf20Sopenharmony_ci }, 3848c2ecf20Sopenharmony_ci { 3858c2ecf20Sopenharmony_ci .callback = dmi_disable_osi_vista, 3868c2ecf20Sopenharmony_ci .ident = "Toshiba Satellite L355", 3878c2ecf20Sopenharmony_ci .matches = { 3888c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), 3898c2ecf20Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_VERSION, "Satellite L355"), 3908c2ecf20Sopenharmony_ci }, 3918c2ecf20Sopenharmony_ci }, 3928c2ecf20Sopenharmony_ci { 3938c2ecf20Sopenharmony_ci .callback = dmi_disable_osi_win7, 3948c2ecf20Sopenharmony_ci .ident = "ASUS K50IJ", 3958c2ecf20Sopenharmony_ci .matches = { 3968c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 3978c2ecf20Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"), 3988c2ecf20Sopenharmony_ci }, 3998c2ecf20Sopenharmony_ci }, 4008c2ecf20Sopenharmony_ci { 4018c2ecf20Sopenharmony_ci .callback = dmi_disable_osi_vista, 4028c2ecf20Sopenharmony_ci .ident = "Toshiba P305D", 4038c2ecf20Sopenharmony_ci .matches = { 4048c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), 4058c2ecf20Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P305D"), 4068c2ecf20Sopenharmony_ci }, 4078c2ecf20Sopenharmony_ci }, 4088c2ecf20Sopenharmony_ci { 4098c2ecf20Sopenharmony_ci .callback = dmi_disable_osi_vista, 4108c2ecf20Sopenharmony_ci .ident = "Toshiba NB100", 4118c2ecf20Sopenharmony_ci .matches = { 4128c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), 4138c2ecf20Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "NB100"), 4148c2ecf20Sopenharmony_ci }, 4158c2ecf20Sopenharmony_ci }, 4168c2ecf20Sopenharmony_ci 4178c2ecf20Sopenharmony_ci /* 4188c2ecf20Sopenharmony_ci * The wireless hotkey does not work on those machines when 4198c2ecf20Sopenharmony_ci * returning true for _OSI("Windows 2012") 4208c2ecf20Sopenharmony_ci */ 4218c2ecf20Sopenharmony_ci { 4228c2ecf20Sopenharmony_ci .callback = dmi_disable_osi_win8, 4238c2ecf20Sopenharmony_ci .ident = "Dell Inspiron 7737", 4248c2ecf20Sopenharmony_ci .matches = { 4258c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 4268c2ecf20Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7737"), 4278c2ecf20Sopenharmony_ci }, 4288c2ecf20Sopenharmony_ci }, 4298c2ecf20Sopenharmony_ci { 4308c2ecf20Sopenharmony_ci .callback = dmi_disable_osi_win8, 4318c2ecf20Sopenharmony_ci .ident = "Dell Inspiron 7537", 4328c2ecf20Sopenharmony_ci .matches = { 4338c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 4348c2ecf20Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7537"), 4358c2ecf20Sopenharmony_ci }, 4368c2ecf20Sopenharmony_ci }, 4378c2ecf20Sopenharmony_ci { 4388c2ecf20Sopenharmony_ci .callback = dmi_disable_osi_win8, 4398c2ecf20Sopenharmony_ci .ident = "Dell Inspiron 5437", 4408c2ecf20Sopenharmony_ci .matches = { 4418c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 4428c2ecf20Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5437"), 4438c2ecf20Sopenharmony_ci }, 4448c2ecf20Sopenharmony_ci }, 4458c2ecf20Sopenharmony_ci { 4468c2ecf20Sopenharmony_ci .callback = dmi_disable_osi_win8, 4478c2ecf20Sopenharmony_ci .ident = "Dell Inspiron 3437", 4488c2ecf20Sopenharmony_ci .matches = { 4498c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 4508c2ecf20Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 3437"), 4518c2ecf20Sopenharmony_ci }, 4528c2ecf20Sopenharmony_ci }, 4538c2ecf20Sopenharmony_ci { 4548c2ecf20Sopenharmony_ci .callback = dmi_disable_osi_win8, 4558c2ecf20Sopenharmony_ci .ident = "Dell Vostro 3446", 4568c2ecf20Sopenharmony_ci .matches = { 4578c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 4588c2ecf20Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3446"), 4598c2ecf20Sopenharmony_ci }, 4608c2ecf20Sopenharmony_ci }, 4618c2ecf20Sopenharmony_ci { 4628c2ecf20Sopenharmony_ci .callback = dmi_disable_osi_win8, 4638c2ecf20Sopenharmony_ci .ident = "Dell Vostro 3546", 4648c2ecf20Sopenharmony_ci .matches = { 4658c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 4668c2ecf20Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3546"), 4678c2ecf20Sopenharmony_ci }, 4688c2ecf20Sopenharmony_ci }, 4698c2ecf20Sopenharmony_ci 4708c2ecf20Sopenharmony_ci /* 4718c2ecf20Sopenharmony_ci * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. 4728c2ecf20Sopenharmony_ci * Linux ignores it, except for the machines enumerated below. 4738c2ecf20Sopenharmony_ci */ 4748c2ecf20Sopenharmony_ci 4758c2ecf20Sopenharmony_ci /* 4768c2ecf20Sopenharmony_ci * Without this EEEpc exports a non working WMI interface, with 4778c2ecf20Sopenharmony_ci * this it exports a working "good old" eeepc_laptop interface, 4788c2ecf20Sopenharmony_ci * fixing both brightness control, and rfkill not working. 4798c2ecf20Sopenharmony_ci */ 4808c2ecf20Sopenharmony_ci { 4818c2ecf20Sopenharmony_ci .callback = dmi_enable_osi_linux, 4828c2ecf20Sopenharmony_ci .ident = "Asus EEE PC 1015PX", 4838c2ecf20Sopenharmony_ci .matches = { 4848c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."), 4858c2ecf20Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "1015PX"), 4868c2ecf20Sopenharmony_ci }, 4878c2ecf20Sopenharmony_ci }, 4888c2ecf20Sopenharmony_ci {} 4898c2ecf20Sopenharmony_ci}; 4908c2ecf20Sopenharmony_ci 4918c2ecf20Sopenharmony_cistatic __init void acpi_osi_dmi_blacklisted(void) 4928c2ecf20Sopenharmony_ci{ 4938c2ecf20Sopenharmony_ci dmi_check_system(acpi_osi_dmi_table); 4948c2ecf20Sopenharmony_ci 4958c2ecf20Sopenharmony_ci /* Enable _OSI("Darwin") for Apple platforms. */ 4968c2ecf20Sopenharmony_ci if (x86_apple_machine) 4978c2ecf20Sopenharmony_ci acpi_osi_dmi_darwin(); 4988c2ecf20Sopenharmony_ci} 4998c2ecf20Sopenharmony_ci 5008c2ecf20Sopenharmony_ciint __init early_acpi_osi_init(void) 5018c2ecf20Sopenharmony_ci{ 5028c2ecf20Sopenharmony_ci acpi_osi_dmi_blacklisted(); 5038c2ecf20Sopenharmony_ci 5048c2ecf20Sopenharmony_ci return 0; 5058c2ecf20Sopenharmony_ci} 5068c2ecf20Sopenharmony_ci 5078c2ecf20Sopenharmony_ciint __init acpi_osi_init(void) 5088c2ecf20Sopenharmony_ci{ 5098c2ecf20Sopenharmony_ci acpi_install_interface_handler(acpi_osi_handler); 5108c2ecf20Sopenharmony_ci acpi_osi_setup_late(); 5118c2ecf20Sopenharmony_ci 5128c2ecf20Sopenharmony_ci return 0; 5138c2ecf20Sopenharmony_ci} 514