summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2016-03-15 09:55:52 -0400
committerBjorn Helgaas <bhelgaas@google.com>2016-03-15 09:55:52 -0400
commit562df5c8521e1371f3cbd0b7b868034da376d714 (patch)
tree798a5b2f688a60307889c632a20e32aae65d51fa /drivers
parentc334f9c89e40d2c9f4598e87e186bf3264d39e51 (diff)
parent5a3aa2a8fae4ce1a3ad786d212b8fffca8ee72f5 (diff)
Merge branch 'pci/host-designware' into next
* pci/host-designware: PCI: designware: Add driver for prototyping kits based on ARC SDP PCI: designware: Add default link up check if sub-driver doesn't override PCI: designware: Add generic dw_pcie_wait_for_link() ARC: Add PCI support
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pci/Makefile1
-rw-r--r--drivers/pci/host/Kconfig12
-rw-r--r--drivers/pci/host/Makefile1
-rw-r--r--drivers/pci/host/pci-dra7xx.c11
-rw-r--r--drivers/pci/host/pci-exynos.c13
-rw-r--r--drivers/pci/host/pci-imx6.c33
-rw-r--r--drivers/pci/host/pci-keystone.c10
-rw-r--r--drivers/pci/host/pcie-designware-plat.c138
-rw-r--r--drivers/pci/host/pcie-designware.c29
-rw-r--r--drivers/pci/host/pcie-designware.h6
-rw-r--r--drivers/pci/host/pcie-qcom.c12
-rw-r--r--drivers/pci/host/pcie-spear13xx.c14
12 files changed, 203 insertions, 77 deletions
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index be3f631c3f75..2154092ddee8 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_PCI_IOV) += iov.o
32# Some architectures use the generic PCI setup functions 32# Some architectures use the generic PCI setup functions
33# 33#
34obj-$(CONFIG_ALPHA) += setup-irq.o 34obj-$(CONFIG_ALPHA) += setup-irq.o
35obj-$(CONFIG_ARC) += setup-irq.o
35obj-$(CONFIG_ARM) += setup-irq.o 36obj-$(CONFIG_ARM) += setup-irq.o
36obj-$(CONFIG_ARM64) += setup-irq.o 37obj-$(CONFIG_ARM64) += setup-irq.o
37obj-$(CONFIG_UNICORE32) += setup-irq.o 38obj-$(CONFIG_UNICORE32) += setup-irq.o
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 4f8e951d7252..391623e516f0 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -16,6 +16,7 @@ config PCI_MVEBU
16 depends on ARCH_MVEBU || ARCH_DOVE 16 depends on ARCH_MVEBU || ARCH_DOVE
17 depends on OF 17 depends on OF
18 18
19
19config PCIE_XILINX_NWL 20config PCIE_XILINX_NWL
20 bool "NWL PCIe Core" 21 bool "NWL PCIe Core"
21 depends on ARCH_ZYNQMP 22 depends on ARCH_ZYNQMP
@@ -26,6 +27,17 @@ config PCIE_XILINX_NWL
26 or End Point. The current option selection will only 27 or End Point. The current option selection will only
27 support root port enabling. 28 support root port enabling.
28 29
30config PCIE_DW_PLAT
31 bool "Platform bus based DesignWare PCIe Controller"
32 select PCIE_DW
33 ---help---
34 This selects the DesignWare PCIe controller support. Select this if
35 you have a PCIe controller on Platform bus.
36
37 If you have a controller with this interface, say Y or M here.
38
39 If unsure, say N.
40
29config PCIE_DW 41config PCIE_DW
30 bool 42 bool
31 43
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 2c7efd8e0762..3ccd743e20b9 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -1,4 +1,5 @@
1obj-$(CONFIG_PCIE_DW) += pcie-designware.o 1obj-$(CONFIG_PCIE_DW) += pcie-designware.o
2obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
2obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o 3obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
3obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o 4obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
4obj-$(CONFIG_PCI_IMX6) += pci-imx6.o 5obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
index 923607bdabc5..2ca3a1f30ebf 100644
--- a/drivers/pci/host/pci-dra7xx.c
+++ b/drivers/pci/host/pci-dra7xx.c
@@ -10,7 +10,6 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13#include <linux/delay.h>
14#include <linux/err.h> 13#include <linux/err.h>
15#include <linux/interrupt.h> 14#include <linux/interrupt.h>
16#include <linux/irq.h> 15#include <linux/irq.h>
@@ -108,7 +107,6 @@ static int dra7xx_pcie_establish_link(struct pcie_port *pp)
108{ 107{
109 struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pp); 108 struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pp);
110 u32 reg; 109 u32 reg;
111 unsigned int retries;
112 110
113 if (dw_pcie_link_up(pp)) { 111 if (dw_pcie_link_up(pp)) {
114 dev_err(pp->dev, "link is already up\n"); 112 dev_err(pp->dev, "link is already up\n");
@@ -119,14 +117,7 @@ static int dra7xx_pcie_establish_link(struct pcie_port *pp)
119 reg |= LTSSM_EN; 117 reg |= LTSSM_EN;
120 dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD, reg); 118 dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD, reg);
121 119
122 for (retries = 0; retries < 1000; retries++) { 120 return dw_pcie_wait_for_link(pp);
123 if (dw_pcie_link_up(pp))
124 return 0;
125 usleep_range(10, 20);
126 }
127
128 dev_err(pp->dev, "link is not up\n");
129 return -EINVAL;
130} 121}
131 122
132static void dra7xx_pcie_enable_interrupts(struct pcie_port *pp) 123static void dra7xx_pcie_enable_interrupts(struct pcie_port *pp)
diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c
index d997d22d4231..219976103efc 100644
--- a/drivers/pci/host/pci-exynos.c
+++ b/drivers/pci/host/pci-exynos.c
@@ -318,7 +318,6 @@ static int exynos_pcie_establish_link(struct pcie_port *pp)
318{ 318{
319 struct exynos_pcie *exynos_pcie = to_exynos_pcie(pp); 319 struct exynos_pcie *exynos_pcie = to_exynos_pcie(pp);
320 u32 val; 320 u32 val;
321 unsigned int retries;
322 321
323 if (dw_pcie_link_up(pp)) { 322 if (dw_pcie_link_up(pp)) {
324 dev_err(pp->dev, "Link already up\n"); 323 dev_err(pp->dev, "Link already up\n");
@@ -357,13 +356,8 @@ static int exynos_pcie_establish_link(struct pcie_port *pp)
357 PCIE_APP_LTSSM_ENABLE); 356 PCIE_APP_LTSSM_ENABLE);
358 357
359 /* check if the link is up or not */ 358 /* check if the link is up or not */
360 for (retries = 0; retries < 10; retries++) { 359 if (!dw_pcie_wait_for_link(pp))
361 if (dw_pcie_link_up(pp)) { 360 return 0;
362 dev_info(pp->dev, "Link up\n");
363 return 0;
364 }
365 mdelay(100);
366 }
367 361
368 while (exynos_phy_readl(exynos_pcie, PCIE_PHY_PLL_LOCKED) == 0) { 362 while (exynos_phy_readl(exynos_pcie, PCIE_PHY_PLL_LOCKED) == 0) {
369 val = exynos_blk_readl(exynos_pcie, PCIE_PHY_PLL_LOCKED); 363 val = exynos_blk_readl(exynos_pcie, PCIE_PHY_PLL_LOCKED);
@@ -372,8 +366,7 @@ static int exynos_pcie_establish_link(struct pcie_port *pp)
372 /* power off phy */ 366 /* power off phy */
373 exynos_pcie_power_off_phy(pp); 367 exynos_pcie_power_off_phy(pp);
374 368
375 dev_err(pp->dev, "PCIe Link Fail\n"); 369 return -ETIMEDOUT;
376 return -EINVAL;
377} 370}
378 371
379static void exynos_pcie_clear_irq_pulse(struct pcie_port *pp) 372static void exynos_pcie_clear_irq_pulse(struct pcie_port *pp)
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
index 8c9b3896d6f5..eb5a2755a164 100644
--- a/drivers/pci/host/pci-imx6.c
+++ b/drivers/pci/host/pci-imx6.c
@@ -357,33 +357,14 @@ static void imx6_pcie_init_phy(struct pcie_port *pp)
357 357
358static int imx6_pcie_wait_for_link(struct pcie_port *pp) 358static int imx6_pcie_wait_for_link(struct pcie_port *pp)
359{ 359{
360 unsigned int retries; 360 /* check if the link is up or not */
361 if (!dw_pcie_wait_for_link(pp))
362 return 0;
361 363
362 /* 364 dev_dbg(pp->dev, "DEBUG_R0: 0x%08x, DEBUG_R1: 0x%08x\n",
363 * Test if the PHY reports that the link is up and also that the LTSSM 365 readl(pp->dbi_base + PCIE_PHY_DEBUG_R0),
364 * training finished. There are three possible states of the link when 366 readl(pp->dbi_base + PCIE_PHY_DEBUG_R1));
365 * this code is called: 367 return -ETIMEDOUT;
366 * 1) The link is DOWN (unlikely)
367 * The link didn't come up yet for some reason. This usually means
368 * we have a real problem somewhere, if it happens with a peripheral
369 * connected. This state calls for inspection of the DEBUG registers.
370 * 2) The link is UP, but still in LTSSM training
371 * Wait for the training to finish, which should take a very short
372 * time. If the training does not finish, we have a problem and we
373 * need to inspect the DEBUG registers. If the training does finish,
374 * the link is up and operating correctly.
375 * 3) The link is UP and no longer in LTSSM training
376 * The link is up and operating correctly.
377 */
378 for (retries = 0; retries < 200; retries++) {
379 u32 reg = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1);
380 if ((reg & PCIE_PHY_DEBUG_R1_XMLH_LINK_UP) &&
381 !(reg & PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING))
382 return 0;
383 usleep_range(1000, 2000);
384 }
385
386 return -EINVAL;
387} 368}
388 369
389static int imx6_pcie_wait_for_speed_change(struct pcie_port *pp) 370static int imx6_pcie_wait_for_speed_change(struct pcie_port *pp)
diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c
index cd7034523f52..b71f55bb0315 100644
--- a/drivers/pci/host/pci-keystone.c
+++ b/drivers/pci/host/pci-keystone.c
@@ -97,17 +97,15 @@ static int ks_pcie_establish_link(struct keystone_pcie *ks_pcie)
97 return 0; 97 return 0;
98 } 98 }
99 99
100 ks_dw_pcie_initiate_link_train(ks_pcie);
101 /* check if the link is up or not */ 100 /* check if the link is up or not */
102 for (retries = 0; retries < 200; retries++) { 101 for (retries = 0; retries < 5; retries++) {
103 if (dw_pcie_link_up(pp))
104 return 0;
105 usleep_range(100, 1000);
106 ks_dw_pcie_initiate_link_train(ks_pcie); 102 ks_dw_pcie_initiate_link_train(ks_pcie);
103 if (!dw_pcie_wait_for_link(pp))
104 return 0;
107 } 105 }
108 106
109 dev_err(pp->dev, "phy link never came up\n"); 107 dev_err(pp->dev, "phy link never came up\n");
110 return -EINVAL; 108 return -ETIMEDOUT;
111} 109}
112 110
113static void ks_pcie_msi_irq_handler(struct irq_desc *desc) 111static void ks_pcie_msi_irq_handler(struct irq_desc *desc)
diff --git a/drivers/pci/host/pcie-designware-plat.c b/drivers/pci/host/pcie-designware-plat.c
new file mode 100644
index 000000000000..b3500994d08a
--- /dev/null
+++ b/drivers/pci/host/pcie-designware-plat.c
@@ -0,0 +1,138 @@
1/*
2 * PCIe RC driver for Synopsys DesignWare Core
3 *
4 * Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com)
5 *
6 * Authors: Joao Pinto <jpinto@synopsys.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#include <linux/clk.h>
13#include <linux/delay.h>
14#include <linux/gpio.h>
15#include <linux/interrupt.h>
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/of_gpio.h>
19#include <linux/pci.h>
20#include <linux/platform_device.h>
21#include <linux/resource.h>
22#include <linux/signal.h>
23#include <linux/types.h>
24
25#include "pcie-designware.h"
26
27struct dw_plat_pcie {
28 void __iomem *mem_base;
29 struct pcie_port pp;
30};
31
32static irqreturn_t dw_plat_pcie_msi_irq_handler(int irq, void *arg)
33{
34 struct pcie_port *pp = arg;
35
36 return dw_handle_msi_irq(pp);
37}
38
39static void dw_plat_pcie_host_init(struct pcie_port *pp)
40{
41 dw_pcie_setup_rc(pp);
42 dw_pcie_wait_for_link(pp);
43
44 if (IS_ENABLED(CONFIG_PCI_MSI))
45 dw_pcie_msi_init(pp);
46}
47
48static struct pcie_host_ops dw_plat_pcie_host_ops = {
49 .host_init = dw_plat_pcie_host_init,
50};
51
52static int dw_plat_add_pcie_port(struct pcie_port *pp,
53 struct platform_device *pdev)
54{
55 int ret;
56
57 pp->irq = platform_get_irq(pdev, 1);
58 if (pp->irq < 0)
59 return pp->irq;
60
61 if (IS_ENABLED(CONFIG_PCI_MSI)) {
62 pp->msi_irq = platform_get_irq(pdev, 0);
63 if (pp->msi_irq < 0)
64 return pp->msi_irq;
65
66 ret = devm_request_irq(&pdev->dev, pp->msi_irq,
67 dw_plat_pcie_msi_irq_handler,
68 IRQF_SHARED, "dw-plat-pcie-msi", pp);
69 if (ret) {
70 dev_err(&pdev->dev, "failed to request MSI IRQ\n");
71 return ret;
72 }
73 }
74
75 pp->root_bus_nr = -1;
76 pp->ops = &dw_plat_pcie_host_ops;
77
78 ret = dw_pcie_host_init(pp);
79 if (ret) {
80 dev_err(&pdev->dev, "failed to initialize host\n");
81 return ret;
82 }
83
84 return 0;
85}
86
87static int dw_plat_pcie_probe(struct platform_device *pdev)
88{
89 struct dw_plat_pcie *dw_plat_pcie;
90 struct pcie_port *pp;
91 struct resource *res; /* Resource from DT */
92 int ret;
93
94 dw_plat_pcie = devm_kzalloc(&pdev->dev, sizeof(*dw_plat_pcie),
95 GFP_KERNEL);
96 if (!dw_plat_pcie)
97 return -ENOMEM;
98
99 pp = &dw_plat_pcie->pp;
100 pp->dev = &pdev->dev;
101
102 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
103 if (!res)
104 return -ENODEV;
105
106 dw_plat_pcie->mem_base = devm_ioremap_resource(&pdev->dev, res);
107 if (IS_ERR(dw_plat_pcie->mem_base))
108 return PTR_ERR(dw_plat_pcie->mem_base);
109
110 pp->dbi_base = dw_plat_pcie->mem_base;
111
112 ret = dw_plat_add_pcie_port(pp, pdev);
113 if (ret < 0)
114 return ret;
115
116 platform_set_drvdata(pdev, dw_plat_pcie);
117 return 0;
118}
119
120static const struct of_device_id dw_plat_pcie_of_match[] = {
121 { .compatible = "snps,dw-pcie", },
122 {},
123};
124MODULE_DEVICE_TABLE(of, dw_plat_pcie_of_match);
125
126static struct platform_driver dw_plat_pcie_driver = {
127 .driver = {
128 .name = "dw-pcie",
129 .of_match_table = dw_plat_pcie_of_match,
130 },
131 .probe = dw_plat_pcie_probe,
132};
133
134module_platform_driver(dw_plat_pcie_driver);
135
136MODULE_AUTHOR("Joao Pinto <Joao.Pinto@synopsys.com>");
137MODULE_DESCRIPTION("Synopsys PCIe host controller glue platform driver");
138MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index f85f10d22049..a4cccd356304 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -22,6 +22,7 @@
22#include <linux/pci_regs.h> 22#include <linux/pci_regs.h>
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/types.h> 24#include <linux/types.h>
25#include <linux/delay.h>
25 26
26#include "pcie-designware.h" 27#include "pcie-designware.h"
27 28
@@ -69,6 +70,11 @@
69#define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16) 70#define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16)
70#define PCIE_ATU_UPPER_TARGET 0x91C 71#define PCIE_ATU_UPPER_TARGET 0x91C
71 72
73/* PCIe Port Logic registers */
74#define PLR_OFFSET 0x700
75#define PCIE_PHY_DEBUG_R1 (PLR_OFFSET + 0x2c)
76#define PCIE_PHY_DEBUG_R1_LINK_UP 0x00000010
77
72static struct pci_ops dw_pcie_ops; 78static struct pci_ops dw_pcie_ops;
73 79
74int dw_pcie_cfg_read(void __iomem *addr, int size, u32 *val) 80int dw_pcie_cfg_read(void __iomem *addr, int size, u32 *val)
@@ -380,12 +386,33 @@ static struct msi_controller dw_pcie_msi_chip = {
380 .teardown_irq = dw_msi_teardown_irq, 386 .teardown_irq = dw_msi_teardown_irq,
381}; 387};
382 388
389int dw_pcie_wait_for_link(struct pcie_port *pp)
390{
391 int retries;
392
393 /* check if the link is up or not */
394 for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
395 if (dw_pcie_link_up(pp)) {
396 dev_info(pp->dev, "link up\n");
397 return 0;
398 }
399 usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX);
400 }
401
402 dev_err(pp->dev, "phy link never came up\n");
403
404 return -ETIMEDOUT;
405}
406
383int dw_pcie_link_up(struct pcie_port *pp) 407int dw_pcie_link_up(struct pcie_port *pp)
384{ 408{
409 u32 val;
410
385 if (pp->ops->link_up) 411 if (pp->ops->link_up)
386 return pp->ops->link_up(pp); 412 return pp->ops->link_up(pp);
387 413
388 return 0; 414 val = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1);
415 return val & PCIE_PHY_DEBUG_R1_LINK_UP;
389} 416}
390 417
391static int dw_pcie_msi_map(struct irq_domain *domain, unsigned int irq, 418static int dw_pcie_msi_map(struct irq_domain *domain, unsigned int irq,
diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
index 2356d29e8527..f437f9b5be04 100644
--- a/drivers/pci/host/pcie-designware.h
+++ b/drivers/pci/host/pcie-designware.h
@@ -22,6 +22,11 @@
22#define MAX_MSI_IRQS 32 22#define MAX_MSI_IRQS 32
23#define MAX_MSI_CTRLS (MAX_MSI_IRQS / 32) 23#define MAX_MSI_CTRLS (MAX_MSI_IRQS / 32)
24 24
25/* Parameters for the waiting for link up routine */
26#define LINK_WAIT_MAX_RETRIES 10
27#define LINK_WAIT_USLEEP_MIN 90000
28#define LINK_WAIT_USLEEP_MAX 100000
29
25struct pcie_port { 30struct pcie_port {
26 struct device *dev; 31 struct device *dev;
27 u8 root_bus_nr; 32 u8 root_bus_nr;
@@ -76,6 +81,7 @@ int dw_pcie_cfg_read(void __iomem *addr, int size, u32 *val);
76int dw_pcie_cfg_write(void __iomem *addr, int size, u32 val); 81int dw_pcie_cfg_write(void __iomem *addr, int size, u32 val);
77irqreturn_t dw_handle_msi_irq(struct pcie_port *pp); 82irqreturn_t dw_handle_msi_irq(struct pcie_port *pp);
78void dw_pcie_msi_init(struct pcie_port *pp); 83void dw_pcie_msi_init(struct pcie_port *pp);
84int dw_pcie_wait_for_link(struct pcie_port *pp);
79int dw_pcie_link_up(struct pcie_port *pp); 85int dw_pcie_link_up(struct pcie_port *pp);
80void dw_pcie_setup_rc(struct pcie_port *pp); 86void dw_pcie_setup_rc(struct pcie_port *pp);
81int dw_pcie_host_init(struct pcie_port *pp); 87int dw_pcie_host_init(struct pcie_port *pp);
diff --git a/drivers/pci/host/pcie-qcom.c b/drivers/pci/host/pcie-qcom.c
index e845fba19632..f2f90c50f75d 100644
--- a/drivers/pci/host/pcie-qcom.c
+++ b/drivers/pci/host/pcie-qcom.c
@@ -116,8 +116,6 @@ static irqreturn_t qcom_pcie_msi_irq_handler(int irq, void *arg)
116 116
117static int qcom_pcie_establish_link(struct qcom_pcie *pcie) 117static int qcom_pcie_establish_link(struct qcom_pcie *pcie)
118{ 118{
119 struct device *dev = pcie->dev;
120 unsigned int retries = 0;
121 u32 val; 119 u32 val;
122 120
123 if (dw_pcie_link_up(&pcie->pp)) 121 if (dw_pcie_link_up(&pcie->pp))
@@ -128,15 +126,7 @@ static int qcom_pcie_establish_link(struct qcom_pcie *pcie)
128 val |= PCIE20_ELBI_SYS_CTRL_LT_ENABLE; 126 val |= PCIE20_ELBI_SYS_CTRL_LT_ENABLE;
129 writel(val, pcie->elbi + PCIE20_ELBI_SYS_CTRL); 127 writel(val, pcie->elbi + PCIE20_ELBI_SYS_CTRL);
130 128
131 do { 129 return dw_pcie_wait_for_link(&pcie->pp);
132 if (dw_pcie_link_up(&pcie->pp))
133 return 0;
134 usleep_range(250, 1000);
135 } while (retries < 200);
136
137 dev_warn(dev, "phy link never came up\n");
138
139 return -ETIMEDOUT;
140} 130}
141 131
142static int qcom_pcie_get_resources_v0(struct qcom_pcie *pcie) 132static int qcom_pcie_get_resources_v0(struct qcom_pcie *pcie)
diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c
index a6cd8233e8c0..a4060b85ab23 100644
--- a/drivers/pci/host/pcie-spear13xx.c
+++ b/drivers/pci/host/pcie-spear13xx.c
@@ -13,7 +13,6 @@
13 */ 13 */
14 14
15#include <linux/clk.h> 15#include <linux/clk.h>
16#include <linux/delay.h>
17#include <linux/interrupt.h> 16#include <linux/interrupt.h>
18#include <linux/kernel.h> 17#include <linux/kernel.h>
19#include <linux/module.h> 18#include <linux/module.h>
@@ -149,7 +148,6 @@ static int spear13xx_pcie_establish_link(struct pcie_port *pp)
149 struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pp); 148 struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pp);
150 struct pcie_app_reg *app_reg = spear13xx_pcie->app_base; 149 struct pcie_app_reg *app_reg = spear13xx_pcie->app_base;
151 u32 exp_cap_off = EXP_CAP_ID_OFFSET; 150 u32 exp_cap_off = EXP_CAP_ID_OFFSET;
152 unsigned int retries;
153 151
154 if (dw_pcie_link_up(pp)) { 152 if (dw_pcie_link_up(pp)) {
155 dev_err(pp->dev, "link already up\n"); 153 dev_err(pp->dev, "link already up\n");
@@ -200,17 +198,7 @@ static int spear13xx_pcie_establish_link(struct pcie_port *pp)
200 | ((u32)1 << REG_TRANSLATION_ENABLE), 198 | ((u32)1 << REG_TRANSLATION_ENABLE),
201 &app_reg->app_ctrl_0); 199 &app_reg->app_ctrl_0);
202 200
203 /* check if the link is up or not */ 201 return dw_pcie_wait_for_link(pp);
204 for (retries = 0; retries < 10; retries++) {
205 if (dw_pcie_link_up(pp)) {
206 dev_info(pp->dev, "link up\n");
207 return 0;
208 }
209 mdelay(100);
210 }
211
212 dev_err(pp->dev, "link Fail\n");
213 return -EINVAL;
214} 202}
215 203
216static irqreturn_t spear13xx_pcie_irq_handler(int irq, void *arg) 204static irqreturn_t spear13xx_pcie_irq_handler(int irq, void *arg)