diff mbox series

[18/18] PCI: aardvark: Optimize PCIe card reset via GPIO

Message ID 20220220193346.23789-19-kabel@kernel.org (mailing list archive)
State New, archived
Headers show
Series PCI: aardvark controller changes BATCH 5 | expand

Commit Message

Marek Behún Feb. 20, 2022, 7:33 p.m. UTC
From: Pali Rohár <pali@kernel.org>

Currently we always assert reset GPIO (if it is available) for ~10ms.
But if the GPIO was asserted before driver probe (by bootloader for
example), we do not need to wait these 10ms.

Assert reset GPIO for 10ms only if it wasn't asserted.

We need to get the GPIO with flag GPIOD_FLAGS_BIT_DIR_OUT instead of
GPIOD_OUT_LOW, so that it's value isn't changed when getting it.

Signed-off-by: Pali Rohár <pali@kernel.org>
Signed-off-by: Marek Behún <kabel@kernel.org>
---
 drivers/pci/controller/pci-aardvark.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 056f49d0e3a4..80eb6e98923f 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -431,10 +431,17 @@  static void advk_pcie_issue_perst(struct advk_pcie *pcie)
 	if (!pcie->reset_gpio)
 		return;
 
-	/* 10ms delay is needed for some cards */
-	dev_info(&pcie->pdev->dev, "issuing PERST via reset GPIO for 10ms\n");
-	gpiod_set_value_cansleep(pcie->reset_gpio, 1);
-	usleep_range(10000, 11000);
+	/*
+	 * Assert PERST# for at least 10ms if it wasn't asserted yet (it could
+	 * have been asserted by bootloader or by GPIO driver, for example).
+	 */
+	if (!gpiod_get_value(pcie->reset_gpio)) {
+		dev_info(&pcie->pdev->dev, "issuing PERST via reset GPIO for 10ms\n");
+		gpiod_set_value_cansleep(pcie->reset_gpio, 1);
+		usleep_range(10000, 11000);
+	}
+
+	/* De-assert PERST# */
 	gpiod_set_value_cansleep(pcie->reset_gpio, 0);
 }
 
@@ -2049,7 +2056,7 @@  static int advk_pcie_probe(struct platform_device *pdev)
 
 	pcie->reset_gpio = devm_gpiod_get_from_of_node(dev, dev->of_node,
 						       "reset-gpios", 0,
-						       GPIOD_OUT_LOW,
+						       GPIOD_FLAGS_BIT_DIR_OUT,
 						       "pcie1-reset");
 	ret = PTR_ERR_OR_ZERO(pcie->reset_gpio);
 	if (ret) {