mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Bjorn Helgaas <helgaas@kernel.org>
To: "Francisco Beltrán Millalén" <fbeltranmillalen@gmail.com>
Cc: rafael@kernel.org, bhelgaas@google.com,
	linux-acpi@vger.kernel.org, linux-pci@vger.kernel.org,
	lenb@kernel.org, linux-kernel@vger.kernel.org,
	Darrell Gum <d@rrell.co>, Matthew Garrett <mjg59@srcf.ucam.org>,
	Andreas Noever <andreas.noever@gmail.com>,
	Mika Westerberg <westeri@kernel.org>,
	Yehezkel Bernat <YehezkelShB@gmail.com>,
	Lukas Wunner <lukas@wunner.de>,
	linux-usb@vger.kernel.org
Subject: Re: [PATCH] ACPI: PCI: take native PME control on Apple machines
Date: Thu, 8 Oct 2026 18:29:12 -0500	[thread overview]
Message-ID: <20261008232912.GA940274@bhelgaas> (raw)
In-Reply-To: <20260924132859.24751-1-fbeltranmillalen@gmail.com>

[+cc Matthew (author of 7bc5a2bad0b8), Darrell, Andreas, Mika,
Yehezkel, Lukas, linux-usb]

On Thu, Sep 24, 2026 at 10:28:59AM -0300, Francisco Beltrán Millalén wrote:
> Since commit 7bc5a2bad0b8 ("ACPI: Support _OSI("Darwin") correctly")
> negotiate_os_control() skips the _OSC handshake on Apple machines and
> hardcodes the set of features the OS takes over, because those firmwares
> return failure once _OSI("Darwin") has been acknowledged.  The hardcoded
> set is ~OSC_PCI_EXPRESS_PME_CONTROL, i.e. everything except PME.  No
> reason was given for leaving PME out.

It's clear there *was* a reason, but I don't know either.  Maybe
Matthew will remember?

> The result is that host_bridge->native_pme stays 0, so portdrv never
> registers the PME service for any root port.  A PCIe device that
> runtime suspends still arms PME# (the PCI core enables it because
> pci_dev_run_wake() only looks at capability), asserts it when it needs
> attention, and is never resumed: no service handles the root port
> interrupt, and the polling fallback in pci_pme_list_scan() skips the
> device whenever the bridge above it is runtime suspended, which is
> exactly when the device itself is suspended.
> 
> On a MacBookPro14,3 this silently breaks USB-C hotplug.  Both xHCI
> controllers sit inside the Thunderbolt (Alpine Ridge) switches and
> runtime suspend to D3hot when idle, together with their parent
> bridges.  Plugging a SuperSpeed device in is then never noticed:
> 
>   0000:7d:00.0 suspended, PMCSR 0x8103 (D3hot, PME_En=1, PME_Status=1)
>   ... no kernel message at all, for minutes ...
> 
> The device only appears once something else resumes the controller,
> which makes it look intermittent.  The firmware on this machine does not
> handle PME on behalf of the OS either: XHC2/XHC3 declare _PRW returning
> GPE 0x6D, that GPE is enabled and has never fired, and its _L6D handler
> notifies PWRB, XHC1 and HDEF only - never XHC2 or XHC3.
> 
> With PME control taken, the root port PME interrupt is serviced and the
> controller is resumed as soon as something is plugged in.
> 
> Use calculate_control() for the assumed set rather than open coding it:
> that is by definition the set that would have been requested, it drops a
> magic constant, and on a kernel built without some of those features it
> no longer claims control of services the OS cannot provide.
> 
> Note this also makes pme_is_native() true for pciehp (drivers/pci/
> hotplug/pciehp_core.c), so hotplug ports now disable their interrupt
> across suspend and clear spurious events on resume, as they do on every
> non-Apple machine.  x86_apple_machine covers Macs back to 2006, so this
> reaches models that were never tested with native PME.
> 
> Tested on a MacBookPro14,3, 6.18.49, with a USB 3.1 SATA enclosure:
> 
>   - before: plugged in at 09:20 with 0000:7d:00.0 runtime suspended, still
>     invisible at 09:21 with PME_Status latched at 1; only appeared when
>     0000:7d:00.0 was forced to power/control=on.
>   - with pcie_ports=native (which reaches the same code path in
>     get_port_device_capability()): pcie_pme bound to 5 root ports, and the
>     same enclosure enumerated in the same second it was plugged in, 66 s
>     after the controller had suspended, with nothing forced.
>   - with this patch, nothing forced: pcie_pme bound to 5 root ports and the
>     _OSC line now reads "OS assumes control of [PCIeHotplug SHPCHotplug PME
>     AER PCIeCapability LTR DPC]".  The enclosure was unplugged at 20:42:13,
>     0000:7d:00.0 runtime suspended to D3hot, and on plugging it back in at
>     20:43:06 (53 s later) the root port took a PME interrupt and the device
>     enumerated in the same second.
>   - wifi, internal keyboard, touchbar and audio all came up; 66 warnings
>     and 45 errors during boot, against 65/43 on the distribution kernel.
> 
> One rough edge, reproducible on both boots: the port driver logs
> "PME: Spurious native interrupt!" right before the device is resumed.
> pcie_pme_handle_request() falls back to pcie_pme_walk_bus() when the root
> port reports its own requester ID without PCI_PM_CTRL_PME_STATUS set, and
> that walk skips PCIe devices, so the xHCI is never attributed.  The device
> is still resumed and the wakeup works, but attributing PMEs from PCIe
> devices behind a switch looks like a separate shortcoming; it is not
> addressed here.
> 
> Boot with pcie_ports=native also showed no new AER/DPC activity and
> slightly fewer warnings than a boot without it, so taking the remaining
> control bit does not appear to disturb anything else on this machine.
> 
> Fixes: 7bc5a2bad0b8 ("ACPI: Support _OSI("Darwin") correctly")
> Signed-off-by: Francisco Beltrán Millalén <fbeltranmillalen@gmail.com>

I don't object from a PCI standpoint, but Rafael generally takes care
of acpi/pci_root.c.  I would again suggest putting some of the commit
log detail below "---" and relying on the https://patch.msgid.link/
tag Rafael adds.

> ---
> --- a/drivers/acpi/pci_root.c
> +++ b/drivers/acpi/pci_root.c
> @@ -568,9 +568,14 @@
>  	 * Apple always return failure on _OSC calls when _OSI("Darwin") has
>  	 * been called successfully. We know the feature set supported by the
>  	 * platform, so avoid calling _OSC at all
> +	 *
> +	 * Assume control of the same features that would have been requested,
> +	 * PCIe PME included.  Leaving PME out disables the PME service for
> +	 * every root port, and nothing takes over: a device that runtime
> +	 * suspends asserts PME# and is never resumed.
>  	 */
>  	if (x86_apple_machine) {
> -		root->osc_control_set = ~OSC_PCI_EXPRESS_PME_CONTROL;
> +		root->osc_control_set = calculate_control();
>  		decode_osc_control(root, "OS assumes control of",
>  				   root->osc_control_set);
>  		return;

  parent reply	other threads:[~2026-10-08 23:29 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-24 13:28 Francisco Beltrán Millalén
2026-10-08 18:55 ` Darrell Gum
2026-10-08 23:29 ` Bjorn Helgaas [this message]
2026-10-09  8:23   ` Matthew Garrett
2026-10-09 12:14     ` Francisco Beltrán Millalén

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261008232912.GA940274@bhelgaas \
    --to=helgaas@kernel.org \
    --cc=YehezkelShB@gmail.com \
    --cc=andreas.noever@gmail.com \
    --cc=bhelgaas@google.com \
    --cc=d@rrell.co \
    --cc=fbeltranmillalen@gmail.com \
    --cc=lenb@kernel.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=lukas@wunner.de \
    --cc=mjg59@srcf.ucam.org \
    --cc=rafael@kernel.org \
    --cc=westeri@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®