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

Marek Behún
2022-02-20T19:34:38Z

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 --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) {
--
2.34.1