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: 10+ 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-05 6:28 ` kernel test robot
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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.