aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-07-02 19:06:00 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-07-02 19:06:00 -0400
commit18d78b64fddc11eb336f01e46ad3303a3f55d039 (patch)
tree806559410131313aa86fa78510e34f1592cbb4ad
parentce55d01e9b4daee5040777d023d52e6b42d3ad8f (diff)
ACPI / init: Make it possible to override _REV
The platform firmware on some systems expects Linux to return "5" as the supported ACPI revision which makes it expose system configuration information in a special way. For example, based on what ACPI exports as the supported revision, Dell XPS 13 (2015) configures its audio device to either work in HDA mode or in I2S mode, where the former is supposed to be used on Linux until the latter is fully supported (in the kernel as well as in user space). Since ACPI 6 mandates that _REV should return "2" if ACPI 2 or later is supported by the OS, a subsequent change will make that happen, so make it possible to override that on systems where "5" is expected to be returned for Linux to work correctly one them (such as the Dell machine mentioned above). Original-by: Dominik Brodowski <linux@dominikbrodowski.net> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--Documentation/kernel-parameters.txt6
-rw-r--r--drivers/acpi/Kconfig20
-rw-r--r--drivers/acpi/blacklist.c26
-rw-r--r--drivers/acpi/internal.h1
-rw-r--r--drivers/acpi/osl.c18
5 files changed, 71 insertions, 0 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 61ab1628a057..180102480fc0 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -274,6 +274,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
274 acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS 274 acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS
275 Format: To spoof as Windows 98: ="Microsoft Windows" 275 Format: To spoof as Windows 98: ="Microsoft Windows"
276 276
277 acpi_rev_override [ACPI] Override the _REV object to return 5 (instead
278 of 2 which is mandated by ACPI 6) as the supported ACPI
279 specification revision (when using this switch, it may
280 be necessary to carry out a cold reboot _twice_ in a
281 row to make it take effect on the platform firmware).
282
277 acpi_osi= [HW,ACPI] Modify list of supported OS interface strings 283 acpi_osi= [HW,ACPI] Modify list of supported OS interface strings
278 acpi_osi="string1" # add string1 284 acpi_osi="string1" # add string1
279 acpi_osi="!string2" # remove string2 285 acpi_osi="!string2" # remove string2
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index ab2cbb51c6aa..2b652f1d4edb 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -77,6 +77,26 @@ config ACPI_PROCFS_POWER
77 77
78 Say N to delete power /proc/acpi/ directories that have moved to /sys/ 78 Say N to delete power /proc/acpi/ directories that have moved to /sys/
79 79
80config ACPI_REV_OVERRIDE_POSSIBLE
81 bool "Allow supported ACPI revision to be overriden"
82 depends on X86
83 default y
84 help
85 The platform firmware on some systems expects Linux to return "5" as
86 the supported ACPI revision which makes it expose system configuration
87 information in a special way.
88
89 For example, based on what ACPI exports as the supported revision,
90 Dell XPS 13 (2015) configures its audio device to either work in HDA
91 mode or in I2S mode, where the former is supposed to be used on Linux
92 until the latter is fully supported (in the kernel as well as in user
93 space).
94
95 This option enables a DMI-based quirk for the above Dell machine (so
96 that HDA audio is exposed by the platform firmware to the kernel) and
97 makes it possible to force the kernel to return "5" as the supported
98 ACPI revision via the "acpi_rev_override" command line switch.
99
80config ACPI_EC_DEBUGFS 100config ACPI_EC_DEBUGFS
81 tristate "EC read/write access through /sys/kernel/debug/ec" 101 tristate "EC read/write access through /sys/kernel/debug/ec"
82 default n 102 default n
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c
index 1d1791935c31..278dc4be992a 100644
--- a/drivers/acpi/blacklist.c
+++ b/drivers/acpi/blacklist.c
@@ -162,6 +162,15 @@ static int __init dmi_disable_osi_win8(const struct dmi_system_id *d)
162 acpi_osi_setup("!Windows 2012"); 162 acpi_osi_setup("!Windows 2012");
163 return 0; 163 return 0;
164} 164}
165#ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE
166static int __init dmi_enable_rev_override(const struct dmi_system_id *d)
167{
168 printk(KERN_NOTICE PREFIX "DMI detected: %s (force ACPI _REV to 5)\n",
169 d->ident);
170 acpi_rev_override_setup(NULL);
171 return 0;
172}
173#endif
165 174
166static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { 175static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
167 { 176 {
@@ -325,6 +334,23 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
325 DMI_MATCH(DMI_PRODUCT_NAME, "1015PX"), 334 DMI_MATCH(DMI_PRODUCT_NAME, "1015PX"),
326 }, 335 },
327 }, 336 },
337
338#ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE
339 /*
340 * DELL XPS 13 (2015) switches sound between HDA and I2S
341 * depending on the ACPI _REV callback. If userspace supports
342 * I2S sufficiently (or if you do not care about sound), you
343 * can safely disable this quirk.
344 */
345 {
346 .callback = dmi_enable_rev_override,
347 .ident = "DELL XPS 13 (2015)",
348 .matches = {
349 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
350 DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9343"),
351 },
352 },
353#endif
328 {} 354 {}
329}; 355};
330 356
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index ba4a61e964be..42f304288829 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -58,6 +58,7 @@ void acpi_cmos_rtc_init(void);
58#else 58#else
59static inline void acpi_cmos_rtc_init(void) {} 59static inline void acpi_cmos_rtc_init(void) {}
60#endif 60#endif
61int acpi_rev_override_setup(char *str);
61 62
62extern bool acpi_force_hot_remove; 63extern bool acpi_force_hot_remove;
63 64
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 39748bb3a543..37e592798cd5 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -537,6 +537,19 @@ acpi_os_get_physical_address(void *virt, acpi_physical_address * phys)
537} 537}
538#endif 538#endif
539 539
540#ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE
541static bool acpi_rev_override;
542
543int __init acpi_rev_override_setup(char *str)
544{
545 acpi_rev_override = true;
546 return 1;
547}
548__setup("acpi_rev_override", acpi_rev_override_setup);
549#else
550#define acpi_rev_override false
551#endif
552
540#define ACPI_MAX_OVERRIDE_LEN 100 553#define ACPI_MAX_OVERRIDE_LEN 100
541 554
542static char acpi_os_name[ACPI_MAX_OVERRIDE_LEN]; 555static char acpi_os_name[ACPI_MAX_OVERRIDE_LEN];
@@ -555,6 +568,11 @@ acpi_os_predefined_override(const struct acpi_predefined_names *init_val,
555 *new_val = acpi_os_name; 568 *new_val = acpi_os_name;
556 } 569 }
557 570
571 if (!memcmp(init_val->name, "_REV", 4) && acpi_rev_override) {
572 printk(KERN_INFO PREFIX "Overriding _REV return value to 5\n");
573 *new_val = (char *)5;
574 }
575
558 return AE_OK; 576 return AE_OK;
559} 577}
560 578