Skip to content

Commit ec3a73d

Browse files
marcanjannau
authored andcommitted
PCI: apple: Add support for optional PWREN GPIO
WiFi and SD card devices on M1 Macs have a separate power enable GPIO. Add support for this to the PCIe controller. This is modeled after how pcie-fu740 does it. Acked-by: Marc Zyngier <maz@kernel.org> Signed-off-by: Hector Martin <marcan@marcan.st>
1 parent 534e1d7 commit ec3a73d

1 file changed

Lines changed: 31 additions & 3 deletions

File tree

drivers/pci/controller/pcie-apple.c

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,16 @@ static int apple_pcie_probe_port(struct device_node *np)
519519
}
520520

521521
gpiod_put(gd);
522+
523+
gd = fwnode_gpiod_get_index(of_fwnode_handle(np), "pwren", 0,
524+
GPIOD_OUT_LOW, "PWREN");
525+
if (IS_ERR(gd)) {
526+
if (PTR_ERR(gd) != -ENOENT)
527+
return PTR_ERR(gd);
528+
} else {
529+
gpiod_put(gd);
530+
}
531+
522532
return 0;
523533
}
524534

@@ -527,7 +537,7 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
527537
{
528538
struct platform_device *platform = to_platform_device(pcie->dev);
529539
struct apple_pcie_port *port;
530-
struct gpio_desc *reset;
540+
struct gpio_desc *reset, *pwren = NULL;
531541
u32 stat, idx;
532542
int ret, i;
533543

@@ -536,6 +546,15 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
536546
if (IS_ERR(reset))
537547
return PTR_ERR(reset);
538548

549+
pwren = devm_fwnode_gpiod_get(pcie->dev, of_fwnode_handle(np), "pwren",
550+
GPIOD_OUT_LOW, "PWREN");
551+
if (IS_ERR(pwren)) {
552+
if (PTR_ERR(pwren) == -ENOENT)
553+
pwren = NULL;
554+
else
555+
return PTR_ERR(pwren);
556+
}
557+
539558
port = devm_kzalloc(pcie->dev, sizeof(*port), GFP_KERNEL);
540559
if (!port)
541560
return -ENOMEM;
@@ -558,12 +577,21 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
558577
/* Assert PERST# before setting up the clock */
559578
gpiod_set_value_cansleep(reset, 1);
560579

580+
/* Power on the device if required */
581+
gpiod_set_value_cansleep(pwren, 1);
582+
561583
ret = apple_pcie_setup_refclk(pcie, port);
562584
if (ret < 0)
563585
return ret;
564586

565-
/* The minimal Tperst-clk value is 100us (PCIe CEM r5.0, 2.9.2) */
566-
usleep_range(100, 200);
587+
/*
588+
* The minimal Tperst-clk value is 100us (PCIe CEM r5.0, 2.9.2)
589+
* If powering up, the minimal Tpvperl is 100ms
590+
*/
591+
if (pwren)
592+
msleep(100);
593+
else
594+
usleep_range(100, 200);
567595

568596
/* Deassert PERST# */
569597
rmw_set(PORT_PERST_OFF, port->base + PORT_PERST);

0 commit comments

Comments
 (0)