[PATCH v2 2/3] PCI: apple: Integrate pwrctrl API
From: Yureka Lilian
Date: Wed Nov 04 2026 - 06:51:49 EST
Integrate the PCI pwrctrl framework into the Apple PCIe host driver to
provide standardized power management for PCI devices.
Notably, this allows enabling powering on the WiFi, SD card reader on
various Macs by means of the pwrctrl framework before probing the ports.
Signed-off-by: Yureka Lilian <yureka@xxxxxxxxxxxxxx>
---
drivers/pci/controller/Kconfig | 1 +
drivers/pci/controller/pcie-apple.c | 23 +++++++++++++++++++++++
2 files changed, 24 insertions(+)
diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index d246bbe37948..791892a6c0c6 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -46,6 +46,7 @@ config PCIE_APPLE
depends on OF
depends on PCI_MSI
select PCI_HOST_COMMON
+ select PCI_PWRCTRL_GENERIC
select IRQ_MSI_LIB
help
Say Y here if you want to enable PCIe controller support on Apple
diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c
index c2cffc0659f4..2d32092e2122 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) {
--
2.56.0