From ef4609dd00a2f73f67e2843d84a351c002554c9a Mon Sep 17 00:00:00 2001 From: Max Krummenacher Date: Mon, 8 Oct 2018 16:12:51 +0200 Subject: pci-imx6.c: allow clean initalisation sequence for colibri imx8qxp pcie/wifi - Port the driver to use the gpiod framework This allows to choose the polarity of the power_on and disable gpio in the device tree. - Actually use the gpios in the initialisation sequence Signed-off-by: Max Krummenacher (cherry picked from commit 91aedb97b4e65c4afc66f5a5b8d670061addd80d) (cherry picked from commit 15a9d28286bba122f15e342cd40c6da7294b9bb6) Fixed gpiod stuff after imx_4.14.98_2.3.0 resp. 4.14-2.3.x-imx merge. Signed-off-by: Marcel Ziswiler --- drivers/pci/dwc/pci-imx6.c | 110 +++++++++++++++++++++------------------------ 1 file changed, 52 insertions(+), 58 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/dwc/pci-imx6.c b/drivers/pci/dwc/pci-imx6.c index cf104ec7ca7a..3353002be1b4 100644 --- a/drivers/pci/dwc/pci-imx6.c +++ b/drivers/pci/dwc/pci-imx6.c @@ -70,10 +70,10 @@ struct imx_pcie { u32 ctrl_id; u32 cpu_base; u32 hard_wired; - int clkreq_gpio; - int dis_gpio; - int power_on_gpio; - int reset_gpio; + struct gpio_desc *clkreq_gpiod; + struct gpio_desc *dis_gpiod; + struct gpio_desc *power_on_gpiod; + struct gpio_desc *reset_gpiod; bool gpio_active_high; struct clk *pcie_bus; struct clk *pcie_phy; @@ -756,6 +756,16 @@ static int imx_pcie_deassert_core_reset(struct imx_pcie *imx_pcie) } } + if (imx_pcie->power_on_gpiod) + gpiod_set_value_cansleep(imx_pcie->power_on_gpiod, 1); + + if (imx_pcie->clkreq_gpiod) + gpiod_set_value_cansleep(imx_pcie->clkreq_gpiod, 1); + + mdelay(2); + if (imx_pcie->dis_gpiod) + gpiod_set_value_cansleep(imx_pcie->dis_gpiod, 0); + ret = clk_prepare_enable(imx_pcie->pcie); if (ret) { dev_err(dev, "unable to enable pcie clock\n"); @@ -950,12 +960,12 @@ static int imx_pcie_deassert_core_reset(struct imx_pcie *imx_pcie) } /* Some boards don't have PCIe reset GPIO. */ - if (gpio_is_valid(imx_pcie->reset_gpio)) { - gpio_set_value_cansleep(imx_pcie->reset_gpio, - imx_pcie->gpio_active_high); - mdelay(20); - gpio_set_value_cansleep(imx_pcie->reset_gpio, + if (imx_pcie->reset_gpiod) { + gpiod_set_value_cansleep(imx_pcie->reset_gpiod, !imx_pcie->gpio_active_high); + mdelay(100); + gpiod_set_value_cansleep(imx_pcie->reset_gpiod, + imx_pcie->gpio_active_high); mdelay(20); } @@ -1634,8 +1644,8 @@ static int imx_pcie_host_init(struct pcie_port *pp) /* enable disp_mix power domain */ pm_runtime_get_sync(pci->dev); - if (gpio_is_valid(imx_pcie->power_on_gpio)) - gpio_set_value_cansleep(imx_pcie->power_on_gpio, 1); + if (imx_pcie->power_on_gpiod) + gpiod_set_value_cansleep(imx_pcie->power_on_gpiod, 1); imx_pcie_assert_core_reset(imx_pcie); imx_pcie_init_phy(imx_pcie); @@ -2046,8 +2056,9 @@ static void pci_imx_pm_turn_off(struct imx_pcie *imx_pcie) } udelay(1000); - if (gpio_is_valid(imx_pcie->reset_gpio)) - gpio_set_value_cansleep(imx_pcie->reset_gpio, 0); + if (imx_pcie->reset_gpiod) + gpiod_set_value_cansleep(imx_pcie->reset_gpiod, + !imx_pcie->gpio_active_high); } static int pci_imx_suspend_noirq(struct device *dev) @@ -2332,59 +2343,42 @@ static int imx_pcie_probe(struct platform_device *pdev) } /* Fetch GPIOs */ - imx_pcie->clkreq_gpio = of_get_named_gpio(node, "clkreq-gpio", 0); - if (gpio_is_valid(imx_pcie->clkreq_gpio)) { - ret = devm_gpio_request_one(&pdev->dev, imx_pcie->clkreq_gpio, - GPIOF_OUT_INIT_LOW, "PCIe CLKREQ"); - if (ret) { + imx_pcie->clkreq_gpiod = devm_gpiod_get_optional(dev, "clkreq", + GPIOD_OUT_LOW); + if (IS_ERR(imx_pcie->clkreq_gpiod)) { + ret = PTR_ERR(imx_pcie->clkreq_gpiod); + if (ret != -EPROBE_DEFER) dev_err(&pdev->dev, "unable to get clkreq gpio\n"); - return ret; - } - } else if (imx_pcie->clkreq_gpio == -EPROBE_DEFER) { - return imx_pcie->clkreq_gpio; + return ret; } - imx_pcie->dis_gpio = of_get_named_gpio(node, "disable-gpio", 0); - if (gpio_is_valid(imx_pcie->dis_gpio)) { - ret = devm_gpio_request_one(&pdev->dev, imx_pcie->dis_gpio, - GPIOF_OUT_INIT_HIGH, "PCIe DIS"); - if (ret) { + imx_pcie->dis_gpiod = devm_gpiod_get_optional(dev, "disable", + GPIOD_OUT_LOW); + if (IS_ERR(imx_pcie->dis_gpiod)) { + ret = PTR_ERR(imx_pcie->dis_gpiod); + if (ret != -EPROBE_DEFER) dev_err(&pdev->dev, "unable to get disable gpio\n"); - return ret; - } - } else if (imx_pcie->dis_gpio == -EPROBE_DEFER) { - return imx_pcie->dis_gpio; + return ret; } - imx_pcie->power_on_gpio = of_get_named_gpio(node, "power-on-gpio", 0); - if (gpio_is_valid(imx_pcie->power_on_gpio)) { - ret = devm_gpio_request_one(&pdev->dev, - imx_pcie->power_on_gpio, - GPIOF_OUT_INIT_LOW, - "PCIe power enable"); - if (ret) { + imx_pcie->power_on_gpiod = devm_gpiod_get_optional(dev, "power-on", + GPIOD_OUT_LOW); + if (IS_ERR(imx_pcie->power_on_gpiod)) { + ret = PTR_ERR(imx_pcie->power_on_gpiod); + if (ret != -EPROBE_DEFER) dev_err(&pdev->dev, "unable to get power-on gpio\n"); - return ret; - } - } else if (imx_pcie->power_on_gpio == -EPROBE_DEFER) { - return imx_pcie->power_on_gpio; - } - - imx_pcie->reset_gpio = of_get_named_gpio(node, "reset-gpio", 0); - imx_pcie->gpio_active_high = of_property_read_bool(node, - "reset-gpio-active-high"); - if (gpio_is_valid(imx_pcie->reset_gpio)) { - ret = devm_gpio_request_one(dev, imx_pcie->reset_gpio, - imx_pcie->gpio_active_high ? - GPIOF_OUT_INIT_HIGH : - GPIOF_OUT_INIT_LOW, - "PCIe reset"); - if (ret) { + return ret; + } + + imx_pcie->reset_gpiod = devm_gpiod_get_optional(dev, "reset", + imx_pcie->gpio_active_high ? + GPIOD_OUT_LOW : + GPIOD_OUT_HIGH); + if (IS_ERR(imx_pcie->reset_gpiod)) { + ret = PTR_ERR(imx_pcie->reset_gpiod); + if (ret != -EPROBE_DEFER) dev_err(dev, "unable to get reset gpio\n"); - return ret; - } - } else if (imx_pcie->reset_gpio == -EPROBE_DEFER) { - return imx_pcie->reset_gpio; + return ret; } imx_pcie->epdev_on = devm_regulator_get(&pdev->dev, "epdev_on"); -- cgit v1.2.3