aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/host/Kconfig13
-rw-r--r--drivers/pci/host/Makefile1
-rw-r--r--drivers/pci/host/pci-dra7xx.c6
-rw-r--r--drivers/pci/host/pci-exynos.c18
-rw-r--r--drivers/pci/host/pci-host-generic.c126
-rw-r--r--drivers/pci/host/pci-imx6.c4
-rw-r--r--drivers/pci/host/pci-layerscape.c179
-rw-r--r--drivers/pci/host/pci-mvebu.c2
-rw-r--r--drivers/pci/host/pcie-designware.c1
-rw-r--r--drivers/pci/host/pcie-rcar.c2
-rw-r--r--drivers/pci/host/pcie-spear13xx.c13
11 files changed, 242 insertions, 123 deletions
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 3dc25fad490c..c4b6568e486d 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -32,7 +32,10 @@ config PCI_IMX6
32 32
33config PCI_TEGRA 33config PCI_TEGRA
34 bool "NVIDIA Tegra PCIe controller" 34 bool "NVIDIA Tegra PCIe controller"
35 depends on ARCH_TEGRA 35 depends on ARCH_TEGRA && !ARM64
36 help
37 Say Y here if you want support for the PCIe host controller found
38 on NVIDIA Tegra SoCs.
36 39
37config PCI_RCAR_GEN2 40config PCI_RCAR_GEN2
38 bool "Renesas R-Car Gen2 Internal PCI controller" 41 bool "Renesas R-Car Gen2 Internal PCI controller"
@@ -91,4 +94,12 @@ config PCI_XGENE
91 There are 5 internal PCIe ports available. Each port is GEN3 capable 94 There are 5 internal PCIe ports available. Each port is GEN3 capable
92 and have varied lanes from x1 to x8. 95 and have varied lanes from x1 to x8.
93 96
97config PCI_LAYERSCAPE
98 bool "Freescale Layerscape PCIe controller"
99 depends on OF && ARM
100 select PCIE_DW
101 select MFD_SYSCON
102 help
103 Say Y here if you want PCIe controller support on Layerscape SoCs.
104
94endmenu 105endmenu
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 26b3461d68d7..44c26998027f 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
11obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone-dw.o pci-keystone.o 11obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone-dw.o pci-keystone.o
12obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o 12obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o
13obj-$(CONFIG_PCI_XGENE) += pci-xgene.o 13obj-$(CONFIG_PCI_XGENE) += pci-xgene.o
14obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o
diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
index 52b34fee07fd..8c6969747acd 100644
--- a/drivers/pci/host/pci-dra7xx.c
+++ b/drivers/pci/host/pci-dra7xx.c
@@ -270,8 +270,8 @@ static irqreturn_t dra7xx_pcie_irq_handler(int irq, void *arg)
270 return IRQ_HANDLED; 270 return IRQ_HANDLED;
271} 271}
272 272
273static int add_pcie_port(struct dra7xx_pcie *dra7xx, 273static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
274 struct platform_device *pdev) 274 struct platform_device *pdev)
275{ 275{
276 int ret; 276 int ret;
277 struct pcie_port *pp; 277 struct pcie_port *pp;
@@ -398,7 +398,7 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
398 398
399 platform_set_drvdata(pdev, dra7xx); 399 platform_set_drvdata(pdev, dra7xx);
400 400
401 ret = add_pcie_port(dra7xx, pdev); 401 ret = dra7xx_add_pcie_port(dra7xx, pdev);
402 if (ret < 0) 402 if (ret < 0)
403 goto err_add_port; 403 goto err_add_port;
404 404
diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c
index c5d0ca384502..850c9f951a3f 100644
--- a/drivers/pci/host/pci-exynos.c
+++ b/drivers/pci/host/pci-exynos.c
@@ -312,7 +312,6 @@ static void exynos_pcie_assert_reset(struct pcie_port *pp)
312 if (exynos_pcie->reset_gpio >= 0) 312 if (exynos_pcie->reset_gpio >= 0)
313 devm_gpio_request_one(pp->dev, exynos_pcie->reset_gpio, 313 devm_gpio_request_one(pp->dev, exynos_pcie->reset_gpio,
314 GPIOF_OUT_INIT_HIGH, "RESET"); 314 GPIOF_OUT_INIT_HIGH, "RESET");
315 return;
316} 315}
317 316
318static int exynos_pcie_establish_link(struct pcie_port *pp) 317static int exynos_pcie_establish_link(struct pcie_port *pp)
@@ -388,7 +387,6 @@ static void exynos_pcie_clear_irq_pulse(struct pcie_port *pp)
388 387
389 val = exynos_elb_readl(exynos_pcie, PCIE_IRQ_PULSE); 388 val = exynos_elb_readl(exynos_pcie, PCIE_IRQ_PULSE);
390 exynos_elb_writel(exynos_pcie, val, PCIE_IRQ_PULSE); 389 exynos_elb_writel(exynos_pcie, val, PCIE_IRQ_PULSE);
391 return;
392} 390}
393 391
394static void exynos_pcie_enable_irq_pulse(struct pcie_port *pp) 392static void exynos_pcie_enable_irq_pulse(struct pcie_port *pp)
@@ -400,7 +398,6 @@ static void exynos_pcie_enable_irq_pulse(struct pcie_port *pp)
400 val = IRQ_INTA_ASSERT | IRQ_INTB_ASSERT | 398 val = IRQ_INTA_ASSERT | IRQ_INTB_ASSERT |
401 IRQ_INTC_ASSERT | IRQ_INTD_ASSERT, 399 IRQ_INTC_ASSERT | IRQ_INTD_ASSERT,
402 exynos_elb_writel(exynos_pcie, val, PCIE_IRQ_EN_PULSE); 400 exynos_elb_writel(exynos_pcie, val, PCIE_IRQ_EN_PULSE);
403 return;
404} 401}
405 402
406static irqreturn_t exynos_pcie_irq_handler(int irq, void *arg) 403static irqreturn_t exynos_pcie_irq_handler(int irq, void *arg)
@@ -429,7 +426,6 @@ static void exynos_pcie_msi_init(struct pcie_port *pp)
429 val = exynos_elb_readl(exynos_pcie, PCIE_IRQ_EN_LEVEL); 426 val = exynos_elb_readl(exynos_pcie, PCIE_IRQ_EN_LEVEL);
430 val |= IRQ_MSI_ENABLE; 427 val |= IRQ_MSI_ENABLE;
431 exynos_elb_writel(exynos_pcie, val, PCIE_IRQ_EN_LEVEL); 428 exynos_elb_writel(exynos_pcie, val, PCIE_IRQ_EN_LEVEL);
432 return;
433} 429}
434 430
435static void exynos_pcie_enable_interrupts(struct pcie_port *pp) 431static void exynos_pcie_enable_interrupts(struct pcie_port *pp)
@@ -438,8 +434,6 @@ static void exynos_pcie_enable_interrupts(struct pcie_port *pp)
438 434
439 if (IS_ENABLED(CONFIG_PCI_MSI)) 435 if (IS_ENABLED(CONFIG_PCI_MSI))
440 exynos_pcie_msi_init(pp); 436 exynos_pcie_msi_init(pp);
441
442 return;
443} 437}
444 438
445static inline void exynos_pcie_readl_rc(struct pcie_port *pp, 439static inline void exynos_pcie_readl_rc(struct pcie_port *pp,
@@ -448,7 +442,6 @@ static inline void exynos_pcie_readl_rc(struct pcie_port *pp,
448 exynos_pcie_sideband_dbi_r_mode(pp, true); 442 exynos_pcie_sideband_dbi_r_mode(pp, true);
449 *val = readl(dbi_base); 443 *val = readl(dbi_base);
450 exynos_pcie_sideband_dbi_r_mode(pp, false); 444 exynos_pcie_sideband_dbi_r_mode(pp, false);
451 return;
452} 445}
453 446
454static inline void exynos_pcie_writel_rc(struct pcie_port *pp, 447static inline void exynos_pcie_writel_rc(struct pcie_port *pp,
@@ -457,7 +450,6 @@ static inline void exynos_pcie_writel_rc(struct pcie_port *pp,
457 exynos_pcie_sideband_dbi_w_mode(pp, true); 450 exynos_pcie_sideband_dbi_w_mode(pp, true);
458 writel(val, dbi_base); 451 writel(val, dbi_base);
459 exynos_pcie_sideband_dbi_w_mode(pp, false); 452 exynos_pcie_sideband_dbi_w_mode(pp, false);
460 return;
461} 453}
462 454
463static int exynos_pcie_rd_own_conf(struct pcie_port *pp, int where, int size, 455static int exynos_pcie_rd_own_conf(struct pcie_port *pp, int where, int size,
@@ -509,8 +501,8 @@ static struct pcie_host_ops exynos_pcie_host_ops = {
509 .host_init = exynos_pcie_host_init, 501 .host_init = exynos_pcie_host_init,
510}; 502};
511 503
512static int __init add_pcie_port(struct pcie_port *pp, 504static int __init exynos_add_pcie_port(struct pcie_port *pp,
513 struct platform_device *pdev) 505 struct platform_device *pdev)
514{ 506{
515 int ret; 507 int ret;
516 508
@@ -615,7 +607,7 @@ static int __init exynos_pcie_probe(struct platform_device *pdev)
615 goto fail_bus_clk; 607 goto fail_bus_clk;
616 } 608 }
617 609
618 ret = add_pcie_port(pp, pdev); 610 ret = exynos_add_pcie_port(pp, pdev);
619 if (ret < 0) 611 if (ret < 0)
620 goto fail_bus_clk; 612 goto fail_bus_clk;
621 613
@@ -656,11 +648,11 @@ static struct platform_driver exynos_pcie_driver = {
656 648
657/* Exynos PCIe driver does not allow module unload */ 649/* Exynos PCIe driver does not allow module unload */
658 650
659static int __init pcie_init(void) 651static int __init exynos_pcie_init(void)
660{ 652{
661 return platform_driver_probe(&exynos_pcie_driver, exynos_pcie_probe); 653 return platform_driver_probe(&exynos_pcie_driver, exynos_pcie_probe);
662} 654}
663subsys_initcall(pcie_init); 655subsys_initcall(exynos_pcie_init);
664 656
665MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>"); 657MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
666MODULE_DESCRIPTION("Samsung PCIe host controller driver"); 658MODULE_DESCRIPTION("Samsung PCIe host controller driver");
diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c
index 3d2076f59911..18959075d164 100644
--- a/drivers/pci/host/pci-host-generic.c
+++ b/drivers/pci/host/pci-host-generic.c
@@ -32,7 +32,7 @@ struct gen_pci_cfg_bus_ops {
32 32
33struct gen_pci_cfg_windows { 33struct gen_pci_cfg_windows {
34 struct resource res; 34 struct resource res;
35 struct resource bus_range; 35 struct resource *bus_range;
36 void __iomem **win; 36 void __iomem **win;
37 37
38 const struct gen_pci_cfg_bus_ops *ops; 38 const struct gen_pci_cfg_bus_ops *ops;
@@ -50,7 +50,7 @@ static void __iomem *gen_pci_map_cfg_bus_cam(struct pci_bus *bus,
50{ 50{
51 struct pci_sys_data *sys = bus->sysdata; 51 struct pci_sys_data *sys = bus->sysdata;
52 struct gen_pci *pci = sys->private_data; 52 struct gen_pci *pci = sys->private_data;
53 resource_size_t idx = bus->number - pci->cfg.bus_range.start; 53 resource_size_t idx = bus->number - pci->cfg.bus_range->start;
54 54
55 return pci->cfg.win[idx] + ((devfn << 8) | where); 55 return pci->cfg.win[idx] + ((devfn << 8) | where);
56} 56}
@@ -66,7 +66,7 @@ static void __iomem *gen_pci_map_cfg_bus_ecam(struct pci_bus *bus,
66{ 66{
67 struct pci_sys_data *sys = bus->sysdata; 67 struct pci_sys_data *sys = bus->sysdata;
68 struct gen_pci *pci = sys->private_data; 68 struct gen_pci *pci = sys->private_data;
69 resource_size_t idx = bus->number - pci->cfg.bus_range.start; 69 resource_size_t idx = bus->number - pci->cfg.bus_range->start;
70 70
71 return pci->cfg.win[idx] + ((devfn << 12) | where); 71 return pci->cfg.win[idx] + ((devfn << 12) | where);
72} 72}
@@ -138,106 +138,50 @@ static const struct of_device_id gen_pci_of_match[] = {
138}; 138};
139MODULE_DEVICE_TABLE(of, gen_pci_of_match); 139MODULE_DEVICE_TABLE(of, gen_pci_of_match);
140 140
141static int gen_pci_calc_io_offset(struct device *dev,
142 struct of_pci_range *range,
143 struct resource *res,
144 resource_size_t *offset)
145{
146 static atomic_t wins = ATOMIC_INIT(0);
147 int err, idx, max_win;
148 unsigned int window;
149
150 if (!PAGE_ALIGNED(range->cpu_addr))
151 return -EINVAL;
152
153 max_win = (IO_SPACE_LIMIT + 1) / SZ_64K;
154 idx = atomic_inc_return(&wins);
155 if (idx > max_win)
156 return -ENOSPC;
157
158 window = (idx - 1) * SZ_64K;
159 err = pci_ioremap_io(window, range->cpu_addr);
160 if (err)
161 return err;
162
163 of_pci_range_to_resource(range, dev->of_node, res);
164 res->start = window;
165 res->end = res->start + range->size - 1;
166 *offset = window - range->pci_addr;
167 return 0;
168}
169
170static int gen_pci_calc_mem_offset(struct device *dev,
171 struct of_pci_range *range,
172 struct resource *res,
173 resource_size_t *offset)
174{
175 of_pci_range_to_resource(range, dev->of_node, res);
176 *offset = range->cpu_addr - range->pci_addr;
177 return 0;
178}
179
180static void gen_pci_release_of_pci_ranges(struct gen_pci *pci) 141static void gen_pci_release_of_pci_ranges(struct gen_pci *pci)
181{ 142{
182 struct pci_host_bridge_window *win;
183
184 list_for_each_entry(win, &pci->resources, list)
185 release_resource(win->res);
186
187 pci_free_resource_list(&pci->resources); 143 pci_free_resource_list(&pci->resources);
188} 144}
189 145
190static int gen_pci_parse_request_of_pci_ranges(struct gen_pci *pci) 146static int gen_pci_parse_request_of_pci_ranges(struct gen_pci *pci)
191{ 147{
192 struct of_pci_range range;
193 struct of_pci_range_parser parser;
194 int err, res_valid = 0; 148 int err, res_valid = 0;
195 struct device *dev = pci->host.dev.parent; 149 struct device *dev = pci->host.dev.parent;
196 struct device_node *np = dev->of_node; 150 struct device_node *np = dev->of_node;
151 resource_size_t iobase;
152 struct pci_host_bridge_window *win;
197 153
198 if (of_pci_range_parser_init(&parser, np)) { 154 err = of_pci_get_host_bridge_resources(np, 0, 0xff, &pci->resources,
199 dev_err(dev, "missing \"ranges\" property\n"); 155 &iobase);
200 return -EINVAL; 156 if (err)
201 } 157 return err;
202
203 for_each_of_pci_range(&parser, &range) {
204 struct resource *parent, *res;
205 resource_size_t offset;
206 u32 restype = range.flags & IORESOURCE_TYPE_BITS;
207 158
208 res = devm_kmalloc(dev, sizeof(*res), GFP_KERNEL); 159 list_for_each_entry(win, &pci->resources, list) {
209 if (!res) { 160 struct resource *parent, *res = win->res;
210 err = -ENOMEM;
211 goto out_release_res;
212 }
213 161
214 switch (restype) { 162 switch (resource_type(res)) {
215 case IORESOURCE_IO: 163 case IORESOURCE_IO:
216 parent = &ioport_resource; 164 parent = &ioport_resource;
217 err = gen_pci_calc_io_offset(dev, &range, res, &offset); 165 err = pci_remap_iospace(res, iobase);
166 if (err) {
167 dev_warn(dev, "error %d: failed to map resource %pR\n",
168 err, res);
169 continue;
170 }
218 break; 171 break;
219 case IORESOURCE_MEM: 172 case IORESOURCE_MEM:
220 parent = &iomem_resource; 173 parent = &iomem_resource;
221 err = gen_pci_calc_mem_offset(dev, &range, res, &offset); 174 res_valid |= !(res->flags & IORESOURCE_PREFETCH);
222 res_valid |= !(res->flags & IORESOURCE_PREFETCH || err);
223 break; 175 break;
176 case IORESOURCE_BUS:
177 pci->cfg.bus_range = res;
224 default: 178 default:
225 err = -EINVAL;
226 continue;
227 }
228
229 if (err) {
230 dev_warn(dev,
231 "error %d: failed to add resource [type 0x%x, %lld bytes]\n",
232 err, restype, range.size);
233 continue; 179 continue;
234 } 180 }
235 181
236 err = request_resource(parent, res); 182 err = devm_request_resource(dev, parent, res);
237 if (err) 183 if (err)
238 goto out_release_res; 184 goto out_release_res;
239
240 pci_add_resource_offset(&pci->resources, res, offset);
241 } 185 }
242 186
243 if (!res_valid) { 187 if (!res_valid) {
@@ -262,38 +206,30 @@ static int gen_pci_parse_map_cfg_windows(struct gen_pci *pci)
262 struct device *dev = pci->host.dev.parent; 206 struct device *dev = pci->host.dev.parent;
263 struct device_node *np = dev->of_node; 207 struct device_node *np = dev->of_node;
264 208
265 if (of_pci_parse_bus_range(np, &pci->cfg.bus_range))
266 pci->cfg.bus_range = (struct resource) {
267 .name = np->name,
268 .start = 0,
269 .end = 0xff,
270 .flags = IORESOURCE_BUS,
271 };
272
273 err = of_address_to_resource(np, 0, &pci->cfg.res); 209 err = of_address_to_resource(np, 0, &pci->cfg.res);
274 if (err) { 210 if (err) {
275 dev_err(dev, "missing \"reg\" property\n"); 211 dev_err(dev, "missing \"reg\" property\n");
276 return err; 212 return err;
277 } 213 }
278 214
279 pci->cfg.win = devm_kcalloc(dev, resource_size(&pci->cfg.bus_range), 215 /* Limit the bus-range to fit within reg */
216 bus_max = pci->cfg.bus_range->start +
217 (resource_size(&pci->cfg.res) >> pci->cfg.ops->bus_shift) - 1;
218 pci->cfg.bus_range->end = min_t(resource_size_t,
219 pci->cfg.bus_range->end, bus_max);
220
221 pci->cfg.win = devm_kcalloc(dev, resource_size(pci->cfg.bus_range),
280 sizeof(*pci->cfg.win), GFP_KERNEL); 222 sizeof(*pci->cfg.win), GFP_KERNEL);
281 if (!pci->cfg.win) 223 if (!pci->cfg.win)
282 return -ENOMEM; 224 return -ENOMEM;
283 225
284 /* Limit the bus-range to fit within reg */
285 bus_max = pci->cfg.bus_range.start +
286 (resource_size(&pci->cfg.res) >> pci->cfg.ops->bus_shift) - 1;
287 pci->cfg.bus_range.end = min_t(resource_size_t, pci->cfg.bus_range.end,
288 bus_max);
289
290 /* Map our Configuration Space windows */ 226 /* Map our Configuration Space windows */
291 if (!devm_request_mem_region(dev, pci->cfg.res.start, 227 if (!devm_request_mem_region(dev, pci->cfg.res.start,
292 resource_size(&pci->cfg.res), 228 resource_size(&pci->cfg.res),
293 "Configuration Space")) 229 "Configuration Space"))
294 return -ENOMEM; 230 return -ENOMEM;
295 231
296 bus_range = &pci->cfg.bus_range; 232 bus_range = pci->cfg.bus_range;
297 for (busn = bus_range->start; busn <= bus_range->end; ++busn) { 233 for (busn = bus_range->start; busn <= bus_range->end; ++busn) {
298 u32 idx = busn - bus_range->start; 234 u32 idx = busn - bus_range->start;
299 u32 sz = 1 << pci->cfg.ops->bus_shift; 235 u32 sz = 1 << pci->cfg.ops->bus_shift;
@@ -305,8 +241,6 @@ static int gen_pci_parse_map_cfg_windows(struct gen_pci *pci)
305 return -ENOMEM; 241 return -ENOMEM;
306 } 242 }
307 243
308 /* Register bus resource */
309 pci_add_resource(&pci->resources, bus_range);
310 return 0; 244 return 0;
311} 245}
312 246
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
index 233fe8a88264..8a7530b3b62a 100644
--- a/drivers/pci/host/pci-imx6.c
+++ b/drivers/pci/host/pci-imx6.c
@@ -526,8 +526,8 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp,
526 } 526 }
527 527
528 ret = devm_request_irq(&pdev->dev, pp->msi_irq, 528 ret = devm_request_irq(&pdev->dev, pp->msi_irq,
529 imx6_pcie_msi_handler, 529 imx6_pcie_msi_handler,
530 IRQF_SHARED, "mx6-pcie-msi", pp); 530 IRQF_SHARED, "mx6-pcie-msi", pp);
531 if (ret) { 531 if (ret) {
532 dev_err(&pdev->dev, "failed to request MSI irq\n"); 532 dev_err(&pdev->dev, "failed to request MSI irq\n");
533 return -ENODEV; 533 return -ENODEV;
diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c
new file mode 100644
index 000000000000..6697b1a4d4fa
--- /dev/null
+++ b/drivers/pci/host/pci-layerscape.c
@@ -0,0 +1,179 @@
1/*
2 * PCIe host controller driver for Freescale Layerscape SoCs
3 *
4 * Copyright (C) 2014 Freescale Semiconductor.
5 *
6 * Author: Minghuan Lian <Minghuan.Lian@freescale.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
13#include <linux/kernel.h>
14#include <linux/delay.h>
15#include <linux/interrupt.h>
16#include <linux/module.h>
17#include <linux/of_pci.h>
18#include <linux/of_platform.h>
19#include <linux/of_irq.h>
20#include <linux/of_address.h>
21#include <linux/pci.h>
22#include <linux/platform_device.h>
23#include <linux/resource.h>
24#include <linux/mfd/syscon.h>
25#include <linux/regmap.h>
26
27#include "pcie-designware.h"
28
29/* PEX1/2 Misc Ports Status Register */
30#define SCFG_PEXMSCPORTSR(pex_idx) (0x94 + (pex_idx) * 4)
31#define LTSSM_STATE_SHIFT 20
32#define LTSSM_STATE_MASK 0x3f
33#define LTSSM_PCIE_L0 0x11 /* L0 state */
34
35/* Symbol Timer Register and Filter Mask Register 1 */
36#define PCIE_STRFMR1 0x71c
37
38struct ls_pcie {
39 struct list_head node;
40 struct device *dev;
41 struct pci_bus *bus;
42 void __iomem *dbi;
43 struct regmap *scfg;
44 struct pcie_port pp;
45 int index;
46 int msi_irq;
47};
48
49#define to_ls_pcie(x) container_of(x, struct ls_pcie, pp)
50
51static int ls_pcie_link_up(struct pcie_port *pp)
52{
53 u32 state;
54 struct ls_pcie *pcie = to_ls_pcie(pp);
55
56 regmap_read(pcie->scfg, SCFG_PEXMSCPORTSR(pcie->index), &state);
57 state = (state >> LTSSM_STATE_SHIFT) & LTSSM_STATE_MASK;
58
59 if (state < LTSSM_PCIE_L0)
60 return 0;
61
62 return 1;
63}
64
65static void ls_pcie_host_init(struct pcie_port *pp)
66{
67 struct ls_pcie *pcie = to_ls_pcie(pp);
68 int count = 0;
69 u32 val;
70
71 dw_pcie_setup_rc(pp);
72
73 while (!ls_pcie_link_up(pp)) {
74 usleep_range(100, 1000);
75 count++;
76 if (count >= 200) {
77 dev_err(pp->dev, "phy link never came up\n");
78 return;
79 }
80 }
81
82 /*
83 * LS1021A Workaround for internal TKT228622
84 * to fix the INTx hang issue
85 */
86 val = ioread32(pcie->dbi + PCIE_STRFMR1);
87 val &= 0xffff;
88 iowrite32(val, pcie->dbi + PCIE_STRFMR1);
89}
90
91static struct pcie_host_ops ls_pcie_host_ops = {
92 .link_up = ls_pcie_link_up,
93 .host_init = ls_pcie_host_init,
94};
95
96static int ls_add_pcie_port(struct ls_pcie *pcie)
97{
98 struct pcie_port *pp;
99 int ret;
100
101 pp = &pcie->pp;
102 pp->dev = pcie->dev;
103 pp->dbi_base = pcie->dbi;
104 pp->root_bus_nr = -1;
105 pp->ops = &ls_pcie_host_ops;
106
107 ret = dw_pcie_host_init(pp);
108 if (ret) {
109 dev_err(pp->dev, "failed to initialize host\n");
110 return ret;
111 }
112
113 return 0;
114}
115
116static int __init ls_pcie_probe(struct platform_device *pdev)
117{
118 struct ls_pcie *pcie;
119 struct resource *dbi_base;
120 u32 index[2];
121 int ret;
122
123 pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
124 if (!pcie)
125 return -ENOMEM;
126
127 pcie->dev = &pdev->dev;
128
129 dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
130 if (!dbi_base) {
131 dev_err(&pdev->dev, "missing *regs* space\n");
132 return -ENODEV;
133 }
134
135 pcie->dbi = devm_ioremap_resource(&pdev->dev, dbi_base);
136 if (IS_ERR(pcie->dbi))
137 return PTR_ERR(pcie->dbi);
138
139 pcie->scfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
140 "fsl,pcie-scfg");
141 if (IS_ERR(pcie->scfg)) {
142 dev_err(&pdev->dev, "No syscfg phandle specified\n");
143 return PTR_ERR(pcie->scfg);
144 }
145
146 ret = of_property_read_u32_array(pdev->dev.of_node,
147 "fsl,pcie-scfg", index, 2);
148 if (ret)
149 return ret;
150 pcie->index = index[1];
151
152 ret = ls_add_pcie_port(pcie);
153 if (ret < 0)
154 return ret;
155
156 platform_set_drvdata(pdev, pcie);
157
158 return 0;
159}
160
161static const struct of_device_id ls_pcie_of_match[] = {
162 { .compatible = "fsl,ls1021a-pcie" },
163 { },
164};
165MODULE_DEVICE_TABLE(of, ls_pcie_of_match);
166
167static struct platform_driver ls_pcie_driver = {
168 .driver = {
169 .name = "layerscape-pcie",
170 .owner = THIS_MODULE,
171 .of_match_table = ls_pcie_of_match,
172 },
173};
174
175module_platform_driver_probe(ls_pcie_driver, ls_pcie_probe);
176
177MODULE_AUTHOR("Minghuan Lian <Minghuan.Lian@freescale.com>");
178MODULE_DESCRIPTION("Freescale Layerscape PCIe host controller driver");
179MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
index b1315e197ffb..e45f88e1244f 100644
--- a/drivers/pci/host/pci-mvebu.c
+++ b/drivers/pci/host/pci-mvebu.c
@@ -622,6 +622,7 @@ static struct mvebu_pcie_port *mvebu_pcie_find_port(struct mvebu_pcie *pcie,
622 622
623 for (i = 0; i < pcie->nports; i++) { 623 for (i = 0; i < pcie->nports; i++) {
624 struct mvebu_pcie_port *port = &pcie->ports[i]; 624 struct mvebu_pcie_port *port = &pcie->ports[i];
625
625 if (bus->number == 0 && port->devfn == devfn) 626 if (bus->number == 0 && port->devfn == devfn)
626 return port; 627 return port;
627 if (bus->number != 0 && 628 if (bus->number != 0 &&
@@ -751,6 +752,7 @@ static int mvebu_pcie_setup(int nr, struct pci_sys_data *sys)
751 752
752 for (i = 0; i < pcie->nports; i++) { 753 for (i = 0; i < pcie->nports; i++) {
753 struct mvebu_pcie_port *port = &pcie->ports[i]; 754 struct mvebu_pcie_port *port = &pcie->ports[i];
755
754 if (!port->base) 756 if (!port->base)
755 continue; 757 continue;
756 mvebu_pcie_setup_hw(port); 758 mvebu_pcie_setup_hw(port);
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index dfed00aa3ac0..f9be37139429 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -380,6 +380,7 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
380 /* Get the I/O and memory ranges from DT */ 380 /* Get the I/O and memory ranges from DT */
381 for_each_of_pci_range(&parser, &range) { 381 for_each_of_pci_range(&parser, &range) {
382 unsigned long restype = range.flags & IORESOURCE_TYPE_BITS; 382 unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
383
383 if (restype == IORESOURCE_IO) { 384 if (restype == IORESOURCE_IO) {
384 of_pci_range_to_resource(&range, np, &pp->io); 385 of_pci_range_to_resource(&range, np, &pp->io);
385 pp->io.name = "I/O"; 386 pp->io.name = "I/O";
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
index 61158e03ab5f..0df9b2941221 100644
--- a/drivers/pci/host/pcie-rcar.c
+++ b/drivers/pci/host/pcie-rcar.c
@@ -389,7 +389,7 @@ static void rcar_pcie_add_bus(struct pci_bus *bus)
389 } 389 }
390} 390}
391 391
392struct hw_pci rcar_pci = { 392static struct hw_pci rcar_pci = {
393 .setup = rcar_pcie_setup, 393 .setup = rcar_pcie_setup,
394 .map_irq = of_irq_parse_and_map_pci, 394 .map_irq = of_irq_parse_and_map_pci,
395 .ops = &rcar_pcie_ops, 395 .ops = &rcar_pcie_ops,
diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c
index 85f594e1708f..2ca10cc887ee 100644
--- a/drivers/pci/host/pcie-spear13xx.c
+++ b/drivers/pci/host/pcie-spear13xx.c
@@ -269,7 +269,8 @@ static struct pcie_host_ops spear13xx_pcie_host_ops = {
269 .host_init = spear13xx_pcie_host_init, 269 .host_init = spear13xx_pcie_host_init,
270}; 270};
271 271
272static int add_pcie_port(struct pcie_port *pp, struct platform_device *pdev) 272static int __init spear13xx_add_pcie_port(struct pcie_port *pp,
273 struct platform_device *pdev)
273{ 274{
274 struct device *dev = &pdev->dev; 275 struct device *dev = &pdev->dev;
275 int ret; 276 int ret;
@@ -308,10 +309,8 @@ static int __init spear13xx_pcie_probe(struct platform_device *pdev)
308 int ret; 309 int ret;
309 310
310 spear13xx_pcie = devm_kzalloc(dev, sizeof(*spear13xx_pcie), GFP_KERNEL); 311 spear13xx_pcie = devm_kzalloc(dev, sizeof(*spear13xx_pcie), GFP_KERNEL);
311 if (!spear13xx_pcie) { 312 if (!spear13xx_pcie)
312 dev_err(dev, "no memory for SPEAr13xx pcie\n");
313 return -ENOMEM; 313 return -ENOMEM;
314 }
315 314
316 spear13xx_pcie->phy = devm_phy_get(dev, "pcie-phy"); 315 spear13xx_pcie->phy = devm_phy_get(dev, "pcie-phy");
317 if (IS_ERR(spear13xx_pcie->phy)) { 316 if (IS_ERR(spear13xx_pcie->phy)) {
@@ -352,7 +351,7 @@ static int __init spear13xx_pcie_probe(struct platform_device *pdev)
352 if (of_property_read_bool(np, "st,pcie-is-gen1")) 351 if (of_property_read_bool(np, "st,pcie-is-gen1"))
353 spear13xx_pcie->is_gen1 = true; 352 spear13xx_pcie->is_gen1 = true;
354 353
355 ret = add_pcie_port(pp, pdev); 354 ret = spear13xx_add_pcie_port(pp, pdev);
356 if (ret < 0) 355 if (ret < 0)
357 goto fail_clk; 356 goto fail_clk;
358 357
@@ -382,11 +381,11 @@ static struct platform_driver spear13xx_pcie_driver __initdata = {
382 381
383/* SPEAr13xx PCIe driver does not allow module unload */ 382/* SPEAr13xx PCIe driver does not allow module unload */
384 383
385static int __init pcie_init(void) 384static int __init spear13xx_pcie_init(void)
386{ 385{
387 return platform_driver_register(&spear13xx_pcie_driver); 386 return platform_driver_register(&spear13xx_pcie_driver);
388} 387}
389module_init(pcie_init); 388module_init(spear13xx_pcie_init);
390 389
391MODULE_DESCRIPTION("ST Microelectronics SPEAr13xx PCIe host controller driver"); 390MODULE_DESCRIPTION("ST Microelectronics SPEAr13xx PCIe host controller driver");
392MODULE_AUTHOR("Pratyush Anand <pratyush.anand@st.com>"); 391MODULE_AUTHOR("Pratyush Anand <pratyush.anand@st.com>");