Skip to content

Commit cb1e098

Browse files
committed
NOT-FOR-UPSTREAM: PCI: apple: Use up to 4 "reset-gpios"
This brings both ASM3142 PCIe xHCI and the Wlan/BT controller in the Mac Pro (M2 Ultra, 2023) online. Handle the device reset-gpios as auxiliary ones until this can be replaced once "PCI/pwrctrl: Allow pwrctrl framework to control PERST# GPIO if available" [1] is upstream. 1: https://lore.kernel.org/linux-pci/20250707-pci-pwrctrl-perst-v1-0-c3c7e513e312@kernel.org/ Signed-off-by: Janne Grunau <j@jannau.net>
1 parent 49d9ae0 commit cb1e098

1 file changed

Lines changed: 23 additions & 0 deletions

File tree

drivers/pci/controller/pcie-apple.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,9 @@ static int apple_pcie_setup_link(struct apple_pcie *pcie,
562562
struct apple_pcie_port *port,
563563
struct device_node *np)
564564
{
565+
#define MAX_AUX_PERST 3
566+
struct gpio_desc *aux_reset[MAX_AUX_PERST] = { NULL };
567+
u32 num_aux_resets = 0;
565568
struct gpio_desc *reset, *pwren = NULL;
566569
u32 stat;
567570
int ret;
@@ -576,6 +579,22 @@ static int apple_pcie_setup_link(struct apple_pcie *pcie,
576579
GPIOD_OUT_HIGH, "PERST#");
577580
if (IS_ERR(reset))
578581
return PTR_ERR(reset);
582+
// HACK: use additional "reset-gpios" until pci-pwrctrl gains PERST# support.
583+
for (u32 idx = 0; idx < MAX_AUX_PERST; idx++) {
584+
aux_reset[idx] = devm_fwnode_gpiod_get_index(pcie->dev,
585+
of_fwnode_handle(np),
586+
"reset", idx + 1,
587+
GPIOD_OUT_HIGH,
588+
"PERST#");
589+
if (IS_ERR(aux_reset[idx])) {
590+
if (PTR_ERR(aux_reset[idx]) == -ENOENT)
591+
break;
592+
else
593+
return PTR_ERR(aux_reset[idx]);
594+
}
595+
num_aux_resets++;
596+
}
597+
dev_info(pcie->dev, "Using %u auxiliary PERST#\n", num_aux_resets);
579598

580599
pwren = devm_fwnode_gpiod_get(pcie->dev, of_fwnode_handle(np), "pwren",
581600
GPIOD_ASIS, "PWREN");
@@ -590,6 +609,8 @@ static int apple_pcie_setup_link(struct apple_pcie *pcie,
590609

591610
/* Assert PERST# before setting up the clock */
592611
gpiod_set_value_cansleep(reset, 1);
612+
for (u32 idx = 0; idx < num_aux_resets; idx++)
613+
gpiod_set_value_cansleep(aux_reset[idx], 1);
593614

594615
/* Power on the device if required */
595616
gpiod_set_value_cansleep(pwren, 1);
@@ -610,6 +631,8 @@ static int apple_pcie_setup_link(struct apple_pcie *pcie,
610631
/* Deassert PERST# */
611632
rmw_set(PORT_PERST_OFF, port->base + pcie->hw->port_perst);
612633
gpiod_set_value_cansleep(reset, 0);
634+
for (u32 idx = 0; idx < num_aux_resets; idx++)
635+
gpiod_set_value_cansleep(aux_reset[idx], 0);
613636

614637
/* Wait for 100ms after PERST# deassertion (PCIe r5.0, 6.6.1) */
615638
msleep(100);

0 commit comments

Comments
 (0)