From: sashiko-bot@kernel.org
To: "Yureka Lilian" <yureka@cyberchaos.dev>
Cc: linux-pci@vger.kernel.org, devicetree@vger.kernel.org,
robh@kernel.org, conor+dt@kernel.org
Subject: Re: [PATCH v2 3/3] arm64: dts: apple: t600x: Add PCIe pwren gpios
Date: Wed, 04 Nov 2026 11:58:02 +0000 [thread overview]
Message-ID: <sashiko-outbox-197217@kernel.org> (raw)
In-Reply-To: <20261104-apple-pcie-pwren-v2-3-216a4066965f@cyberchaos.dev>
Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
- [High] arm64: dts: apple: t600x PCIe regulators break PCIe power on t602x boards
- [Medium] PCI: apple: missing pwrctrl power-off and cleanup on error in apple_pcie_init()
- [Low] arm64: dts: apple: undocumented power-supply property on PCIe bridge nodes
- [Low] PCI/pwrctrl: missing !CONFIG_PCI_PWRCTRL stubs for per-device pwrctrl APIs
- [Low] PCI/pwrctrl: mismatched kernel-doc parameter names in drivers/pci/pwrctrl/core.c
--
commit fc220e60fe2546bbee22affe9598f38be84ac7dc
Author: Yureka Lilian <yureka@cyberchaos.dev>
arm64: dts: apple: t600x: Add PCIe pwren gpios
This series exports per-device PCI power control helpers, integrates them into
the Apple PCIe controller driver, and adds SMC GPIO-controlled fixed
regulators for PCIe root ports on Apple T600x devicetrees.
> diff --git a/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi b/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
> index caded1636f3d2..4f9dccf839ad0 100644
> --- a/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
> +++ b/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
> @@ -55,6 +55,20 @@ led-0 {
> default-state = "keep";
> };
> };
> +
> + vreg_pcie0_port0: regulator-pcie0-port0 {
> + compatible = "regulator-fixed";
> + regulator-name = "pwren-pcie0-port0";
> + gpio = <&smc_gpio 13 GPIO_ACTIVE_HIGH>;
> + enable-active-high;
> + };
> +
> + vreg_pcie0_port1: regulator-pcie0-port1 {
> + compatible = "regulator-fixed";
> + regulator-name = "pwren-pcie0-port1";
> + gpio = <&smc_gpio 26 GPIO_ACTIVE_HIGH>;
> + enable-active-high;
> + };
> };
[Severity: High]
Will adding these regulators to t600x-j314-j316.dtsi and t600x-j375.dtsi cut
power to PCIe endpoints on T602x systems?
Both files are included by the T602x board files:
arch/arm64/boot/dts/apple/t602x-j414-j416.dtsi:
/*
* These models are essentially identical to the previous generation, other than
* the GPIO indices.
*/
#include "t600x-j314-j316.dtsi"
arch/arm64/boot/dts/apple/t602x-j474-j475.dtsi:
/*
* These models are very similar to the previous generation Mac Studio, other
* than GPIO indices.
*/
#include "t600x-j375.dtsi"
Because vreg_pcie0_port0, vreg_pcie0_port1, and vreg_pcie0_port3 do not set
regulator-boot-on, reg_fixed_voltage_probe() requests each SMC GPIO with
GPIOD_OUT_LOW and immediately drives the pin low via macsmc_gpio_set().
However, port00 through port03 in arch/arm64/boot/dts/apple/t602x-die0.dtsi do
not have compatible = "pciclass,0604":
arch/arm64/boot/dts/apple/t602x-die0.dtsi:
port00: pci@0,0 {
device_type = "pci";
reg = <0x0 0x0 0x0 0x0 0x0>;
reset-gpios = <&pinctrl_ap 4 GPIO_ACTIVE_LOW>;
As a result, pci_pwrctrl_is_required() returns false on T602x, no pwrctrl
device binds to re-enable the regulators after reg_fixed_voltage_probe() turns
them off, the T602x files note that GPIO indices differ from T600x, and
arch/arm64/boot/dts/apple/t6020-j474s.dts has an unused port01 where sdhci0 is
deleted (/delete-node/ &sdhci0;) while vreg_pcie0_port1 still claims smc_gpio
26.
[ ... ]
> @@ -176,6 +190,7 @@ &nco_clkref {
> /* PCIe devices */
> &port00 {
> /* WLAN */
> + power-supply = <&vreg_pcie0_port0>;
> bus-range = <1 1>;
> wifi0: wifi@0,0 {
> compatible = "pci14e4,4433";
> @@ -195,6 +210,7 @@ bluetooth0: bluetooth@0,1 {
>
> &port01 {
> /* SD card reader */
> + power-supply = <&vreg_pcie0_port1>;
> bus-range = <2 2>;
> sdhci0: mmc@0,0 {
> compatible = "pci17a0,9755";
[Severity: Low]
Should port00 and port01 here (and port00, port01, and port03 in
arch/arm64/boot/dts/apple/t600x-j375.dtsi) use a documented PCI slot supply
property such as vpcie3v3-supply instead of power-supply?
Documentation/devicetree/bindings/pci/apple,pcie.yaml sets
unevaluatedProperties: false and references /schemas/pci/pci-host-bridge.yaml#
for child bridge nodes, where power-supply is not a documented property and
causes dtbs_check warnings, whereas vpcie3v3-supply is defined by the PCI slot
schema and consumed by pci-pwrctrl-slot via of_pci_supply_present() and
of_regulator_bulk_get_all().
[ ... ]
> diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c
> index c2cffc0659f44..2d32092e2122b 100644
> --- a/drivers/pci/controller/pcie-apple.c
> +++ b/drivers/pci/controller/pcie-apple.c
> @@ -30,6 +30,7 @@
> #include <linux/msi.h>
> #include <linux/of_irq.h>
> #include <linux/pci-ecam.h>
> +#include <linux/pci-pwrctrl.h>
>
> #include "pci-host-common.h"
>
> @@ -825,6 +826,28 @@ static int apple_pcie_init(struct pci_config_window *cfg)
> if (WARN_ON(!pcie))
> return -ENOENT;
>
> + // Ensure all ports can be powered on before attempting initialization
> + for_each_available_child_of_node_scoped(dev->of_node, of_port) {
> + ret = pci_pwrctrl_create_device(of_port, pcie->dev);
> + if (ret) {
> + dev_err(pcie->dev, "Failed to create pwrctrl device: %pe\n", ERR_PTR(ret));
> + return ret;
> + }
> +
> + ret = pci_pwrctrl_power_on_device(of_port);
> + if (ret) {
> + if (ret != -EPROBE_DEFER) {
> + dev_err(pcie->dev,
> + "Failed to power on device: %pe\n",
> + ERR_PTR(ret));
> + for_each_available_child_of_node_scoped(dev->of_node, of_port) {
> + pci_pwrctrl_destroy_device(of_port);
> + }
> + }
> + return ret;
> + }
> + }
> +
> for_each_available_child_of_node_scoped(dev->of_node, of_port) {
> ret = apple_pcie_setup_port(pcie, of_port);
> if (ret) {
[Severity: Medium]
What happens to already-enabled port regulators if a subsequent port fails or
defers in apple_pcie_init()?
Once an earlier port succeeds in pci_pwrctrl_power_on_device(), its regulator
has been enabled via slot_pwrctrl_power_on().
1. If a later port returns -EPROBE_DEFER from pci_pwrctrl_power_on_device(),
apple_pcie_init() returns without calling pci_pwrctrl_power_off_device() on
the ports that were already powered on. On the next probe retry,
pci_pwrctrl_power_on_device() will enable those regulators a second time,
leaking regulator enable reference counts.
2. If pci_pwrctrl_power_on_device() fails with an error other than
-EPROBE_DEFER, apple_pcie_init() calls pci_pwrctrl_destroy_device() on all
ports without calling pci_pwrctrl_power_off_device() first, which unbinds
the slot pwrctrl device and runs devm_slot_pwrctrl_release() ->
regulator_bulk_free() while the regulator is still enabled, triggering
WARN_ON(regulator->enable_count) in _regulator_put().
3. If pci_pwrctrl_create_device() fails on a later port or
apple_pcie_setup_port() fails in the second loop, the previously created
and powered-on pwrctrl devices are neither powered off nor destroyed.
Could apple_pcie_init() use pci_pwrctrl_create_devices() and
pci_pwrctrl_power_on_devices() (which already unwind previously powered-on or
created child nodes on error), and call pci_pwrctrl_power_off_devices() and
pci_pwrctrl_destroy_devices() if apple_pcie_setup_port() fails?
> diff --git a/drivers/pci/pwrctrl/core.c b/drivers/pci/pwrctrl/core.c
> index 0e2387cf46577..b59dbedf251bc 100644
> --- a/drivers/pci/pwrctrl/core.c
> +++ b/drivers/pci/pwrctrl/core.c
> @@ -191,7 +191,16 @@ static int __pci_pwrctrl_power_off_device(struct device *dev)
> return pwrctrl->power_off(pwrctrl);
> }
>
> -static void pci_pwrctrl_power_off_device(struct device_node *np)
> +/**
> + * pci_pwrctrl_power_off_device - Power off pwrctrl devices
> + *
> + * @device_node: PCI port or device to operate on
> + *
> + * Recursively traverse all pwrctrl devices for the devicetree hierarchy
> + * below the specified PCI port or device and power them off in a depth
> + * first manner.
> + */
> +void pci_pwrctrl_power_off_device(struct device_node *np)
[ ... ]
> @@ -245,11 +255,21 @@ static int __pci_pwrctrl_power_on_device(struct device *dev)
> return pwrctrl->power_on(pwrctrl);
> }
>
> -/*
> +/**
> + * pci_pwrctrl_power_on_device - Power on pwrctrl devices
> + *
> + * @device_node: PCI port or device to operate on
> + *
> * Power on the devices in a depth first manner. Before powering on the device,
> * make sure its driver is bound.
> + * Recursively traverse all pwrctrl devices for the devicetree hierarchy
> + * below the specified PCI port or device and power them on in a depth
> + * first manner. Before powering on the device, make sure its driver is bound.
> + *
> + * Return: 0 on success, -EPROBE_DEFER if any pwrctrl driver is not bound, an
> + * appropriate error code otherwise.
> */
> -static int pci_pwrctrl_power_on_device(struct device_node *np)
> +int pci_pwrctrl_power_on_device(struct device_node *np)
[ ... ]
> @@ -335,7 +356,17 @@ int pci_pwrctrl_power_on_devices(struct device *parent)
> }
> EXPORT_SYMBOL_GPL(pci_pwrctrl_power_on_devices);
>
> -static int pci_pwrctrl_create_device(struct device_node *np,
> +/**
> + * pci_pwrctrl_create_device - Create pwrctrl devices
> + *
> + * @device_node: PCI port or device to operate on
> + *
> + * Recursively create pwrctrl devices for the devicetree hierarchy below
> + * the specified PCI port or device in a depth first manner.
> + *
> + * Return: 0 on success, negative error number on error.
> + */
> +int pci_pwrctrl_create_device(struct device_node *np,
> struct device *parent)
[ ... ]
> @@ -396,7 +428,15 @@ int pci_pwrctrl_create_devices(struct device *parent)
> }
> EXPORT_SYMBOL_GPL(pci_pwrctrl_create_devices);
>
> -static void pci_pwrctrl_destroy_device(struct device_node *np)
> +/**
> + * pci_pwrctrl_destroy_device - Destroy pwrctrl devices
> + *
> + * @device_node: PCI port or device to operate on
> + *
> + * Recursively destroy pwrctrl devices for the devicetree hierarchy below
> + * the specified PCI port or device in a depth first manner.
> + */
> +void pci_pwrctrl_destroy_device(struct device_node *np)
[Severity: Low]
In these four kernel-doc comments in drivers/pci/pwrctrl/core.c, the parameter
is documented as @device_node instead of @np, pci_pwrctrl_create_device() is
missing @parent, and pci_pwrctrl_power_on_device() repeats "Before powering on
the device, make sure its driver is bound." twice. Could these be updated to
avoid W=1 kernel-doc warnings?
[ ... ]
> diff --git a/include/linux/pci-pwrctrl.h b/include/linux/pci-pwrctrl.h
> index 1192a2527521d..f27be6489b50f 100644
> --- a/include/linux/pci-pwrctrl.h
> +++ b/include/linux/pci-pwrctrl.h
> @@ -59,6 +59,10 @@ int pci_pwrctrl_create_devices(struct device *parent);
> void pci_pwrctrl_destroy_devices(struct device *parent);
> int pci_pwrctrl_power_on_devices(struct device *parent);
> void pci_pwrctrl_power_off_devices(struct device *parent);
> +int pci_pwrctrl_create_device(struct device_node *np, struct device *parent);
> +void pci_pwrctrl_destroy_device(struct device_node *np);
> +int pci_pwrctrl_power_on_device(struct device_node *np);
> +void pci_pwrctrl_power_off_device(struct device_node *np);
> #else
> static inline int pci_pwrctrl_create_devices(struct device *parent) { return 0; }
> static void pci_pwrctrl_destroy_devices(struct device *parent) { }
[Severity: Low]
Should include/linux/pci-pwrctrl.h also provide static inline stubs in the
#else (!CONFIG_PCI_PWRCTRL) branch for pci_pwrctrl_create_device(),
pci_pwrctrl_destroy_device(), pci_pwrctrl_power_on_device(), and
pci_pwrctrl_power_off_device(), along with a struct device_node forward
declaration?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261104-apple-pcie-pwren-v2-0-216a4066965f@cyberchaos.dev?part=3
next prev parent reply other threads:[~2026-11-04 11:58 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-04 11:40 [PATCH v2 0/3] PCI: apple: Integrate pwrctrl API Yureka Lilian
2026-11-04 11:40 ` [PATCH v2 1/3] PCI/pwrctrl: Export per-device APIs Yureka Lilian
2026-11-04 11:48 ` sashiko-bot
2026-11-04 11:40 ` [PATCH v2 2/3] PCI: apple: Integrate pwrctrl API Yureka Lilian
2026-11-04 11:51 ` sashiko-bot
2026-11-04 13:41 ` Janne Grunau
2026-11-04 11:40 ` [PATCH v2 3/3] arm64: dts: apple: t600x: Add PCIe pwren gpios Yureka Lilian
2026-11-04 11:58 ` sashiko-bot [this message]
2026-11-04 13:57 ` Janne Grunau
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=sashiko-outbox-197217@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=robh@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=yureka@cyberchaos.dev \
/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