Skip to content

Commit dde1efe

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 8d623f7 commit dde1efe

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
@@ -555,7 +555,7 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
555555
{
556556
struct platform_device *platform = to_platform_device(pcie->dev);
557557
struct apple_pcie_port *port;
558-
struct gpio_desc *reset;
558+
struct gpio_desc *reset, *pwren = NULL;
559559
struct resource *res;
560560
char name[16];
561561
u32 stat, idx;
@@ -566,6 +566,15 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
566566
if (IS_ERR(reset))
567567
return PTR_ERR(reset);
568568

569+
pwren = devm_fwnode_gpiod_get(pcie->dev, of_fwnode_handle(np), "pwren",
570+
GPIOD_ASIS, "PWREN");
571+
if (IS_ERR(pwren)) {
572+
if (PTR_ERR(pwren) == -ENOENT)
573+
pwren = NULL;
574+
else
575+
return PTR_ERR(pwren);
576+
}
577+
569578
port = devm_kzalloc(pcie->dev, sizeof(*port), GFP_KERNEL);
570579
if (!port)
571580
return -ENOMEM;
@@ -606,12 +615,21 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
606615
/* Assert PERST# before setting up the clock */
607616
gpiod_set_value_cansleep(reset, 1);
608617

618+
/* Power on the device if required */
619+
gpiod_set_value_cansleep(pwren, 1);
620+
609621
ret = apple_pcie_setup_refclk(pcie, port);
610622
if (ret < 0)
611623
return ret;
612624

613-
/* The minimal Tperst-clk value is 100us (PCIe CEM r5.0, 2.9.2) */
614-
usleep_range(100, 200);
625+
/*
626+
* The minimal Tperst-clk value is 100us (PCIe CEM r5.0, 2.9.2)
627+
* If powering up, the minimal Tpvperl is 100ms
628+
*/
629+
if (pwren)
630+
msleep(100);
631+
else
632+
usleep_range(100, 200);
615633

616634
/* Deassert PERST# */
617635
rmw_set(PORT_PERST_OFF, port->base + pcie->hw->port_perst);
@@ -856,6 +874,16 @@ static int apple_pcie_probe_port(struct device_node *np)
856874
return PTR_ERR(gd);
857875

858876
gpiod_put(gd);
877+
878+
gd = fwnode_gpiod_get_index(of_fwnode_handle(np), "pwren", 0,
879+
GPIOD_ASIS, "PWREN");
880+
if (IS_ERR(gd)) {
881+
if (PTR_ERR(gd) != -ENOENT)
882+
return PTR_ERR(gd);
883+
} else {
884+
gpiod_put(gd);
885+
}
886+
859887
return 0;
860888
}
861889

0 commit comments

Comments
 (0)