Skip to content

Commit 7bc5a2b

Browse files
Matthew Garrettrafaeljw
authored andcommitted
ACPI: Support _OSI("Darwin") correctly
Apple hardware queries _OSI("Darwin") in order to determine whether the system is running OS X, and changes firmware behaviour based on the answer. The most obvious difference in behaviour is that Thunderbolt hardware is forcibly powered down unless the system is running OS X. The obvious solution would be to simply add Darwin to the list of supported _OSI strings, but this causes problems. Recent Apple hardware includes two separate methods for checking _OSI strings. The first will check whether Darwin is supported, and if so will exit. The second will check whether Darwin is supported, but will then continue to check for further operating systems. If a further operating system is found then later firmware code will assume that the OS is not OS X. This results in the unfortunate situation where the Thunderbolt controller is available at boot time but remains powered down after suspend. The easiest way to handle this is to special-case it in the Linux-specific OSI handling code. If we see Darwin, we should answer true and then disable all other _OSI vendor strings. The next problem is that the Apple PCI _OSC method has the following code: if (LEqual (0x01, OSDW ())) if (LAnd (LEqual (Arg0, GUID), NEXP) (do stuff) else (fail) NEXP is a value in high memory and is presumably under the control of the firmware. No methods sets it. The methods that are called in the "do stuff" path are dummies. Unless there's some additional firmware call in early boot, there's no way for this call to succeed - and even if it does, it doesn't do anything. The easiest way to handle this is simply to ignore it. We know which flags would be set, so just set them by hand if the platform is running in Darwin mode. Signed-off-by: Matthew Garrett <[email protected]> [[email protected]: merged two patches, do not touch ACPICA] Signed-off-by: Andreas Noever <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 9faf613 commit 7bc5a2b

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

drivers/acpi/osl.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,16 @@ static u32 acpi_osi_handler(acpi_string interface, u32 supported)
152152
osi_linux.dmi ? " via DMI" : "");
153153
}
154154

155+
if (!strcmp("Darwin", interface)) {
156+
/*
157+
* Apple firmware will behave poorly if it receives positive
158+
* answers to "Darwin" and any other OS. Respond positively
159+
* to Darwin and then disable all other vendor strings.
160+
*/
161+
acpi_update_interfaces(ACPI_DISABLE_ALL_VENDOR_STRINGS);
162+
supported = ACPI_UINT32_MAX;
163+
}
164+
155165
return supported;
156166
}
157167

drivers/acpi/pci_root.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include <linux/pci-aspm.h>
3636
#include <linux/acpi.h>
3737
#include <linux/slab.h>
38+
#include <linux/dmi.h>
3839
#include <acpi/apei.h> /* for acpi_hest_init() */
3940

4041
#include "internal.h"
@@ -429,6 +430,19 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm,
429430
struct acpi_device *device = root->device;
430431
acpi_handle handle = device->handle;
431432

433+
/*
434+
* Apple always return failure on _OSC calls when _OSI("Darwin") has
435+
* been called successfully. We know the feature set supported by the
436+
* platform, so avoid calling _OSC at all
437+
*/
438+
439+
if (dmi_match(DMI_SYS_VENDOR, "Apple Inc.")) {
440+
root->osc_control_set = ~OSC_PCI_EXPRESS_PME_CONTROL;
441+
decode_osc_control(root, "OS assumes control of",
442+
root->osc_control_set);
443+
return;
444+
}
445+
432446
/*
433447
* All supported architectures that use ACPI have support for
434448
* PCI domains, so we indicate this in _OSC support capabilities.

0 commit comments

Comments
 (0)