Skip to content

Commit a4aac29

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 3f8e903 commit a4aac29

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
@@ -581,7 +581,7 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
581581
{
582582
struct platform_device *platform = to_platform_device(pcie->dev);
583583
struct apple_pcie_port *port;
584-
struct gpio_desc *reset;
584+
struct gpio_desc *reset, *pwren = NULL;
585585
struct resource *res;
586586
char name[16];
587587
u32 stat, idx;
@@ -592,6 +592,15 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
592592
if (IS_ERR(reset))
593593
return PTR_ERR(reset);
594594

595+
pwren = devm_fwnode_gpiod_get(pcie->dev, of_fwnode_handle(np), "pwren",
596+
GPIOD_ASIS, "PWREN");
597+
if (IS_ERR(pwren)) {
598+
if (PTR_ERR(pwren) == -ENOENT)
599+
pwren = NULL;
600+
else
601+
return PTR_ERR(pwren);
602+
}
603+
595604
port = devm_kzalloc(pcie->dev, sizeof(*port), GFP_KERNEL);
596605
if (!port)
597606
return -ENOMEM;
@@ -632,12 +641,21 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
632641
/* Assert PERST# before setting up the clock */
633642
gpiod_set_value_cansleep(reset, 1);
634643

644+
/* Power on the device if required */
645+
gpiod_set_value_cansleep(pwren, 1);
646+
635647
ret = apple_pcie_setup_refclk(pcie, port);
636648
if (ret < 0)
637649
return ret;
638650

639-
/* The minimal Tperst-clk value is 100us (PCIe CEM r5.0, 2.9.2) */
640-
usleep_range(100, 200);
651+
/*
652+
* The minimal Tperst-clk value is 100us (PCIe CEM r5.0, 2.9.2)
653+
* If powering up, the minimal Tpvperl is 100ms
654+
*/
655+
if (pwren)
656+
msleep(100);
657+
else
658+
usleep_range(100, 200);
641659

642660
/* Deassert PERST# */
643661
rmw_set(PORT_PERST_OFF, port->base + pcie->hw->port_perst);
@@ -864,6 +882,16 @@ static int apple_pcie_probe_port(struct device_node *np)
864882
return PTR_ERR(gd);
865883

866884
gpiod_put(gd);
885+
886+
gd = fwnode_gpiod_get_index(of_fwnode_handle(np), "pwren", 0,
887+
GPIOD_ASIS, "PWREN");
888+
if (IS_ERR(gd)) {
889+
if (PTR_ERR(gd) != -ENOENT)
890+
return PTR_ERR(gd);
891+
} else {
892+
gpiod_put(gd);
893+
}
894+
867895
return 0;
868896
}
869897

0 commit comments

Comments
 (0)