diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/pci/host/Kconfig | 13 | ||||
| -rw-r--r-- | drivers/pci/host/Makefile | 1 | ||||
| -rw-r--r-- | drivers/pci/host/pci-dra7xx.c | 6 | ||||
| -rw-r--r-- | drivers/pci/host/pci-exynos.c | 18 | ||||
| -rw-r--r-- | drivers/pci/host/pci-host-generic.c | 126 | ||||
| -rw-r--r-- | drivers/pci/host/pci-imx6.c | 4 | ||||
| -rw-r--r-- | drivers/pci/host/pci-keystone-dw.c | 2 | ||||
| -rw-r--r-- | drivers/pci/host/pci-keystone.c | 5 | ||||
| -rw-r--r-- | drivers/pci/host/pci-layerscape.c | 179 | ||||
| -rw-r--r-- | drivers/pci/host/pci-mvebu.c | 2 | ||||
| -rw-r--r-- | drivers/pci/host/pcie-designware.c | 1 | ||||
| -rw-r--r-- | drivers/pci/host/pcie-rcar.c | 2 | ||||
| -rw-r--r-- | drivers/pci/host/pcie-spear13xx.c | 13 | ||||
| -rw-r--r-- | drivers/pci/hotplug/ibmphp_res.c | 5 | ||||
| -rw-r--r-- | drivers/pci/iov.c | 11 | ||||
| -rw-r--r-- | drivers/pci/pci-acpi.c | 3 | ||||
| -rw-r--r-- | drivers/pci/pci.c | 21 | ||||
| -rw-r--r-- | drivers/pci/pci.h | 6 | ||||
| -rw-r--r-- | drivers/pci/probe.c | 80 | ||||
| -rw-r--r-- | drivers/pci/search.c | 3 | ||||
| -rw-r--r-- | drivers/pci/xen-pcifront.c | 13 |
21 files changed, 305 insertions, 209 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 | ||
| 33 | config PCI_TEGRA | 33 | config 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 | ||
| 37 | config PCI_RCAR_GEN2 | 40 | config 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 | ||
| 97 | config 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 | |||
| 94 | endmenu | 105 | endmenu |
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 | |||
| 11 | obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone-dw.o pci-keystone.o | 11 | obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone-dw.o pci-keystone.o |
| 12 | obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o | 12 | obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o |
| 13 | obj-$(CONFIG_PCI_XGENE) += pci-xgene.o | 13 | obj-$(CONFIG_PCI_XGENE) += pci-xgene.o |
| 14 | obj-$(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 | ||
| 273 | static int add_pcie_port(struct dra7xx_pcie *dra7xx, | 273 | static 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 | ||
| 318 | static int exynos_pcie_establish_link(struct pcie_port *pp) | 317 | static 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 | ||
| 394 | static void exynos_pcie_enable_irq_pulse(struct pcie_port *pp) | 392 | static 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 | ||
| 406 | static irqreturn_t exynos_pcie_irq_handler(int irq, void *arg) | 403 | static 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 | ||
| 435 | static void exynos_pcie_enable_interrupts(struct pcie_port *pp) | 431 | static 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 | ||
| 445 | static inline void exynos_pcie_readl_rc(struct pcie_port *pp, | 439 | static 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 | ||
| 454 | static inline void exynos_pcie_writel_rc(struct pcie_port *pp, | 447 | static 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 | ||
| 463 | static int exynos_pcie_rd_own_conf(struct pcie_port *pp, int where, int size, | 455 | static 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 | ||
| 512 | static int __init add_pcie_port(struct pcie_port *pp, | 504 | static 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 | ||
| 659 | static int __init pcie_init(void) | 651 | static 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 | } |
| 663 | subsys_initcall(pcie_init); | 655 | subsys_initcall(exynos_pcie_init); |
| 664 | 656 | ||
| 665 | MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>"); | 657 | MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>"); |
| 666 | MODULE_DESCRIPTION("Samsung PCIe host controller driver"); | 658 | MODULE_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 | ||
| 33 | struct gen_pci_cfg_windows { | 33 | struct 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 | }; |
| 139 | MODULE_DEVICE_TABLE(of, gen_pci_of_match); | 139 | MODULE_DEVICE_TABLE(of, gen_pci_of_match); |
| 140 | 140 | ||
| 141 | static 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 | |||
| 170 | static 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 | |||
| 180 | static void gen_pci_release_of_pci_ranges(struct gen_pci *pci) | 141 | static 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 | ||
| 190 | static int gen_pci_parse_request_of_pci_ranges(struct gen_pci *pci) | 146 | static 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-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c index 34086ce88e8e..4a97cd14e6fb 100644 --- a/drivers/pci/host/pci-keystone-dw.c +++ b/drivers/pci/host/pci-keystone-dw.c | |||
| @@ -201,7 +201,7 @@ static int ks_dw_pcie_msi_map(struct irq_domain *domain, unsigned int irq, | |||
| 201 | return 0; | 201 | return 0; |
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | const struct irq_domain_ops ks_dw_pcie_msi_domain_ops = { | 204 | static const struct irq_domain_ops ks_dw_pcie_msi_domain_ops = { |
| 205 | .map = ks_dw_pcie_msi_map, | 205 | .map = ks_dw_pcie_msi_map, |
| 206 | }; | 206 | }; |
| 207 | 207 | ||
diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c index 1b893bc8b842..62b9454c86fb 100644 --- a/drivers/pci/host/pci-keystone.c +++ b/drivers/pci/host/pci-keystone.c | |||
| @@ -353,10 +353,9 @@ static int __init ks_pcie_probe(struct platform_device *pdev) | |||
| 353 | 353 | ||
| 354 | ks_pcie = devm_kzalloc(&pdev->dev, sizeof(*ks_pcie), | 354 | ks_pcie = devm_kzalloc(&pdev->dev, sizeof(*ks_pcie), |
| 355 | GFP_KERNEL); | 355 | GFP_KERNEL); |
| 356 | if (!ks_pcie) { | 356 | if (!ks_pcie) |
| 357 | dev_err(dev, "no memory for keystone pcie\n"); | ||
| 358 | return -ENOMEM; | 357 | return -ENOMEM; |
| 359 | } | 358 | |
| 360 | pp = &ks_pcie->pp; | 359 | pp = &ks_pcie->pp; |
| 361 | 360 | ||
| 362 | /* initialize SerDes Phy if present */ | 361 | /* initialize SerDes Phy if present */ |
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 | |||
| 38 | struct 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 | |||
| 51 | static 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 | |||
| 65 | static 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 | |||
| 91 | static struct pcie_host_ops ls_pcie_host_ops = { | ||
| 92 | .link_up = ls_pcie_link_up, | ||
| 93 | .host_init = ls_pcie_host_init, | ||
| 94 | }; | ||
| 95 | |||
| 96 | static 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 | |||
| 116 | static 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 | |||
| 161 | static const struct of_device_id ls_pcie_of_match[] = { | ||
| 162 | { .compatible = "fsl,ls1021a-pcie" }, | ||
| 163 | { }, | ||
| 164 | }; | ||
| 165 | MODULE_DEVICE_TABLE(of, ls_pcie_of_match); | ||
| 166 | |||
| 167 | static 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 | |||
| 175 | module_platform_driver_probe(ls_pcie_driver, ls_pcie_probe); | ||
| 176 | |||
| 177 | MODULE_AUTHOR("Minghuan Lian <Minghuan.Lian@freescale.com>"); | ||
| 178 | MODULE_DESCRIPTION("Freescale Layerscape PCIe host controller driver"); | ||
| 179 | MODULE_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 | ||
| 392 | struct hw_pci rcar_pci = { | 392 | static 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 | ||
| 272 | static int add_pcie_port(struct pcie_port *pp, struct platform_device *pdev) | 272 | static 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 | ||
| 385 | static int __init pcie_init(void) | 384 | static 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 | } |
| 389 | module_init(pcie_init); | 388 | module_init(spear13xx_pcie_init); |
| 390 | 389 | ||
| 391 | MODULE_DESCRIPTION("ST Microelectronics SPEAr13xx PCIe host controller driver"); | 390 | MODULE_DESCRIPTION("ST Microelectronics SPEAr13xx PCIe host controller driver"); |
| 392 | MODULE_AUTHOR("Pratyush Anand <pratyush.anand@st.com>"); | 391 | MODULE_AUTHOR("Pratyush Anand <pratyush.anand@st.com>"); |
diff --git a/drivers/pci/hotplug/ibmphp_res.c b/drivers/pci/hotplug/ibmphp_res.c index 219ba8090a37..f279060cf6e2 100644 --- a/drivers/pci/hotplug/ibmphp_res.c +++ b/drivers/pci/hotplug/ibmphp_res.c | |||
| @@ -376,10 +376,7 @@ int __init ibmphp_rsrc_init (void) | |||
| 376 | if (rc) | 376 | if (rc) |
| 377 | return rc; | 377 | return rc; |
| 378 | } | 378 | } |
| 379 | rc = once_over (); /* This is to align ranges (so no -1) */ | 379 | return once_over (); /* This is to align ranges (so no -1) */ |
| 380 | if (rc) | ||
| 381 | return rc; | ||
| 382 | return 0; | ||
| 383 | } | 380 | } |
| 384 | 381 | ||
| 385 | /******************************************************************************** | 382 | /******************************************************************************** |
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 4d109c07294a..4b3a4eaad996 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c | |||
| @@ -479,20 +479,16 @@ void pci_iov_release(struct pci_dev *dev) | |||
| 479 | * pci_iov_resource_bar - get position of the SR-IOV BAR | 479 | * pci_iov_resource_bar - get position of the SR-IOV BAR |
| 480 | * @dev: the PCI device | 480 | * @dev: the PCI device |
| 481 | * @resno: the resource number | 481 | * @resno: the resource number |
| 482 | * @type: the BAR type to be filled in | ||
| 483 | * | 482 | * |
| 484 | * Returns position of the BAR encapsulated in the SR-IOV capability. | 483 | * Returns position of the BAR encapsulated in the SR-IOV capability. |
| 485 | */ | 484 | */ |
| 486 | int pci_iov_resource_bar(struct pci_dev *dev, int resno, | 485 | int pci_iov_resource_bar(struct pci_dev *dev, int resno) |
| 487 | enum pci_bar_type *type) | ||
| 488 | { | 486 | { |
| 489 | if (resno < PCI_IOV_RESOURCES || resno > PCI_IOV_RESOURCE_END) | 487 | if (resno < PCI_IOV_RESOURCES || resno > PCI_IOV_RESOURCE_END) |
| 490 | return 0; | 488 | return 0; |
| 491 | 489 | ||
| 492 | BUG_ON(!dev->is_physfn); | 490 | BUG_ON(!dev->is_physfn); |
| 493 | 491 | ||
| 494 | *type = pci_bar_unknown; | ||
| 495 | |||
| 496 | return dev->sriov->pos + PCI_SRIOV_BAR + | 492 | return dev->sriov->pos + PCI_SRIOV_BAR + |
| 497 | 4 * (resno - PCI_IOV_RESOURCES); | 493 | 4 * (resno - PCI_IOV_RESOURCES); |
| 498 | } | 494 | } |
| @@ -510,13 +506,12 @@ int pci_iov_resource_bar(struct pci_dev *dev, int resno, | |||
| 510 | resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno) | 506 | resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno) |
| 511 | { | 507 | { |
| 512 | struct resource tmp; | 508 | struct resource tmp; |
| 513 | enum pci_bar_type type; | 509 | int reg = pci_iov_resource_bar(dev, resno); |
| 514 | int reg = pci_iov_resource_bar(dev, resno, &type); | ||
| 515 | 510 | ||
| 516 | if (!reg) | 511 | if (!reg) |
| 517 | return 0; | 512 | return 0; |
| 518 | 513 | ||
| 519 | __pci_read_base(dev, type, &tmp, reg); | 514 | __pci_read_base(dev, pci_bar_unknown, &tmp, reg); |
| 520 | return resource_alignment(&tmp); | 515 | return resource_alignment(&tmp); |
| 521 | } | 516 | } |
| 522 | 517 | ||
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 6ebf8edc5f3c..3542150fc8a3 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
| @@ -322,8 +322,7 @@ static void pci_acpi_wake_dev(struct work_struct *work) | |||
| 322 | pci_wakeup_event(pci_dev); | 322 | pci_wakeup_event(pci_dev); |
| 323 | pm_runtime_resume(&pci_dev->dev); | 323 | pm_runtime_resume(&pci_dev->dev); |
| 324 | 324 | ||
| 325 | if (pci_dev->subordinate) | 325 | pci_pme_wakeup_bus(pci_dev->subordinate); |
| 326 | pci_pme_wakeup_bus(pci_dev->subordinate); | ||
| 327 | } | 326 | } |
| 328 | 327 | ||
| 329 | /** | 328 | /** |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 625a4ace10b4..a7ac72639c52 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
| @@ -1012,11 +1012,7 @@ int pci_save_state(struct pci_dev *dev) | |||
| 1012 | if (i != 0) | 1012 | if (i != 0) |
| 1013 | return i; | 1013 | return i; |
| 1014 | 1014 | ||
| 1015 | i = pci_save_vc_state(dev); | 1015 | return pci_save_vc_state(dev); |
| 1016 | if (i != 0) | ||
| 1017 | return i; | ||
| 1018 | |||
| 1019 | return 0; | ||
| 1020 | } | 1016 | } |
| 1021 | EXPORT_SYMBOL(pci_save_state); | 1017 | EXPORT_SYMBOL(pci_save_state); |
| 1022 | 1018 | ||
| @@ -3144,12 +3140,10 @@ static int pcie_flr(struct pci_dev *dev, int probe) | |||
| 3144 | return 0; | 3140 | return 0; |
| 3145 | 3141 | ||
| 3146 | if (!pci_wait_for_pending_transaction(dev)) | 3142 | if (!pci_wait_for_pending_transaction(dev)) |
| 3147 | dev_err(&dev->dev, "transaction is not cleared; proceeding with reset anyway\n"); | 3143 | dev_err(&dev->dev, "timed out waiting for pending transaction; performing function level reset anyway\n"); |
| 3148 | 3144 | ||
| 3149 | pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR); | 3145 | pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR); |
| 3150 | |||
| 3151 | msleep(100); | 3146 | msleep(100); |
| 3152 | |||
| 3153 | return 0; | 3147 | return 0; |
| 3154 | } | 3148 | } |
| 3155 | 3149 | ||
| @@ -3174,16 +3168,12 @@ static int pci_af_flr(struct pci_dev *dev, int probe) | |||
| 3174 | * is used, so we use the conrol offset rather than status and shift | 3168 | * is used, so we use the conrol offset rather than status and shift |
| 3175 | * the test bit to match. | 3169 | * the test bit to match. |
| 3176 | */ | 3170 | */ |
| 3177 | if (pci_wait_for_pending(dev, pos + PCI_AF_CTRL, | 3171 | if (!pci_wait_for_pending(dev, pos + PCI_AF_CTRL, |
| 3178 | PCI_AF_STATUS_TP << 8)) | 3172 | PCI_AF_STATUS_TP << 8)) |
| 3179 | goto clear; | 3173 | dev_err(&dev->dev, "timed out waiting for pending transaction; performing AF function level reset anyway\n"); |
| 3180 | |||
| 3181 | dev_err(&dev->dev, "transaction is not cleared; proceeding with reset anyway\n"); | ||
| 3182 | 3174 | ||
| 3183 | clear: | ||
| 3184 | pci_write_config_byte(dev, pos + PCI_AF_CTRL, PCI_AF_CTRL_FLR); | 3175 | pci_write_config_byte(dev, pos + PCI_AF_CTRL, PCI_AF_CTRL_FLR); |
| 3185 | msleep(100); | 3176 | msleep(100); |
| 3186 | |||
| 3187 | return 0; | 3177 | return 0; |
| 3188 | } | 3178 | } |
| 3189 | 3179 | ||
| @@ -4180,7 +4170,8 @@ int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type) | |||
| 4180 | return dev->rom_base_reg; | 4170 | return dev->rom_base_reg; |
| 4181 | } else if (resno < PCI_BRIDGE_RESOURCES) { | 4171 | } else if (resno < PCI_BRIDGE_RESOURCES) { |
| 4182 | /* device specific resource */ | 4172 | /* device specific resource */ |
| 4183 | reg = pci_iov_resource_bar(dev, resno, type); | 4173 | *type = pci_bar_unknown; |
| 4174 | reg = pci_iov_resource_bar(dev, resno); | ||
| 4184 | if (reg) | 4175 | if (reg) |
| 4185 | return reg; | 4176 | return reg; |
| 4186 | } | 4177 | } |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 0601890db22d..a0905a0985ce 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
| @@ -251,8 +251,7 @@ static inline void pci_restore_ats_state(struct pci_dev *dev) | |||
| 251 | #ifdef CONFIG_PCI_IOV | 251 | #ifdef CONFIG_PCI_IOV |
| 252 | int pci_iov_init(struct pci_dev *dev); | 252 | int pci_iov_init(struct pci_dev *dev); |
| 253 | void pci_iov_release(struct pci_dev *dev); | 253 | void pci_iov_release(struct pci_dev *dev); |
| 254 | int pci_iov_resource_bar(struct pci_dev *dev, int resno, | 254 | int pci_iov_resource_bar(struct pci_dev *dev, int resno); |
| 255 | enum pci_bar_type *type); | ||
| 256 | resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno); | 255 | resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno); |
| 257 | void pci_restore_iov_state(struct pci_dev *dev); | 256 | void pci_restore_iov_state(struct pci_dev *dev); |
| 258 | int pci_iov_bus_range(struct pci_bus *bus); | 257 | int pci_iov_bus_range(struct pci_bus *bus); |
| @@ -266,8 +265,7 @@ static inline void pci_iov_release(struct pci_dev *dev) | |||
| 266 | 265 | ||
| 267 | { | 266 | { |
| 268 | } | 267 | } |
| 269 | static inline int pci_iov_resource_bar(struct pci_dev *dev, int resno, | 268 | static inline int pci_iov_resource_bar(struct pci_dev *dev, int resno) |
| 270 | enum pci_bar_type *type) | ||
| 271 | { | 269 | { |
| 272 | return 0; | 270 | return 0; |
| 273 | } | 271 | } |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 5ed99309c758..a9e34ca119e1 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
| @@ -87,8 +87,7 @@ static void release_pcibus_dev(struct device *dev) | |||
| 87 | { | 87 | { |
| 88 | struct pci_bus *pci_bus = to_pci_bus(dev); | 88 | struct pci_bus *pci_bus = to_pci_bus(dev); |
| 89 | 89 | ||
| 90 | if (pci_bus->bridge) | 90 | put_device(pci_bus->bridge); |
| 91 | put_device(pci_bus->bridge); | ||
| 92 | pci_bus_remove_resources(pci_bus); | 91 | pci_bus_remove_resources(pci_bus); |
| 93 | pci_release_bus_of_node(pci_bus); | 92 | pci_release_bus_of_node(pci_bus); |
| 94 | kfree(pci_bus); | 93 | kfree(pci_bus); |
| @@ -175,7 +174,6 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
| 175 | u64 l64, sz64, mask64; | 174 | u64 l64, sz64, mask64; |
| 176 | u16 orig_cmd; | 175 | u16 orig_cmd; |
| 177 | struct pci_bus_region region, inverted_region; | 176 | struct pci_bus_region region, inverted_region; |
| 178 | bool bar_too_big = false, bar_too_high = false, bar_invalid = false; | ||
| 179 | 177 | ||
| 180 | mask = type ? PCI_ROM_ADDRESS_MASK : ~0; | 178 | mask = type ? PCI_ROM_ADDRESS_MASK : ~0; |
| 181 | 179 | ||
| @@ -201,8 +199,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
| 201 | * memory BAR or a ROM, bit 0 must be clear; if it's an io BAR, bit | 199 | * memory BAR or a ROM, bit 0 must be clear; if it's an io BAR, bit |
| 202 | * 1 must be clear. | 200 | * 1 must be clear. |
| 203 | */ | 201 | */ |
| 204 | if (!sz || sz == 0xffffffff) | 202 | if (sz == 0xffffffff) |
| 205 | goto fail; | 203 | sz = 0; |
| 206 | 204 | ||
| 207 | /* | 205 | /* |
| 208 | * I don't know how l can have all bits set. Copied from old code. | 206 | * I don't know how l can have all bits set. Copied from old code. |
| @@ -215,23 +213,22 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
| 215 | res->flags = decode_bar(dev, l); | 213 | res->flags = decode_bar(dev, l); |
| 216 | res->flags |= IORESOURCE_SIZEALIGN; | 214 | res->flags |= IORESOURCE_SIZEALIGN; |
| 217 | if (res->flags & IORESOURCE_IO) { | 215 | if (res->flags & IORESOURCE_IO) { |
| 218 | l &= PCI_BASE_ADDRESS_IO_MASK; | 216 | l64 = l & PCI_BASE_ADDRESS_IO_MASK; |
| 219 | mask = PCI_BASE_ADDRESS_IO_MASK & (u32) IO_SPACE_LIMIT; | 217 | sz64 = sz & PCI_BASE_ADDRESS_IO_MASK; |
| 218 | mask64 = PCI_BASE_ADDRESS_IO_MASK & (u32)IO_SPACE_LIMIT; | ||
| 220 | } else { | 219 | } else { |
| 221 | l &= PCI_BASE_ADDRESS_MEM_MASK; | 220 | l64 = l & PCI_BASE_ADDRESS_MEM_MASK; |
| 222 | mask = (u32)PCI_BASE_ADDRESS_MEM_MASK; | 221 | sz64 = sz & PCI_BASE_ADDRESS_MEM_MASK; |
| 222 | mask64 = (u32)PCI_BASE_ADDRESS_MEM_MASK; | ||
| 223 | } | 223 | } |
| 224 | } else { | 224 | } else { |
| 225 | res->flags |= (l & IORESOURCE_ROM_ENABLE); | 225 | res->flags |= (l & IORESOURCE_ROM_ENABLE); |
| 226 | l &= PCI_ROM_ADDRESS_MASK; | 226 | l64 = l & PCI_ROM_ADDRESS_MASK; |
| 227 | mask = (u32)PCI_ROM_ADDRESS_MASK; | 227 | sz64 = sz & PCI_ROM_ADDRESS_MASK; |
| 228 | mask64 = (u32)PCI_ROM_ADDRESS_MASK; | ||
| 228 | } | 229 | } |
| 229 | 230 | ||
| 230 | if (res->flags & IORESOURCE_MEM_64) { | 231 | if (res->flags & IORESOURCE_MEM_64) { |
| 231 | l64 = l; | ||
| 232 | sz64 = sz; | ||
| 233 | mask64 = mask | (u64)~0 << 32; | ||
| 234 | |||
| 235 | pci_read_config_dword(dev, pos + 4, &l); | 232 | pci_read_config_dword(dev, pos + 4, &l); |
| 236 | pci_write_config_dword(dev, pos + 4, ~0); | 233 | pci_write_config_dword(dev, pos + 4, ~0); |
| 237 | pci_read_config_dword(dev, pos + 4, &sz); | 234 | pci_read_config_dword(dev, pos + 4, &sz); |
| @@ -239,18 +236,30 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
| 239 | 236 | ||
| 240 | l64 |= ((u64)l << 32); | 237 | l64 |= ((u64)l << 32); |
| 241 | sz64 |= ((u64)sz << 32); | 238 | sz64 |= ((u64)sz << 32); |
| 239 | mask64 |= ((u64)~0 << 32); | ||
| 240 | } | ||
| 242 | 241 | ||
| 243 | sz64 = pci_size(l64, sz64, mask64); | 242 | if (!dev->mmio_always_on && (orig_cmd & PCI_COMMAND_DECODE_ENABLE)) |
| 243 | pci_write_config_word(dev, PCI_COMMAND, orig_cmd); | ||
| 244 | 244 | ||
| 245 | if (!sz64) | 245 | if (!sz64) |
| 246 | goto fail; | 246 | goto fail; |
| 247 | 247 | ||
| 248 | sz64 = pci_size(l64, sz64, mask64); | ||
| 249 | if (!sz64) { | ||
| 250 | dev_info(&dev->dev, FW_BUG "reg 0x%x: invalid BAR (can't size)\n", | ||
| 251 | pos); | ||
| 252 | goto fail; | ||
| 253 | } | ||
| 254 | |||
| 255 | if (res->flags & IORESOURCE_MEM_64) { | ||
| 248 | if ((sizeof(dma_addr_t) < 8 || sizeof(resource_size_t) < 8) && | 256 | if ((sizeof(dma_addr_t) < 8 || sizeof(resource_size_t) < 8) && |
| 249 | sz64 > 0x100000000ULL) { | 257 | sz64 > 0x100000000ULL) { |
| 250 | res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED; | 258 | res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED; |
| 251 | res->start = 0; | 259 | res->start = 0; |
| 252 | res->end = 0; | 260 | res->end = 0; |
| 253 | bar_too_big = true; | 261 | dev_err(&dev->dev, "reg 0x%x: can't handle BAR larger than 4GB (size %#010llx)\n", |
| 262 | pos, (unsigned long long)sz64); | ||
| 254 | goto out; | 263 | goto out; |
| 255 | } | 264 | } |
| 256 | 265 | ||
| @@ -259,22 +268,15 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
| 259 | res->flags |= IORESOURCE_UNSET; | 268 | res->flags |= IORESOURCE_UNSET; |
| 260 | res->start = 0; | 269 | res->start = 0; |
| 261 | res->end = sz64; | 270 | res->end = sz64; |
| 262 | bar_too_high = true; | 271 | dev_info(&dev->dev, "reg 0x%x: can't handle BAR above 4GB (bus address %#010llx)\n", |
| 272 | pos, (unsigned long long)l64); | ||
| 263 | goto out; | 273 | goto out; |
| 264 | } else { | ||
| 265 | region.start = l64; | ||
| 266 | region.end = l64 + sz64; | ||
| 267 | } | 274 | } |
| 268 | } else { | ||
| 269 | sz = pci_size(l, sz, mask); | ||
| 270 | |||
| 271 | if (!sz) | ||
| 272 | goto fail; | ||
| 273 | |||
| 274 | region.start = l; | ||
| 275 | region.end = l + sz; | ||
| 276 | } | 275 | } |
| 277 | 276 | ||
| 277 | region.start = l64; | ||
| 278 | region.end = l64 + sz64; | ||
| 279 | |||
| 278 | pcibios_bus_to_resource(dev->bus, res, ®ion); | 280 | pcibios_bus_to_resource(dev->bus, res, ®ion); |
| 279 | pcibios_resource_to_bus(dev->bus, &inverted_region, res); | 281 | pcibios_resource_to_bus(dev->bus, &inverted_region, res); |
| 280 | 282 | ||
| @@ -293,7 +295,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
| 293 | res->flags |= IORESOURCE_UNSET; | 295 | res->flags |= IORESOURCE_UNSET; |
| 294 | res->start = 0; | 296 | res->start = 0; |
| 295 | res->end = region.end - region.start; | 297 | res->end = region.end - region.start; |
| 296 | bar_invalid = true; | 298 | dev_info(&dev->dev, "reg 0x%x: initial BAR value %#010llx invalid\n", |
| 299 | pos, (unsigned long long)region.start); | ||
| 297 | } | 300 | } |
| 298 | 301 | ||
| 299 | goto out; | 302 | goto out; |
| @@ -302,19 +305,6 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
| 302 | fail: | 305 | fail: |
| 303 | res->flags = 0; | 306 | res->flags = 0; |
| 304 | out: | 307 | out: |
| 305 | if (!dev->mmio_always_on && | ||
| 306 | (orig_cmd & PCI_COMMAND_DECODE_ENABLE)) | ||
| 307 | pci_write_config_word(dev, PCI_COMMAND, orig_cmd); | ||
| 308 | |||
| 309 | if (bar_too_big) | ||
| 310 | dev_err(&dev->dev, "reg 0x%x: can't handle BAR larger than 4GB (size %#010llx)\n", | ||
| 311 | pos, (unsigned long long) sz64); | ||
| 312 | if (bar_too_high) | ||
| 313 | dev_info(&dev->dev, "reg 0x%x: can't handle BAR above 4G (bus address %#010llx)\n", | ||
| 314 | pos, (unsigned long long) l64); | ||
| 315 | if (bar_invalid) | ||
| 316 | dev_info(&dev->dev, "reg 0x%x: initial BAR value %#010llx invalid\n", | ||
| 317 | pos, (unsigned long long) region.start); | ||
| 318 | if (res->flags) | 308 | if (res->flags) |
| 319 | dev_printk(KERN_DEBUG, &dev->dev, "reg 0x%x: %pR\n", pos, res); | 309 | dev_printk(KERN_DEBUG, &dev->dev, "reg 0x%x: %pR\n", pos, res); |
| 320 | 310 | ||
diff --git a/drivers/pci/search.c b/drivers/pci/search.c index a81f413083e4..a20ce7d5e2a7 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c | |||
| @@ -271,8 +271,7 @@ static struct pci_dev *pci_get_dev_by_id(const struct pci_device_id *id, | |||
| 271 | match_pci_dev_by_id); | 271 | match_pci_dev_by_id); |
| 272 | if (dev) | 272 | if (dev) |
| 273 | pdev = to_pci_dev(dev); | 273 | pdev = to_pci_dev(dev); |
| 274 | if (from) | 274 | pci_dev_put(from); |
| 275 | pci_dev_put(from); | ||
| 276 | return pdev; | 275 | return pdev; |
| 277 | } | 276 | } |
| 278 | 277 | ||
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c index 116ca3746adb..b1ffebec9b9e 100644 --- a/drivers/pci/xen-pcifront.c +++ b/drivers/pci/xen-pcifront.c | |||
| @@ -596,8 +596,7 @@ static pci_ers_result_t pcifront_common_process(int cmd, | |||
| 596 | pcidev = pci_get_bus_and_slot(bus, devfn); | 596 | pcidev = pci_get_bus_and_slot(bus, devfn); |
| 597 | if (!pcidev || !pcidev->driver) { | 597 | if (!pcidev || !pcidev->driver) { |
| 598 | dev_err(&pdev->xdev->dev, "device or AER driver is NULL\n"); | 598 | dev_err(&pdev->xdev->dev, "device or AER driver is NULL\n"); |
| 599 | if (pcidev) | 599 | pci_dev_put(pcidev); |
| 600 | pci_dev_put(pcidev); | ||
| 601 | return result; | 600 | return result; |
| 602 | } | 601 | } |
| 603 | pdrv = pcidev->driver; | 602 | pdrv = pcidev->driver; |
| @@ -866,6 +865,11 @@ static int pcifront_try_connect(struct pcifront_device *pdev) | |||
| 866 | xenbus_dev_error(pdev->xdev, err, | 865 | xenbus_dev_error(pdev->xdev, err, |
| 867 | "No PCI Roots found, trying 0000:00"); | 866 | "No PCI Roots found, trying 0000:00"); |
| 868 | err = pcifront_scan_root(pdev, 0, 0); | 867 | err = pcifront_scan_root(pdev, 0, 0); |
| 868 | if (err) { | ||
| 869 | xenbus_dev_fatal(pdev->xdev, err, | ||
| 870 | "Error scanning PCI root 0000:00"); | ||
| 871 | goto out; | ||
| 872 | } | ||
| 869 | num_roots = 0; | 873 | num_roots = 0; |
| 870 | } else if (err != 1) { | 874 | } else if (err != 1) { |
| 871 | if (err == 0) | 875 | if (err == 0) |
| @@ -947,6 +951,11 @@ static int pcifront_attach_devices(struct pcifront_device *pdev) | |||
| 947 | xenbus_dev_error(pdev->xdev, err, | 951 | xenbus_dev_error(pdev->xdev, err, |
| 948 | "No PCI Roots found, trying 0000:00"); | 952 | "No PCI Roots found, trying 0000:00"); |
| 949 | err = pcifront_rescan_root(pdev, 0, 0); | 953 | err = pcifront_rescan_root(pdev, 0, 0); |
| 954 | if (err) { | ||
| 955 | xenbus_dev_fatal(pdev->xdev, err, | ||
| 956 | "Error scanning PCI root 0000:00"); | ||
| 957 | goto out; | ||
| 958 | } | ||
| 950 | num_roots = 0; | 959 | num_roots = 0; |
| 951 | } else if (err != 1) { | 960 | } else if (err != 1) { |
| 952 | if (err == 0) | 961 | if (err == 0) |
