mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-07-16 12:46:59 +08:00
89 lines
2.5 KiB
Diff
89 lines
2.5 KiB
Diff
From 6cb714273e04b6d82734c6c8a70907f3871e409b Mon Sep 17 00:00:00 2001
|
|
From: Hector Martin <marcan@marcan.st>
|
|
Date: Sun, 6 Feb 2022 21:18:18 +0900
|
|
Subject: [PATCH 165/171] 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>
|
|
---
|
|
drivers/pci/controller/pcie-apple.c | 34 ++++++++++++++++++++++++++---
|
|
1 file changed, 31 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c
|
|
index e3aa2d461739..f26a617ea5c5 100644
|
|
--- a/drivers/pci/controller/pcie-apple.c
|
|
+++ b/drivers/pci/controller/pcie-apple.c
|
|
@@ -518,6 +518,16 @@ static int apple_pcie_probe_port(struct device_node *np)
|
|
}
|
|
|
|
gpiod_put(gd);
|
|
+
|
|
+ gd = gpiod_get_from_of_node(np, "pwren-gpios", 0,
|
|
+ GPIOD_OUT_LOW, "PWREN");
|
|
+ if (IS_ERR(gd)) {
|
|
+ if (PTR_ERR(gd) != -ENOENT)
|
|
+ return PTR_ERR(gd);
|
|
+ } else {
|
|
+ gpiod_put(gd);
|
|
+ }
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -526,7 +536,7 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
|
|
{
|
|
struct platform_device *platform = to_platform_device(pcie->dev);
|
|
struct apple_pcie_port *port;
|
|
- struct gpio_desc *reset;
|
|
+ struct gpio_desc *reset, *pwren = NULL;
|
|
u32 stat, idx;
|
|
int ret, i;
|
|
|
|
@@ -535,6 +545,15 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
|
|
if (IS_ERR(reset))
|
|
return PTR_ERR(reset);
|
|
|
|
+ pwren = devm_gpiod_get_from_of_node(pcie->dev, np, "pwren-gpios", 0,
|
|
+ GPIOD_OUT_LOW, "PWREN");
|
|
+ if (IS_ERR(pwren)) {
|
|
+ if (PTR_ERR(pwren) == -ENOENT)
|
|
+ pwren = NULL;
|
|
+ else
|
|
+ return PTR_ERR(pwren);
|
|
+ }
|
|
+
|
|
port = devm_kzalloc(pcie->dev, sizeof(*port), GFP_KERNEL);
|
|
if (!port)
|
|
return -ENOMEM;
|
|
@@ -557,12 +576,21 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
|
|
/* Assert PERST# before setting up the clock */
|
|
gpiod_set_value_cansleep(reset, 1);
|
|
|
|
+ /* Power on the device if required */
|
|
+ gpiod_set_value_cansleep(pwren, 1);
|
|
+
|
|
ret = apple_pcie_setup_refclk(pcie, port);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
- /* The minimal Tperst-clk value is 100us (PCIe CEM r5.0, 2.9.2) */
|
|
- usleep_range(100, 200);
|
|
+ /*
|
|
+ * The minimal Tperst-clk value is 100us (PCIe CEM r5.0, 2.9.2)
|
|
+ * If powering up, the minimal Tpvperl is 100ms
|
|
+ */
|
|
+ if (pwren)
|
|
+ msleep(100);
|
|
+ else
|
|
+ usleep_range(100, 200);
|
|
|
|
/* Deassert PERST# */
|
|
rmw_set(PORT_PERST_OFF, port->base + PORT_PERST);
|
|
--
|
|
2.34.1
|
|
|