aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-04-13 18:45:47 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-13 18:45:47 -0400
commit3be1b98e073bdd4c1bb3144201a927c4a21330ba (patch)
tree6eb0619a4715d8f83388e8fd7a56f58d1c99f6cf /drivers/pci
parent392b46f31f43a71c5391eb9cffe304979d2d6c30 (diff)
parent5468d5a64bf1e002e5081fa280186d0eba09fa0e (diff)
Merge tag 'pci-v4.1-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI changes from Bjorn Helgaas: "Enumeration - Read capability list as dwords, not bytes (Sean O. Stalley) Resource management - Don't check for PNP overlaps with unassigned PCI BARs (Bjorn Helgaas) - Mark invalid BARs as unassigned (Bjorn Helgaas) - Show driver, BAR#, and resource on pci_ioremap_bar() failure (Bjorn Helgaas) - Fail pci_ioremap_bar() on unassigned resources (Bjorn Helgaas) - Assign resources before drivers claim devices (Yijing Wang) - Claim bus resources before pci_bus_add_devices() (Yijing Wang) Power management - Optimize device state transition delays (Aaron Lu) - Don't clear ASPM bits when the FADT declares it's unsupported (Matthew Garrett) Virtualization - Add ACS quirks for Intel 1G NICs (Alex Williamson) IOMMU - Add ptr to OF node arg to of_iommu_configure() (Murali Karicheri) - Move of_dma_configure() to device.c to help re-use (Murali Karicheri) - Fix size when dma-range is not used (Murali Karicheri) - Add helper functions pci_get[put]_host_bridge_device() (Murali Karicheri) - Add of_pci_dma_configure() to update DMA configuration (Murali Karicheri) - Update DMA configuration from DT (Murali Karicheri) - dma-mapping: limit IOMMU mapping size (Murali Karicheri) - Calculate device DMA masks based on DT dma-range size (Murali Karicheri) ARM Versatile host bridge driver - Check for devm_ioremap_resource() failures (Jisheng Zhang) Broadcom iProc host bridge driver - Add Broadcom iProc PCIe driver (Ray Jui) Marvell MVEBU host bridge driver - Add suspend/resume support (Thomas Petazzoni) Renesas R-Car host bridge driver - Fix position of MSI enable bit (Nobuhiro Iwamatsu) - Write zeroes to reserved PCIEPARL bits (Nobuhiro Iwamatsu) - Change PCIEPARL and PCIEPARH to PCIEPALR and PCIEPAUR (Nobuhiro Iwamatsu) - Verify that mem_res is 64K-aligned (Nobuhiro Iwamatsu) Samsung Exynos host bridge driver - Fix INTx enablement statement termination error (Jaehoon Chung) Miscellaneous - Make a shareable UUID for PCI firmware ACPI _DSM (Aaron Lu) - Clarify policy for vendor IDs in pci.txt (Michael S. Tsirkin)" * tag 'pci-v4.1-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (36 commits) PCI: Read capability list as dwords, not bytes PCI: layerscape: Simplify platform_get_resource_byname() failure checking PCI: keystone: Don't dereference possible NULL pointer PCI: versatile: Check for devm_ioremap_resource() failures PCI: Don't clear ASPM bits when the FADT declares it's unsupported PCI: Clarify policy for vendor IDs in pci.txt PCI/ACPI: Optimize device state transition delays PCI: Export pci_find_host_bridge() for use inside PCI core PCI: Make a shareable UUID for PCI firmware ACPI _DSM PCI: Fix typo in Thunderbolt kernel message PCI: exynos: Fix INTx enablement statement termination error PCI: iproc: Add Broadcom iProc PCIe support PCI: iproc: Add DT docs for Broadcom iProc PCIe driver PCI: Export symbols required for loadable host driver modules PCI: Add ACS quirks for Intel 1G NICs PCI: mvebu: Add suspend/resume support PCI: Cleanup control flow sparc/PCI: Claim bus resources before pci_bus_add_devices() PCI: Assign resources before drivers claim devices (pci_scan_root_bus()) PCI: Fail pci_ioremap_bar() on unassigned resources ...
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/host-bridge.c20
-rw-r--r--drivers/pci/host/Kconfig19
-rw-r--r--drivers/pci/host/Makefile2
-rw-r--r--drivers/pci/host/pci-exynos.c2
-rw-r--r--drivers/pci/host/pci-keystone-dw.c3
-rw-r--r--drivers/pci/host/pci-layerscape.c9
-rw-r--r--drivers/pci/host/pci-mvebu.c38
-rw-r--r--drivers/pci/host/pci-rcar-gen2.c3
-rw-r--r--drivers/pci/host/pci-versatile.c13
-rw-r--r--drivers/pci/host/pcie-iproc-platform.c108
-rw-r--r--drivers/pci/host/pcie-iproc.c268
-rw-r--r--drivers/pci/host/pcie-iproc.h42
-rw-r--r--drivers/pci/host/pcie-rcar.c11
-rw-r--r--drivers/pci/hotplug/ibmphp_core.c8
-rw-r--r--drivers/pci/pci-acpi.c83
-rw-r--r--drivers/pci/pci-label.c11
-rw-r--r--drivers/pci/pci.c21
-rw-r--r--drivers/pci/pci.h2
-rw-r--r--drivers/pci/pcie/aspm.c18
-rw-r--r--drivers/pci/probe.c5
-rw-r--r--drivers/pci/quirks.c34
-rw-r--r--drivers/pci/remove.c2
-rw-r--r--drivers/pci/setup-bus.c1
-rw-r--r--drivers/pci/setup-irq.c1
-rw-r--r--drivers/pci/setup-res.c2
25 files changed, 664 insertions, 62 deletions
diff --git a/drivers/pci/host-bridge.c b/drivers/pci/host-bridge.c
index 39b2dbe585aa..5f4a2e04c8d7 100644
--- a/drivers/pci/host-bridge.c
+++ b/drivers/pci/host-bridge.c
@@ -16,13 +16,27 @@ static struct pci_bus *find_pci_root_bus(struct pci_bus *bus)
16 return bus; 16 return bus;
17} 17}
18 18
19static struct pci_host_bridge *find_pci_host_bridge(struct pci_bus *bus) 19struct pci_host_bridge *pci_find_host_bridge(struct pci_bus *bus)
20{ 20{
21 struct pci_bus *root_bus = find_pci_root_bus(bus); 21 struct pci_bus *root_bus = find_pci_root_bus(bus);
22 22
23 return to_pci_host_bridge(root_bus->bridge); 23 return to_pci_host_bridge(root_bus->bridge);
24} 24}
25 25
26struct device *pci_get_host_bridge_device(struct pci_dev *dev)
27{
28 struct pci_bus *root_bus = find_pci_root_bus(dev->bus);
29 struct device *bridge = root_bus->bridge;
30
31 kobject_get(&bridge->kobj);
32 return bridge;
33}
34
35void pci_put_host_bridge_device(struct device *dev)
36{
37 kobject_put(&dev->kobj);
38}
39
26void pci_set_host_bridge_release(struct pci_host_bridge *bridge, 40void pci_set_host_bridge_release(struct pci_host_bridge *bridge,
27 void (*release_fn)(struct pci_host_bridge *), 41 void (*release_fn)(struct pci_host_bridge *),
28 void *release_data) 42 void *release_data)
@@ -34,7 +48,7 @@ void pci_set_host_bridge_release(struct pci_host_bridge *bridge,
34void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region, 48void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region,
35 struct resource *res) 49 struct resource *res)
36{ 50{
37 struct pci_host_bridge *bridge = find_pci_host_bridge(bus); 51 struct pci_host_bridge *bridge = pci_find_host_bridge(bus);
38 struct resource_entry *window; 52 struct resource_entry *window;
39 resource_size_t offset = 0; 53 resource_size_t offset = 0;
40 54
@@ -59,7 +73,7 @@ static bool region_contains(struct pci_bus_region *region1,
59void pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res, 73void pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res,
60 struct pci_bus_region *region) 74 struct pci_bus_region *region)
61{ 75{
62 struct pci_host_bridge *bridge = find_pci_host_bridge(bus); 76 struct pci_host_bridge *bridge = pci_find_host_bridge(bus);
63 struct resource_entry *window; 77 struct resource_entry *window;
64 resource_size_t offset = 0; 78 resource_size_t offset = 0;
65 79
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 7b892a9cc4fc..1dfb567b3522 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -106,4 +106,23 @@ config PCI_VERSATILE
106 bool "ARM Versatile PB PCI controller" 106 bool "ARM Versatile PB PCI controller"
107 depends on ARCH_VERSATILE 107 depends on ARCH_VERSATILE
108 108
109config PCIE_IPROC
110 tristate "Broadcom iProc PCIe controller"
111 depends on OF && ARM
112 default n
113 help
114 This enables the iProc PCIe core controller support for Broadcom's
115 iProc family of SoCs. An appropriate bus interface driver also needs
116 to be enabled
117
118config PCIE_IPROC_PLATFORM
119 tristate "Broadcom iProc PCIe platform bus driver"
120 depends on ARCH_BCM_IPROC || (ARM && COMPILE_TEST)
121 depends on OF
122 select PCIE_IPROC
123 default ARCH_BCM_IPROC
124 help
125 Say Y here if you want to use the Broadcom iProc PCIe controller
126 through the generic platform bus interface
127
109endmenu 128endmenu
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index e61d91c92bf1..f733b4e27642 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -13,3 +13,5 @@ obj-$(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 14obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o
15obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o 15obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o
16obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o
17obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o
diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c
index d202b37c3698..c139237e0e52 100644
--- a/drivers/pci/host/pci-exynos.c
+++ b/drivers/pci/host/pci-exynos.c
@@ -396,7 +396,7 @@ static void exynos_pcie_enable_irq_pulse(struct pcie_port *pp)
396 396
397 /* enable INTX interrupt */ 397 /* enable INTX interrupt */
398 val = IRQ_INTA_ASSERT | IRQ_INTB_ASSERT | 398 val = IRQ_INTA_ASSERT | IRQ_INTB_ASSERT |
399 IRQ_INTC_ASSERT | IRQ_INTD_ASSERT, 399 IRQ_INTC_ASSERT | IRQ_INTD_ASSERT;
400 exynos_elb_writel(exynos_pcie, val, PCIE_IRQ_EN_PULSE); 400 exynos_elb_writel(exynos_pcie, val, PCIE_IRQ_EN_PULSE);
401} 401}
402 402
diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c
index 66d8ea41b972..f34892e0edb4 100644
--- a/drivers/pci/host/pci-keystone-dw.c
+++ b/drivers/pci/host/pci-keystone-dw.c
@@ -496,11 +496,12 @@ int __init ks_dw_pcie_host_init(struct keystone_pcie *ks_pcie,
496 496
497 /* Index 1 is the application reg. space address */ 497 /* Index 1 is the application reg. space address */
498 res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 498 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
499 ks_pcie->app = *res;
500 ks_pcie->va_app_base = devm_ioremap_resource(pp->dev, res); 499 ks_pcie->va_app_base = devm_ioremap_resource(pp->dev, res);
501 if (IS_ERR(ks_pcie->va_app_base)) 500 if (IS_ERR(ks_pcie->va_app_base))
502 return PTR_ERR(ks_pcie->va_app_base); 501 return PTR_ERR(ks_pcie->va_app_base);
503 502
503 ks_pcie->app = *res;
504
504 /* Create legacy IRQ domain */ 505 /* Create legacy IRQ domain */
505 ks_pcie->legacy_irq_domain = 506 ks_pcie->legacy_irq_domain =
506 irq_domain_add_linear(ks_pcie->legacy_intc_np, 507 irq_domain_add_linear(ks_pcie->legacy_intc_np,
diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c
index 68c9e5e9b0a8..4a6e62f67579 100644
--- a/drivers/pci/host/pci-layerscape.c
+++ b/drivers/pci/host/pci-layerscape.c
@@ -127,14 +127,11 @@ static int __init ls_pcie_probe(struct platform_device *pdev)
127 pcie->dev = &pdev->dev; 127 pcie->dev = &pdev->dev;
128 128
129 dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); 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); 130 pcie->dbi = devm_ioremap_resource(&pdev->dev, dbi_base);
136 if (IS_ERR(pcie->dbi)) 131 if (IS_ERR(pcie->dbi)) {
132 dev_err(&pdev->dev, "missing *regs* space\n");
137 return PTR_ERR(pcie->dbi); 133 return PTR_ERR(pcie->dbi);
134 }
138 135
139 pcie->scfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, 136 pcie->scfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
140 "fsl,pcie-scfg"); 137 "fsl,pcie-scfg");
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
index 1309cfbaa719..1ab863551920 100644
--- a/drivers/pci/host/pci-mvebu.c
+++ b/drivers/pci/host/pci-mvebu.c
@@ -129,6 +129,7 @@ struct mvebu_pcie_port {
129 size_t memwin_size; 129 size_t memwin_size;
130 phys_addr_t iowin_base; 130 phys_addr_t iowin_base;
131 size_t iowin_size; 131 size_t iowin_size;
132 u32 saved_pcie_stat;
132}; 133};
133 134
134static inline void mvebu_writel(struct mvebu_pcie_port *port, u32 val, u32 reg) 135static inline void mvebu_writel(struct mvebu_pcie_port *port, u32 val, u32 reg)
@@ -899,6 +900,35 @@ static void mvebu_pcie_msi_enable(struct mvebu_pcie *pcie)
899 pcie->msi->dev = &pcie->pdev->dev; 900 pcie->msi->dev = &pcie->pdev->dev;
900} 901}
901 902
903static int mvebu_pcie_suspend(struct device *dev)
904{
905 struct mvebu_pcie *pcie;
906 int i;
907
908 pcie = dev_get_drvdata(dev);
909 for (i = 0; i < pcie->nports; i++) {
910 struct mvebu_pcie_port *port = pcie->ports + i;
911 port->saved_pcie_stat = mvebu_readl(port, PCIE_STAT_OFF);
912 }
913
914 return 0;
915}
916
917static int mvebu_pcie_resume(struct device *dev)
918{
919 struct mvebu_pcie *pcie;
920 int i;
921
922 pcie = dev_get_drvdata(dev);
923 for (i = 0; i < pcie->nports; i++) {
924 struct mvebu_pcie_port *port = pcie->ports + i;
925 mvebu_writel(port, port->saved_pcie_stat, PCIE_STAT_OFF);
926 mvebu_pcie_setup_hw(port);
927 }
928
929 return 0;
930}
931
902static int mvebu_pcie_probe(struct platform_device *pdev) 932static int mvebu_pcie_probe(struct platform_device *pdev)
903{ 933{
904 struct mvebu_pcie *pcie; 934 struct mvebu_pcie *pcie;
@@ -1056,6 +1086,8 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
1056 mvebu_pcie_msi_enable(pcie); 1086 mvebu_pcie_msi_enable(pcie);
1057 mvebu_pcie_enable(pcie); 1087 mvebu_pcie_enable(pcie);
1058 1088
1089 platform_set_drvdata(pdev, pcie);
1090
1059 return 0; 1091 return 0;
1060} 1092}
1061 1093
@@ -1068,12 +1100,18 @@ static const struct of_device_id mvebu_pcie_of_match_table[] = {
1068}; 1100};
1069MODULE_DEVICE_TABLE(of, mvebu_pcie_of_match_table); 1101MODULE_DEVICE_TABLE(of, mvebu_pcie_of_match_table);
1070 1102
1103static struct dev_pm_ops mvebu_pcie_pm_ops = {
1104 .suspend_noirq = mvebu_pcie_suspend,
1105 .resume_noirq = mvebu_pcie_resume,
1106};
1107
1071static struct platform_driver mvebu_pcie_driver = { 1108static struct platform_driver mvebu_pcie_driver = {
1072 .driver = { 1109 .driver = {
1073 .name = "mvebu-pcie", 1110 .name = "mvebu-pcie",
1074 .of_match_table = mvebu_pcie_of_match_table, 1111 .of_match_table = mvebu_pcie_of_match_table,
1075 /* driver unloading/unbinding currently not supported */ 1112 /* driver unloading/unbinding currently not supported */
1076 .suppress_bind_attrs = true, 1113 .suppress_bind_attrs = true,
1114 .pm = &mvebu_pcie_pm_ops,
1077 }, 1115 },
1078 .probe = mvebu_pcie_probe, 1116 .probe = mvebu_pcie_probe,
1079}; 1117};
diff --git a/drivers/pci/host/pci-rcar-gen2.c b/drivers/pci/host/pci-rcar-gen2.c
index dd6b84e6206c..367e28fa7564 100644
--- a/drivers/pci/host/pci-rcar-gen2.c
+++ b/drivers/pci/host/pci-rcar-gen2.c
@@ -301,6 +301,9 @@ static int rcar_pci_probe(struct platform_device *pdev)
301 if (!mem_res || !mem_res->start) 301 if (!mem_res || !mem_res->start)
302 return -ENODEV; 302 return -ENODEV;
303 303
304 if (mem_res->start & 0xFFFF)
305 return -EINVAL;
306
304 priv = devm_kzalloc(&pdev->dev, 307 priv = devm_kzalloc(&pdev->dev,
305 sizeof(struct rcar_pci_priv), GFP_KERNEL); 308 sizeof(struct rcar_pci_priv), GFP_KERNEL);
306 if (!priv) 309 if (!priv)
diff --git a/drivers/pci/host/pci-versatile.c b/drivers/pci/host/pci-versatile.c
index 464bf492ee2a..0863d9cc25f8 100644
--- a/drivers/pci/host/pci-versatile.c
+++ b/drivers/pci/host/pci-versatile.c
@@ -138,19 +138,19 @@ static int versatile_pci_probe(struct platform_device *pdev)
138 LIST_HEAD(pci_res); 138 LIST_HEAD(pci_res);
139 139
140 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 140 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
141 if (!res)
142 return -ENODEV;
143 versatile_pci_base = devm_ioremap_resource(&pdev->dev, res); 141 versatile_pci_base = devm_ioremap_resource(&pdev->dev, res);
142 if (IS_ERR(versatile_pci_base))
143 return PTR_ERR(versatile_pci_base);
144 144
145 res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 145 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
146 if (!res)
147 return -ENODEV;
148 versatile_cfg_base[0] = devm_ioremap_resource(&pdev->dev, res); 146 versatile_cfg_base[0] = devm_ioremap_resource(&pdev->dev, res);
147 if (IS_ERR(versatile_cfg_base[0]))
148 return PTR_ERR(versatile_cfg_base[0]);
149 149
150 res = platform_get_resource(pdev, IORESOURCE_MEM, 2); 150 res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
151 if (!res)
152 return -ENODEV;
153 versatile_cfg_base[1] = devm_ioremap_resource(&pdev->dev, res); 151 versatile_cfg_base[1] = devm_ioremap_resource(&pdev->dev, res);
152 if (IS_ERR(versatile_cfg_base[1]))
153 return PTR_ERR(versatile_cfg_base[1]);
154 154
155 ret = versatile_pci_parse_request_of_pci_ranges(&pdev->dev, &pci_res); 155 ret = versatile_pci_parse_request_of_pci_ranges(&pdev->dev, &pci_res);
156 if (ret) 156 if (ret)
@@ -214,6 +214,7 @@ static int versatile_pci_probe(struct platform_device *pdev)
214 214
215 pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci); 215 pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
216 pci_assign_unassigned_bus_resources(bus); 216 pci_assign_unassigned_bus_resources(bus);
217 pci_bus_add_devices(bus);
217 218
218 return 0; 219 return 0;
219} 220}
diff --git a/drivers/pci/host/pcie-iproc-platform.c b/drivers/pci/host/pcie-iproc-platform.c
new file mode 100644
index 000000000000..afad6c21fcfa
--- /dev/null
+++ b/drivers/pci/host/pcie-iproc-platform.c
@@ -0,0 +1,108 @@
1/*
2 * Copyright (C) 2015 Broadcom Corporation
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation version 2.
7 *
8 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
9 * kind, whether express or implied; without even the implied warranty
10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <linux/kernel.h>
15#include <linux/pci.h>
16#include <linux/clk.h>
17#include <linux/module.h>
18#include <linux/slab.h>
19#include <linux/interrupt.h>
20#include <linux/platform_device.h>
21#include <linux/of_address.h>
22#include <linux/of_pci.h>
23#include <linux/of_irq.h>
24#include <linux/of_platform.h>
25#include <linux/phy/phy.h>
26
27#include "pcie-iproc.h"
28
29static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
30{
31 struct iproc_pcie *pcie;
32 struct device_node *np = pdev->dev.of_node;
33 struct resource reg;
34 resource_size_t iobase = 0;
35 LIST_HEAD(res);
36 int ret;
37
38 pcie = devm_kzalloc(&pdev->dev, sizeof(struct iproc_pcie), GFP_KERNEL);
39 if (!pcie)
40 return -ENOMEM;
41
42 pcie->dev = &pdev->dev;
43 platform_set_drvdata(pdev, pcie);
44
45 ret = of_address_to_resource(np, 0, &reg);
46 if (ret < 0) {
47 dev_err(pcie->dev, "unable to obtain controller resources\n");
48 return ret;
49 }
50
51 pcie->base = devm_ioremap(pcie->dev, reg.start, resource_size(&reg));
52 if (!pcie->base) {
53 dev_err(pcie->dev, "unable to map controller registers\n");
54 return -ENOMEM;
55 }
56
57 /* PHY use is optional */
58 pcie->phy = devm_phy_get(&pdev->dev, "pcie-phy");
59 if (IS_ERR(pcie->phy)) {
60 if (PTR_ERR(pcie->phy) == -EPROBE_DEFER)
61 return -EPROBE_DEFER;
62 pcie->phy = NULL;
63 }
64
65 ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &iobase);
66 if (ret) {
67 dev_err(pcie->dev,
68 "unable to get PCI host bridge resources\n");
69 return ret;
70 }
71
72 pcie->resources = &res;
73
74 ret = iproc_pcie_setup(pcie);
75 if (ret) {
76 dev_err(pcie->dev, "PCIe controller setup failed\n");
77 return ret;
78 }
79
80 return 0;
81}
82
83static int iproc_pcie_pltfm_remove(struct platform_device *pdev)
84{
85 struct iproc_pcie *pcie = platform_get_drvdata(pdev);
86
87 return iproc_pcie_remove(pcie);
88}
89
90static const struct of_device_id iproc_pcie_of_match_table[] = {
91 { .compatible = "brcm,iproc-pcie", },
92 { /* sentinel */ }
93};
94MODULE_DEVICE_TABLE(of, iproc_pcie_of_match_table);
95
96static struct platform_driver iproc_pcie_pltfm_driver = {
97 .driver = {
98 .name = "iproc-pcie",
99 .of_match_table = of_match_ptr(iproc_pcie_of_match_table),
100 },
101 .probe = iproc_pcie_pltfm_probe,
102 .remove = iproc_pcie_pltfm_remove,
103};
104module_platform_driver(iproc_pcie_pltfm_driver);
105
106MODULE_AUTHOR("Ray Jui <rjui@broadcom.com>");
107MODULE_DESCRIPTION("Broadcom iPROC PCIe platform driver");
108MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/host/pcie-iproc.c b/drivers/pci/host/pcie-iproc.c
new file mode 100644
index 000000000000..329e1b54528b
--- /dev/null
+++ b/drivers/pci/host/pcie-iproc.c
@@ -0,0 +1,268 @@
1/*
2 * Copyright (C) 2014 Hauke Mehrtens <hauke@hauke-m.de>
3 * Copyright (C) 2015 Broadcom Corporatcommon ion
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation version 2.
8 *
9 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
10 * kind, whether express or implied; without even the implied warranty
11 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include <linux/kernel.h>
16#include <linux/pci.h>
17#include <linux/msi.h>
18#include <linux/clk.h>
19#include <linux/module.h>
20#include <linux/mbus.h>
21#include <linux/slab.h>
22#include <linux/delay.h>
23#include <linux/interrupt.h>
24#include <linux/platform_device.h>
25#include <linux/of_address.h>
26#include <linux/of_pci.h>
27#include <linux/of_irq.h>
28#include <linux/of_platform.h>
29#include <linux/phy/phy.h>
30
31#include "pcie-iproc.h"
32
33#define CLK_CONTROL_OFFSET 0x000
34#define EP_MODE_SURVIVE_PERST_SHIFT 1
35#define EP_MODE_SURVIVE_PERST BIT(EP_MODE_SURVIVE_PERST_SHIFT)
36#define RC_PCIE_RST_OUTPUT_SHIFT 0
37#define RC_PCIE_RST_OUTPUT BIT(RC_PCIE_RST_OUTPUT_SHIFT)
38
39#define CFG_IND_ADDR_OFFSET 0x120
40#define CFG_IND_ADDR_MASK 0x00001ffc
41
42#define CFG_IND_DATA_OFFSET 0x124
43
44#define CFG_ADDR_OFFSET 0x1f8
45#define CFG_ADDR_BUS_NUM_SHIFT 20
46#define CFG_ADDR_BUS_NUM_MASK 0x0ff00000
47#define CFG_ADDR_DEV_NUM_SHIFT 15
48#define CFG_ADDR_DEV_NUM_MASK 0x000f8000
49#define CFG_ADDR_FUNC_NUM_SHIFT 12
50#define CFG_ADDR_FUNC_NUM_MASK 0x00007000
51#define CFG_ADDR_REG_NUM_SHIFT 2
52#define CFG_ADDR_REG_NUM_MASK 0x00000ffc
53#define CFG_ADDR_CFG_TYPE_SHIFT 0
54#define CFG_ADDR_CFG_TYPE_MASK 0x00000003
55
56#define CFG_DATA_OFFSET 0x1fc
57
58#define SYS_RC_INTX_EN 0x330
59#define SYS_RC_INTX_MASK 0xf
60
61static inline struct iproc_pcie *sys_to_pcie(struct pci_sys_data *sys)
62{
63 return sys->private_data;
64}
65
66/**
67 * Note access to the configuration registers are protected at the higher layer
68 * by 'pci_lock' in drivers/pci/access.c
69 */
70static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus,
71 unsigned int devfn,
72 int where)
73{
74 struct pci_sys_data *sys = bus->sysdata;
75 struct iproc_pcie *pcie = sys_to_pcie(sys);
76 unsigned slot = PCI_SLOT(devfn);
77 unsigned fn = PCI_FUNC(devfn);
78 unsigned busno = bus->number;
79 u32 val;
80
81 /* root complex access */
82 if (busno == 0) {
83 if (slot >= 1)
84 return NULL;
85 writel(where & CFG_IND_ADDR_MASK,
86 pcie->base + CFG_IND_ADDR_OFFSET);
87 return (pcie->base + CFG_IND_DATA_OFFSET);
88 }
89
90 if (fn > 1)
91 return NULL;
92
93 /* EP device access */
94 val = (busno << CFG_ADDR_BUS_NUM_SHIFT) |
95 (slot << CFG_ADDR_DEV_NUM_SHIFT) |
96 (fn << CFG_ADDR_FUNC_NUM_SHIFT) |
97 (where & CFG_ADDR_REG_NUM_MASK) |
98 (1 & CFG_ADDR_CFG_TYPE_MASK);
99 writel(val, pcie->base + CFG_ADDR_OFFSET);
100
101 return (pcie->base + CFG_DATA_OFFSET);
102}
103
104static struct pci_ops iproc_pcie_ops = {
105 .map_bus = iproc_pcie_map_cfg_bus,
106 .read = pci_generic_config_read32,
107 .write = pci_generic_config_write32,
108};
109
110static void iproc_pcie_reset(struct iproc_pcie *pcie)
111{
112 u32 val;
113
114 /*
115 * Configure the PCIe controller as root complex and send a downstream
116 * reset
117 */
118 val = EP_MODE_SURVIVE_PERST | RC_PCIE_RST_OUTPUT;
119 writel(val, pcie->base + CLK_CONTROL_OFFSET);
120 udelay(250);
121 val &= ~EP_MODE_SURVIVE_PERST;
122 writel(val, pcie->base + CLK_CONTROL_OFFSET);
123 msleep(250);
124}
125
126static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus)
127{
128 u8 hdr_type;
129 u32 link_ctrl;
130 u16 pos, link_status;
131 int link_is_active = 0;
132
133 /* make sure we are not in EP mode */
134 pci_bus_read_config_byte(bus, 0, PCI_HEADER_TYPE, &hdr_type);
135 if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE) {
136 dev_err(pcie->dev, "in EP mode, hdr=%#02x\n", hdr_type);
137 return -EFAULT;
138 }
139
140 /* force class to PCI_CLASS_BRIDGE_PCI (0x0604) */
141 pci_bus_write_config_word(bus, 0, PCI_CLASS_DEVICE,
142 PCI_CLASS_BRIDGE_PCI);
143
144 /* check link status to see if link is active */
145 pos = pci_bus_find_capability(bus, 0, PCI_CAP_ID_EXP);
146 pci_bus_read_config_word(bus, 0, pos + PCI_EXP_LNKSTA, &link_status);
147 if (link_status & PCI_EXP_LNKSTA_NLW)
148 link_is_active = 1;
149
150 if (!link_is_active) {
151 /* try GEN 1 link speed */
152#define PCI_LINK_STATUS_CTRL_2_OFFSET 0x0dc
153#define PCI_TARGET_LINK_SPEED_MASK 0xf
154#define PCI_TARGET_LINK_SPEED_GEN2 0x2
155#define PCI_TARGET_LINK_SPEED_GEN1 0x1
156 pci_bus_read_config_dword(bus, 0,
157 PCI_LINK_STATUS_CTRL_2_OFFSET,
158 &link_ctrl);
159 if ((link_ctrl & PCI_TARGET_LINK_SPEED_MASK) ==
160 PCI_TARGET_LINK_SPEED_GEN2) {
161 link_ctrl &= ~PCI_TARGET_LINK_SPEED_MASK;
162 link_ctrl |= PCI_TARGET_LINK_SPEED_GEN1;
163 pci_bus_write_config_dword(bus, 0,
164 PCI_LINK_STATUS_CTRL_2_OFFSET,
165 link_ctrl);
166 msleep(100);
167
168 pos = pci_bus_find_capability(bus, 0, PCI_CAP_ID_EXP);
169 pci_bus_read_config_word(bus, 0, pos + PCI_EXP_LNKSTA,
170 &link_status);
171 if (link_status & PCI_EXP_LNKSTA_NLW)
172 link_is_active = 1;
173 }
174 }
175
176 dev_info(pcie->dev, "link: %s\n", link_is_active ? "UP" : "DOWN");
177
178 return link_is_active ? 0 : -ENODEV;
179}
180
181static void iproc_pcie_enable(struct iproc_pcie *pcie)
182{
183 writel(SYS_RC_INTX_MASK, pcie->base + SYS_RC_INTX_EN);
184}
185
186int iproc_pcie_setup(struct iproc_pcie *pcie)
187{
188 int ret;
189 struct pci_bus *bus;
190
191 if (!pcie || !pcie->dev || !pcie->base)
192 return -EINVAL;
193
194 if (pcie->phy) {
195 ret = phy_init(pcie->phy);
196 if (ret) {
197 dev_err(pcie->dev, "unable to initialize PCIe PHY\n");
198 return ret;
199 }
200
201 ret = phy_power_on(pcie->phy);
202 if (ret) {
203 dev_err(pcie->dev, "unable to power on PCIe PHY\n");
204 goto err_exit_phy;
205 }
206
207 }
208
209 iproc_pcie_reset(pcie);
210
211 pcie->sysdata.private_data = pcie;
212
213 bus = pci_create_root_bus(pcie->dev, 0, &iproc_pcie_ops,
214 &pcie->sysdata, pcie->resources);
215 if (!bus) {
216 dev_err(pcie->dev, "unable to create PCI root bus\n");
217 ret = -ENOMEM;
218 goto err_power_off_phy;
219 }
220 pcie->root_bus = bus;
221
222 ret = iproc_pcie_check_link(pcie, bus);
223 if (ret) {
224 dev_err(pcie->dev, "no PCIe EP device detected\n");
225 goto err_rm_root_bus;
226 }
227
228 iproc_pcie_enable(pcie);
229
230 pci_scan_child_bus(bus);
231 pci_assign_unassigned_bus_resources(bus);
232 pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
233 pci_bus_add_devices(bus);
234
235 return 0;
236
237err_rm_root_bus:
238 pci_stop_root_bus(bus);
239 pci_remove_root_bus(bus);
240
241err_power_off_phy:
242 if (pcie->phy)
243 phy_power_off(pcie->phy);
244err_exit_phy:
245 if (pcie->phy)
246 phy_exit(pcie->phy);
247
248 return ret;
249}
250EXPORT_SYMBOL(iproc_pcie_setup);
251
252int iproc_pcie_remove(struct iproc_pcie *pcie)
253{
254 pci_stop_root_bus(pcie->root_bus);
255 pci_remove_root_bus(pcie->root_bus);
256
257 if (pcie->phy) {
258 phy_power_off(pcie->phy);
259 phy_exit(pcie->phy);
260 }
261
262 return 0;
263}
264EXPORT_SYMBOL(iproc_pcie_remove);
265
266MODULE_AUTHOR("Ray Jui <rjui@broadcom.com>");
267MODULE_DESCRIPTION("Broadcom iPROC PCIe common driver");
268MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/host/pcie-iproc.h b/drivers/pci/host/pcie-iproc.h
new file mode 100644
index 000000000000..e28075ed1856
--- /dev/null
+++ b/drivers/pci/host/pcie-iproc.h
@@ -0,0 +1,42 @@
1/*
2 * Copyright (C) 2014-2015 Broadcom Corporation
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation version 2.
7 *
8 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
9 * kind, whether express or implied; without even the implied warranty
10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#ifndef _PCIE_IPROC_H
15#define _PCIE_IPROC_H
16
17#define IPROC_PCIE_MAX_NUM_IRQS 6
18
19/**
20 * iProc PCIe device
21 * @dev: pointer to device data structure
22 * @base: PCIe host controller I/O register base
23 * @resources: linked list of all PCI resources
24 * @sysdata: Per PCI controller data
25 * @root_bus: pointer to root bus
26 * @phy: optional PHY device that controls the Serdes
27 * @irqs: interrupt IDs
28 */
29struct iproc_pcie {
30 struct device *dev;
31 void __iomem *base;
32 struct list_head *resources;
33 struct pci_sys_data sysdata;
34 struct pci_bus *root_bus;
35 struct phy *phy;
36 int irqs[IPROC_PCIE_MAX_NUM_IRQS];
37};
38
39int iproc_pcie_setup(struct iproc_pcie *pcie);
40int iproc_pcie_remove(struct iproc_pcie *pcie);
41
42#endif /* _PCIE_IPROC_H */
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
index c57bd0ac39a0..c086210f2ffd 100644
--- a/drivers/pci/host/pcie-rcar.c
+++ b/drivers/pci/host/pcie-rcar.c
@@ -64,8 +64,8 @@
64#define LAR_ENABLE (1 << 1) 64#define LAR_ENABLE (1 << 1)
65 65
66/* PCIe address reg & mask */ 66/* PCIe address reg & mask */
67#define PCIEPARL(x) (0x03400 + ((x) * 0x20)) 67#define PCIEPALR(x) (0x03400 + ((x) * 0x20))
68#define PCIEPARH(x) (0x03404 + ((x) * 0x20)) 68#define PCIEPAUR(x) (0x03404 + ((x) * 0x20))
69#define PCIEPAMR(x) (0x03408 + ((x) * 0x20)) 69#define PCIEPAMR(x) (0x03408 + ((x) * 0x20))
70#define PCIEPTCTLR(x) (0x0340c + ((x) * 0x20)) 70#define PCIEPTCTLR(x) (0x0340c + ((x) * 0x20))
71#define PAR_ENABLE (1 << 31) 71#define PAR_ENABLE (1 << 31)
@@ -341,8 +341,9 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie)
341 else 341 else
342 res_start = res->start; 342 res_start = res->start;
343 343
344 rcar_pci_write_reg(pcie, upper_32_bits(res_start), PCIEPARH(win)); 344 rcar_pci_write_reg(pcie, upper_32_bits(res_start), PCIEPAUR(win));
345 rcar_pci_write_reg(pcie, lower_32_bits(res_start), PCIEPARL(win)); 345 rcar_pci_write_reg(pcie, lower_32_bits(res_start) & ~0x7F,
346 PCIEPALR(win));
346 347
347 /* First resource is for IO */ 348 /* First resource is for IO */
348 mask = PAR_ENABLE; 349 mask = PAR_ENABLE;
@@ -501,7 +502,7 @@ static int rcar_pcie_hw_init(struct rcar_pcie *pcie)
501 502
502 /* Enable MSI */ 503 /* Enable MSI */
503 if (IS_ENABLED(CONFIG_PCI_MSI)) 504 if (IS_ENABLED(CONFIG_PCI_MSI))
504 rcar_pci_write_reg(pcie, 0x101f0000, PCIEMSITXR); 505 rcar_pci_write_reg(pcie, 0x801f0000, PCIEMSITXR);
505 506
506 /* Finish initialization - establish a PCI Express link */ 507 /* Finish initialization - establish a PCI Express link */
507 rcar_pci_write_reg(pcie, CFINIT, PCIETCTLR); 508 rcar_pci_write_reg(pcie, CFINIT, PCIETCTLR);
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
index 96c5c729cdbc..15302475f5b7 100644
--- a/drivers/pci/hotplug/ibmphp_core.c
+++ b/drivers/pci/hotplug/ibmphp_core.c
@@ -738,7 +738,7 @@ static void ibm_unconfigure_device(struct pci_func *func)
738 */ 738 */
739static u8 bus_structure_fixup(u8 busno) 739static u8 bus_structure_fixup(u8 busno)
740{ 740{
741 struct pci_bus *bus; 741 struct pci_bus *bus, *b;
742 struct pci_dev *dev; 742 struct pci_dev *dev;
743 u16 l; 743 u16 l;
744 744
@@ -765,7 +765,11 @@ static u8 bus_structure_fixup(u8 busno)
765 (l != 0x0000) && (l != 0xffff)) { 765 (l != 0x0000) && (l != 0xffff)) {
766 debug("%s - Inside bus_structure_fixup()\n", 766 debug("%s - Inside bus_structure_fixup()\n",
767 __func__); 767 __func__);
768 pci_scan_bus(busno, ibmphp_pci_bus->ops, NULL); 768 b = pci_scan_bus(busno, ibmphp_pci_bus->ops, NULL);
769 if (!b)
770 continue;
771
772 pci_bus_add_devices(b);
769 break; 773 break;
770 } 774 }
771 } 775 }
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index c93fbe76d281..6f6f175f51f7 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -18,6 +18,15 @@
18#include <linux/pm_qos.h> 18#include <linux/pm_qos.h>
19#include "pci.h" 19#include "pci.h"
20 20
21/*
22 * The UUID is defined in the PCI Firmware Specification available here:
23 * https://www.pcisig.com/members/downloads/pcifw_r3_1_13Dec10.pdf
24 */
25const u8 pci_acpi_dsm_uuid[] = {
26 0xd0, 0x37, 0xc9, 0xe5, 0x53, 0x35, 0x7a, 0x4d,
27 0x91, 0x17, 0xea, 0x4d, 0x19, 0xc3, 0x43, 0x4d
28};
29
21phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle) 30phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle)
22{ 31{
23 acpi_status status = AE_NOT_EXIST; 32 acpi_status status = AE_NOT_EXIST;
@@ -531,11 +540,32 @@ static struct pci_platform_pm_ops acpi_pci_platform_pm = {
531 540
532void acpi_pci_add_bus(struct pci_bus *bus) 541void acpi_pci_add_bus(struct pci_bus *bus)
533{ 542{
543 union acpi_object *obj;
544 struct pci_host_bridge *bridge;
545
534 if (acpi_pci_disabled || !bus->bridge) 546 if (acpi_pci_disabled || !bus->bridge)
535 return; 547 return;
536 548
537 acpi_pci_slot_enumerate(bus); 549 acpi_pci_slot_enumerate(bus);
538 acpiphp_enumerate_slots(bus); 550 acpiphp_enumerate_slots(bus);
551
552 /*
553 * For a host bridge, check its _DSM for function 8 and if
554 * that is available, mark it in pci_host_bridge.
555 */
556 if (!pci_is_root_bus(bus))
557 return;
558
559 obj = acpi_evaluate_dsm(ACPI_HANDLE(bus->bridge), pci_acpi_dsm_uuid, 3,
560 RESET_DELAY_DSM, NULL);
561 if (!obj)
562 return;
563
564 if (obj->type == ACPI_TYPE_INTEGER && obj->integer.value == 1) {
565 bridge = pci_find_host_bridge(bus);
566 bridge->ignore_reset_delay = 1;
567 }
568 ACPI_FREE(obj);
539} 569}
540 570
541void acpi_pci_remove_bus(struct pci_bus *bus) 571void acpi_pci_remove_bus(struct pci_bus *bus)
@@ -561,6 +591,57 @@ static struct acpi_device *acpi_pci_find_companion(struct device *dev)
561 check_children); 591 check_children);
562} 592}
563 593
594/**
595 * pci_acpi_optimize_delay - optimize PCI D3 and D3cold delay from ACPI
596 * @pdev: the PCI device whose delay is to be updated
597 * @adev: the companion ACPI device of this PCI device
598 *
599 * Update the d3_delay and d3cold_delay of a PCI device from the ACPI _DSM
600 * control method of either the device itself or the PCI host bridge.
601 *
602 * Function 8, "Reset Delay," applies to the entire hierarchy below a PCI
603 * host bridge. If it returns one, the OS may assume that all devices in
604 * the hierarchy have already completed power-on reset delays.
605 *
606 * Function 9, "Device Readiness Durations," applies only to the object
607 * where it is located. It returns delay durations required after various
608 * events if the device requires less time than the spec requires. Delays
609 * from this function take precedence over the Reset Delay function.
610 *
611 * These _DSM functions are defined by the draft ECN of January 28, 2014,
612 * titled "ACPI additions for FW latency optimizations."
613 */
614static void pci_acpi_optimize_delay(struct pci_dev *pdev,
615 acpi_handle handle)
616{
617 struct pci_host_bridge *bridge = pci_find_host_bridge(pdev->bus);
618 int value;
619 union acpi_object *obj, *elements;
620
621 if (bridge->ignore_reset_delay)
622 pdev->d3cold_delay = 0;
623
624 obj = acpi_evaluate_dsm(handle, pci_acpi_dsm_uuid, 3,
625 FUNCTION_DELAY_DSM, NULL);
626 if (!obj)
627 return;
628
629 if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 5) {
630 elements = obj->package.elements;
631 if (elements[0].type == ACPI_TYPE_INTEGER) {
632 value = (int)elements[0].integer.value / 1000;
633 if (value < PCI_PM_D3COLD_WAIT)
634 pdev->d3cold_delay = value;
635 }
636 if (elements[3].type == ACPI_TYPE_INTEGER) {
637 value = (int)elements[3].integer.value / 1000;
638 if (value < PCI_PM_D3_WAIT)
639 pdev->d3_delay = value;
640 }
641 }
642 ACPI_FREE(obj);
643}
644
564static void pci_acpi_setup(struct device *dev) 645static void pci_acpi_setup(struct device *dev)
565{ 646{
566 struct pci_dev *pci_dev = to_pci_dev(dev); 647 struct pci_dev *pci_dev = to_pci_dev(dev);
@@ -569,6 +650,8 @@ static void pci_acpi_setup(struct device *dev)
569 if (!adev) 650 if (!adev)
570 return; 651 return;
571 652
653 pci_acpi_optimize_delay(pci_dev, adev->handle);
654
572 pci_acpi_add_pm_notifier(adev, pci_dev); 655 pci_acpi_add_pm_notifier(adev, pci_dev);
573 if (!adev->wakeup.flags.valid) 656 if (!adev->wakeup.flags.valid)
574 return; 657 return;
diff --git a/drivers/pci/pci-label.c b/drivers/pci/pci-label.c
index 2ab1b47c7651..024b5c179348 100644
--- a/drivers/pci/pci-label.c
+++ b/drivers/pci/pci-label.c
@@ -31,8 +31,6 @@
31#include <linux/pci-acpi.h> 31#include <linux/pci-acpi.h>
32#include "pci.h" 32#include "pci.h"
33 33
34#define DEVICE_LABEL_DSM 0x07
35
36#ifdef CONFIG_DMI 34#ifdef CONFIG_DMI
37enum smbios_attr_enum { 35enum smbios_attr_enum {
38 SMBIOS_ATTR_NONE = 0, 36 SMBIOS_ATTR_NONE = 0,
@@ -148,11 +146,6 @@ static inline void pci_remove_smbiosname_file(struct pci_dev *pdev)
148#endif 146#endif
149 147
150#ifdef CONFIG_ACPI 148#ifdef CONFIG_ACPI
151static const char device_label_dsm_uuid[] = {
152 0xD0, 0x37, 0xC9, 0xE5, 0x53, 0x35, 0x7A, 0x4D,
153 0x91, 0x17, 0xEA, 0x4D, 0x19, 0xC3, 0x43, 0x4D
154};
155
156enum acpi_attr_enum { 149enum acpi_attr_enum {
157 ACPI_ATTR_LABEL_SHOW, 150 ACPI_ATTR_LABEL_SHOW,
158 ACPI_ATTR_INDEX_SHOW, 151 ACPI_ATTR_INDEX_SHOW,
@@ -179,7 +172,7 @@ static int dsm_get_label(struct device *dev, char *buf,
179 if (!handle) 172 if (!handle)
180 return -1; 173 return -1;
181 174
182 obj = acpi_evaluate_dsm(handle, device_label_dsm_uuid, 0x2, 175 obj = acpi_evaluate_dsm(handle, pci_acpi_dsm_uuid, 0x2,
183 DEVICE_LABEL_DSM, NULL); 176 DEVICE_LABEL_DSM, NULL);
184 if (!obj) 177 if (!obj)
185 return -1; 178 return -1;
@@ -219,7 +212,7 @@ static bool device_has_dsm(struct device *dev)
219 if (!handle) 212 if (!handle)
220 return false; 213 return false;
221 214
222 return !!acpi_check_dsm(handle, device_label_dsm_uuid, 0x2, 215 return !!acpi_check_dsm(handle, pci_acpi_dsm_uuid, 0x2,
223 1 << DEVICE_LABEL_DSM); 216 1 << DEVICE_LABEL_DSM);
224} 217}
225 218
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 81f06e8dcc04..acc4b6ef78c4 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -126,15 +126,16 @@ EXPORT_SYMBOL_GPL(pci_bus_max_busnr);
126#ifdef CONFIG_HAS_IOMEM 126#ifdef CONFIG_HAS_IOMEM
127void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar) 127void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar)
128{ 128{
129 struct resource *res = &pdev->resource[bar];
130
129 /* 131 /*
130 * Make sure the BAR is actually a memory resource, not an IO resource 132 * Make sure the BAR is actually a memory resource, not an IO resource
131 */ 133 */
132 if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) { 134 if (res->flags & IORESOURCE_UNSET || !(res->flags & IORESOURCE_MEM)) {
133 WARN_ON(1); 135 dev_warn(&pdev->dev, "can't ioremap BAR %d: %pR\n", bar, res);
134 return NULL; 136 return NULL;
135 } 137 }
136 return ioremap_nocache(pci_resource_start(pdev, bar), 138 return ioremap_nocache(res->start, resource_size(res));
137 pci_resource_len(pdev, bar));
138} 139}
139EXPORT_SYMBOL_GPL(pci_ioremap_bar); 140EXPORT_SYMBOL_GPL(pci_ioremap_bar);
140#endif 141#endif
@@ -145,19 +146,22 @@ static int __pci_find_next_cap_ttl(struct pci_bus *bus, unsigned int devfn,
145 u8 pos, int cap, int *ttl) 146 u8 pos, int cap, int *ttl)
146{ 147{
147 u8 id; 148 u8 id;
149 u16 ent;
150
151 pci_bus_read_config_byte(bus, devfn, pos, &pos);
148 152
149 while ((*ttl)--) { 153 while ((*ttl)--) {
150 pci_bus_read_config_byte(bus, devfn, pos, &pos);
151 if (pos < 0x40) 154 if (pos < 0x40)
152 break; 155 break;
153 pos &= ~3; 156 pos &= ~3;
154 pci_bus_read_config_byte(bus, devfn, pos + PCI_CAP_LIST_ID, 157 pci_bus_read_config_word(bus, devfn, pos, &ent);
155 &id); 158
159 id = ent & 0xff;
156 if (id == 0xff) 160 if (id == 0xff)
157 break; 161 break;
158 if (id == cap) 162 if (id == cap)
159 return pos; 163 return pos;
160 pos += PCI_CAP_LIST_NEXT; 164 pos = (ent >> 8);
161 } 165 }
162 return 0; 166 return 0;
163} 167}
@@ -2492,6 +2496,7 @@ u8 pci_common_swizzle(struct pci_dev *dev, u8 *pinp)
2492 *pinp = pin; 2496 *pinp = pin;
2493 return PCI_SLOT(dev->devfn); 2497 return PCI_SLOT(dev->devfn);
2494} 2498}
2499EXPORT_SYMBOL_GPL(pci_common_swizzle);
2495 2500
2496/** 2501/**
2497 * pci_release_region - Release a PCI bar 2502 * pci_release_region - Release a PCI bar
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 4091f82239cd..d72f849174a4 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -321,4 +321,6 @@ static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe)
321} 321}
322#endif 322#endif
323 323
324struct pci_host_bridge *pci_find_host_bridge(struct pci_bus *bus);
325
324#endif /* DRIVERS_PCI_H */ 326#endif /* DRIVERS_PCI_H */
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 820740a22e94..7d4fcdc512aa 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -782,24 +782,6 @@ void pci_disable_link_state(struct pci_dev *pdev, int state)
782} 782}
783EXPORT_SYMBOL(pci_disable_link_state); 783EXPORT_SYMBOL(pci_disable_link_state);
784 784
785void pcie_clear_aspm(struct pci_bus *bus)
786{
787 struct pci_dev *child;
788
789 if (aspm_force)
790 return;
791
792 /*
793 * Clear any ASPM setup that the firmware has carried out on this bus
794 */
795 list_for_each_entry(child, &bus->devices, bus_list) {
796 __pci_disable_link_state(child, PCIE_LINK_STATE_L0S |
797 PCIE_LINK_STATE_L1 |
798 PCIE_LINK_STATE_CLKPM,
799 false, true);
800 }
801}
802
803static int pcie_aspm_set_policy(const char *val, struct kernel_param *kp) 785static int pcie_aspm_set_policy(const char *val, struct kernel_param *kp)
804{ 786{
805 int i; 787 int i;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 8d2f400e96cb..6675a7a1b9fc 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -6,6 +6,7 @@
6#include <linux/delay.h> 6#include <linux/delay.h>
7#include <linux/init.h> 7#include <linux/init.h>
8#include <linux/pci.h> 8#include <linux/pci.h>
9#include <linux/of_pci.h>
9#include <linux/pci_hotplug.h> 10#include <linux/pci_hotplug.h>
10#include <linux/slab.h> 11#include <linux/slab.h>
11#include <linux/module.h> 12#include <linux/module.h>
@@ -1520,6 +1521,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
1520 dev->dev.dma_mask = &dev->dma_mask; 1521 dev->dev.dma_mask = &dev->dma_mask;
1521 dev->dev.dma_parms = &dev->dma_parms; 1522 dev->dev.dma_parms = &dev->dma_parms;
1522 dev->dev.coherent_dma_mask = 0xffffffffull; 1523 dev->dev.coherent_dma_mask = 0xffffffffull;
1524 of_pci_dma_configure(dev);
1523 1525
1524 pci_set_dma_max_seg_size(dev, 65536); 1526 pci_set_dma_max_seg_size(dev, 65536);
1525 pci_set_dma_seg_boundary(dev, 0xffffffff); 1527 pci_set_dma_seg_boundary(dev, 0xffffffff);
@@ -1993,6 +1995,7 @@ err_out:
1993 kfree(b); 1995 kfree(b);
1994 return NULL; 1996 return NULL;
1995} 1997}
1998EXPORT_SYMBOL_GPL(pci_create_root_bus);
1996 1999
1997int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max) 2000int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max)
1998{ 2001{
@@ -2087,7 +2090,6 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
2087 if (!found) 2090 if (!found)
2088 pci_bus_update_busn_res_end(b, max); 2091 pci_bus_update_busn_res_end(b, max);
2089 2092
2090 pci_bus_add_devices(b);
2091 return b; 2093 return b;
2092} 2094}
2093EXPORT_SYMBOL(pci_scan_root_bus); 2095EXPORT_SYMBOL(pci_scan_root_bus);
@@ -2123,7 +2125,6 @@ struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops,
2123 b = pci_create_root_bus(NULL, bus, ops, sysdata, &resources); 2125 b = pci_create_root_bus(NULL, bus, ops, sysdata, &resources);
2124 if (b) { 2126 if (b) {
2125 pci_scan_child_bus(b); 2127 pci_scan_child_bus(b);
2126 pci_bus_add_devices(b);
2127 } else { 2128 } else {
2128 pci_free_resource_list(&resources); 2129 pci_free_resource_list(&resources);
2129 } 2130 }
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 85f247e28a80..c6dc1dfd25d5 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3182,7 +3182,7 @@ static void quirk_apple_wait_for_thunderbolt(struct pci_dev *dev)
3182 || nhi->subsystem_vendor != 0x2222 3182 || nhi->subsystem_vendor != 0x2222
3183 || nhi->subsystem_device != 0x1111) 3183 || nhi->subsystem_device != 0x1111)
3184 goto out; 3184 goto out;
3185 dev_info(&dev->dev, "quirk: wating for thunderbolt to reestablish pci tunnels...\n"); 3185 dev_info(&dev->dev, "quirk: waiting for thunderbolt to reestablish PCI tunnels...\n");
3186 device_pm_wait_for_dev(&dev->dev, &nhi->dev); 3186 device_pm_wait_for_dev(&dev->dev, &nhi->dev);
3187out: 3187out:
3188 pci_dev_put(nhi); 3188 pci_dev_put(nhi);
@@ -3822,6 +3822,38 @@ static const struct pci_dev_acs_enabled {
3822 { PCI_VENDOR_ID_INTEL, 0x154F, pci_quirk_mf_endpoint_acs }, 3822 { PCI_VENDOR_ID_INTEL, 0x154F, pci_quirk_mf_endpoint_acs },
3823 { PCI_VENDOR_ID_INTEL, 0x1551, pci_quirk_mf_endpoint_acs }, 3823 { PCI_VENDOR_ID_INTEL, 0x1551, pci_quirk_mf_endpoint_acs },
3824 { PCI_VENDOR_ID_INTEL, 0x1558, pci_quirk_mf_endpoint_acs }, 3824 { PCI_VENDOR_ID_INTEL, 0x1558, pci_quirk_mf_endpoint_acs },
3825 /* 82580 */
3826 { PCI_VENDOR_ID_INTEL, 0x1509, pci_quirk_mf_endpoint_acs },
3827 { PCI_VENDOR_ID_INTEL, 0x150E, pci_quirk_mf_endpoint_acs },
3828 { PCI_VENDOR_ID_INTEL, 0x150F, pci_quirk_mf_endpoint_acs },
3829 { PCI_VENDOR_ID_INTEL, 0x1510, pci_quirk_mf_endpoint_acs },
3830 { PCI_VENDOR_ID_INTEL, 0x1511, pci_quirk_mf_endpoint_acs },
3831 { PCI_VENDOR_ID_INTEL, 0x1516, pci_quirk_mf_endpoint_acs },
3832 { PCI_VENDOR_ID_INTEL, 0x1527, pci_quirk_mf_endpoint_acs },
3833 /* 82576 */
3834 { PCI_VENDOR_ID_INTEL, 0x10C9, pci_quirk_mf_endpoint_acs },
3835 { PCI_VENDOR_ID_INTEL, 0x10E6, pci_quirk_mf_endpoint_acs },
3836 { PCI_VENDOR_ID_INTEL, 0x10E7, pci_quirk_mf_endpoint_acs },
3837 { PCI_VENDOR_ID_INTEL, 0x10E8, pci_quirk_mf_endpoint_acs },
3838 { PCI_VENDOR_ID_INTEL, 0x150A, pci_quirk_mf_endpoint_acs },
3839 { PCI_VENDOR_ID_INTEL, 0x150D, pci_quirk_mf_endpoint_acs },
3840 { PCI_VENDOR_ID_INTEL, 0x1518, pci_quirk_mf_endpoint_acs },
3841 { PCI_VENDOR_ID_INTEL, 0x1526, pci_quirk_mf_endpoint_acs },
3842 /* 82575 */
3843 { PCI_VENDOR_ID_INTEL, 0x10A7, pci_quirk_mf_endpoint_acs },
3844 { PCI_VENDOR_ID_INTEL, 0x10A9, pci_quirk_mf_endpoint_acs },
3845 { PCI_VENDOR_ID_INTEL, 0x10D6, pci_quirk_mf_endpoint_acs },
3846 /* I350 */
3847 { PCI_VENDOR_ID_INTEL, 0x1521, pci_quirk_mf_endpoint_acs },
3848 { PCI_VENDOR_ID_INTEL, 0x1522, pci_quirk_mf_endpoint_acs },
3849 { PCI_VENDOR_ID_INTEL, 0x1523, pci_quirk_mf_endpoint_acs },
3850 { PCI_VENDOR_ID_INTEL, 0x1524, pci_quirk_mf_endpoint_acs },
3851 /* 82571 (Quads omitted due to non-ACS switch) */
3852 { PCI_VENDOR_ID_INTEL, 0x105E, pci_quirk_mf_endpoint_acs },
3853 { PCI_VENDOR_ID_INTEL, 0x105F, pci_quirk_mf_endpoint_acs },
3854 { PCI_VENDOR_ID_INTEL, 0x1060, pci_quirk_mf_endpoint_acs },
3855 { PCI_VENDOR_ID_INTEL, 0x10D9, pci_quirk_mf_endpoint_acs },
3856 /* Intel PCH root ports */
3825 { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs }, 3857 { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs },
3826 { 0x19a2, 0x710, pci_quirk_mf_endpoint_acs }, /* Emulex BE3-R */ 3858 { 0x19a2, 0x710, pci_quirk_mf_endpoint_acs }, /* Emulex BE3-R */
3827 { 0x10df, 0x720, pci_quirk_mf_endpoint_acs }, /* Emulex Skyhawk-R */ 3859 { 0x10df, 0x720, pci_quirk_mf_endpoint_acs }, /* Emulex Skyhawk-R */
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index 8bd76c9ba21c..8a280e9c2ad1 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -139,6 +139,7 @@ void pci_stop_root_bus(struct pci_bus *bus)
139 /* stop the host bridge */ 139 /* stop the host bridge */
140 device_release_driver(&host_bridge->dev); 140 device_release_driver(&host_bridge->dev);
141} 141}
142EXPORT_SYMBOL_GPL(pci_stop_root_bus);
142 143
143void pci_remove_root_bus(struct pci_bus *bus) 144void pci_remove_root_bus(struct pci_bus *bus)
144{ 145{
@@ -158,3 +159,4 @@ void pci_remove_root_bus(struct pci_bus *bus)
158 /* remove the host bridge */ 159 /* remove the host bridge */
159 device_unregister(&host_bridge->dev); 160 device_unregister(&host_bridge->dev);
160} 161}
162EXPORT_SYMBOL_GPL(pci_remove_root_bus);
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index e3e17f3c0f0f..8169597e47cb 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1750,3 +1750,4 @@ void pci_assign_unassigned_bus_resources(struct pci_bus *bus)
1750 __pci_bus_assign_resources(bus, &add_list, NULL); 1750 __pci_bus_assign_resources(bus, &add_list, NULL);
1751 BUG_ON(!list_empty(&add_list)); 1751 BUG_ON(!list_empty(&add_list));
1752} 1752}
1753EXPORT_SYMBOL_GPL(pci_assign_unassigned_bus_resources);
diff --git a/drivers/pci/setup-irq.c b/drivers/pci/setup-irq.c
index 4e2d595d50ca..95c225be49d1 100644
--- a/drivers/pci/setup-irq.c
+++ b/drivers/pci/setup-irq.c
@@ -65,3 +65,4 @@ void pci_fixup_irqs(u8 (*swizzle)(struct pci_dev *, u8 *),
65 for_each_pci_dev(dev) 65 for_each_pci_dev(dev)
66 pdev_fixup_irq(dev, swizzle, map_irq); 66 pdev_fixup_irq(dev, swizzle, map_irq);
67} 67}
68EXPORT_SYMBOL_GPL(pci_fixup_irqs);
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index b7c3a5ea1fca..232f9254c11a 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -120,6 +120,7 @@ int pci_claim_resource(struct pci_dev *dev, int resource)
120 if (!root) { 120 if (!root) {
121 dev_info(&dev->dev, "can't claim BAR %d %pR: no compatible bridge window\n", 121 dev_info(&dev->dev, "can't claim BAR %d %pR: no compatible bridge window\n",
122 resource, res); 122 resource, res);
123 res->flags |= IORESOURCE_UNSET;
123 return -EINVAL; 124 return -EINVAL;
124 } 125 }
125 126
@@ -127,6 +128,7 @@ int pci_claim_resource(struct pci_dev *dev, int resource)
127 if (conflict) { 128 if (conflict) {
128 dev_info(&dev->dev, "can't claim BAR %d %pR: address conflict with %s %pR\n", 129 dev_info(&dev->dev, "can't claim BAR %d %pR: address conflict with %s %pR\n",
129 resource, res, conflict->name, conflict); 130 resource, res, conflict->name, conflict);
131 res->flags |= IORESOURCE_UNSET;
130 return -EBUSY; 132 return -EBUSY;
131 } 133 }
132 134