Skip to content

Commit cac6032

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 a338d7a commit cac6032

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
@@ -518,6 +518,16 @@ static int apple_pcie_probe_port(struct device_node *np)
518518
}
519519

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

@@ -526,7 +536,7 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
526536
{
527537
struct platform_device *platform = to_platform_device(pcie->dev);
528538
struct apple_pcie_port *port;
529-
struct gpio_desc *reset;
539+
struct gpio_desc *reset, *pwren = NULL;
530540
u32 stat, idx;
531541
int ret, i;
532542

@@ -535,6 +545,15 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
535545
if (IS_ERR(reset))
536546
return PTR_ERR(reset);
537547

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

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

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

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

0 commit comments

Comments
 (0)