Skip to content

Commit 6172c2b

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 62193aa commit 6172c2b

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
@@ -559,7 +559,7 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
559559
{
560560
struct platform_device *platform = to_platform_device(pcie->dev);
561561
struct apple_pcie_port *port;
562-
struct gpio_desc *reset;
562+
struct gpio_desc *reset, *pwren = NULL;
563563
struct resource *res;
564564
char name[16];
565565
u32 stat, idx;
@@ -570,6 +570,15 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
570570
if (IS_ERR(reset))
571571
return PTR_ERR(reset);
572572

573+
pwren = devm_fwnode_gpiod_get(pcie->dev, of_fwnode_handle(np), "pwren",
574+
GPIOD_ASIS, "PWREN");
575+
if (IS_ERR(pwren)) {
576+
if (PTR_ERR(pwren) == -ENOENT)
577+
pwren = NULL;
578+
else
579+
return PTR_ERR(pwren);
580+
}
581+
573582
port = devm_kzalloc(pcie->dev, sizeof(*port), GFP_KERNEL);
574583
if (!port)
575584
return -ENOMEM;
@@ -610,12 +619,21 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
610619
/* Assert PERST# before setting up the clock */
611620
gpiod_set_value_cansleep(reset, 1);
612621

622+
/* Power on the device if required */
623+
gpiod_set_value_cansleep(pwren, 1);
624+
613625
ret = apple_pcie_setup_refclk(pcie, port);
614626
if (ret < 0)
615627
return ret;
616628

617-
/* The minimal Tperst-clk value is 100us (PCIe CEM r5.0, 2.9.2) */
618-
usleep_range(100, 200);
629+
/*
630+
* The minimal Tperst-clk value is 100us (PCIe CEM r5.0, 2.9.2)
631+
* If powering up, the minimal Tpvperl is 100ms
632+
*/
633+
if (pwren)
634+
msleep(100);
635+
else
636+
usleep_range(100, 200);
619637

620638
/* Deassert PERST# */
621639
rmw_set(PORT_PERST_OFF, port->base + pcie->hw->port_perst);
@@ -883,6 +901,16 @@ static int apple_pcie_probe_port(struct device_node *np)
883901
return PTR_ERR(gd);
884902

885903
gpiod_put(gd);
904+
905+
gd = fwnode_gpiod_get_index(of_fwnode_handle(np), "pwren", 0,
906+
GPIOD_ASIS, "PWREN");
907+
if (IS_ERR(gd)) {
908+
if (PTR_ERR(gd) != -ENOENT)
909+
return PTR_ERR(gd);
910+
} else {
911+
gpiod_put(gd);
912+
}
913+
886914
return 0;
887915
}
888916

0 commit comments

Comments
 (0)