diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-10 17:31:28 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-10 17:31:28 -0500 |
commit | c08f8467939e7d2eebcba7cf2330242c4f53f2f7 (patch) | |
tree | 3430b9acdac374da5fda10d913b52f608494894c /drivers/pci | |
parent | bdccc4edeb03ad68c55053b0260bdaaac547bbd9 (diff) | |
parent | cb8e92d8e4d9f8562071b6ab39e1b837e9e7af39 (diff) |
Merge tag 'pci-v3.20-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI changes from Bjorn Helgaas:
"Enumeration
- Move domain assignment from arm64 to generic code (Lorenzo Pieralisi)
- ARM: Remove artificial dependency on pci_sys_data domain (Lorenzo Pieralisi)
- ARM: Move to generic PCI domains (Lorenzo Pieralisi)
- Generate uppercase hex for modalias var in uevent (Ricardo Ribalda Delgado)
- Add and use generic config accessors on ARM, PowerPC (Rob Herring)
Resource management
- Free resources on failure in of_pci_get_host_bridge_resources() (Lorenzo Pieralisi)
- Fix infinite loop with ROM image of size 0 (Michel Dänzer)
PCI device hotplug
- Handle surprise add even if surprise removal isn't supported (Bjorn Helgaas)
Virtualization
- Mark AMD/ATI VGA devices that don't reset on D3hot->D0 transition (Alex Williamson)
- Add DMA alias quirk for Adaptec 3405 (Alex Williamson)
- Add Wellsburg (X99) to Intel PCH root port ACS quirk (Alex Williamson)
- Add ACS quirk for Emulex NICs (Vasundhara Volam)
MSI
- Fail MSI-X mappings if there's no space assigned to MSI-X BAR (Yijing Wang)
Freescale Layerscape host bridge driver
- Fix platform_no_drv_owner.cocci warnings (Julia Lawall)
NVIDIA Tegra host bridge driver
- Remove unnecessary tegra_pcie_fixup_bridge() (Lucas Stach)
Renesas R-Car host bridge driver
- Fix error handling of irq_of_parse_and_map() (Dmitry Torokhov)
TI Keystone host bridge driver
- Fix error handling of irq_of_parse_and_map() (Dmitry Torokhov)
- Fix misspelling of current function in debug output (Julia Lawall)
Xilinx AXI host bridge driver
- Fix harmless format string warning (Arnd Bergmann)
Miscellaneous
- Use standard parsing functions for ASPM sysfs setters (Chris J Arges)
- Add pci_device_to_OF_node() stub for !CONFIG_OF (Kevin Hao)
- Delete unnecessary NULL pointer checks (Markus Elfring)
- Add and use defines for PCIe Max_Read_Request_Size (Rafał Miłecki)
- Include clk.h instead of clk-private.h (Stephen Boyd)"
* tag 'pci-v3.20-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (48 commits)
PCI: Add pci_device_to_OF_node() stub for !CONFIG_OF
PCI: xilinx: Convert to use generic config accessors
PCI: xgene: Convert to use generic config accessors
PCI: tegra: Convert to use generic config accessors
PCI: rcar: Convert to use generic config accessors
PCI: generic: Convert to use generic config accessors
powerpc/powermac: Convert PCI to use generic config accessors
powerpc/fsl_pci: Convert PCI to use generic config accessors
ARM: ks8695: Convert PCI to use generic config accessors
ARM: sa1100: Convert PCI to use generic config accessors
ARM: integrator: Convert PCI to use generic config accessors
PCI: versatile: Add DT-based ARM Versatile PB PCIe host driver
ARM: dts: versatile: add PCI controller binding
of/pci: Free resources on failure in of_pci_get_host_bridge_resources()
PCI: versatile: Add DT docs for ARM Versatile PB PCIe driver
PCI: Fail MSI-X mappings if there's no space assigned to MSI-X BAR
r8169: use PCI define for Max_Read_Request_Size
[SCSI] esas2r: use PCI define for Max_Read_Request_Size
tile: use PCI define for Max_Read_Request_Size
rapidio/tsi721: use PCI define for Max_Read_Request_Size
...
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/access.c | 87 | ||||
-rw-r--r-- | drivers/pci/host/Kconfig | 4 | ||||
-rw-r--r-- | drivers/pci/host/Makefile | 1 | ||||
-rw-r--r-- | drivers/pci/host/pci-host-generic.c | 51 | ||||
-rw-r--r-- | drivers/pci/host/pci-keystone.c | 4 | ||||
-rw-r--r-- | drivers/pci/host/pci-layerscape.c | 1 | ||||
-rw-r--r-- | drivers/pci/host/pci-mvebu.c | 15 | ||||
-rw-r--r-- | drivers/pci/host/pci-rcar-gen2.c | 51 | ||||
-rw-r--r-- | drivers/pci/host/pci-tegra.c | 68 | ||||
-rw-r--r-- | drivers/pci/host/pci-versatile.c | 237 | ||||
-rw-r--r-- | drivers/pci/host/pci-xgene.c | 152 | ||||
-rw-r--r-- | drivers/pci/host/pcie-designware.c | 3 | ||||
-rw-r--r-- | drivers/pci/host/pcie-rcar.c | 7 | ||||
-rw-r--r-- | drivers/pci/host/pcie-xilinx.c | 92 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpci_hotplug_core.c | 3 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_ctrl.c | 2 | ||||
-rw-r--r-- | drivers/pci/msi.c | 5 | ||||
-rw-r--r-- | drivers/pci/pci-driver.c | 2 | ||||
-rw-r--r-- | drivers/pci/pci.c | 51 | ||||
-rw-r--r-- | drivers/pci/pcie/aspm.c | 12 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 64 | ||||
-rw-r--r-- | drivers/pci/rom.c | 7 |
22 files changed, 497 insertions, 422 deletions
diff --git a/drivers/pci/access.c b/drivers/pci/access.c index 49dd766852ba..d9b64a175990 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c | |||
@@ -67,6 +67,93 @@ EXPORT_SYMBOL(pci_bus_write_config_byte); | |||
67 | EXPORT_SYMBOL(pci_bus_write_config_word); | 67 | EXPORT_SYMBOL(pci_bus_write_config_word); |
68 | EXPORT_SYMBOL(pci_bus_write_config_dword); | 68 | EXPORT_SYMBOL(pci_bus_write_config_dword); |
69 | 69 | ||
70 | int pci_generic_config_read(struct pci_bus *bus, unsigned int devfn, | ||
71 | int where, int size, u32 *val) | ||
72 | { | ||
73 | void __iomem *addr; | ||
74 | |||
75 | addr = bus->ops->map_bus(bus, devfn, where); | ||
76 | if (!addr) { | ||
77 | *val = ~0; | ||
78 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
79 | } | ||
80 | |||
81 | if (size == 1) | ||
82 | *val = readb(addr); | ||
83 | else if (size == 2) | ||
84 | *val = readw(addr); | ||
85 | else | ||
86 | *val = readl(addr); | ||
87 | |||
88 | return PCIBIOS_SUCCESSFUL; | ||
89 | } | ||
90 | EXPORT_SYMBOL_GPL(pci_generic_config_read); | ||
91 | |||
92 | int pci_generic_config_write(struct pci_bus *bus, unsigned int devfn, | ||
93 | int where, int size, u32 val) | ||
94 | { | ||
95 | void __iomem *addr; | ||
96 | |||
97 | addr = bus->ops->map_bus(bus, devfn, where); | ||
98 | if (!addr) | ||
99 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
100 | |||
101 | if (size == 1) | ||
102 | writeb(val, addr); | ||
103 | else if (size == 2) | ||
104 | writew(val, addr); | ||
105 | else | ||
106 | writel(val, addr); | ||
107 | |||
108 | return PCIBIOS_SUCCESSFUL; | ||
109 | } | ||
110 | EXPORT_SYMBOL_GPL(pci_generic_config_write); | ||
111 | |||
112 | int pci_generic_config_read32(struct pci_bus *bus, unsigned int devfn, | ||
113 | int where, int size, u32 *val) | ||
114 | { | ||
115 | void __iomem *addr; | ||
116 | |||
117 | addr = bus->ops->map_bus(bus, devfn, where & ~0x3); | ||
118 | if (!addr) { | ||
119 | *val = ~0; | ||
120 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
121 | } | ||
122 | |||
123 | *val = readl(addr); | ||
124 | |||
125 | if (size <= 2) | ||
126 | *val = (*val >> (8 * (where & 3))) & ((1 << (size * 8)) - 1); | ||
127 | |||
128 | return PCIBIOS_SUCCESSFUL; | ||
129 | } | ||
130 | EXPORT_SYMBOL_GPL(pci_generic_config_read32); | ||
131 | |||
132 | int pci_generic_config_write32(struct pci_bus *bus, unsigned int devfn, | ||
133 | int where, int size, u32 val) | ||
134 | { | ||
135 | void __iomem *addr; | ||
136 | u32 mask, tmp; | ||
137 | |||
138 | addr = bus->ops->map_bus(bus, devfn, where & ~0x3); | ||
139 | if (!addr) | ||
140 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
141 | |||
142 | if (size == 4) { | ||
143 | writel(val, addr); | ||
144 | return PCIBIOS_SUCCESSFUL; | ||
145 | } else { | ||
146 | mask = ~(((1 << (size * 8)) - 1) << ((where & 0x3) * 8)); | ||
147 | } | ||
148 | |||
149 | tmp = readl(addr) & mask; | ||
150 | tmp |= val << ((where & 0x3) * 8); | ||
151 | writel(tmp, addr); | ||
152 | |||
153 | return PCIBIOS_SUCCESSFUL; | ||
154 | } | ||
155 | EXPORT_SYMBOL_GPL(pci_generic_config_write32); | ||
156 | |||
70 | /** | 157 | /** |
71 | * pci_bus_set_ops - Set raw operations of pci bus | 158 | * pci_bus_set_ops - Set raw operations of pci bus |
72 | * @bus: pci bus struct | 159 | * @bus: pci bus struct |
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index c4b6568e486d..7b892a9cc4fc 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig | |||
@@ -102,4 +102,8 @@ config PCI_LAYERSCAPE | |||
102 | help | 102 | help |
103 | Say Y here if you want PCIe controller support on Layerscape SoCs. | 103 | Say Y here if you want PCIe controller support on Layerscape SoCs. |
104 | 104 | ||
105 | config PCI_VERSATILE | ||
106 | bool "ARM Versatile PB PCI controller" | ||
107 | depends on ARCH_VERSATILE | ||
108 | |||
105 | endmenu | 109 | endmenu |
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index 44c26998027f..e61d91c92bf1 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile | |||
@@ -12,3 +12,4 @@ 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 | 14 | obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o |
15 | obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o | ||
diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c index 6eb1aa75bd37..925e29e3d4c8 100644 --- a/drivers/pci/host/pci-host-generic.c +++ b/drivers/pci/host/pci-host-generic.c | |||
@@ -76,55 +76,9 @@ static struct gen_pci_cfg_bus_ops gen_pci_cfg_ecam_bus_ops = { | |||
76 | .map_bus = gen_pci_map_cfg_bus_ecam, | 76 | .map_bus = gen_pci_map_cfg_bus_ecam, |
77 | }; | 77 | }; |
78 | 78 | ||
79 | static int gen_pci_config_read(struct pci_bus *bus, unsigned int devfn, | ||
80 | int where, int size, u32 *val) | ||
81 | { | ||
82 | void __iomem *addr; | ||
83 | struct pci_sys_data *sys = bus->sysdata; | ||
84 | struct gen_pci *pci = sys->private_data; | ||
85 | |||
86 | addr = pci->cfg.ops->map_bus(bus, devfn, where); | ||
87 | |||
88 | switch (size) { | ||
89 | case 1: | ||
90 | *val = readb(addr); | ||
91 | break; | ||
92 | case 2: | ||
93 | *val = readw(addr); | ||
94 | break; | ||
95 | default: | ||
96 | *val = readl(addr); | ||
97 | } | ||
98 | |||
99 | return PCIBIOS_SUCCESSFUL; | ||
100 | } | ||
101 | |||
102 | static int gen_pci_config_write(struct pci_bus *bus, unsigned int devfn, | ||
103 | int where, int size, u32 val) | ||
104 | { | ||
105 | void __iomem *addr; | ||
106 | struct pci_sys_data *sys = bus->sysdata; | ||
107 | struct gen_pci *pci = sys->private_data; | ||
108 | |||
109 | addr = pci->cfg.ops->map_bus(bus, devfn, where); | ||
110 | |||
111 | switch (size) { | ||
112 | case 1: | ||
113 | writeb(val, addr); | ||
114 | break; | ||
115 | case 2: | ||
116 | writew(val, addr); | ||
117 | break; | ||
118 | default: | ||
119 | writel(val, addr); | ||
120 | } | ||
121 | |||
122 | return PCIBIOS_SUCCESSFUL; | ||
123 | } | ||
124 | |||
125 | static struct pci_ops gen_pci_ops = { | 79 | static struct pci_ops gen_pci_ops = { |
126 | .read = gen_pci_config_read, | 80 | .read = pci_generic_config_read, |
127 | .write = gen_pci_config_write, | 81 | .write = pci_generic_config_write, |
128 | }; | 82 | }; |
129 | 83 | ||
130 | static const struct of_device_id gen_pci_of_match[] = { | 84 | static const struct of_device_id gen_pci_of_match[] = { |
@@ -287,6 +241,7 @@ static int gen_pci_probe(struct platform_device *pdev) | |||
287 | 241 | ||
288 | of_id = of_match_node(gen_pci_of_match, np); | 242 | of_id = of_match_node(gen_pci_of_match, np); |
289 | pci->cfg.ops = of_id->data; | 243 | pci->cfg.ops = of_id->data; |
244 | gen_pci_ops.map_bus = pci->cfg.ops->map_bus; | ||
290 | pci->host.dev.parent = dev; | 245 | pci->host.dev.parent = dev; |
291 | INIT_LIST_HEAD(&pci->host.windows); | 246 | INIT_LIST_HEAD(&pci->host.windows); |
292 | INIT_LIST_HEAD(&pci->resources); | 247 | INIT_LIST_HEAD(&pci->resources); |
diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c index 78f79e31ac5c..75333b0c4f0a 100644 --- a/drivers/pci/host/pci-keystone.c +++ b/drivers/pci/host/pci-keystone.c | |||
@@ -119,7 +119,7 @@ static void ks_pcie_msi_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
119 | struct pcie_port *pp = &ks_pcie->pp; | 119 | struct pcie_port *pp = &ks_pcie->pp; |
120 | struct irq_chip *chip = irq_desc_get_chip(desc); | 120 | struct irq_chip *chip = irq_desc_get_chip(desc); |
121 | 121 | ||
122 | dev_dbg(pp->dev, "ks_pci_msi_irq_handler, irq %d\n", irq); | 122 | dev_dbg(pp->dev, "%s, irq %d\n", __func__, irq); |
123 | 123 | ||
124 | /* | 124 | /* |
125 | * The chained irq handler installation would have replaced normal | 125 | * The chained irq handler installation would have replaced normal |
@@ -197,7 +197,7 @@ static int ks_pcie_get_irq_controller_info(struct keystone_pcie *ks_pcie, | |||
197 | */ | 197 | */ |
198 | for (temp = 0; temp < max_host_irqs; temp++) { | 198 | for (temp = 0; temp < max_host_irqs; temp++) { |
199 | host_irqs[temp] = irq_of_parse_and_map(*np_temp, temp); | 199 | host_irqs[temp] = irq_of_parse_and_map(*np_temp, temp); |
200 | if (host_irqs[temp] < 0) | 200 | if (!host_irqs[temp]) |
201 | break; | 201 | break; |
202 | } | 202 | } |
203 | if (temp) { | 203 | if (temp) { |
diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c index 6697b1a4d4fa..68c9e5e9b0a8 100644 --- a/drivers/pci/host/pci-layerscape.c +++ b/drivers/pci/host/pci-layerscape.c | |||
@@ -167,7 +167,6 @@ MODULE_DEVICE_TABLE(of, ls_pcie_of_match); | |||
167 | static struct platform_driver ls_pcie_driver = { | 167 | static struct platform_driver ls_pcie_driver = { |
168 | .driver = { | 168 | .driver = { |
169 | .name = "layerscape-pcie", | 169 | .name = "layerscape-pcie", |
170 | .owner = THIS_MODULE, | ||
171 | .of_match_table = ls_pcie_of_match, | 170 | .of_match_table = ls_pcie_of_match, |
172 | }, | 171 | }, |
173 | }; | 172 | }; |
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index 1dd759596b0a..1309cfbaa719 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c | |||
@@ -101,9 +101,7 @@ struct mvebu_pcie { | |||
101 | struct mvebu_pcie_port *ports; | 101 | struct mvebu_pcie_port *ports; |
102 | struct msi_controller *msi; | 102 | struct msi_controller *msi; |
103 | struct resource io; | 103 | struct resource io; |
104 | char io_name[30]; | ||
105 | struct resource realio; | 104 | struct resource realio; |
106 | char mem_name[30]; | ||
107 | struct resource mem; | 105 | struct resource mem; |
108 | struct resource busn; | 106 | struct resource busn; |
109 | int nports; | 107 | int nports; |
@@ -723,18 +721,9 @@ static int mvebu_pcie_setup(int nr, struct pci_sys_data *sys) | |||
723 | { | 721 | { |
724 | struct mvebu_pcie *pcie = sys_to_pcie(sys); | 722 | struct mvebu_pcie *pcie = sys_to_pcie(sys); |
725 | int i; | 723 | int i; |
726 | int domain = 0; | ||
727 | 724 | ||
728 | #ifdef CONFIG_PCI_DOMAINS | 725 | pcie->mem.name = "PCI MEM"; |
729 | domain = sys->domain; | 726 | pcie->realio.name = "PCI I/O"; |
730 | #endif | ||
731 | |||
732 | snprintf(pcie->mem_name, sizeof(pcie->mem_name), "PCI MEM %04x", | ||
733 | domain); | ||
734 | pcie->mem.name = pcie->mem_name; | ||
735 | |||
736 | snprintf(pcie->io_name, sizeof(pcie->io_name), "PCI I/O %04x", domain); | ||
737 | pcie->realio.name = pcie->io_name; | ||
738 | 727 | ||
739 | if (request_resource(&iomem_resource, &pcie->mem)) | 728 | if (request_resource(&iomem_resource, &pcie->mem)) |
740 | return 0; | 729 | return 0; |
diff --git a/drivers/pci/host/pci-rcar-gen2.c b/drivers/pci/host/pci-rcar-gen2.c index d9c042febb1a..dd6b84e6206c 100644 --- a/drivers/pci/host/pci-rcar-gen2.c +++ b/drivers/pci/host/pci-rcar-gen2.c | |||
@@ -131,52 +131,6 @@ static void __iomem *rcar_pci_cfg_base(struct pci_bus *bus, unsigned int devfn, | |||
131 | return priv->reg + (slot >> 1) * 0x100 + where; | 131 | return priv->reg + (slot >> 1) * 0x100 + where; |
132 | } | 132 | } |
133 | 133 | ||
134 | static int rcar_pci_read_config(struct pci_bus *bus, unsigned int devfn, | ||
135 | int where, int size, u32 *val) | ||
136 | { | ||
137 | void __iomem *reg = rcar_pci_cfg_base(bus, devfn, where); | ||
138 | |||
139 | if (!reg) | ||
140 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
141 | |||
142 | switch (size) { | ||
143 | case 1: | ||
144 | *val = ioread8(reg); | ||
145 | break; | ||
146 | case 2: | ||
147 | *val = ioread16(reg); | ||
148 | break; | ||
149 | default: | ||
150 | *val = ioread32(reg); | ||
151 | break; | ||
152 | } | ||
153 | |||
154 | return PCIBIOS_SUCCESSFUL; | ||
155 | } | ||
156 | |||
157 | static int rcar_pci_write_config(struct pci_bus *bus, unsigned int devfn, | ||
158 | int where, int size, u32 val) | ||
159 | { | ||
160 | void __iomem *reg = rcar_pci_cfg_base(bus, devfn, where); | ||
161 | |||
162 | if (!reg) | ||
163 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
164 | |||
165 | switch (size) { | ||
166 | case 1: | ||
167 | iowrite8(val, reg); | ||
168 | break; | ||
169 | case 2: | ||
170 | iowrite16(val, reg); | ||
171 | break; | ||
172 | default: | ||
173 | iowrite32(val, reg); | ||
174 | break; | ||
175 | } | ||
176 | |||
177 | return PCIBIOS_SUCCESSFUL; | ||
178 | } | ||
179 | |||
180 | /* PCI interrupt mapping */ | 134 | /* PCI interrupt mapping */ |
181 | static int rcar_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | 135 | static int rcar_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) |
182 | { | 136 | { |
@@ -325,8 +279,9 @@ static int rcar_pci_setup(int nr, struct pci_sys_data *sys) | |||
325 | } | 279 | } |
326 | 280 | ||
327 | static struct pci_ops rcar_pci_ops = { | 281 | static struct pci_ops rcar_pci_ops = { |
328 | .read = rcar_pci_read_config, | 282 | .map_bus = rcar_pci_cfg_base, |
329 | .write = rcar_pci_write_config, | 283 | .read = pci_generic_config_read, |
284 | .write = pci_generic_config_write, | ||
330 | }; | 285 | }; |
331 | 286 | ||
332 | static int rcar_pci_probe(struct platform_device *pdev) | 287 | static int rcar_pci_probe(struct platform_device *pdev) |
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index a800ae916394..00e92720d7f7 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c | |||
@@ -480,59 +480,10 @@ static void __iomem *tegra_pcie_conf_address(struct pci_bus *bus, | |||
480 | return addr; | 480 | return addr; |
481 | } | 481 | } |
482 | 482 | ||
483 | static int tegra_pcie_read_conf(struct pci_bus *bus, unsigned int devfn, | ||
484 | int where, int size, u32 *value) | ||
485 | { | ||
486 | void __iomem *addr; | ||
487 | |||
488 | addr = tegra_pcie_conf_address(bus, devfn, where); | ||
489 | if (!addr) { | ||
490 | *value = 0xffffffff; | ||
491 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
492 | } | ||
493 | |||
494 | *value = readl(addr); | ||
495 | |||
496 | if (size == 1) | ||
497 | *value = (*value >> (8 * (where & 3))) & 0xff; | ||
498 | else if (size == 2) | ||
499 | *value = (*value >> (8 * (where & 3))) & 0xffff; | ||
500 | |||
501 | return PCIBIOS_SUCCESSFUL; | ||
502 | } | ||
503 | |||
504 | static int tegra_pcie_write_conf(struct pci_bus *bus, unsigned int devfn, | ||
505 | int where, int size, u32 value) | ||
506 | { | ||
507 | void __iomem *addr; | ||
508 | u32 mask, tmp; | ||
509 | |||
510 | addr = tegra_pcie_conf_address(bus, devfn, where); | ||
511 | if (!addr) | ||
512 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
513 | |||
514 | if (size == 4) { | ||
515 | writel(value, addr); | ||
516 | return PCIBIOS_SUCCESSFUL; | ||
517 | } | ||
518 | |||
519 | if (size == 2) | ||
520 | mask = ~(0xffff << ((where & 0x3) * 8)); | ||
521 | else if (size == 1) | ||
522 | mask = ~(0xff << ((where & 0x3) * 8)); | ||
523 | else | ||
524 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
525 | |||
526 | tmp = readl(addr) & mask; | ||
527 | tmp |= value << ((where & 0x3) * 8); | ||
528 | writel(tmp, addr); | ||
529 | |||
530 | return PCIBIOS_SUCCESSFUL; | ||
531 | } | ||
532 | |||
533 | static struct pci_ops tegra_pcie_ops = { | 483 | static struct pci_ops tegra_pcie_ops = { |
534 | .read = tegra_pcie_read_conf, | 484 | .map_bus = tegra_pcie_conf_address, |
535 | .write = tegra_pcie_write_conf, | 485 | .read = pci_generic_config_read32, |
486 | .write = pci_generic_config_write32, | ||
536 | }; | 487 | }; |
537 | 488 | ||
538 | static unsigned long tegra_pcie_port_get_pex_ctrl(struct tegra_pcie_port *port) | 489 | static unsigned long tegra_pcie_port_get_pex_ctrl(struct tegra_pcie_port *port) |
@@ -625,19 +576,6 @@ static void tegra_pcie_port_free(struct tegra_pcie_port *port) | |||
625 | devm_kfree(pcie->dev, port); | 576 | devm_kfree(pcie->dev, port); |
626 | } | 577 | } |
627 | 578 | ||
628 | static void tegra_pcie_fixup_bridge(struct pci_dev *dev) | ||
629 | { | ||
630 | u16 reg; | ||
631 | |||
632 | if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) { | ||
633 | pci_read_config_word(dev, PCI_COMMAND, ®); | ||
634 | reg |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | | ||
635 | PCI_COMMAND_MASTER | PCI_COMMAND_SERR); | ||
636 | pci_write_config_word(dev, PCI_COMMAND, reg); | ||
637 | } | ||
638 | } | ||
639 | DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_fixup_bridge); | ||
640 | |||
641 | /* Tegra PCIE root complex wrongly reports device class */ | 579 | /* Tegra PCIE root complex wrongly reports device class */ |
642 | static void tegra_pcie_fixup_class(struct pci_dev *dev) | 580 | static void tegra_pcie_fixup_class(struct pci_dev *dev) |
643 | { | 581 | { |
diff --git a/drivers/pci/host/pci-versatile.c b/drivers/pci/host/pci-versatile.c new file mode 100644 index 000000000000..341529ca23e8 --- /dev/null +++ b/drivers/pci/host/pci-versatile.c | |||
@@ -0,0 +1,237 @@ | |||
1 | /* | ||
2 | * Copyright 2004 Koninklijke Philips Electronics NV | ||
3 | * | ||
4 | * Conversion to platform driver and DT: | ||
5 | * Copyright 2014 Linaro Ltd. | ||
6 | * | ||
7 | * This software is licensed under the terms of the GNU General Public | ||
8 | * License version 2, as published by the Free Software Foundation, and | ||
9 | * may be copied, distributed, and modified under those terms. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * 14/04/2005 Initial version, colin.king@philips.com | ||
17 | */ | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/of_address.h> | ||
21 | #include <linux/of_pci.h> | ||
22 | #include <linux/of_platform.h> | ||
23 | #include <linux/pci.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | |||
26 | static void __iomem *versatile_pci_base; | ||
27 | static void __iomem *versatile_cfg_base[2]; | ||
28 | |||
29 | #define PCI_IMAP(m) (versatile_pci_base + ((m) * 4)) | ||
30 | #define PCI_SMAP(m) (versatile_pci_base + 0x14 + ((m) * 4)) | ||
31 | #define PCI_SELFID (versatile_pci_base + 0xc) | ||
32 | |||
33 | #define VP_PCI_DEVICE_ID 0x030010ee | ||
34 | #define VP_PCI_CLASS_ID 0x0b400000 | ||
35 | |||
36 | static u32 pci_slot_ignore; | ||
37 | |||
38 | static int __init versatile_pci_slot_ignore(char *str) | ||
39 | { | ||
40 | int retval; | ||
41 | int slot; | ||
42 | |||
43 | while ((retval = get_option(&str, &slot))) { | ||
44 | if ((slot < 0) || (slot > 31)) | ||
45 | pr_err("Illegal slot value: %d\n", slot); | ||
46 | else | ||
47 | pci_slot_ignore |= (1 << slot); | ||
48 | } | ||
49 | return 1; | ||
50 | } | ||
51 | __setup("pci_slot_ignore=", versatile_pci_slot_ignore); | ||
52 | |||
53 | |||
54 | static void __iomem *versatile_map_bus(struct pci_bus *bus, | ||
55 | unsigned int devfn, int offset) | ||
56 | { | ||
57 | unsigned int busnr = bus->number; | ||
58 | |||
59 | if (pci_slot_ignore & (1 << PCI_SLOT(devfn))) | ||
60 | return NULL; | ||
61 | |||
62 | return versatile_cfg_base[1] + ((busnr << 16) | (devfn << 8) | offset); | ||
63 | } | ||
64 | |||
65 | static struct pci_ops pci_versatile_ops = { | ||
66 | .map_bus = versatile_map_bus, | ||
67 | .read = pci_generic_config_read32, | ||
68 | .write = pci_generic_config_write, | ||
69 | }; | ||
70 | |||
71 | static int versatile_pci_parse_request_of_pci_ranges(struct device *dev, | ||
72 | struct list_head *res) | ||
73 | { | ||
74 | int err, mem = 1, res_valid = 0; | ||
75 | struct device_node *np = dev->of_node; | ||
76 | resource_size_t iobase; | ||
77 | struct pci_host_bridge_window *win; | ||
78 | |||
79 | err = of_pci_get_host_bridge_resources(np, 0, 0xff, res, &iobase); | ||
80 | if (err) | ||
81 | return err; | ||
82 | |||
83 | list_for_each_entry(win, res, list) { | ||
84 | struct resource *parent, *res = win->res; | ||
85 | |||
86 | switch (resource_type(res)) { | ||
87 | case IORESOURCE_IO: | ||
88 | parent = &ioport_resource; | ||
89 | err = pci_remap_iospace(res, iobase); | ||
90 | if (err) { | ||
91 | dev_warn(dev, "error %d: failed to map resource %pR\n", | ||
92 | err, res); | ||
93 | continue; | ||
94 | } | ||
95 | break; | ||
96 | case IORESOURCE_MEM: | ||
97 | parent = &iomem_resource; | ||
98 | res_valid |= !(res->flags & IORESOURCE_PREFETCH); | ||
99 | |||
100 | writel(res->start >> 28, PCI_IMAP(mem)); | ||
101 | writel(PHYS_OFFSET >> 28, PCI_SMAP(mem)); | ||
102 | mem++; | ||
103 | |||
104 | break; | ||
105 | case IORESOURCE_BUS: | ||
106 | default: | ||
107 | continue; | ||
108 | } | ||
109 | |||
110 | err = devm_request_resource(dev, parent, res); | ||
111 | if (err) | ||
112 | goto out_release_res; | ||
113 | } | ||
114 | |||
115 | if (!res_valid) { | ||
116 | dev_err(dev, "non-prefetchable memory resource required\n"); | ||
117 | err = -EINVAL; | ||
118 | goto out_release_res; | ||
119 | } | ||
120 | |||
121 | return 0; | ||
122 | |||
123 | out_release_res: | ||
124 | pci_free_resource_list(res); | ||
125 | return err; | ||
126 | } | ||
127 | |||
128 | /* Unused, temporary to satisfy ARM arch code */ | ||
129 | struct pci_sys_data sys; | ||
130 | |||
131 | static int versatile_pci_probe(struct platform_device *pdev) | ||
132 | { | ||
133 | struct resource *res; | ||
134 | int ret, i, myslot = -1; | ||
135 | u32 val; | ||
136 | void __iomem *local_pci_cfg_base; | ||
137 | struct pci_bus *bus; | ||
138 | LIST_HEAD(pci_res); | ||
139 | |||
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); | ||
144 | |||
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); | ||
149 | |||
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); | ||
154 | |||
155 | ret = versatile_pci_parse_request_of_pci_ranges(&pdev->dev, &pci_res); | ||
156 | if (ret) | ||
157 | return ret; | ||
158 | |||
159 | /* | ||
160 | * We need to discover the PCI core first to configure itself | ||
161 | * before the main PCI probing is performed | ||
162 | */ | ||
163 | for (i = 0; i < 32; i++) { | ||
164 | if ((readl(versatile_cfg_base[0] + (i << 11) + PCI_VENDOR_ID) == VP_PCI_DEVICE_ID) && | ||
165 | (readl(versatile_cfg_base[0] + (i << 11) + PCI_CLASS_REVISION) == VP_PCI_CLASS_ID)) { | ||
166 | myslot = i; | ||
167 | break; | ||
168 | } | ||
169 | } | ||
170 | if (myslot == -1) { | ||
171 | dev_err(&pdev->dev, "Cannot find PCI core!\n"); | ||
172 | return -EIO; | ||
173 | } | ||
174 | /* | ||
175 | * Do not to map Versatile FPGA PCI device into memory space | ||
176 | */ | ||
177 | pci_slot_ignore |= (1 << myslot); | ||
178 | |||
179 | dev_info(&pdev->dev, "PCI core found (slot %d)\n", myslot); | ||
180 | |||
181 | writel(myslot, PCI_SELFID); | ||
182 | local_pci_cfg_base = versatile_cfg_base[1] + (myslot << 11); | ||
183 | |||
184 | val = readl(local_pci_cfg_base + PCI_COMMAND); | ||
185 | val |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE; | ||
186 | writel(val, local_pci_cfg_base + PCI_COMMAND); | ||
187 | |||
188 | /* | ||
189 | * Configure the PCI inbound memory windows to be 1:1 mapped to SDRAM | ||
190 | */ | ||
191 | writel(PHYS_OFFSET, local_pci_cfg_base + PCI_BASE_ADDRESS_0); | ||
192 | writel(PHYS_OFFSET, local_pci_cfg_base + PCI_BASE_ADDRESS_1); | ||
193 | writel(PHYS_OFFSET, local_pci_cfg_base + PCI_BASE_ADDRESS_2); | ||
194 | |||
195 | /* | ||
196 | * For many years the kernel and QEMU were symbiotically buggy | ||
197 | * in that they both assumed the same broken IRQ mapping. | ||
198 | * QEMU therefore attempts to auto-detect old broken kernels | ||
199 | * so that they still work on newer QEMU as they did on old | ||
200 | * QEMU. Since we now use the correct (ie matching-hardware) | ||
201 | * IRQ mapping we write a definitely different value to a | ||
202 | * PCI_INTERRUPT_LINE register to tell QEMU that we expect | ||
203 | * real hardware behaviour and it need not be backwards | ||
204 | * compatible for us. This write is harmless on real hardware. | ||
205 | */ | ||
206 | writel(0, versatile_cfg_base[0] + PCI_INTERRUPT_LINE); | ||
207 | |||
208 | pci_add_flags(PCI_ENABLE_PROC_DOMAINS); | ||
209 | pci_add_flags(PCI_REASSIGN_ALL_BUS | PCI_REASSIGN_ALL_RSRC); | ||
210 | |||
211 | bus = pci_scan_root_bus(&pdev->dev, 0, &pci_versatile_ops, &sys, &pci_res); | ||
212 | if (!bus) | ||
213 | return -ENOMEM; | ||
214 | |||
215 | pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci); | ||
216 | pci_assign_unassigned_bus_resources(bus); | ||
217 | |||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | static const struct of_device_id versatile_pci_of_match[] = { | ||
222 | { .compatible = "arm,versatile-pci", }, | ||
223 | { }, | ||
224 | }; | ||
225 | MODULE_DEVICE_TABLE(of, versatile_pci_of_match); | ||
226 | |||
227 | static struct platform_driver versatile_pci_driver = { | ||
228 | .driver = { | ||
229 | .name = "versatile-pci", | ||
230 | .of_match_table = versatile_pci_of_match, | ||
231 | }, | ||
232 | .probe = versatile_pci_probe, | ||
233 | }; | ||
234 | module_platform_driver(versatile_pci_driver); | ||
235 | |||
236 | MODULE_DESCRIPTION("Versatile PCI driver"); | ||
237 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c index b1d0596457c5..e77d831dc241 100644 --- a/drivers/pci/host/pci-xgene.c +++ b/drivers/pci/host/pci-xgene.c | |||
@@ -16,7 +16,7 @@ | |||
16 | * GNU General Public License for more details. | 16 | * GNU General Public License for more details. |
17 | * | 17 | * |
18 | */ | 18 | */ |
19 | #include <linux/clk-private.h> | 19 | #include <linux/clk.h> |
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
22 | #include <linux/jiffies.h> | 22 | #include <linux/jiffies.h> |
@@ -74,92 +74,6 @@ static inline u32 pcie_bar_low_val(u32 addr, u32 flags) | |||
74 | return (addr & PCI_BASE_ADDRESS_MEM_MASK) | flags; | 74 | return (addr & PCI_BASE_ADDRESS_MEM_MASK) | flags; |
75 | } | 75 | } |
76 | 76 | ||
77 | /* PCIe Configuration Out/In */ | ||
78 | static inline void xgene_pcie_cfg_out32(void __iomem *addr, int offset, u32 val) | ||
79 | { | ||
80 | writel(val, addr + offset); | ||
81 | } | ||
82 | |||
83 | static inline void xgene_pcie_cfg_out16(void __iomem *addr, int offset, u16 val) | ||
84 | { | ||
85 | u32 val32 = readl(addr + (offset & ~0x3)); | ||
86 | |||
87 | switch (offset & 0x3) { | ||
88 | case 2: | ||
89 | val32 &= ~0xFFFF0000; | ||
90 | val32 |= (u32)val << 16; | ||
91 | break; | ||
92 | case 0: | ||
93 | default: | ||
94 | val32 &= ~0xFFFF; | ||
95 | val32 |= val; | ||
96 | break; | ||
97 | } | ||
98 | writel(val32, addr + (offset & ~0x3)); | ||
99 | } | ||
100 | |||
101 | static inline void xgene_pcie_cfg_out8(void __iomem *addr, int offset, u8 val) | ||
102 | { | ||
103 | u32 val32 = readl(addr + (offset & ~0x3)); | ||
104 | |||
105 | switch (offset & 0x3) { | ||
106 | case 0: | ||
107 | val32 &= ~0xFF; | ||
108 | val32 |= val; | ||
109 | break; | ||
110 | case 1: | ||
111 | val32 &= ~0xFF00; | ||
112 | val32 |= (u32)val << 8; | ||
113 | break; | ||
114 | case 2: | ||
115 | val32 &= ~0xFF0000; | ||
116 | val32 |= (u32)val << 16; | ||
117 | break; | ||
118 | case 3: | ||
119 | default: | ||
120 | val32 &= ~0xFF000000; | ||
121 | val32 |= (u32)val << 24; | ||
122 | break; | ||
123 | } | ||
124 | writel(val32, addr + (offset & ~0x3)); | ||
125 | } | ||
126 | |||
127 | static inline void xgene_pcie_cfg_in32(void __iomem *addr, int offset, u32 *val) | ||
128 | { | ||
129 | *val = readl(addr + offset); | ||
130 | } | ||
131 | |||
132 | static inline void xgene_pcie_cfg_in16(void __iomem *addr, int offset, u32 *val) | ||
133 | { | ||
134 | *val = readl(addr + (offset & ~0x3)); | ||
135 | |||
136 | switch (offset & 0x3) { | ||
137 | case 2: | ||
138 | *val >>= 16; | ||
139 | break; | ||
140 | } | ||
141 | |||
142 | *val &= 0xFFFF; | ||
143 | } | ||
144 | |||
145 | static inline void xgene_pcie_cfg_in8(void __iomem *addr, int offset, u32 *val) | ||
146 | { | ||
147 | *val = readl(addr + (offset & ~0x3)); | ||
148 | |||
149 | switch (offset & 0x3) { | ||
150 | case 3: | ||
151 | *val = *val >> 24; | ||
152 | break; | ||
153 | case 2: | ||
154 | *val = *val >> 16; | ||
155 | break; | ||
156 | case 1: | ||
157 | *val = *val >> 8; | ||
158 | break; | ||
159 | } | ||
160 | *val &= 0xFF; | ||
161 | } | ||
162 | |||
163 | /* | 77 | /* |
164 | * When the address bit [17:16] is 2'b01, the Configuration access will be | 78 | * When the address bit [17:16] is 2'b01, the Configuration access will be |
165 | * treated as Type 1 and it will be forwarded to external PCIe device. | 79 | * treated as Type 1 and it will be forwarded to external PCIe device. |
@@ -213,69 +127,23 @@ static bool xgene_pcie_hide_rc_bars(struct pci_bus *bus, int offset) | |||
213 | return false; | 127 | return false; |
214 | } | 128 | } |
215 | 129 | ||
216 | static int xgene_pcie_read_config(struct pci_bus *bus, unsigned int devfn, | 130 | static int xgene_pcie_map_bus(struct pci_bus *bus, unsigned int devfn, |
217 | int offset, int len, u32 *val) | 131 | int offset) |
218 | { | ||
219 | struct xgene_pcie_port *port = bus->sysdata; | ||
220 | void __iomem *addr; | ||
221 | |||
222 | if ((pci_is_root_bus(bus) && devfn != 0) || !port->link_up) | ||
223 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
224 | |||
225 | if (xgene_pcie_hide_rc_bars(bus, offset)) { | ||
226 | *val = 0; | ||
227 | return PCIBIOS_SUCCESSFUL; | ||
228 | } | ||
229 | |||
230 | xgene_pcie_set_rtdid_reg(bus, devfn); | ||
231 | addr = xgene_pcie_get_cfg_base(bus); | ||
232 | switch (len) { | ||
233 | case 1: | ||
234 | xgene_pcie_cfg_in8(addr, offset, val); | ||
235 | break; | ||
236 | case 2: | ||
237 | xgene_pcie_cfg_in16(addr, offset, val); | ||
238 | break; | ||
239 | default: | ||
240 | xgene_pcie_cfg_in32(addr, offset, val); | ||
241 | break; | ||
242 | } | ||
243 | |||
244 | return PCIBIOS_SUCCESSFUL; | ||
245 | } | ||
246 | |||
247 | static int xgene_pcie_write_config(struct pci_bus *bus, unsigned int devfn, | ||
248 | int offset, int len, u32 val) | ||
249 | { | 132 | { |
250 | struct xgene_pcie_port *port = bus->sysdata; | 133 | struct xgene_pcie_port *port = bus->sysdata; |
251 | void __iomem *addr; | ||
252 | 134 | ||
253 | if ((pci_is_root_bus(bus) && devfn != 0) || !port->link_up) | 135 | if ((pci_is_root_bus(bus) && devfn != 0) || !port->link_up || |
254 | return PCIBIOS_DEVICE_NOT_FOUND; | 136 | xgene_pcie_hide_rc_bars(bus, offset)) |
255 | 137 | return NULL; | |
256 | if (xgene_pcie_hide_rc_bars(bus, offset)) | ||
257 | return PCIBIOS_SUCCESSFUL; | ||
258 | 138 | ||
259 | xgene_pcie_set_rtdid_reg(bus, devfn); | 139 | xgene_pcie_set_rtdid_reg(bus, devfn); |
260 | addr = xgene_pcie_get_cfg_base(bus); | 140 | return xgene_pcie_get_cfg_base(bus); |
261 | switch (len) { | ||
262 | case 1: | ||
263 | xgene_pcie_cfg_out8(addr, offset, (u8)val); | ||
264 | break; | ||
265 | case 2: | ||
266 | xgene_pcie_cfg_out16(addr, offset, (u16)val); | ||
267 | break; | ||
268 | default: | ||
269 | xgene_pcie_cfg_out32(addr, offset, val); | ||
270 | break; | ||
271 | } | ||
272 | |||
273 | return PCIBIOS_SUCCESSFUL; | ||
274 | } | 141 | } |
275 | 142 | ||
276 | static struct pci_ops xgene_pcie_ops = { | 143 | static struct pci_ops xgene_pcie_ops = { |
277 | .read = xgene_pcie_read_config, | 144 | .map_bus = xgene_pcie_map_bus, |
278 | .write = xgene_pcie_write_config | 145 | .read = pci_generic_config_read32, |
146 | .write = pci_generic_config_write32, | ||
279 | }; | 147 | }; |
280 | 148 | ||
281 | static u64 xgene_pcie_set_ib_mask(void __iomem *csr_base, u32 addr, | 149 | static u64 xgene_pcie_set_ib_mask(void __iomem *csr_base, u32 addr, |
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index 17ca98657a28..1f4ea6f2d910 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c | |||
@@ -511,9 +511,6 @@ int __init dw_pcie_host_init(struct pcie_port *pp) | |||
511 | dw_pci.private_data = (void **)&pp; | 511 | dw_pci.private_data = (void **)&pp; |
512 | 512 | ||
513 | pci_common_init_dev(pp->dev, &dw_pci); | 513 | pci_common_init_dev(pp->dev, &dw_pci); |
514 | #ifdef CONFIG_PCI_DOMAINS | ||
515 | dw_pci.domain++; | ||
516 | #endif | ||
517 | 514 | ||
518 | return 0; | 515 | return 0; |
519 | } | 516 | } |
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c index 748786c402fc..c57bd0ac39a0 100644 --- a/drivers/pci/host/pcie-rcar.c +++ b/drivers/pci/host/pcie-rcar.c | |||
@@ -397,9 +397,6 @@ static void rcar_pcie_enable(struct rcar_pcie *pcie) | |||
397 | #endif | 397 | #endif |
398 | 398 | ||
399 | pci_common_init_dev(&pdev->dev, &rcar_pci); | 399 | pci_common_init_dev(&pdev->dev, &rcar_pci); |
400 | #ifdef CONFIG_PCI_DOMAINS | ||
401 | rcar_pci.domain++; | ||
402 | #endif | ||
403 | } | 400 | } |
404 | 401 | ||
405 | static int phy_wait_for_ack(struct rcar_pcie *pcie) | 402 | static int phy_wait_for_ack(struct rcar_pcie *pcie) |
@@ -757,7 +754,7 @@ static int rcar_pcie_get_resources(struct platform_device *pdev, | |||
757 | goto err_map_reg; | 754 | goto err_map_reg; |
758 | 755 | ||
759 | i = irq_of_parse_and_map(pdev->dev.of_node, 0); | 756 | i = irq_of_parse_and_map(pdev->dev.of_node, 0); |
760 | if (i < 0) { | 757 | if (!i) { |
761 | dev_err(pcie->dev, "cannot get platform resources for msi interrupt\n"); | 758 | dev_err(pcie->dev, "cannot get platform resources for msi interrupt\n"); |
762 | err = -ENOENT; | 759 | err = -ENOENT; |
763 | goto err_map_reg; | 760 | goto err_map_reg; |
@@ -765,7 +762,7 @@ static int rcar_pcie_get_resources(struct platform_device *pdev, | |||
765 | pcie->msi.irq1 = i; | 762 | pcie->msi.irq1 = i; |
766 | 763 | ||
767 | i = irq_of_parse_and_map(pdev->dev.of_node, 1); | 764 | i = irq_of_parse_and_map(pdev->dev.of_node, 1); |
768 | if (i < 0) { | 765 | if (!i) { |
769 | dev_err(pcie->dev, "cannot get platform resources for msi interrupt\n"); | 766 | dev_err(pcie->dev, "cannot get platform resources for msi interrupt\n"); |
770 | err = -ENOENT; | 767 | err = -ENOENT; |
771 | goto err_map_reg; | 768 | goto err_map_reg; |
diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c index ef3ebaf9a738..eac4a4b957ca 100644 --- a/drivers/pci/host/pcie-xilinx.c +++ b/drivers/pci/host/pcie-xilinx.c | |||
@@ -148,10 +148,10 @@ static inline bool xilinx_pcie_link_is_up(struct xilinx_pcie_port *port) | |||
148 | */ | 148 | */ |
149 | static void xilinx_pcie_clear_err_interrupts(struct xilinx_pcie_port *port) | 149 | static void xilinx_pcie_clear_err_interrupts(struct xilinx_pcie_port *port) |
150 | { | 150 | { |
151 | u32 val = pcie_read(port, XILINX_PCIE_REG_RPEFR); | 151 | unsigned long val = pcie_read(port, XILINX_PCIE_REG_RPEFR); |
152 | 152 | ||
153 | if (val & XILINX_PCIE_RPEFR_ERR_VALID) { | 153 | if (val & XILINX_PCIE_RPEFR_ERR_VALID) { |
154 | dev_dbg(port->dev, "Requester ID %d\n", | 154 | dev_dbg(port->dev, "Requester ID %lu\n", |
155 | val & XILINX_PCIE_RPEFR_REQ_ID); | 155 | val & XILINX_PCIE_RPEFR_REQ_ID); |
156 | pcie_write(port, XILINX_PCIE_RPEFR_ALL_MASK, | 156 | pcie_write(port, XILINX_PCIE_RPEFR_ALL_MASK, |
157 | XILINX_PCIE_REG_RPEFR); | 157 | XILINX_PCIE_REG_RPEFR); |
@@ -189,7 +189,7 @@ static bool xilinx_pcie_valid_device(struct pci_bus *bus, unsigned int devfn) | |||
189 | } | 189 | } |
190 | 190 | ||
191 | /** | 191 | /** |
192 | * xilinx_pcie_config_base - Get configuration base | 192 | * xilinx_pcie_map_bus - Get configuration base |
193 | * @bus: PCI Bus structure | 193 | * @bus: PCI Bus structure |
194 | * @devfn: Device/function | 194 | * @devfn: Device/function |
195 | * @where: Offset from base | 195 | * @where: Offset from base |
@@ -197,96 +197,26 @@ static bool xilinx_pcie_valid_device(struct pci_bus *bus, unsigned int devfn) | |||
197 | * Return: Base address of the configuration space needed to be | 197 | * Return: Base address of the configuration space needed to be |
198 | * accessed. | 198 | * accessed. |
199 | */ | 199 | */ |
200 | static void __iomem *xilinx_pcie_config_base(struct pci_bus *bus, | 200 | static void __iomem *xilinx_pcie_map_bus(struct pci_bus *bus, |
201 | unsigned int devfn, int where) | 201 | unsigned int devfn, int where) |
202 | { | 202 | { |
203 | struct xilinx_pcie_port *port = sys_to_pcie(bus->sysdata); | 203 | struct xilinx_pcie_port *port = sys_to_pcie(bus->sysdata); |
204 | int relbus; | 204 | int relbus; |
205 | 205 | ||
206 | if (!xilinx_pcie_valid_device(bus, devfn)) | ||
207 | return NULL; | ||
208 | |||
206 | relbus = (bus->number << ECAM_BUS_NUM_SHIFT) | | 209 | relbus = (bus->number << ECAM_BUS_NUM_SHIFT) | |
207 | (devfn << ECAM_DEV_NUM_SHIFT); | 210 | (devfn << ECAM_DEV_NUM_SHIFT); |
208 | 211 | ||
209 | return port->reg_base + relbus + where; | 212 | return port->reg_base + relbus + where; |
210 | } | 213 | } |
211 | 214 | ||
212 | /** | ||
213 | * xilinx_pcie_read_config - Read configuration space | ||
214 | * @bus: PCI Bus structure | ||
215 | * @devfn: Device/function | ||
216 | * @where: Offset from base | ||
217 | * @size: Byte/word/dword | ||
218 | * @val: Value to be read | ||
219 | * | ||
220 | * Return: PCIBIOS_SUCCESSFUL on success | ||
221 | * PCIBIOS_DEVICE_NOT_FOUND on failure | ||
222 | */ | ||
223 | static int xilinx_pcie_read_config(struct pci_bus *bus, unsigned int devfn, | ||
224 | int where, int size, u32 *val) | ||
225 | { | ||
226 | void __iomem *addr; | ||
227 | |||
228 | if (!xilinx_pcie_valid_device(bus, devfn)) { | ||
229 | *val = 0xFFFFFFFF; | ||
230 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
231 | } | ||
232 | |||
233 | addr = xilinx_pcie_config_base(bus, devfn, where); | ||
234 | |||
235 | switch (size) { | ||
236 | case 1: | ||
237 | *val = readb(addr); | ||
238 | break; | ||
239 | case 2: | ||
240 | *val = readw(addr); | ||
241 | break; | ||
242 | default: | ||
243 | *val = readl(addr); | ||
244 | break; | ||
245 | } | ||
246 | |||
247 | return PCIBIOS_SUCCESSFUL; | ||
248 | } | ||
249 | |||
250 | /** | ||
251 | * xilinx_pcie_write_config - Write configuration space | ||
252 | * @bus: PCI Bus structure | ||
253 | * @devfn: Device/function | ||
254 | * @where: Offset from base | ||
255 | * @size: Byte/word/dword | ||
256 | * @val: Value to be written to device | ||
257 | * | ||
258 | * Return: PCIBIOS_SUCCESSFUL on success | ||
259 | * PCIBIOS_DEVICE_NOT_FOUND on failure | ||
260 | */ | ||
261 | static int xilinx_pcie_write_config(struct pci_bus *bus, unsigned int devfn, | ||
262 | int where, int size, u32 val) | ||
263 | { | ||
264 | void __iomem *addr; | ||
265 | |||
266 | if (!xilinx_pcie_valid_device(bus, devfn)) | ||
267 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
268 | |||
269 | addr = xilinx_pcie_config_base(bus, devfn, where); | ||
270 | |||
271 | switch (size) { | ||
272 | case 1: | ||
273 | writeb(val, addr); | ||
274 | break; | ||
275 | case 2: | ||
276 | writew(val, addr); | ||
277 | break; | ||
278 | default: | ||
279 | writel(val, addr); | ||
280 | break; | ||
281 | } | ||
282 | |||
283 | return PCIBIOS_SUCCESSFUL; | ||
284 | } | ||
285 | |||
286 | /* PCIe operations */ | 215 | /* PCIe operations */ |
287 | static struct pci_ops xilinx_pcie_ops = { | 216 | static struct pci_ops xilinx_pcie_ops = { |
288 | .read = xilinx_pcie_read_config, | 217 | .map_bus = xilinx_pcie_map_bus, |
289 | .write = xilinx_pcie_write_config, | 218 | .read = pci_generic_config_read, |
219 | .write = pci_generic_config_write, | ||
290 | }; | 220 | }; |
291 | 221 | ||
292 | /* MSI functions */ | 222 | /* MSI functions */ |
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c index a5a7fd8332ac..46db29395a62 100644 --- a/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/drivers/pci/hotplug/cpci_hotplug_core.c | |||
@@ -214,8 +214,7 @@ static void release_slot(struct hotplug_slot *hotplug_slot) | |||
214 | 214 | ||
215 | kfree(slot->hotplug_slot->info); | 215 | kfree(slot->hotplug_slot->info); |
216 | kfree(slot->hotplug_slot); | 216 | kfree(slot->hotplug_slot); |
217 | if (slot->dev) | 217 | pci_dev_put(slot->dev); |
218 | pci_dev_put(slot->dev); | ||
219 | kfree(slot); | 218 | kfree(slot); |
220 | } | 219 | } |
221 | 220 | ||
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index ff32e85e1de6..f052e951b23e 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c | |||
@@ -532,8 +532,6 @@ static void interrupt_event_handler(struct work_struct *work) | |||
532 | pciehp_green_led_off(p_slot); | 532 | pciehp_green_led_off(p_slot); |
533 | break; | 533 | break; |
534 | case INT_PRESENCE_ON: | 534 | case INT_PRESENCE_ON: |
535 | if (!HP_SUPR_RM(ctrl)) | ||
536 | break; | ||
537 | ctrl_dbg(ctrl, "Surprise Insertion\n"); | 535 | ctrl_dbg(ctrl, "Surprise Insertion\n"); |
538 | handle_surprise_event(p_slot); | 536 | handle_surprise_event(p_slot); |
539 | break; | 537 | break; |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index fd60806d3fd0..c3e7dfcf9ff5 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -694,11 +694,16 @@ static void __iomem *msix_map_region(struct pci_dev *dev, unsigned nr_entries) | |||
694 | { | 694 | { |
695 | resource_size_t phys_addr; | 695 | resource_size_t phys_addr; |
696 | u32 table_offset; | 696 | u32 table_offset; |
697 | unsigned long flags; | ||
697 | u8 bir; | 698 | u8 bir; |
698 | 699 | ||
699 | pci_read_config_dword(dev, dev->msix_cap + PCI_MSIX_TABLE, | 700 | pci_read_config_dword(dev, dev->msix_cap + PCI_MSIX_TABLE, |
700 | &table_offset); | 701 | &table_offset); |
701 | bir = (u8)(table_offset & PCI_MSIX_TABLE_BIR); | 702 | bir = (u8)(table_offset & PCI_MSIX_TABLE_BIR); |
703 | flags = pci_resource_flags(dev, bir); | ||
704 | if (!flags || (flags & IORESOURCE_UNSET)) | ||
705 | return NULL; | ||
706 | |||
702 | table_offset &= PCI_MSIX_TABLE_OFFSET; | 707 | table_offset &= PCI_MSIX_TABLE_OFFSET; |
703 | phys_addr = pci_resource_start(dev, bir) + table_offset; | 708 | phys_addr = pci_resource_start(dev, bir) + table_offset; |
704 | 709 | ||
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 887e6bd95af7..09a66bad8018 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -1383,7 +1383,7 @@ static int pci_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
1383 | if (add_uevent_var(env, "PCI_SLOT_NAME=%s", pci_name(pdev))) | 1383 | if (add_uevent_var(env, "PCI_SLOT_NAME=%s", pci_name(pdev))) |
1384 | return -ENOMEM; | 1384 | return -ENOMEM; |
1385 | 1385 | ||
1386 | if (add_uevent_var(env, "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x", | 1386 | if (add_uevent_var(env, "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02X", |
1387 | pdev->vendor, pdev->device, | 1387 | pdev->vendor, pdev->device, |
1388 | pdev->subsystem_vendor, pdev->subsystem_device, | 1388 | pdev->subsystem_vendor, pdev->subsystem_device, |
1389 | (u8)(pdev->class >> 16), (u8)(pdev->class >> 8), | 1389 | (u8)(pdev->class >> 16), (u8)(pdev->class >> 8), |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e9d4fd861ba1..460d046ab6fe 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -10,6 +10,8 @@ | |||
10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
11 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/of.h> | ||
14 | #include <linux/of_pci.h> | ||
13 | #include <linux/pci.h> | 15 | #include <linux/pci.h> |
14 | #include <linux/pm.h> | 16 | #include <linux/pm.h> |
15 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
@@ -3197,7 +3199,7 @@ static int pci_pm_reset(struct pci_dev *dev, int probe) | |||
3197 | { | 3199 | { |
3198 | u16 csr; | 3200 | u16 csr; |
3199 | 3201 | ||
3200 | if (!dev->pm_cap) | 3202 | if (!dev->pm_cap || dev->dev_flags & PCI_DEV_FLAGS_NO_PM_RESET) |
3201 | return -ENOTTY; | 3203 | return -ENOTTY; |
3202 | 3204 | ||
3203 | pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &csr); | 3205 | pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &csr); |
@@ -4471,6 +4473,53 @@ int pci_get_new_domain_nr(void) | |||
4471 | { | 4473 | { |
4472 | return atomic_inc_return(&__domain_nr); | 4474 | return atomic_inc_return(&__domain_nr); |
4473 | } | 4475 | } |
4476 | |||
4477 | #ifdef CONFIG_PCI_DOMAINS_GENERIC | ||
4478 | void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent) | ||
4479 | { | ||
4480 | static int use_dt_domains = -1; | ||
4481 | int domain = of_get_pci_domain_nr(parent->of_node); | ||
4482 | |||
4483 | /* | ||
4484 | * Check DT domain and use_dt_domains values. | ||
4485 | * | ||
4486 | * If DT domain property is valid (domain >= 0) and | ||
4487 | * use_dt_domains != 0, the DT assignment is valid since this means | ||
4488 | * we have not previously allocated a domain number by using | ||
4489 | * pci_get_new_domain_nr(); we should also update use_dt_domains to | ||
4490 | * 1, to indicate that we have just assigned a domain number from | ||
4491 | * DT. | ||
4492 | * | ||
4493 | * If DT domain property value is not valid (ie domain < 0), and we | ||
4494 | * have not previously assigned a domain number from DT | ||
4495 | * (use_dt_domains != 1) we should assign a domain number by | ||
4496 | * using the: | ||
4497 | * | ||
4498 | * pci_get_new_domain_nr() | ||
4499 | * | ||
4500 | * API and update the use_dt_domains value to keep track of method we | ||
4501 | * are using to assign domain numbers (use_dt_domains = 0). | ||
4502 | * | ||
4503 | * All other combinations imply we have a platform that is trying | ||
4504 | * to mix domain numbers obtained from DT and pci_get_new_domain_nr(), | ||
4505 | * which is a recipe for domain mishandling and it is prevented by | ||
4506 | * invalidating the domain value (domain = -1) and printing a | ||
4507 | * corresponding error. | ||
4508 | */ | ||
4509 | if (domain >= 0 && use_dt_domains) { | ||
4510 | use_dt_domains = 1; | ||
4511 | } else if (domain < 0 && use_dt_domains != 1) { | ||
4512 | use_dt_domains = 0; | ||
4513 | domain = pci_get_new_domain_nr(); | ||
4514 | } else { | ||
4515 | dev_err(parent, "Node %s has inconsistent \"linux,pci-domain\" property in DT\n", | ||
4516 | parent->of_node->full_name); | ||
4517 | domain = -1; | ||
4518 | } | ||
4519 | |||
4520 | bus->domain_nr = domain; | ||
4521 | } | ||
4522 | #endif | ||
4474 | #endif | 4523 | #endif |
4475 | 4524 | ||
4476 | /** | 4525 | /** |
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index e1e7026b838d..820740a22e94 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
@@ -859,7 +859,10 @@ static ssize_t link_state_store(struct device *dev, | |||
859 | { | 859 | { |
860 | struct pci_dev *pdev = to_pci_dev(dev); | 860 | struct pci_dev *pdev = to_pci_dev(dev); |
861 | struct pcie_link_state *link, *root = pdev->link_state->root; | 861 | struct pcie_link_state *link, *root = pdev->link_state->root; |
862 | u32 val = buf[0] - '0', state = 0; | 862 | u32 val, state = 0; |
863 | |||
864 | if (kstrtouint(buf, 10, &val)) | ||
865 | return -EINVAL; | ||
863 | 866 | ||
864 | if (aspm_disabled) | 867 | if (aspm_disabled) |
865 | return -EPERM; | 868 | return -EPERM; |
@@ -900,15 +903,14 @@ static ssize_t clk_ctl_store(struct device *dev, | |||
900 | size_t n) | 903 | size_t n) |
901 | { | 904 | { |
902 | struct pci_dev *pdev = to_pci_dev(dev); | 905 | struct pci_dev *pdev = to_pci_dev(dev); |
903 | int state; | 906 | bool state; |
904 | 907 | ||
905 | if (n < 1) | 908 | if (strtobool(buf, &state)) |
906 | return -EINVAL; | 909 | return -EINVAL; |
907 | state = buf[0]-'0'; | ||
908 | 910 | ||
909 | down_read(&pci_bus_sem); | 911 | down_read(&pci_bus_sem); |
910 | mutex_lock(&aspm_lock); | 912 | mutex_lock(&aspm_lock); |
911 | pcie_set_clkpm_nocheck(pdev->link_state, !!state); | 913 | pcie_set_clkpm_nocheck(pdev->link_state, state); |
912 | mutex_unlock(&aspm_lock); | 914 | mutex_unlock(&aspm_lock); |
913 | up_read(&pci_bus_sem); | 915 | up_read(&pci_bus_sem); |
914 | 916 | ||
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 903d5078b5ed..85f247e28a80 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -3076,6 +3076,27 @@ static void quirk_no_bus_reset(struct pci_dev *dev) | |||
3076 | */ | 3076 | */ |
3077 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0030, quirk_no_bus_reset); | 3077 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0030, quirk_no_bus_reset); |
3078 | 3078 | ||
3079 | static void quirk_no_pm_reset(struct pci_dev *dev) | ||
3080 | { | ||
3081 | /* | ||
3082 | * We can't do a bus reset on root bus devices, but an ineffective | ||
3083 | * PM reset may be better than nothing. | ||
3084 | */ | ||
3085 | if (!pci_is_root_bus(dev->bus)) | ||
3086 | dev->dev_flags |= PCI_DEV_FLAGS_NO_PM_RESET; | ||
3087 | } | ||
3088 | |||
3089 | /* | ||
3090 | * Some AMD/ATI GPUS (HD8570 - Oland) report that a D3hot->D0 transition | ||
3091 | * causes a reset (i.e., they advertise NoSoftRst-). This transition seems | ||
3092 | * to have no effect on the device: it retains the framebuffer contents and | ||
3093 | * monitor sync. Advertising this support makes other layers, like VFIO, | ||
3094 | * assume pci_reset_function() is viable for this device. Mark it as | ||
3095 | * unavailable to skip it when testing reset methods. | ||
3096 | */ | ||
3097 | DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_ATI, PCI_ANY_ID, | ||
3098 | PCI_CLASS_DISPLAY_VGA, 8, quirk_no_pm_reset); | ||
3099 | |||
3079 | #ifdef CONFIG_ACPI | 3100 | #ifdef CONFIG_ACPI |
3080 | /* | 3101 | /* |
3081 | * Apple: Shutdown Cactus Ridge Thunderbolt controller. | 3102 | * Apple: Shutdown Cactus Ridge Thunderbolt controller. |
@@ -3576,6 +3597,44 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_JMICRON, | |||
3576 | quirk_dma_func1_alias); | 3597 | quirk_dma_func1_alias); |
3577 | 3598 | ||
3578 | /* | 3599 | /* |
3600 | * Some devices DMA with the wrong devfn, not just the wrong function. | ||
3601 | * quirk_fixed_dma_alias() uses this table to create fixed aliases, where | ||
3602 | * the alias is "fixed" and independent of the device devfn. | ||
3603 | * | ||
3604 | * For example, the Adaptec 3405 is a PCIe card with an Intel 80333 I/O | ||
3605 | * processor. To software, this appears as a PCIe-to-PCI/X bridge with a | ||
3606 | * single device on the secondary bus. In reality, the single exposed | ||
3607 | * device at 0e.0 is the Address Translation Unit (ATU) of the controller | ||
3608 | * that provides a bridge to the internal bus of the I/O processor. The | ||
3609 | * controller supports private devices, which can be hidden from PCI config | ||
3610 | * space. In the case of the Adaptec 3405, a private device at 01.0 | ||
3611 | * appears to be the DMA engine, which therefore needs to become a DMA | ||
3612 | * alias for the device. | ||
3613 | */ | ||
3614 | static const struct pci_device_id fixed_dma_alias_tbl[] = { | ||
3615 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x0285, | ||
3616 | PCI_VENDOR_ID_ADAPTEC2, 0x02bb), /* Adaptec 3405 */ | ||
3617 | .driver_data = PCI_DEVFN(1, 0) }, | ||
3618 | { 0 } | ||
3619 | }; | ||
3620 | |||
3621 | static void quirk_fixed_dma_alias(struct pci_dev *dev) | ||
3622 | { | ||
3623 | const struct pci_device_id *id; | ||
3624 | |||
3625 | id = pci_match_id(fixed_dma_alias_tbl, dev); | ||
3626 | if (id) { | ||
3627 | dev->dma_alias_devfn = id->driver_data; | ||
3628 | dev->dev_flags |= PCI_DEV_FLAGS_DMA_ALIAS_DEVFN; | ||
3629 | dev_info(&dev->dev, "Enabling fixed DMA alias to %02x.%d\n", | ||
3630 | PCI_SLOT(dev->dma_alias_devfn), | ||
3631 | PCI_FUNC(dev->dma_alias_devfn)); | ||
3632 | } | ||
3633 | } | ||
3634 | |||
3635 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ADAPTEC2, 0x0285, quirk_fixed_dma_alias); | ||
3636 | |||
3637 | /* | ||
3579 | * A few PCIe-to-PCI bridges fail to expose a PCIe capability, resulting in | 3638 | * A few PCIe-to-PCI bridges fail to expose a PCIe capability, resulting in |
3580 | * using the wrong DMA alias for the device. Some of these devices can be | 3639 | * using the wrong DMA alias for the device. Some of these devices can be |
3581 | * used as either forward or reverse bridges, so we need to test whether the | 3640 | * used as either forward or reverse bridges, so we need to test whether the |
@@ -3678,6 +3737,9 @@ static const u16 pci_quirk_intel_pch_acs_ids[] = { | |||
3678 | 0x9c98, 0x9c99, 0x9c9a, 0x9c9b, | 3737 | 0x9c98, 0x9c99, 0x9c9a, 0x9c9b, |
3679 | /* Patsburg (X79) PCH */ | 3738 | /* Patsburg (X79) PCH */ |
3680 | 0x1d10, 0x1d12, 0x1d14, 0x1d16, 0x1d18, 0x1d1a, 0x1d1c, 0x1d1e, | 3739 | 0x1d10, 0x1d12, 0x1d14, 0x1d16, 0x1d18, 0x1d1a, 0x1d1c, 0x1d1e, |
3740 | /* Wellsburg (X99) PCH */ | ||
3741 | 0x8d10, 0x8d11, 0x8d12, 0x8d13, 0x8d14, 0x8d15, 0x8d16, 0x8d17, | ||
3742 | 0x8d18, 0x8d19, 0x8d1a, 0x8d1b, 0x8d1c, 0x8d1d, 0x8d1e, | ||
3681 | }; | 3743 | }; |
3682 | 3744 | ||
3683 | static bool pci_quirk_intel_pch_acs_match(struct pci_dev *dev) | 3745 | static bool pci_quirk_intel_pch_acs_match(struct pci_dev *dev) |
@@ -3761,6 +3823,8 @@ static const struct pci_dev_acs_enabled { | |||
3761 | { PCI_VENDOR_ID_INTEL, 0x1551, pci_quirk_mf_endpoint_acs }, | 3823 | { PCI_VENDOR_ID_INTEL, 0x1551, pci_quirk_mf_endpoint_acs }, |
3762 | { PCI_VENDOR_ID_INTEL, 0x1558, pci_quirk_mf_endpoint_acs }, | 3824 | { PCI_VENDOR_ID_INTEL, 0x1558, pci_quirk_mf_endpoint_acs }, |
3763 | { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs }, | 3825 | { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs }, |
3826 | { 0x19a2, 0x710, pci_quirk_mf_endpoint_acs }, /* Emulex BE3-R */ | ||
3827 | { 0x10df, 0x720, pci_quirk_mf_endpoint_acs }, /* Emulex Skyhawk-R */ | ||
3764 | { 0 } | 3828 | { 0 } |
3765 | }; | 3829 | }; |
3766 | 3830 | ||
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index f955edb9bea7..eb0ad530dc43 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c | |||
@@ -71,6 +71,7 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size) | |||
71 | { | 71 | { |
72 | void __iomem *image; | 72 | void __iomem *image; |
73 | int last_image; | 73 | int last_image; |
74 | unsigned length; | ||
74 | 75 | ||
75 | image = rom; | 76 | image = rom; |
76 | do { | 77 | do { |
@@ -93,9 +94,9 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size) | |||
93 | if (readb(pds + 3) != 'R') | 94 | if (readb(pds + 3) != 'R') |
94 | break; | 95 | break; |
95 | last_image = readb(pds + 21) & 0x80; | 96 | last_image = readb(pds + 21) & 0x80; |
96 | /* this length is reliable */ | 97 | length = readw(pds + 16); |
97 | image += readw(pds + 16) * 512; | 98 | image += length * 512; |
98 | } while (!last_image); | 99 | } while (length && !last_image); |
99 | 100 | ||
100 | /* never return a size larger than the PCI resource window */ | 101 | /* never return a size larger than the PCI resource window */ |
101 | /* there are known ROMs that get the size wrong */ | 102 | /* there are known ROMs that get the size wrong */ |