Skip to content

Commit

Permalink
ACPI / init: Make it possible to override _REV
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Rafael J. Wysocki <[email protected]>
  • Loading branch information
rafaeljw committed Jul 2, 2015
1 parent ce55d01 commit 18d78b6
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 0 deletions.
6 changes: 6 additions & 0 deletions Documentation/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS
Format: To spoof as Windows 98: ="Microsoft Windows"

acpi_rev_override [ACPI] Override the _REV object to return 5 (instead
of 2 which is mandated by ACPI 6) as the supported ACPI
specification revision (when using this switch, it may
be necessary to carry out a cold reboot _twice_ in a
row to make it take effect on the platform firmware).

acpi_osi= [HW,ACPI] Modify list of supported OS interface strings
acpi_osi="string1" # add string1
acpi_osi="!string2" # remove string2
Expand Down
20 changes: 20 additions & 0 deletions drivers/acpi/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,26 @@ config ACPI_PROCFS_POWER

Say N to delete power /proc/acpi/ directories that have moved to /sys/

config ACPI_REV_OVERRIDE_POSSIBLE
bool "Allow supported ACPI revision to be overriden"
depends on X86
default y
help
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).

This option enables a DMI-based quirk for the above Dell machine (so
that HDA audio is exposed by the platform firmware to the kernel) and
makes it possible to force the kernel to return "5" as the supported
ACPI revision via the "acpi_rev_override" command line switch.

config ACPI_EC_DEBUGFS
tristate "EC read/write access through /sys/kernel/debug/ec"
default n
Expand Down
26 changes: 26 additions & 0 deletions drivers/acpi/blacklist.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,15 @@ static int __init dmi_disable_osi_win8(const struct dmi_system_id *d)
acpi_osi_setup("!Windows 2012");
return 0;
}
#ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE
static int __init dmi_enable_rev_override(const struct dmi_system_id *d)
{
printk(KERN_NOTICE PREFIX "DMI detected: %s (force ACPI _REV to 5)\n",
d->ident);
acpi_rev_override_setup(NULL);
return 0;
}
#endif

static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
{
Expand Down Expand Up @@ -325,6 +334,23 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
DMI_MATCH(DMI_PRODUCT_NAME, "1015PX"),
},
},

#ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE
/*
* DELL XPS 13 (2015) switches sound between HDA and I2S
* depending on the ACPI _REV callback. If userspace supports
* I2S sufficiently (or if you do not care about sound), you
* can safely disable this quirk.
*/
{
.callback = dmi_enable_rev_override,
.ident = "DELL XPS 13 (2015)",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9343"),
},
},
#endif
{}
};

Expand Down
1 change: 1 addition & 0 deletions drivers/acpi/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ void acpi_cmos_rtc_init(void);
#else
static inline void acpi_cmos_rtc_init(void) {}
#endif
int acpi_rev_override_setup(char *str);

extern bool acpi_force_hot_remove;

Expand Down
18 changes: 18 additions & 0 deletions drivers/acpi/osl.c
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,19 @@ acpi_os_get_physical_address(void *virt, acpi_physical_address * phys)
}
#endif

#ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE
static bool acpi_rev_override;

int __init acpi_rev_override_setup(char *str)
{
acpi_rev_override = true;
return 1;
}
__setup("acpi_rev_override", acpi_rev_override_setup);
#else
#define acpi_rev_override false
#endif

#define ACPI_MAX_OVERRIDE_LEN 100

static char acpi_os_name[ACPI_MAX_OVERRIDE_LEN];
Expand All @@ -555,6 +568,11 @@ acpi_os_predefined_override(const struct acpi_predefined_names *init_val,
*new_val = acpi_os_name;
}

if (!memcmp(init_val->name, "_REV", 4) && acpi_rev_override) {
printk(KERN_INFO PREFIX "Overriding _REV return value to 5\n");
*new_val = (char *)5;
}

return AE_OK;
}

Expand Down

0 comments on commit 18d78b6

Please sign in to comment.