diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-02 17:12:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-02 17:12:29 -0400 |
commit | c8d0267efdb4ab16cd0ed6e0218e8c164006de48 (patch) | |
tree | d3e5367dbb5f05761323a8a98d87e061dc11774b | |
parent | affe8a2abd0d7815bb2653eea2717d0e0f8ac7e3 (diff) | |
parent | 9454c23852ca6d7aec89fd6fd46a046c323caac3 (diff) |
Merge tag 'pci-v4.8-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI updates from Bjorn Helgaas:
"Highlights:
- ARM64 support for ACPI host bridges
- new drivers for Axis ARTPEC-6 and Marvell Aardvark
- new pci_alloc_irq_vectors() interface for MSI-X, MSI, legacy INTx
- pci_resource_to_user() cleanup (more to come)
Detailed summary:
Enumeration:
- Move ecam.h to linux/include/pci-ecam.h (Jayachandran C)
- Add parent device field to ECAM struct pci_config_window (Jayachandran C)
- Add generic MCFG table handling (Tomasz Nowicki)
- Refactor pci_bus_assign_domain_nr() for CONFIG_PCI_DOMAINS_GENERIC (Tomasz Nowicki)
- Factor DT-specific pci_bus_find_domain_nr() code out (Tomasz Nowicki)
Resource management:
- Add devm_request_pci_bus_resources() (Bjorn Helgaas)
- Unify pci_resource_to_user() declarations (Bjorn Helgaas)
- Implement pci_resource_to_user() with pcibios_resource_to_bus() (microblaze, powerpc, sparc) (Bjorn Helgaas)
- Request host bridge window resources (designware, iproc, rcar, xgene, xilinx, xilinx-nwl) (Bjorn Helgaas)
- Make PCI I/O space optional on ARM32 (Bjorn Helgaas)
- Ignore write combining when mapping I/O port space (Bjorn Helgaas)
- Claim bus resources on MIPS PCI_PROBE_ONLY set-ups (Bjorn Helgaas)
- Remove unicore32 pci=firmware command line parameter handling (Bjorn Helgaas)
- Support I/O resources when parsing host bridge resources (Jayachandran C)
- Add helpers to request/release memory and I/O regions (Johannes Thumshirn)
- Use pci_(request|release)_mem_regions (NVMe, lpfc, GenWQE, ethernet/intel, alx) (Johannes Thumshirn)
- Extend pci=resource_alignment to specify device/vendor IDs (Koehrer Mathias (ETAS/ESW5))
- Add generic pci_bus_claim_resources() (Lorenzo Pieralisi)
- Claim bus resources on ARM32 PCI_PROBE_ONLY set-ups (Lorenzo Pieralisi)
- Remove ARM32 and ARM64 arch-specific pcibios_enable_device() (Lorenzo Pieralisi)
- Add pci_unmap_iospace() to unmap I/O resources (Sinan Kaya)
- Remove powerpc __pci_mmap_set_pgprot() (Yinghai Lu)
PCI device hotplug:
- Allow additional bus numbers for hotplug bridges (Keith Busch)
- Ignore interrupts during D3cold (Lukas Wunner)
Power management:
- Enforce type casting for pci_power_t (Andy Shevchenko)
- Don't clear d3cold_allowed for PCIe ports (Mika Westerberg)
- Put PCIe ports into D3 during suspend (Mika Westerberg)
- Power on bridges before scanning new devices (Mika Westerberg)
- Runtime resume bridge before rescan (Mika Westerberg)
- Add runtime PM support for PCIe ports (Mika Westerberg)
- Remove redundant check of pcie_set_clkpm (Shawn Lin)
Virtualization:
- Add function 1 DMA alias quirk for Marvell 88SE9182 (Aaron Sierra)
- Add DMA alias quirk for Adaptec 3805 (Alex Williamson)
- Mark Atheros AR9485 and QCA9882 to avoid bus reset (Chris Blake)
- Add ACS quirk for Solarflare SFC9220 (Edward Cree)
MSI:
- Fix PCI_MSI dependencies (Arnd Bergmann)
- Add pci_msix_desc_addr() helper (Christoph Hellwig)
- Switch msix_program_entries() to use pci_msix_desc_addr() (Christoph Hellwig)
- Make the "entries" argument to pci_enable_msix() optional (Christoph Hellwig)
- Provide sensible IRQ vector alloc/free routines (Christoph Hellwig)
- Spread interrupt vectors in pci_alloc_irq_vectors() (Christoph Hellwig)
Error Handling:
- Bind DPC to Root Ports as well as Downstream Ports (Keith Busch)
- Remove DPC tristate module option (Keith Busch)
- Convert Downstream Port Containment driver to use devm_* functions (Mika Westerberg)
Generic host bridge driver:
- Select IRQ_DOMAIN (Arnd Bergmann)
- Claim bus resources on PCI_PROBE_ONLY set-ups (Lorenzo Pieralisi)
ACPI host bridge driver:
- Add ARM64 acpi_pci_bus_find_domain_nr() (Tomasz Nowicki)
- Add ARM64 ACPI support for legacy IRQs parsing and consolidation with DT code (Tomasz Nowicki)
- Implement ARM64 AML accessors for PCI_Config region (Tomasz Nowicki)
- Support ARM64 ACPI-based PCI host controller (Tomasz Nowicki)
Altera host bridge driver:
- Check link status before retrain link (Ley Foon Tan)
- Poll for link up status after retraining the link (Ley Foon Tan)
Axis ARTPEC-6 host bridge driver:
- Add PCI_MSI_IRQ_DOMAIN dependency (Arnd Bergmann)
- Add DT binding for Axis ARTPEC-6 PCIe controller (Niklas Cassel)
- Add Axis ARTPEC-6 PCIe controller driver (Niklas Cassel)
Intel VMD host bridge driver:
- Use lock save/restore in interrupt enable path (Jon Derrick)
- Select device dma ops to override (Keith Busch)
- Initialize list item in IRQ disable (Keith Busch)
- Use x86_vector_domain as parent domain (Keith Busch)
- Separate MSI and MSI-X vector sharing (Keith Busch)
Marvell Aardvark host bridge driver:
- Add DT binding for the Aardvark PCIe controller (Thomas Petazzoni)
- Add Aardvark PCI host controller driver (Thomas Petazzoni)
- Add Aardvark PCIe support for Armada 3700 (Thomas Petazzoni)
Microsoft Hyper-V host bridge driver:
- Fix interrupt cleanup path (Cathy Avery)
- Don't leak buffer in hv_pci_onchannelcallback() (Vitaly Kuznetsov)
- Handle all pending messages in hv_pci_onchannelcallback() (Vitaly Kuznetsov)
NVIDIA Tegra host bridge driver:
- Program PADS_REFCLK_CFG* always, not just on legacy SoCs (Stephen Warren)
- Program PADS_REFCLK_CFG* registers with per-SoC values (Stephen Warren)
- Use lower-case hex consistently for register definitions (Thierry Reding)
- Use generic pci_remap_iospace() rather than ARM32-specific one (Thierry Reding)
- Stop setting pcibios_min_mem (Thierry Reding)
Renesas R-Car host bridge driver:
- Drop gen2 dummy I/O port region (Bjorn Helgaas)
TI DRA7xx host bridge driver:
- Fix return value in case of error (Christophe JAILLET)
Xilinx AXI host bridge driver:
- Fix return value in case of error (Christophe JAILLET)
Miscellaneous:
- Make bus_attr_resource_alignment static (Ben Dooks)
- Include <asm/dma.h> for isa_dma_bridge_buggy (Ben Dooks)
- MAINTAINERS: Add file patterns for PCI device tree bindings (Geert Uytterhoeven)
- Make host bridge drivers explicitly non-modular (Paul Gortmaker)"
* tag 'pci-v4.8-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (125 commits)
PCI: xgene: Make explicitly non-modular
PCI: thunder-pem: Make explicitly non-modular
PCI: thunder-ecam: Make explicitly non-modular
PCI: tegra: Make explicitly non-modular
PCI: rcar-gen2: Make explicitly non-modular
PCI: rcar: Make explicitly non-modular
PCI: mvebu: Make explicitly non-modular
PCI: layerscape: Make explicitly non-modular
PCI: keystone: Make explicitly non-modular
PCI: hisi: Make explicitly non-modular
PCI: generic: Make explicitly non-modular
PCI: designware-plat: Make it explicitly non-modular
PCI: artpec6: Make explicitly non-modular
PCI: armada8k: Make explicitly non-modular
PCI: artpec: Add PCI_MSI_IRQ_DOMAIN dependency
PCI: Add ACS quirk for Solarflare SFC9220
arm64: dts: marvell: Add Aardvark PCIe support for Armada 3700
PCI: aardvark: Add Aardvark PCI host controller driver
dt-bindings: add DT binding for the Aardvark PCIe controller
PCI: tegra: Program PADS_REFCLK_CFG* registers with per-SoC values
...
87 files changed, 3014 insertions, 1176 deletions
diff --git a/Documentation/PCI/MSI-HOWTO.txt b/Documentation/PCI/MSI-HOWTO.txt index 1179850f453c..c55df2911136 100644 --- a/Documentation/PCI/MSI-HOWTO.txt +++ b/Documentation/PCI/MSI-HOWTO.txt | |||
@@ -78,422 +78,111 @@ CONFIG_PCI_MSI option. | |||
78 | 78 | ||
79 | 4.2 Using MSI | 79 | 4.2 Using MSI |
80 | 80 | ||
81 | Most of the hard work is done for the driver in the PCI layer. It simply | 81 | Most of the hard work is done for the driver in the PCI layer. The driver |
82 | has to request that the PCI layer set up the MSI capability for this | 82 | simply has to request that the PCI layer set up the MSI capability for this |
83 | device. | 83 | device. |
84 | 84 | ||
85 | 4.2.1 pci_enable_msi | 85 | To automatically use MSI or MSI-X interrupt vectors, use the following |
86 | function: | ||
86 | 87 | ||
87 | int pci_enable_msi(struct pci_dev *dev) | 88 | int pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs, |
89 | unsigned int max_vecs, unsigned int flags); | ||
88 | 90 | ||
89 | A successful call allocates ONE interrupt to the device, regardless | 91 | which allocates up to max_vecs interrupt vectors for a PCI device. It |
90 | of how many MSIs the device supports. The device is switched from | 92 | returns the number of vectors allocated or a negative error. If the device |
91 | pin-based interrupt mode to MSI mode. The dev->irq number is changed | 93 | has a requirements for a minimum number of vectors the driver can pass a |
92 | to a new number which represents the message signaled interrupt; | 94 | min_vecs argument set to this limit, and the PCI core will return -ENOSPC |
93 | consequently, this function should be called before the driver calls | 95 | if it can't meet the minimum number of vectors. |
94 | request_irq(), because an MSI is delivered via a vector that is | ||
95 | different from the vector of a pin-based interrupt. | ||
96 | 96 | ||
97 | 4.2.2 pci_enable_msi_range | 97 | The flags argument should normally be set to 0, but can be used to pass the |
98 | PCI_IRQ_NOMSI and PCI_IRQ_NOMSIX flag in case a device claims to support | ||
99 | MSI or MSI-X, but the support is broken, or to pass PCI_IRQ_NOLEGACY in | ||
100 | case the device does not support legacy interrupt lines. | ||
98 | 101 | ||
99 | int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec) | 102 | By default this function will spread the interrupts around the available |
103 | CPUs, but this feature can be disabled by passing the PCI_IRQ_NOAFFINITY | ||
104 | flag. | ||
100 | 105 | ||
101 | This function allows a device driver to request any number of MSI | 106 | To get the Linux IRQ numbers passed to request_irq() and free_irq() and the |
102 | interrupts within specified range from 'minvec' to 'maxvec'. | 107 | vectors, use the following function: |
103 | 108 | ||
104 | If this function returns a positive number it indicates the number of | 109 | int pci_irq_vector(struct pci_dev *dev, unsigned int nr); |
105 | MSI interrupts that have been successfully allocated. In this case | ||
106 | the device is switched from pin-based interrupt mode to MSI mode and | ||
107 | updates dev->irq to be the lowest of the new interrupts assigned to it. | ||
108 | The other interrupts assigned to the device are in the range dev->irq | ||
109 | to dev->irq + returned value - 1. Device driver can use the returned | ||
110 | number of successfully allocated MSI interrupts to further allocate | ||
111 | and initialize device resources. | ||
112 | 110 | ||
113 | If this function returns a negative number, it indicates an error and | 111 | Any allocated resources should be freed before removing the device using |
114 | the driver should not attempt to request any more MSI interrupts for | 112 | the following function: |
115 | this device. | ||
116 | 113 | ||
117 | This function should be called before the driver calls request_irq(), | 114 | void pci_free_irq_vectors(struct pci_dev *dev); |
118 | because MSI interrupts are delivered via vectors that are different | ||
119 | from the vector of a pin-based interrupt. | ||
120 | 115 | ||
121 | It is ideal if drivers can cope with a variable number of MSI interrupts; | 116 | If a device supports both MSI-X and MSI capabilities, this API will use the |
122 | there are many reasons why the platform may not be able to provide the | 117 | MSI-X facilities in preference to the MSI facilities. MSI-X supports any |
123 | exact number that a driver asks for. | 118 | number of interrupts between 1 and 2048. In contrast, MSI is restricted to |
119 | a maximum of 32 interrupts (and must be a power of two). In addition, the | ||
120 | MSI interrupt vectors must be allocated consecutively, so the system might | ||
121 | not be able to allocate as many vectors for MSI as it could for MSI-X. On | ||
122 | some platforms, MSI interrupts must all be targeted at the same set of CPUs | ||
123 | whereas MSI-X interrupts can all be targeted at different CPUs. | ||
124 | 124 | ||
125 | There could be devices that can not operate with just any number of MSI | 125 | If a device supports neither MSI-X or MSI it will fall back to a single |
126 | interrupts within a range. See chapter 4.3.1.3 to get the idea how to | 126 | legacy IRQ vector. |
127 | handle such devices for MSI-X - the same logic applies to MSI. | ||
128 | 127 | ||
129 | 4.2.1.1 Maximum possible number of MSI interrupts | 128 | The typical usage of MSI or MSI-X interrupts is to allocate as many vectors |
129 | as possible, likely up to the limit supported by the device. If nvec is | ||
130 | larger than the number supported by the device it will automatically be | ||
131 | capped to the supported limit, so there is no need to query the number of | ||
132 | vectors supported beforehand: | ||
130 | 133 | ||
131 | The typical usage of MSI interrupts is to allocate as many vectors as | 134 | nvec = pci_alloc_irq_vectors(pdev, 1, nvec, 0); |
132 | possible, likely up to the limit returned by pci_msi_vec_count() function: | 135 | if (nvec < 0) |
133 | 136 | goto out_err; | |
134 | static int foo_driver_enable_msi(struct pci_dev *pdev, int nvec) | ||
135 | { | ||
136 | return pci_enable_msi_range(pdev, 1, nvec); | ||
137 | } | ||
138 | |||
139 | Note the value of 'minvec' parameter is 1. As 'minvec' is inclusive, | ||
140 | the value of 0 would be meaningless and could result in error. | ||
141 | |||
142 | Some devices have a minimal limit on number of MSI interrupts. | ||
143 | In this case the function could look like this: | ||
144 | |||
145 | static int foo_driver_enable_msi(struct pci_dev *pdev, int nvec) | ||
146 | { | ||
147 | return pci_enable_msi_range(pdev, FOO_DRIVER_MINIMUM_NVEC, nvec); | ||
148 | } | ||
149 | |||
150 | 4.2.1.2 Exact number of MSI interrupts | ||
151 | 137 | ||
152 | If a driver is unable or unwilling to deal with a variable number of MSI | 138 | If a driver is unable or unwilling to deal with a variable number of MSI |
153 | interrupts it could request a particular number of interrupts by passing | 139 | interrupts it can request a particular number of interrupts by passing that |
154 | that number to pci_enable_msi_range() function as both 'minvec' and 'maxvec' | 140 | number to pci_alloc_irq_vectors() function as both 'min_vecs' and |
155 | parameters: | 141 | 'max_vecs' parameters: |
156 | |||
157 | static int foo_driver_enable_msi(struct pci_dev *pdev, int nvec) | ||
158 | { | ||
159 | return pci_enable_msi_range(pdev, nvec, nvec); | ||
160 | } | ||
161 | |||
162 | Note, unlike pci_enable_msi_exact() function, which could be also used to | ||
163 | enable a particular number of MSI-X interrupts, pci_enable_msi_range() | ||
164 | returns either a negative errno or 'nvec' (not negative errno or 0 - as | ||
165 | pci_enable_msi_exact() does). | ||
166 | |||
167 | 4.2.1.3 Single MSI mode | ||
168 | |||
169 | The most notorious example of the request type described above is | ||
170 | enabling the single MSI mode for a device. It could be done by passing | ||
171 | two 1s as 'minvec' and 'maxvec': | ||
172 | |||
173 | static int foo_driver_enable_single_msi(struct pci_dev *pdev) | ||
174 | { | ||
175 | return pci_enable_msi_range(pdev, 1, 1); | ||
176 | } | ||
177 | |||
178 | Note, unlike pci_enable_msi() function, which could be also used to | ||
179 | enable the single MSI mode, pci_enable_msi_range() returns either a | ||
180 | negative errno or 1 (not negative errno or 0 - as pci_enable_msi() | ||
181 | does). | ||
182 | |||
183 | 4.2.3 pci_enable_msi_exact | ||
184 | |||
185 | int pci_enable_msi_exact(struct pci_dev *dev, int nvec) | ||
186 | |||
187 | This variation on pci_enable_msi_range() call allows a device driver to | ||
188 | request exactly 'nvec' MSIs. | ||
189 | |||
190 | If this function returns a negative number, it indicates an error and | ||
191 | the driver should not attempt to request any more MSI interrupts for | ||
192 | this device. | ||
193 | |||
194 | By contrast with pci_enable_msi_range() function, pci_enable_msi_exact() | ||
195 | returns zero in case of success, which indicates MSI interrupts have been | ||
196 | successfully allocated. | ||
197 | |||
198 | 4.2.4 pci_disable_msi | ||
199 | |||
200 | void pci_disable_msi(struct pci_dev *dev) | ||
201 | |||
202 | This function should be used to undo the effect of pci_enable_msi_range(). | ||
203 | Calling it restores dev->irq to the pin-based interrupt number and frees | ||
204 | the previously allocated MSIs. The interrupts may subsequently be assigned | ||
205 | to another device, so drivers should not cache the value of dev->irq. | ||
206 | |||
207 | Before calling this function, a device driver must always call free_irq() | ||
208 | on any interrupt for which it previously called request_irq(). | ||
209 | Failure to do so results in a BUG_ON(), leaving the device with | ||
210 | MSI enabled and thus leaking its vector. | ||
211 | |||
212 | 4.2.4 pci_msi_vec_count | ||
213 | |||
214 | int pci_msi_vec_count(struct pci_dev *dev) | ||
215 | |||
216 | This function could be used to retrieve the number of MSI vectors the | ||
217 | device requested (via the Multiple Message Capable register). The MSI | ||
218 | specification only allows the returned value to be a power of two, | ||
219 | up to a maximum of 2^5 (32). | ||
220 | |||
221 | If this function returns a negative number, it indicates the device is | ||
222 | not capable of sending MSIs. | ||
223 | |||
224 | If this function returns a positive number, it indicates the maximum | ||
225 | number of MSI interrupt vectors that could be allocated. | ||
226 | |||
227 | 4.3 Using MSI-X | ||
228 | |||
229 | The MSI-X capability is much more flexible than the MSI capability. | ||
230 | It supports up to 2048 interrupts, each of which can be controlled | ||
231 | independently. To support this flexibility, drivers must use an array of | ||
232 | `struct msix_entry': | ||
233 | |||
234 | struct msix_entry { | ||
235 | u16 vector; /* kernel uses to write alloc vector */ | ||
236 | u16 entry; /* driver uses to specify entry */ | ||
237 | }; | ||
238 | |||
239 | This allows for the device to use these interrupts in a sparse fashion; | ||
240 | for example, it could use interrupts 3 and 1027 and yet allocate only a | ||
241 | two-element array. The driver is expected to fill in the 'entry' value | ||
242 | in each element of the array to indicate for which entries the kernel | ||
243 | should assign interrupts; it is invalid to fill in two entries with the | ||
244 | same number. | ||
245 | |||
246 | 4.3.1 pci_enable_msix_range | ||
247 | |||
248 | int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, | ||
249 | int minvec, int maxvec) | ||
250 | |||
251 | Calling this function asks the PCI subsystem to allocate any number of | ||
252 | MSI-X interrupts within specified range from 'minvec' to 'maxvec'. | ||
253 | The 'entries' argument is a pointer to an array of msix_entry structs | ||
254 | which should be at least 'maxvec' entries in size. | ||
255 | |||
256 | On success, the device is switched into MSI-X mode and the function | ||
257 | returns the number of MSI-X interrupts that have been successfully | ||
258 | allocated. In this case the 'vector' member in entries numbered from | ||
259 | 0 to the returned value - 1 is populated with the interrupt number; | ||
260 | the driver should then call request_irq() for each 'vector' that it | ||
261 | decides to use. The device driver is responsible for keeping track of the | ||
262 | interrupts assigned to the MSI-X vectors so it can free them again later. | ||
263 | Device driver can use the returned number of successfully allocated MSI-X | ||
264 | interrupts to further allocate and initialize device resources. | ||
265 | |||
266 | If this function returns a negative number, it indicates an error and | ||
267 | the driver should not attempt to allocate any more MSI-X interrupts for | ||
268 | this device. | ||
269 | |||
270 | This function, in contrast with pci_enable_msi_range(), does not adjust | ||
271 | dev->irq. The device will not generate interrupts for this interrupt | ||
272 | number once MSI-X is enabled. | ||
273 | |||
274 | Device drivers should normally call this function once per device | ||
275 | during the initialization phase. | ||
276 | |||
277 | It is ideal if drivers can cope with a variable number of MSI-X interrupts; | ||
278 | there are many reasons why the platform may not be able to provide the | ||
279 | exact number that a driver asks for. | ||
280 | |||
281 | There could be devices that can not operate with just any number of MSI-X | ||
282 | interrupts within a range. E.g., an network adapter might need let's say | ||
283 | four vectors per each queue it provides. Therefore, a number of MSI-X | ||
284 | interrupts allocated should be a multiple of four. In this case interface | ||
285 | pci_enable_msix_range() can not be used alone to request MSI-X interrupts | ||
286 | (since it can allocate any number within the range, without any notion of | ||
287 | the multiple of four) and the device driver should master a custom logic | ||
288 | to request the required number of MSI-X interrupts. | ||
289 | |||
290 | 4.3.1.1 Maximum possible number of MSI-X interrupts | ||
291 | |||
292 | The typical usage of MSI-X interrupts is to allocate as many vectors as | ||
293 | possible, likely up to the limit returned by pci_msix_vec_count() function: | ||
294 | |||
295 | static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) | ||
296 | { | ||
297 | return pci_enable_msix_range(adapter->pdev, adapter->msix_entries, | ||
298 | 1, nvec); | ||
299 | } | ||
300 | |||
301 | Note the value of 'minvec' parameter is 1. As 'minvec' is inclusive, | ||
302 | the value of 0 would be meaningless and could result in error. | ||
303 | |||
304 | Some devices have a minimal limit on number of MSI-X interrupts. | ||
305 | In this case the function could look like this: | ||
306 | |||
307 | static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) | ||
308 | { | ||
309 | return pci_enable_msix_range(adapter->pdev, adapter->msix_entries, | ||
310 | FOO_DRIVER_MINIMUM_NVEC, nvec); | ||
311 | } | ||
312 | |||
313 | 4.3.1.2 Exact number of MSI-X interrupts | ||
314 | |||
315 | If a driver is unable or unwilling to deal with a variable number of MSI-X | ||
316 | interrupts it could request a particular number of interrupts by passing | ||
317 | that number to pci_enable_msix_range() function as both 'minvec' and 'maxvec' | ||
318 | parameters: | ||
319 | |||
320 | static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) | ||
321 | { | ||
322 | return pci_enable_msix_range(adapter->pdev, adapter->msix_entries, | ||
323 | nvec, nvec); | ||
324 | } | ||
325 | |||
326 | Note, unlike pci_enable_msix_exact() function, which could be also used to | ||
327 | enable a particular number of MSI-X interrupts, pci_enable_msix_range() | ||
328 | returns either a negative errno or 'nvec' (not negative errno or 0 - as | ||
329 | pci_enable_msix_exact() does). | ||
330 | |||
331 | 4.3.1.3 Specific requirements to the number of MSI-X interrupts | ||
332 | |||
333 | As noted above, there could be devices that can not operate with just any | ||
334 | number of MSI-X interrupts within a range. E.g., let's assume a device that | ||
335 | is only capable sending the number of MSI-X interrupts which is a power of | ||
336 | two. A routine that enables MSI-X mode for such device might look like this: | ||
337 | |||
338 | /* | ||
339 | * Assume 'minvec' and 'maxvec' are non-zero | ||
340 | */ | ||
341 | static int foo_driver_enable_msix(struct foo_adapter *adapter, | ||
342 | int minvec, int maxvec) | ||
343 | { | ||
344 | int rc; | ||
345 | |||
346 | minvec = roundup_pow_of_two(minvec); | ||
347 | maxvec = rounddown_pow_of_two(maxvec); | ||
348 | |||
349 | if (minvec > maxvec) | ||
350 | return -ERANGE; | ||
351 | |||
352 | retry: | ||
353 | rc = pci_enable_msix_range(adapter->pdev, adapter->msix_entries, | ||
354 | maxvec, maxvec); | ||
355 | /* | ||
356 | * -ENOSPC is the only error code allowed to be analyzed | ||
357 | */ | ||
358 | if (rc == -ENOSPC) { | ||
359 | if (maxvec == 1) | ||
360 | return -ENOSPC; | ||
361 | |||
362 | maxvec /= 2; | ||
363 | |||
364 | if (minvec > maxvec) | ||
365 | return -ENOSPC; | ||
366 | |||
367 | goto retry; | ||
368 | } | ||
369 | |||
370 | return rc; | ||
371 | } | ||
372 | |||
373 | Note how pci_enable_msix_range() return value is analyzed for a fallback - | ||
374 | any error code other than -ENOSPC indicates a fatal error and should not | ||
375 | be retried. | ||
376 | |||
377 | 4.3.2 pci_enable_msix_exact | ||
378 | |||
379 | int pci_enable_msix_exact(struct pci_dev *dev, | ||
380 | struct msix_entry *entries, int nvec) | ||
381 | |||
382 | This variation on pci_enable_msix_range() call allows a device driver to | ||
383 | request exactly 'nvec' MSI-Xs. | ||
384 | |||
385 | If this function returns a negative number, it indicates an error and | ||
386 | the driver should not attempt to allocate any more MSI-X interrupts for | ||
387 | this device. | ||
388 | |||
389 | By contrast with pci_enable_msix_range() function, pci_enable_msix_exact() | ||
390 | returns zero in case of success, which indicates MSI-X interrupts have been | ||
391 | successfully allocated. | ||
392 | |||
393 | Another version of a routine that enables MSI-X mode for a device with | ||
394 | specific requirements described in chapter 4.3.1.3 might look like this: | ||
395 | |||
396 | /* | ||
397 | * Assume 'minvec' and 'maxvec' are non-zero | ||
398 | */ | ||
399 | static int foo_driver_enable_msix(struct foo_adapter *adapter, | ||
400 | int minvec, int maxvec) | ||
401 | { | ||
402 | int rc; | ||
403 | |||
404 | minvec = roundup_pow_of_two(minvec); | ||
405 | maxvec = rounddown_pow_of_two(maxvec); | ||
406 | |||
407 | if (minvec > maxvec) | ||
408 | return -ERANGE; | ||
409 | |||
410 | retry: | ||
411 | rc = pci_enable_msix_exact(adapter->pdev, | ||
412 | adapter->msix_entries, maxvec); | ||
413 | |||
414 | /* | ||
415 | * -ENOSPC is the only error code allowed to be analyzed | ||
416 | */ | ||
417 | if (rc == -ENOSPC) { | ||
418 | if (maxvec == 1) | ||
419 | return -ENOSPC; | ||
420 | |||
421 | maxvec /= 2; | ||
422 | |||
423 | if (minvec > maxvec) | ||
424 | return -ENOSPC; | ||
425 | |||
426 | goto retry; | ||
427 | } else if (rc < 0) { | ||
428 | return rc; | ||
429 | } | ||
430 | |||
431 | return maxvec; | ||
432 | } | ||
433 | |||
434 | 4.3.3 pci_disable_msix | ||
435 | |||
436 | void pci_disable_msix(struct pci_dev *dev) | ||
437 | |||
438 | This function should be used to undo the effect of pci_enable_msix_range(). | ||
439 | It frees the previously allocated MSI-X interrupts. The interrupts may | ||
440 | subsequently be assigned to another device, so drivers should not cache | ||
441 | the value of the 'vector' elements over a call to pci_disable_msix(). | ||
442 | |||
443 | Before calling this function, a device driver must always call free_irq() | ||
444 | on any interrupt for which it previously called request_irq(). | ||
445 | Failure to do so results in a BUG_ON(), leaving the device with | ||
446 | MSI-X enabled and thus leaking its vector. | ||
447 | |||
448 | 4.3.3 The MSI-X Table | ||
449 | |||
450 | The MSI-X capability specifies a BAR and offset within that BAR for the | ||
451 | MSI-X Table. This address is mapped by the PCI subsystem, and should not | ||
452 | be accessed directly by the device driver. If the driver wishes to | ||
453 | mask or unmask an interrupt, it should call disable_irq() / enable_irq(). | ||
454 | 142 | ||
455 | 4.3.4 pci_msix_vec_count | 143 | ret = pci_alloc_irq_vectors(pdev, nvec, nvec, 0); |
144 | if (ret < 0) | ||
145 | goto out_err; | ||
456 | 146 | ||
457 | int pci_msix_vec_count(struct pci_dev *dev) | 147 | The most notorious example of the request type described above is enabling |
148 | the single MSI mode for a device. It could be done by passing two 1s as | ||
149 | 'min_vecs' and 'max_vecs': | ||
458 | 150 | ||
459 | This function could be used to retrieve number of entries in the device | 151 | ret = pci_alloc_irq_vectors(pdev, 1, 1, 0); |
460 | MSI-X table. | 152 | if (ret < 0) |
153 | goto out_err; | ||
461 | 154 | ||
462 | If this function returns a negative number, it indicates the device is | 155 | Some devices might not support using legacy line interrupts, in which case |
463 | not capable of sending MSI-Xs. | 156 | the PCI_IRQ_NOLEGACY flag can be used to fail the request if the platform |
157 | can't provide MSI or MSI-X interrupts: | ||
464 | 158 | ||
465 | If this function returns a positive number, it indicates the maximum | 159 | nvec = pci_alloc_irq_vectors(pdev, 1, nvec, PCI_IRQ_NOLEGACY); |
466 | number of MSI-X interrupt vectors that could be allocated. | 160 | if (nvec < 0) |
161 | goto out_err; | ||
467 | 162 | ||
468 | 4.4 Handling devices implementing both MSI and MSI-X capabilities | 163 | 4.3 Legacy APIs |
469 | 164 | ||
470 | If a device implements both MSI and MSI-X capabilities, it can | 165 | The following old APIs to enable and disable MSI or MSI-X interrupts should |
471 | run in either MSI mode or MSI-X mode, but not both simultaneously. | 166 | not be used in new code: |
472 | This is a requirement of the PCI spec, and it is enforced by the | ||
473 | PCI layer. Calling pci_enable_msi_range() when MSI-X is already | ||
474 | enabled or pci_enable_msix_range() when MSI is already enabled | ||
475 | results in an error. If a device driver wishes to switch between MSI | ||
476 | and MSI-X at runtime, it must first quiesce the device, then switch | ||
477 | it back to pin-interrupt mode, before calling pci_enable_msi_range() | ||
478 | or pci_enable_msix_range() and resuming operation. This is not expected | ||
479 | to be a common operation but may be useful for debugging or testing | ||
480 | during development. | ||
481 | 167 | ||
482 | 4.5 Considerations when using MSIs | 168 | pci_enable_msi() /* deprecated */ |
169 | pci_enable_msi_range() /* deprecated */ | ||
170 | pci_enable_msi_exact() /* deprecated */ | ||
171 | pci_disable_msi() /* deprecated */ | ||
172 | pci_enable_msix_range() /* deprecated */ | ||
173 | pci_enable_msix_exact() /* deprecated */ | ||
174 | pci_disable_msix() /* deprecated */ | ||
483 | 175 | ||
484 | 4.5.1 Choosing between MSI-X and MSI | 176 | Additionally there are APIs to provide the number of supported MSI or MSI-X |
177 | vectors: pci_msi_vec_count() and pci_msix_vec_count(). In general these | ||
178 | should be avoided in favor of letting pci_alloc_irq_vectors() cap the | ||
179 | number of vectors. If you have a legitimate special use case for the count | ||
180 | of vectors we might have to revisit that decision and add a | ||
181 | pci_nr_irq_vectors() helper that handles MSI and MSI-X transparently. | ||
485 | 182 | ||
486 | If your device supports both MSI-X and MSI capabilities, you should use | 183 | 4.4 Considerations when using MSIs |
487 | the MSI-X facilities in preference to the MSI facilities. As mentioned | ||
488 | above, MSI-X supports any number of interrupts between 1 and 2048. | ||
489 | In contrast, MSI is restricted to a maximum of 32 interrupts (and | ||
490 | must be a power of two). In addition, the MSI interrupt vectors must | ||
491 | be allocated consecutively, so the system might not be able to allocate | ||
492 | as many vectors for MSI as it could for MSI-X. On some platforms, MSI | ||
493 | interrupts must all be targeted at the same set of CPUs whereas MSI-X | ||
494 | interrupts can all be targeted at different CPUs. | ||
495 | 184 | ||
496 | 4.5.2 Spinlocks | 185 | 4.4.1 Spinlocks |
497 | 186 | ||
498 | Most device drivers have a per-device spinlock which is taken in the | 187 | Most device drivers have a per-device spinlock which is taken in the |
499 | interrupt handler. With pin-based interrupts or a single MSI, it is not | 188 | interrupt handler. With pin-based interrupts or a single MSI, it is not |
@@ -505,7 +194,7 @@ acquire the spinlock. Such deadlocks can be avoided by using | |||
505 | spin_lock_irqsave() or spin_lock_irq() which disable local interrupts | 194 | spin_lock_irqsave() or spin_lock_irq() which disable local interrupts |
506 | and acquire the lock (see Documentation/DocBook/kernel-locking). | 195 | and acquire the lock (see Documentation/DocBook/kernel-locking). |
507 | 196 | ||
508 | 4.6 How to tell whether MSI/MSI-X is enabled on a device | 197 | 4.5 How to tell whether MSI/MSI-X is enabled on a device |
509 | 198 | ||
510 | Using 'lspci -v' (as root) may show some devices with "MSI", "Message | 199 | Using 'lspci -v' (as root) may show some devices with "MSI", "Message |
511 | Signalled Interrupts" or "MSI-X" capabilities. Each of these capabilities | 200 | Signalled Interrupts" or "MSI-X" capabilities. Each of these capabilities |
diff --git a/Documentation/devicetree/bindings/pci/aardvark-pci.txt b/Documentation/devicetree/bindings/pci/aardvark-pci.txt new file mode 100644 index 000000000000..bbcd9f4c501f --- /dev/null +++ b/Documentation/devicetree/bindings/pci/aardvark-pci.txt | |||
@@ -0,0 +1,56 @@ | |||
1 | Aardvark PCIe controller | ||
2 | |||
3 | This PCIe controller is used on the Marvell Armada 3700 ARM64 SoC. | ||
4 | |||
5 | The Device Tree node describing an Aardvark PCIe controller must | ||
6 | contain the following properties: | ||
7 | |||
8 | - compatible: Should be "marvell,armada-3700-pcie" | ||
9 | - reg: range of registers for the PCIe controller | ||
10 | - interrupts: the interrupt line of the PCIe controller | ||
11 | - #address-cells: set to <3> | ||
12 | - #size-cells: set to <2> | ||
13 | - device_type: set to "pci" | ||
14 | - ranges: ranges for the PCI memory and I/O regions | ||
15 | - #interrupt-cells: set to <1> | ||
16 | - msi-controller: indicates that the PCIe controller can itself | ||
17 | handle MSI interrupts | ||
18 | - msi-parent: pointer to the MSI controller to be used | ||
19 | - interrupt-map-mask and interrupt-map: standard PCI properties to | ||
20 | define the mapping of the PCIe interface to interrupt numbers. | ||
21 | - bus-range: PCI bus numbers covered | ||
22 | |||
23 | In addition, the Device Tree describing an Aardvark PCIe controller | ||
24 | must include a sub-node that describes the legacy interrupt controller | ||
25 | built into the PCIe controller. This sub-node must have the following | ||
26 | properties: | ||
27 | |||
28 | - interrupt-controller | ||
29 | - #interrupt-cells: set to <1> | ||
30 | |||
31 | Example: | ||
32 | |||
33 | pcie0: pcie@d0070000 { | ||
34 | compatible = "marvell,armada-3700-pcie"; | ||
35 | device_type = "pci"; | ||
36 | status = "disabled"; | ||
37 | reg = <0 0xd0070000 0 0x20000>; | ||
38 | #address-cells = <3>; | ||
39 | #size-cells = <2>; | ||
40 | bus-range = <0x00 0xff>; | ||
41 | interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; | ||
42 | #interrupt-cells = <1>; | ||
43 | msi-controller; | ||
44 | msi-parent = <&pcie0>; | ||
45 | ranges = <0x82000000 0 0xe8000000 0 0xe8000000 0 0x1000000 /* Port 0 MEM */ | ||
46 | 0x81000000 0 0xe9000000 0 0xe9000000 0 0x10000>; /* Port 0 IO*/ | ||
47 | interrupt-map-mask = <0 0 0 7>; | ||
48 | interrupt-map = <0 0 0 1 &pcie_intc 0>, | ||
49 | <0 0 0 2 &pcie_intc 1>, | ||
50 | <0 0 0 3 &pcie_intc 2>, | ||
51 | <0 0 0 4 &pcie_intc 3>; | ||
52 | pcie_intc: interrupt-controller { | ||
53 | interrupt-controller; | ||
54 | #interrupt-cells = <1>; | ||
55 | }; | ||
56 | }; | ||
diff --git a/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt b/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt new file mode 100644 index 000000000000..330a45b5f0b5 --- /dev/null +++ b/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt | |||
@@ -0,0 +1,46 @@ | |||
1 | * Axis ARTPEC-6 PCIe interface | ||
2 | |||
3 | This PCIe host controller is based on the Synopsys DesignWare PCIe IP | ||
4 | and thus inherits all the common properties defined in designware-pcie.txt. | ||
5 | |||
6 | Required properties: | ||
7 | - compatible: "axis,artpec6-pcie", "snps,dw-pcie" | ||
8 | - reg: base addresses and lengths of the PCIe controller (DBI), | ||
9 | the phy controller, and configuration address space. | ||
10 | - reg-names: Must include the following entries: | ||
11 | - "dbi" | ||
12 | - "phy" | ||
13 | - "config" | ||
14 | - interrupts: A list of interrupt outputs of the controller. Must contain an | ||
15 | entry for each entry in the interrupt-names property. | ||
16 | - interrupt-names: Must include the following entries: | ||
17 | - "msi": The interrupt that is asserted when an MSI is received | ||
18 | - axis,syscon-pcie: A phandle pointing to the ARTPEC-6 system controller, | ||
19 | used to enable and control the Synopsys IP. | ||
20 | |||
21 | Example: | ||
22 | |||
23 | pcie@f8050000 { | ||
24 | compatible = "axis,artpec6-pcie", "snps,dw-pcie"; | ||
25 | reg = <0xf8050000 0x2000 | ||
26 | 0xf8040000 0x1000 | ||
27 | 0xc0000000 0x1000>; | ||
28 | reg-names = "dbi", "phy", "config"; | ||
29 | #address-cells = <3>; | ||
30 | #size-cells = <2>; | ||
31 | device_type = "pci"; | ||
32 | /* downstream I/O */ | ||
33 | ranges = <0x81000000 0 0x00010000 0xc0010000 0 0x00010000 | ||
34 | /* non-prefetchable memory */ | ||
35 | 0x82000000 0 0xc0020000 0xc0020000 0 0x1ffe0000>; | ||
36 | num-lanes = <2>; | ||
37 | interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>; | ||
38 | interrupt-names = "msi"; | ||
39 | #interrupt-cells = <1>; | ||
40 | interrupt-map-mask = <0 0 0 0x7>; | ||
41 | interrupt-map = <0 0 0 1 &intc GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>, | ||
42 | <0 0 0 2 &intc GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>, | ||
43 | <0 0 0 3 &intc GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>, | ||
44 | <0 0 0 4 &intc GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>; | ||
45 | axis,syscon-pcie = <&syscon>; | ||
46 | }; | ||
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index e24aa11e8f8a..642029012059 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -3021,6 +3021,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
3021 | resource_alignment= | 3021 | resource_alignment= |
3022 | Format: | 3022 | Format: |
3023 | [<order of align>@][<domain>:]<bus>:<slot>.<func>[; ...] | 3023 | [<order of align>@][<domain>:]<bus>:<slot>.<func>[; ...] |
3024 | [<order of align>@]pci:<vendor>:<device>\ | ||
3025 | [:<subvendor>:<subdevice>][; ...] | ||
3024 | Specifies alignment and device to reassign | 3026 | Specifies alignment and device to reassign |
3025 | aligned memory resources. | 3027 | aligned memory resources. |
3026 | If <order of align> is not specified, | 3028 | If <order of align> is not specified, |
@@ -3039,6 +3041,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
3039 | hpmemsize=nn[KMG] The fixed amount of bus space which is | 3041 | hpmemsize=nn[KMG] The fixed amount of bus space which is |
3040 | reserved for hotplug bridge's memory window. | 3042 | reserved for hotplug bridge's memory window. |
3041 | Default size is 2 megabytes. | 3043 | Default size is 2 megabytes. |
3044 | hpbussize=nn The minimum amount of additional bus numbers | ||
3045 | reserved for buses below a hotplug bridge. | ||
3046 | Default is 1. | ||
3042 | realloc= Enable/disable reallocating PCI bridge resources | 3047 | realloc= Enable/disable reallocating PCI bridge resources |
3043 | if allocations done by BIOS are too small to | 3048 | if allocations done by BIOS are too small to |
3044 | accommodate resources required by all child | 3049 | accommodate resources required by all child |
@@ -3070,6 +3075,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
3070 | compat Treat PCIe ports as PCI-to-PCI bridges, disable the PCIe | 3075 | compat Treat PCIe ports as PCI-to-PCI bridges, disable the PCIe |
3071 | ports driver. | 3076 | ports driver. |
3072 | 3077 | ||
3078 | pcie_port_pm= [PCIE] PCIe port power management handling: | ||
3079 | off Disable power management of all PCIe ports | ||
3080 | force Forcibly enable power management of all PCIe ports | ||
3081 | |||
3073 | pcie_pme= [PCIE,PM] Native PCIe PME signaling options: | 3082 | pcie_pme= [PCIE,PM] Native PCIe PME signaling options: |
3074 | nomsi Do not use MSI for native PCIe PME signaling (this makes | 3083 | nomsi Do not use MSI for native PCIe PME signaling (this makes |
3075 | all PCIe root ports use INTx for all services). | 3084 | all PCIe root ports use INTx for all services). |
diff --git a/MAINTAINERS b/MAINTAINERS index 8f950e2752de..10074ff03c57 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -8883,6 +8883,7 @@ L: linux-pci@vger.kernel.org | |||
8883 | Q: http://patchwork.ozlabs.org/project/linux-pci/list/ | 8883 | Q: http://patchwork.ozlabs.org/project/linux-pci/list/ |
8884 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git | 8884 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git |
8885 | S: Supported | 8885 | S: Supported |
8886 | F: Documentation/devicetree/bindings/pci/ | ||
8886 | F: Documentation/PCI/ | 8887 | F: Documentation/PCI/ |
8887 | F: drivers/pci/ | 8888 | F: drivers/pci/ |
8888 | F: include/linux/pci* | 8889 | F: include/linux/pci* |
@@ -8946,6 +8947,13 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | |||
8946 | S: Maintained | 8947 | S: Maintained |
8947 | F: drivers/pci/host/*mvebu* | 8948 | F: drivers/pci/host/*mvebu* |
8948 | 8949 | ||
8950 | PCI DRIVER FOR AARDVARK (Marvell Armada 3700) | ||
8951 | M: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
8952 | L: linux-pci@vger.kernel.org | ||
8953 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||
8954 | S: Maintained | ||
8955 | F: drivers/pci/host/pci-aardvark.c | ||
8956 | |||
8949 | PCI DRIVER FOR NVIDIA TEGRA | 8957 | PCI DRIVER FOR NVIDIA TEGRA |
8950 | M: Thierry Reding <thierry.reding@gmail.com> | 8958 | M: Thierry Reding <thierry.reding@gmail.com> |
8951 | L: linux-tegra@vger.kernel.org | 8959 | L: linux-tegra@vger.kernel.org |
@@ -9028,6 +9036,15 @@ S: Maintained | |||
9028 | F: Documentation/devicetree/bindings/pci/xgene-pci-msi.txt | 9036 | F: Documentation/devicetree/bindings/pci/xgene-pci-msi.txt |
9029 | F: drivers/pci/host/pci-xgene-msi.c | 9037 | F: drivers/pci/host/pci-xgene-msi.c |
9030 | 9038 | ||
9039 | PCIE DRIVER FOR AXIS ARTPEC | ||
9040 | M: Niklas Cassel <niklas.cassel@axis.com> | ||
9041 | M: Jesper Nilsson <jesper.nilsson@axis.com> | ||
9042 | L: linux-arm-kernel@axis.com | ||
9043 | L: linux-pci@vger.kernel.org | ||
9044 | S: Maintained | ||
9045 | F: Documentation/devicetree/bindings/pci/axis,artpec* | ||
9046 | F: drivers/pci/host/*artpec* | ||
9047 | |||
9031 | PCIE DRIVER FOR HISILICON | 9048 | PCIE DRIVER FOR HISILICON |
9032 | M: Zhou Wang <wangzhou1@hisilicon.com> | 9049 | M: Zhou Wang <wangzhou1@hisilicon.com> |
9033 | M: Gabriele Paoloni <gabriele.paoloni@huawei.com> | 9050 | M: Gabriele Paoloni <gabriele.paoloni@huawei.com> |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index fc3dc0b90be2..2d601d769a1c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -700,7 +700,7 @@ config ARCH_VIRT | |||
700 | depends on ARCH_MULTI_V7 | 700 | depends on ARCH_MULTI_V7 |
701 | select ARM_AMBA | 701 | select ARM_AMBA |
702 | select ARM_GIC | 702 | select ARM_GIC |
703 | select ARM_GIC_V2M if PCI_MSI | 703 | select ARM_GIC_V2M if PCI |
704 | select ARM_GIC_V3 | 704 | select ARM_GIC_V3 |
705 | select ARM_PSCI | 705 | select ARM_PSCI |
706 | select HAVE_ARM_ARCH_TIMER | 706 | select HAVE_ARM_ARCH_TIMER |
diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h index 0070e8520cd4..2d88af5be45f 100644 --- a/arch/arm/include/asm/mach/pci.h +++ b/arch/arm/include/asm/mach/pci.h | |||
@@ -22,6 +22,7 @@ struct hw_pci { | |||
22 | struct msi_controller *msi_ctrl; | 22 | struct msi_controller *msi_ctrl; |
23 | struct pci_ops *ops; | 23 | struct pci_ops *ops; |
24 | int nr_controllers; | 24 | int nr_controllers; |
25 | unsigned int io_optional:1; | ||
25 | void **private_data; | 26 | void **private_data; |
26 | int (*setup)(int nr, struct pci_sys_data *); | 27 | int (*setup)(int nr, struct pci_sys_data *); |
27 | struct pci_bus *(*scan)(int nr, struct pci_sys_data *); | 28 | struct pci_bus *(*scan)(int nr, struct pci_sys_data *); |
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index 05e61a2eeabe..2f0e07735d1d 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c | |||
@@ -410,7 +410,8 @@ static int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |||
410 | return irq; | 410 | return irq; |
411 | } | 411 | } |
412 | 412 | ||
413 | static int pcibios_init_resources(int busnr, struct pci_sys_data *sys) | 413 | static int pcibios_init_resource(int busnr, struct pci_sys_data *sys, |
414 | int io_optional) | ||
414 | { | 415 | { |
415 | int ret; | 416 | int ret; |
416 | struct resource_entry *window; | 417 | struct resource_entry *window; |
@@ -420,6 +421,14 @@ static int pcibios_init_resources(int busnr, struct pci_sys_data *sys) | |||
420 | &iomem_resource, sys->mem_offset); | 421 | &iomem_resource, sys->mem_offset); |
421 | } | 422 | } |
422 | 423 | ||
424 | /* | ||
425 | * If a platform says I/O port support is optional, we don't add | ||
426 | * the default I/O space. The platform is responsible for adding | ||
427 | * any I/O space it needs. | ||
428 | */ | ||
429 | if (io_optional) | ||
430 | return 0; | ||
431 | |||
423 | resource_list_for_each_entry(window, &sys->resources) | 432 | resource_list_for_each_entry(window, &sys->resources) |
424 | if (resource_type(window->res) == IORESOURCE_IO) | 433 | if (resource_type(window->res) == IORESOURCE_IO) |
425 | return 0; | 434 | return 0; |
@@ -466,7 +475,7 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw, | |||
466 | if (ret > 0) { | 475 | if (ret > 0) { |
467 | struct pci_host_bridge *host_bridge; | 476 | struct pci_host_bridge *host_bridge; |
468 | 477 | ||
469 | ret = pcibios_init_resources(nr, sys); | 478 | ret = pcibios_init_resource(nr, sys, hw->io_optional); |
470 | if (ret) { | 479 | if (ret) { |
471 | kfree(sys); | 480 | kfree(sys); |
472 | break; | 481 | break; |
@@ -515,25 +524,23 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw) | |||
515 | list_for_each_entry(sys, &head, node) { | 524 | list_for_each_entry(sys, &head, node) { |
516 | struct pci_bus *bus = sys->bus; | 525 | struct pci_bus *bus = sys->bus; |
517 | 526 | ||
518 | if (!pci_has_flag(PCI_PROBE_ONLY)) { | 527 | /* |
528 | * We insert PCI resources into the iomem_resource and | ||
529 | * ioport_resource trees in either pci_bus_claim_resources() | ||
530 | * or pci_bus_assign_resources(). | ||
531 | */ | ||
532 | if (pci_has_flag(PCI_PROBE_ONLY)) { | ||
533 | pci_bus_claim_resources(bus); | ||
534 | } else { | ||
519 | struct pci_bus *child; | 535 | struct pci_bus *child; |
520 | 536 | ||
521 | /* | ||
522 | * Size the bridge windows. | ||
523 | */ | ||
524 | pci_bus_size_bridges(bus); | 537 | pci_bus_size_bridges(bus); |
525 | |||
526 | /* | ||
527 | * Assign resources. | ||
528 | */ | ||
529 | pci_bus_assign_resources(bus); | 538 | pci_bus_assign_resources(bus); |
530 | 539 | ||
531 | list_for_each_entry(child, &bus->children, node) | 540 | list_for_each_entry(child, &bus->children, node) |
532 | pcie_bus_configure_settings(child); | 541 | pcie_bus_configure_settings(child); |
533 | } | 542 | } |
534 | /* | 543 | |
535 | * Tell drivers about devices found. | ||
536 | */ | ||
537 | pci_bus_add_devices(bus); | 544 | pci_bus_add_devices(bus); |
538 | } | 545 | } |
539 | } | 546 | } |
@@ -590,18 +597,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, | |||
590 | return start; | 597 | return start; |
591 | } | 598 | } |
592 | 599 | ||
593 | /** | ||
594 | * pcibios_enable_device - Enable I/O and memory. | ||
595 | * @dev: PCI device to be enabled | ||
596 | */ | ||
597 | int pcibios_enable_device(struct pci_dev *dev, int mask) | ||
598 | { | ||
599 | if (pci_has_flag(PCI_PROBE_ONLY)) | ||
600 | return 0; | ||
601 | |||
602 | return pci_enable_resources(dev, mask); | ||
603 | } | ||
604 | |||
605 | int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | 600 | int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, |
606 | enum pci_mmap_state mmap_state, int write_combine) | 601 | enum pci_mmap_state mmap_state, int write_combine) |
607 | { | 602 | { |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 1b06db571fff..69c8787bec7d 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig | |||
@@ -3,6 +3,7 @@ config ARM64 | |||
3 | select ACPI_CCA_REQUIRED if ACPI | 3 | select ACPI_CCA_REQUIRED if ACPI |
4 | select ACPI_GENERIC_GSI if ACPI | 4 | select ACPI_GENERIC_GSI if ACPI |
5 | select ACPI_REDUCED_HARDWARE_ONLY if ACPI | 5 | select ACPI_REDUCED_HARDWARE_ONLY if ACPI |
6 | select ACPI_MCFG if ACPI | ||
6 | select ARCH_HAS_DEVMEM_IS_ALLOWED | 7 | select ARCH_HAS_DEVMEM_IS_ALLOWED |
7 | select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI | 8 | select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI |
8 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE | 9 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE |
@@ -22,9 +23,9 @@ config ARM64 | |||
22 | select ARM_ARCH_TIMER | 23 | select ARM_ARCH_TIMER |
23 | select ARM_GIC | 24 | select ARM_GIC |
24 | select AUDIT_ARCH_COMPAT_GENERIC | 25 | select AUDIT_ARCH_COMPAT_GENERIC |
25 | select ARM_GIC_V2M if PCI_MSI | 26 | select ARM_GIC_V2M if PCI |
26 | select ARM_GIC_V3 | 27 | select ARM_GIC_V3 |
27 | select ARM_GIC_V3_ITS if PCI_MSI | 28 | select ARM_GIC_V3_ITS if PCI |
28 | select ARM_PSCI_FW | 29 | select ARM_PSCI_FW |
29 | select BUILDTIME_EXTABLE_SORT | 30 | select BUILDTIME_EXTABLE_SORT |
30 | select CLONE_BACKWARDS | 31 | select CLONE_BACKWARDS |
@@ -102,6 +103,7 @@ config ARM64 | |||
102 | select OF_EARLY_FLATTREE | 103 | select OF_EARLY_FLATTREE |
103 | select OF_NUMA if NUMA && OF | 104 | select OF_NUMA if NUMA && OF |
104 | select OF_RESERVED_MEM | 105 | select OF_RESERVED_MEM |
106 | select PCI_ECAM if ACPI | ||
105 | select PERF_USE_VMALLOC | 107 | select PERF_USE_VMALLOC |
106 | select POWER_RESET | 108 | select POWER_RESET |
107 | select POWER_SUPPLY | 109 | select POWER_SUPPLY |
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-db.dts b/arch/arm64/boot/dts/marvell/armada-3720-db.dts index 86110a6ae330..1372e9a6aaa4 100644 --- a/arch/arm64/boot/dts/marvell/armada-3720-db.dts +++ b/arch/arm64/boot/dts/marvell/armada-3720-db.dts | |||
@@ -76,3 +76,8 @@ | |||
76 | &usb3 { | 76 | &usb3 { |
77 | status = "okay"; | 77 | status = "okay"; |
78 | }; | 78 | }; |
79 | |||
80 | /* CON17 (PCIe) / CON12 (mini-PCIe) */ | ||
81 | &pcie0 { | ||
82 | status = "okay"; | ||
83 | }; | ||
diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi index eb29280962d7..c4762538ec01 100644 --- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi | |||
@@ -176,5 +176,30 @@ | |||
176 | <0x1d40000 0x40000>; /* GICR */ | 176 | <0x1d40000 0x40000>; /* GICR */ |
177 | }; | 177 | }; |
178 | }; | 178 | }; |
179 | |||
180 | pcie0: pcie@d0070000 { | ||
181 | compatible = "marvell,armada-3700-pcie"; | ||
182 | device_type = "pci"; | ||
183 | status = "disabled"; | ||
184 | reg = <0 0xd0070000 0 0x20000>; | ||
185 | #address-cells = <3>; | ||
186 | #size-cells = <2>; | ||
187 | bus-range = <0x00 0xff>; | ||
188 | interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; | ||
189 | #interrupt-cells = <1>; | ||
190 | msi-parent = <&pcie0>; | ||
191 | msi-controller; | ||
192 | ranges = <0x82000000 0 0xe8000000 0 0xe8000000 0 0x1000000 /* Port 0 MEM */ | ||
193 | 0x81000000 0 0xe9000000 0 0xe9000000 0 0x10000>; /* Port 0 IO*/ | ||
194 | interrupt-map-mask = <0 0 0 7>; | ||
195 | interrupt-map = <0 0 0 1 &pcie_intc 0>, | ||
196 | <0 0 0 2 &pcie_intc 1>, | ||
197 | <0 0 0 3 &pcie_intc 2>, | ||
198 | <0 0 0 4 &pcie_intc 3>; | ||
199 | pcie_intc: interrupt-controller { | ||
200 | interrupt-controller; | ||
201 | #interrupt-cells = <1>; | ||
202 | }; | ||
203 | }; | ||
179 | }; | 204 | }; |
180 | }; | 205 | }; |
diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c index 3c4e308b40a0..acf38722457b 100644 --- a/arch/arm64/kernel/pci.c +++ b/arch/arm64/kernel/pci.c | |||
@@ -17,6 +17,9 @@ | |||
17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
18 | #include <linux/of_pci.h> | 18 | #include <linux/of_pci.h> |
19 | #include <linux/of_platform.h> | 19 | #include <linux/of_platform.h> |
20 | #include <linux/pci.h> | ||
21 | #include <linux/pci-acpi.h> | ||
22 | #include <linux/pci-ecam.h> | ||
20 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
21 | 24 | ||
22 | /* | 25 | /* |
@@ -36,25 +39,17 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, | |||
36 | return res->start; | 39 | return res->start; |
37 | } | 40 | } |
38 | 41 | ||
39 | /** | ||
40 | * pcibios_enable_device - Enable I/O and memory. | ||
41 | * @dev: PCI device to be enabled | ||
42 | * @mask: bitmask of BARs to enable | ||
43 | */ | ||
44 | int pcibios_enable_device(struct pci_dev *dev, int mask) | ||
45 | { | ||
46 | if (pci_has_flag(PCI_PROBE_ONLY)) | ||
47 | return 0; | ||
48 | |||
49 | return pci_enable_resources(dev, mask); | ||
50 | } | ||
51 | |||
52 | /* | 42 | /* |
53 | * Try to assign the IRQ number from DT when adding a new device | 43 | * Try to assign the IRQ number when probing a new device |
54 | */ | 44 | */ |
55 | int pcibios_add_device(struct pci_dev *dev) | 45 | int pcibios_alloc_irq(struct pci_dev *dev) |
56 | { | 46 | { |
57 | dev->irq = of_irq_parse_and_map_pci(dev, 0, 0); | 47 | if (acpi_disabled) |
48 | dev->irq = of_irq_parse_and_map_pci(dev, 0, 0); | ||
49 | #ifdef CONFIG_ACPI | ||
50 | else | ||
51 | return acpi_pci_irq_enable(dev); | ||
52 | #endif | ||
58 | 53 | ||
59 | return 0; | 54 | return 0; |
60 | } | 55 | } |
@@ -65,13 +60,21 @@ int pcibios_add_device(struct pci_dev *dev) | |||
65 | int raw_pci_read(unsigned int domain, unsigned int bus, | 60 | int raw_pci_read(unsigned int domain, unsigned int bus, |
66 | unsigned int devfn, int reg, int len, u32 *val) | 61 | unsigned int devfn, int reg, int len, u32 *val) |
67 | { | 62 | { |
68 | return -ENXIO; | 63 | struct pci_bus *b = pci_find_bus(domain, bus); |
64 | |||
65 | if (!b) | ||
66 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
67 | return b->ops->read(b, devfn, reg, len, val); | ||
69 | } | 68 | } |
70 | 69 | ||
71 | int raw_pci_write(unsigned int domain, unsigned int bus, | 70 | int raw_pci_write(unsigned int domain, unsigned int bus, |
72 | unsigned int devfn, int reg, int len, u32 val) | 71 | unsigned int devfn, int reg, int len, u32 val) |
73 | { | 72 | { |
74 | return -ENXIO; | 73 | struct pci_bus *b = pci_find_bus(domain, bus); |
74 | |||
75 | if (!b) | ||
76 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
77 | return b->ops->write(b, devfn, reg, len, val); | ||
75 | } | 78 | } |
76 | 79 | ||
77 | #ifdef CONFIG_NUMA | 80 | #ifdef CONFIG_NUMA |
@@ -85,10 +88,124 @@ EXPORT_SYMBOL(pcibus_to_node); | |||
85 | #endif | 88 | #endif |
86 | 89 | ||
87 | #ifdef CONFIG_ACPI | 90 | #ifdef CONFIG_ACPI |
88 | /* Root bridge scanning */ | 91 | |
92 | struct acpi_pci_generic_root_info { | ||
93 | struct acpi_pci_root_info common; | ||
94 | struct pci_config_window *cfg; /* config space mapping */ | ||
95 | }; | ||
96 | |||
97 | int acpi_pci_bus_find_domain_nr(struct pci_bus *bus) | ||
98 | { | ||
99 | struct pci_config_window *cfg = bus->sysdata; | ||
100 | struct acpi_device *adev = to_acpi_device(cfg->parent); | ||
101 | struct acpi_pci_root *root = acpi_driver_data(adev); | ||
102 | |||
103 | return root->segment; | ||
104 | } | ||
105 | |||
106 | int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) | ||
107 | { | ||
108 | if (!acpi_disabled) { | ||
109 | struct pci_config_window *cfg = bridge->bus->sysdata; | ||
110 | struct acpi_device *adev = to_acpi_device(cfg->parent); | ||
111 | ACPI_COMPANION_SET(&bridge->dev, adev); | ||
112 | } | ||
113 | |||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | /* | ||
118 | * Lookup the bus range for the domain in MCFG, and set up config space | ||
119 | * mapping. | ||
120 | */ | ||
121 | static struct pci_config_window * | ||
122 | pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root) | ||
123 | { | ||
124 | struct resource *bus_res = &root->secondary; | ||
125 | u16 seg = root->segment; | ||
126 | struct pci_config_window *cfg; | ||
127 | struct resource cfgres; | ||
128 | unsigned int bsz; | ||
129 | |||
130 | /* Use address from _CBA if present, otherwise lookup MCFG */ | ||
131 | if (!root->mcfg_addr) | ||
132 | root->mcfg_addr = pci_mcfg_lookup(seg, bus_res); | ||
133 | |||
134 | if (!root->mcfg_addr) { | ||
135 | dev_err(&root->device->dev, "%04x:%pR ECAM region not found\n", | ||
136 | seg, bus_res); | ||
137 | return NULL; | ||
138 | } | ||
139 | |||
140 | bsz = 1 << pci_generic_ecam_ops.bus_shift; | ||
141 | cfgres.start = root->mcfg_addr + bus_res->start * bsz; | ||
142 | cfgres.end = cfgres.start + resource_size(bus_res) * bsz - 1; | ||
143 | cfgres.flags = IORESOURCE_MEM; | ||
144 | cfg = pci_ecam_create(&root->device->dev, &cfgres, bus_res, | ||
145 | &pci_generic_ecam_ops); | ||
146 | if (IS_ERR(cfg)) { | ||
147 | dev_err(&root->device->dev, "%04x:%pR error %ld mapping ECAM\n", | ||
148 | seg, bus_res, PTR_ERR(cfg)); | ||
149 | return NULL; | ||
150 | } | ||
151 | |||
152 | return cfg; | ||
153 | } | ||
154 | |||
155 | /* release_info: free resources allocated by init_info */ | ||
156 | static void pci_acpi_generic_release_info(struct acpi_pci_root_info *ci) | ||
157 | { | ||
158 | struct acpi_pci_generic_root_info *ri; | ||
159 | |||
160 | ri = container_of(ci, struct acpi_pci_generic_root_info, common); | ||
161 | pci_ecam_free(ri->cfg); | ||
162 | kfree(ri); | ||
163 | } | ||
164 | |||
165 | static struct acpi_pci_root_ops acpi_pci_root_ops = { | ||
166 | .release_info = pci_acpi_generic_release_info, | ||
167 | }; | ||
168 | |||
169 | /* Interface called from ACPI code to setup PCI host controller */ | ||
89 | struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) | 170 | struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) |
90 | { | 171 | { |
91 | /* TODO: Should be revisited when implementing PCI on ACPI */ | 172 | int node = acpi_get_node(root->device->handle); |
92 | return NULL; | 173 | struct acpi_pci_generic_root_info *ri; |
174 | struct pci_bus *bus, *child; | ||
175 | |||
176 | ri = kzalloc_node(sizeof(*ri), GFP_KERNEL, node); | ||
177 | if (!ri) | ||
178 | return NULL; | ||
179 | |||
180 | ri->cfg = pci_acpi_setup_ecam_mapping(root); | ||
181 | if (!ri->cfg) { | ||
182 | kfree(ri); | ||
183 | return NULL; | ||
184 | } | ||
185 | |||
186 | acpi_pci_root_ops.pci_ops = &ri->cfg->ops->pci_ops; | ||
187 | bus = acpi_pci_root_create(root, &acpi_pci_root_ops, &ri->common, | ||
188 | ri->cfg); | ||
189 | if (!bus) | ||
190 | return NULL; | ||
191 | |||
192 | pci_bus_size_bridges(bus); | ||
193 | pci_bus_assign_resources(bus); | ||
194 | |||
195 | list_for_each_entry(child, &bus->children, node) | ||
196 | pcie_bus_configure_settings(child); | ||
197 | |||
198 | return bus; | ||
93 | } | 199 | } |
200 | |||
201 | void pcibios_add_bus(struct pci_bus *bus) | ||
202 | { | ||
203 | acpi_pci_add_bus(bus); | ||
204 | } | ||
205 | |||
206 | void pcibios_remove_bus(struct pci_bus *bus) | ||
207 | { | ||
208 | acpi_pci_remove_bus(bus); | ||
209 | } | ||
210 | |||
94 | #endif | 211 | #endif |
diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h index fc3ecb55f1b2..2a120bb70e54 100644 --- a/arch/microblaze/include/asm/pci.h +++ b/arch/microblaze/include/asm/pci.h | |||
@@ -82,9 +82,6 @@ extern pgprot_t pci_phys_mem_access_prot(struct file *file, | |||
82 | pgprot_t prot); | 82 | pgprot_t prot); |
83 | 83 | ||
84 | #define HAVE_ARCH_PCI_RESOURCE_TO_USER | 84 | #define HAVE_ARCH_PCI_RESOURCE_TO_USER |
85 | extern void pci_resource_to_user(const struct pci_dev *dev, int bar, | ||
86 | const struct resource *rsrc, | ||
87 | resource_size_t *start, resource_size_t *end); | ||
88 | 85 | ||
89 | extern void pcibios_setup_bus_devices(struct pci_bus *bus); | 86 | extern void pcibios_setup_bus_devices(struct pci_bus *bus); |
90 | extern void pcibios_setup_bus_self(struct pci_bus *bus); | 87 | extern void pcibios_setup_bus_self(struct pci_bus *bus); |
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index 14cba600da7a..81556b843a8e 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c | |||
@@ -219,33 +219,6 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, | |||
219 | } | 219 | } |
220 | 220 | ||
221 | /* | 221 | /* |
222 | * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci | ||
223 | * device mapping. | ||
224 | */ | ||
225 | static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, | ||
226 | pgprot_t protection, | ||
227 | enum pci_mmap_state mmap_state, | ||
228 | int write_combine) | ||
229 | { | ||
230 | pgprot_t prot = protection; | ||
231 | |||
232 | /* Write combine is always 0 on non-memory space mappings. On | ||
233 | * memory space, if the user didn't pass 1, we check for a | ||
234 | * "prefetchable" resource. This is a bit hackish, but we use | ||
235 | * this to workaround the inability of /sysfs to provide a write | ||
236 | * combine bit | ||
237 | */ | ||
238 | if (mmap_state != pci_mmap_mem) | ||
239 | write_combine = 0; | ||
240 | else if (write_combine == 0) { | ||
241 | if (rp->flags & IORESOURCE_PREFETCH) | ||
242 | write_combine = 1; | ||
243 | } | ||
244 | |||
245 | return pgprot_noncached(prot); | ||
246 | } | ||
247 | |||
248 | /* | ||
249 | * This one is used by /dev/mem and fbdev who have no clue about the | 222 | * This one is used by /dev/mem and fbdev who have no clue about the |
250 | * PCI device, it tries to find the PCI device first and calls the | 223 | * PCI device, it tries to find the PCI device first and calls the |
251 | * above routine | 224 | * above routine |
@@ -317,9 +290,7 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |||
317 | return -EINVAL; | 290 | return -EINVAL; |
318 | 291 | ||
319 | vma->vm_pgoff = offset >> PAGE_SHIFT; | 292 | vma->vm_pgoff = offset >> PAGE_SHIFT; |
320 | vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp, | 293 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
321 | vma->vm_page_prot, | ||
322 | mmap_state, write_combine); | ||
323 | 294 | ||
324 | ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, | 295 | ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, |
325 | vma->vm_end - vma->vm_start, vma->vm_page_prot); | 296 | vma->vm_end - vma->vm_start, vma->vm_page_prot); |
@@ -473,39 +444,25 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar, | |||
473 | const struct resource *rsrc, | 444 | const struct resource *rsrc, |
474 | resource_size_t *start, resource_size_t *end) | 445 | resource_size_t *start, resource_size_t *end) |
475 | { | 446 | { |
476 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | 447 | struct pci_bus_region region; |
477 | resource_size_t offset = 0; | ||
478 | 448 | ||
479 | if (hose == NULL) | 449 | if (rsrc->flags & IORESOURCE_IO) { |
450 | pcibios_resource_to_bus(dev->bus, ®ion, | ||
451 | (struct resource *) rsrc); | ||
452 | *start = region.start; | ||
453 | *end = region.end; | ||
480 | return; | 454 | return; |
455 | } | ||
481 | 456 | ||
482 | if (rsrc->flags & IORESOURCE_IO) | 457 | /* We pass a CPU physical address to userland for MMIO instead of a |
483 | offset = (unsigned long)hose->io_base_virt - _IO_BASE; | 458 | * BAR value because X is lame and expects to be able to use that |
484 | 459 | * to pass to /dev/mem! | |
485 | /* We pass a fully fixed up address to userland for MMIO instead of | ||
486 | * a BAR value because X is lame and expects to be able to use that | ||
487 | * to pass to /dev/mem ! | ||
488 | * | 460 | * |
489 | * That means that we'll have potentially 64 bits values where some | 461 | * That means we may have 64-bit values where some apps only expect |
490 | * userland apps only expect 32 (like X itself since it thinks only | 462 | * 32 (like X itself since it thinks only Sparc has 64-bit MMIO). |
491 | * Sparc has 64 bits MMIO) but if we don't do that, we break it on | ||
492 | * 32 bits CHRPs :-( | ||
493 | * | ||
494 | * Hopefully, the sysfs insterface is immune to that gunk. Once X | ||
495 | * has been fixed (and the fix spread enough), we can re-enable the | ||
496 | * 2 lines below and pass down a BAR value to userland. In that case | ||
497 | * we'll also have to re-enable the matching code in | ||
498 | * __pci_mmap_make_offset(). | ||
499 | * | ||
500 | * BenH. | ||
501 | */ | 463 | */ |
502 | #if 0 | 464 | *start = rsrc->start; |
503 | else if (rsrc->flags & IORESOURCE_MEM) | 465 | *end = rsrc->end; |
504 | offset = hose->pci_mem_offset; | ||
505 | #endif | ||
506 | |||
507 | *start = rsrc->start - offset; | ||
508 | *end = rsrc->end - offset; | ||
509 | } | 466 | } |
510 | 467 | ||
511 | /** | 468 | /** |
diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h index 86b239d9d75d..9b63cd41213d 100644 --- a/arch/mips/include/asm/pci.h +++ b/arch/mips/include/asm/pci.h | |||
@@ -80,16 +80,6 @@ extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |||
80 | 80 | ||
81 | #define HAVE_ARCH_PCI_RESOURCE_TO_USER | 81 | #define HAVE_ARCH_PCI_RESOURCE_TO_USER |
82 | 82 | ||
83 | static inline void pci_resource_to_user(const struct pci_dev *dev, int bar, | ||
84 | const struct resource *rsrc, resource_size_t *start, | ||
85 | resource_size_t *end) | ||
86 | { | ||
87 | phys_addr_t size = resource_size(rsrc); | ||
88 | |||
89 | *start = fixup_bigphys_addr(rsrc->start, size); | ||
90 | *end = rsrc->start + size; | ||
91 | } | ||
92 | |||
93 | /* | 83 | /* |
94 | * Dynamic DMA mapping stuff. | 84 | * Dynamic DMA mapping stuff. |
95 | * MIPS has everything mapped statically. | 85 | * MIPS has everything mapped statically. |
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index f1b11f0dea2d..b4c02f29663e 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c | |||
@@ -112,7 +112,14 @@ static void pcibios_scanbus(struct pci_controller *hose) | |||
112 | need_domain_info = 1; | 112 | need_domain_info = 1; |
113 | } | 113 | } |
114 | 114 | ||
115 | if (!pci_has_flag(PCI_PROBE_ONLY)) { | 115 | /* |
116 | * We insert PCI resources into the iomem_resource and | ||
117 | * ioport_resource trees in either pci_bus_claim_resources() | ||
118 | * or pci_bus_assign_resources(). | ||
119 | */ | ||
120 | if (pci_has_flag(PCI_PROBE_ONLY)) { | ||
121 | pci_bus_claim_resources(bus); | ||
122 | } else { | ||
116 | pci_bus_size_bridges(bus); | 123 | pci_bus_size_bridges(bus); |
117 | pci_bus_assign_resources(bus); | 124 | pci_bus_assign_resources(bus); |
118 | } | 125 | } |
@@ -319,6 +326,16 @@ void pcibios_fixup_bus(struct pci_bus *bus) | |||
319 | EXPORT_SYMBOL(PCIBIOS_MIN_IO); | 326 | EXPORT_SYMBOL(PCIBIOS_MIN_IO); |
320 | EXPORT_SYMBOL(PCIBIOS_MIN_MEM); | 327 | EXPORT_SYMBOL(PCIBIOS_MIN_MEM); |
321 | 328 | ||
329 | void pci_resource_to_user(const struct pci_dev *dev, int bar, | ||
330 | const struct resource *rsrc, resource_size_t *start, | ||
331 | resource_size_t *end) | ||
332 | { | ||
333 | phys_addr_t size = resource_size(rsrc); | ||
334 | |||
335 | *start = fixup_bigphys_addr(rsrc->start, size); | ||
336 | *end = rsrc->start + size; | ||
337 | } | ||
338 | |||
322 | int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | 339 | int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, |
323 | enum pci_mmap_state mmap_state, int write_combine) | 340 | enum pci_mmap_state mmap_state, int write_combine) |
324 | { | 341 | { |
diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h index a6f3ac0d4602..e9bd6cf0212f 100644 --- a/arch/powerpc/include/asm/pci.h +++ b/arch/powerpc/include/asm/pci.h | |||
@@ -136,9 +136,6 @@ extern pgprot_t pci_phys_mem_access_prot(struct file *file, | |||
136 | pgprot_t prot); | 136 | pgprot_t prot); |
137 | 137 | ||
138 | #define HAVE_ARCH_PCI_RESOURCE_TO_USER | 138 | #define HAVE_ARCH_PCI_RESOURCE_TO_USER |
139 | extern void pci_resource_to_user(const struct pci_dev *dev, int bar, | ||
140 | const struct resource *rsrc, | ||
141 | resource_size_t *start, resource_size_t *end); | ||
142 | 139 | ||
143 | extern resource_size_t pcibios_io_space_offset(struct pci_controller *hose); | 140 | extern resource_size_t pcibios_io_space_offset(struct pci_controller *hose); |
144 | extern void pcibios_setup_bus_devices(struct pci_bus *bus); | 141 | extern void pcibios_setup_bus_devices(struct pci_bus *bus); |
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index f93942b4b6a6..a5c0153ede37 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
@@ -412,36 +412,6 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, | |||
412 | } | 412 | } |
413 | 413 | ||
414 | /* | 414 | /* |
415 | * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci | ||
416 | * device mapping. | ||
417 | */ | ||
418 | static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, | ||
419 | pgprot_t protection, | ||
420 | enum pci_mmap_state mmap_state, | ||
421 | int write_combine) | ||
422 | { | ||
423 | |||
424 | /* Write combine is always 0 on non-memory space mappings. On | ||
425 | * memory space, if the user didn't pass 1, we check for a | ||
426 | * "prefetchable" resource. This is a bit hackish, but we use | ||
427 | * this to workaround the inability of /sysfs to provide a write | ||
428 | * combine bit | ||
429 | */ | ||
430 | if (mmap_state != pci_mmap_mem) | ||
431 | write_combine = 0; | ||
432 | else if (write_combine == 0) { | ||
433 | if (rp->flags & IORESOURCE_PREFETCH) | ||
434 | write_combine = 1; | ||
435 | } | ||
436 | |||
437 | /* XXX would be nice to have a way to ask for write-through */ | ||
438 | if (write_combine) | ||
439 | return pgprot_noncached_wc(protection); | ||
440 | else | ||
441 | return pgprot_noncached(protection); | ||
442 | } | ||
443 | |||
444 | /* | ||
445 | * This one is used by /dev/mem and fbdev who have no clue about the | 415 | * This one is used by /dev/mem and fbdev who have no clue about the |
446 | * PCI device, it tries to find the PCI device first and calls the | 416 | * PCI device, it tries to find the PCI device first and calls the |
447 | * above routine | 417 | * above routine |
@@ -514,9 +484,10 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |||
514 | return -EINVAL; | 484 | return -EINVAL; |
515 | 485 | ||
516 | vma->vm_pgoff = offset >> PAGE_SHIFT; | 486 | vma->vm_pgoff = offset >> PAGE_SHIFT; |
517 | vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp, | 487 | if (write_combine) |
518 | vma->vm_page_prot, | 488 | vma->vm_page_prot = pgprot_noncached_wc(vma->vm_page_prot); |
519 | mmap_state, write_combine); | 489 | else |
490 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | ||
520 | 491 | ||
521 | ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, | 492 | ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, |
522 | vma->vm_end - vma->vm_start, vma->vm_page_prot); | 493 | vma->vm_end - vma->vm_start, vma->vm_page_prot); |
@@ -666,39 +637,25 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar, | |||
666 | const struct resource *rsrc, | 637 | const struct resource *rsrc, |
667 | resource_size_t *start, resource_size_t *end) | 638 | resource_size_t *start, resource_size_t *end) |
668 | { | 639 | { |
669 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | 640 | struct pci_bus_region region; |
670 | resource_size_t offset = 0; | ||
671 | 641 | ||
672 | if (hose == NULL) | 642 | if (rsrc->flags & IORESOURCE_IO) { |
643 | pcibios_resource_to_bus(dev->bus, ®ion, | ||
644 | (struct resource *) rsrc); | ||
645 | *start = region.start; | ||
646 | *end = region.end; | ||
673 | return; | 647 | return; |
648 | } | ||
674 | 649 | ||
675 | if (rsrc->flags & IORESOURCE_IO) | 650 | /* We pass a CPU physical address to userland for MMIO instead of a |
676 | offset = (unsigned long)hose->io_base_virt - _IO_BASE; | 651 | * BAR value because X is lame and expects to be able to use that |
677 | 652 | * to pass to /dev/mem! | |
678 | /* We pass a fully fixed up address to userland for MMIO instead of | ||
679 | * a BAR value because X is lame and expects to be able to use that | ||
680 | * to pass to /dev/mem ! | ||
681 | * | ||
682 | * That means that we'll have potentially 64 bits values where some | ||
683 | * userland apps only expect 32 (like X itself since it thinks only | ||
684 | * Sparc has 64 bits MMIO) but if we don't do that, we break it on | ||
685 | * 32 bits CHRPs :-( | ||
686 | * | ||
687 | * Hopefully, the sysfs insterface is immune to that gunk. Once X | ||
688 | * has been fixed (and the fix spread enough), we can re-enable the | ||
689 | * 2 lines below and pass down a BAR value to userland. In that case | ||
690 | * we'll also have to re-enable the matching code in | ||
691 | * __pci_mmap_make_offset(). | ||
692 | * | 653 | * |
693 | * BenH. | 654 | * That means we may have 64-bit values where some apps only expect |
655 | * 32 (like X itself since it thinks only Sparc has 64-bit MMIO). | ||
694 | */ | 656 | */ |
695 | #if 0 | 657 | *start = rsrc->start; |
696 | else if (rsrc->flags & IORESOURCE_MEM) | 658 | *end = rsrc->end; |
697 | offset = hose->pci_mem_offset; | ||
698 | #endif | ||
699 | |||
700 | *start = rsrc->start - offset; | ||
701 | *end = rsrc->end - offset; | ||
702 | } | 659 | } |
703 | 660 | ||
704 | /** | 661 | /** |
diff --git a/arch/sparc/include/asm/pci_64.h b/arch/sparc/include/asm/pci_64.h index 022d16008a00..2303635158f5 100644 --- a/arch/sparc/include/asm/pci_64.h +++ b/arch/sparc/include/asm/pci_64.h | |||
@@ -55,9 +55,6 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) | |||
55 | } | 55 | } |
56 | 56 | ||
57 | #define HAVE_ARCH_PCI_RESOURCE_TO_USER | 57 | #define HAVE_ARCH_PCI_RESOURCE_TO_USER |
58 | void pci_resource_to_user(const struct pci_dev *dev, int bar, | ||
59 | const struct resource *rsrc, | ||
60 | resource_size_t *start, resource_size_t *end); | ||
61 | #endif /* __KERNEL__ */ | 58 | #endif /* __KERNEL__ */ |
62 | 59 | ||
63 | #endif /* __SPARC64_PCI_H */ | 60 | #endif /* __SPARC64_PCI_H */ |
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index c2b202d763a1..9c1878f4fa9f 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c | |||
@@ -986,16 +986,18 @@ void pci_resource_to_user(const struct pci_dev *pdev, int bar, | |||
986 | const struct resource *rp, resource_size_t *start, | 986 | const struct resource *rp, resource_size_t *start, |
987 | resource_size_t *end) | 987 | resource_size_t *end) |
988 | { | 988 | { |
989 | struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; | 989 | struct pci_bus_region region; |
990 | unsigned long offset; | ||
991 | |||
992 | if (rp->flags & IORESOURCE_IO) | ||
993 | offset = pbm->io_space.start; | ||
994 | else | ||
995 | offset = pbm->mem_space.start; | ||
996 | 990 | ||
997 | *start = rp->start - offset; | 991 | /* |
998 | *end = rp->end - offset; | 992 | * "User" addresses are shown in /sys/devices/pci.../.../resource |
993 | * and /proc/bus/pci/devices and used as mmap offsets for | ||
994 | * /proc/bus/pci/BB/DD.F files (see proc_bus_pci_mmap()). | ||
995 | * | ||
996 | * On sparc, these are PCI bus addresses, i.e., raw BAR values. | ||
997 | */ | ||
998 | pcibios_resource_to_bus(pdev->bus, ®ion, (struct resource *) rp); | ||
999 | *start = region.start; | ||
1000 | *end = region.end; | ||
999 | } | 1001 | } |
1000 | 1002 | ||
1001 | void pcibios_set_master(struct pci_dev *dev) | 1003 | void pcibios_set_master(struct pci_dev *dev) |
diff --git a/arch/unicore32/kernel/pci.c b/arch/unicore32/kernel/pci.c index d45fa5f3e9c4..62137d13c6f9 100644 --- a/arch/unicore32/kernel/pci.c +++ b/arch/unicore32/kernel/pci.c | |||
@@ -265,10 +265,8 @@ static int __init pci_common_init(void) | |||
265 | 265 | ||
266 | pci_fixup_irqs(pci_common_swizzle, pci_puv3_map_irq); | 266 | pci_fixup_irqs(pci_common_swizzle, pci_puv3_map_irq); |
267 | 267 | ||
268 | if (!pci_has_flag(PCI_PROBE_ONLY)) { | 268 | pci_bus_size_bridges(puv3_bus); |
269 | pci_bus_size_bridges(puv3_bus); | 269 | pci_bus_assign_resources(puv3_bus); |
270 | pci_bus_assign_resources(puv3_bus); | ||
271 | } | ||
272 | pci_bus_add_devices(puv3_bus); | 270 | pci_bus_add_devices(puv3_bus); |
273 | return 0; | 271 | return 0; |
274 | } | 272 | } |
@@ -279,9 +277,6 @@ char * __init pcibios_setup(char *str) | |||
279 | if (!strcmp(str, "debug")) { | 277 | if (!strcmp(str, "debug")) { |
280 | debug_pci = 1; | 278 | debug_pci = 1; |
281 | return NULL; | 279 | return NULL; |
282 | } else if (!strcmp(str, "firmware")) { | ||
283 | pci_add_flags(PCI_PROBE_ONLY); | ||
284 | return NULL; | ||
285 | } | 280 | } |
286 | return str; | 281 | return str; |
287 | } | 282 | } |
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 8196054fedb0..7b6a9d14c8c0 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c | |||
@@ -133,7 +133,7 @@ static void pcibios_fixup_device_resources(struct pci_dev *dev) | |||
133 | if (pci_probe & PCI_NOASSIGN_BARS) { | 133 | if (pci_probe & PCI_NOASSIGN_BARS) { |
134 | /* | 134 | /* |
135 | * If the BIOS did not assign the BAR, zero out the | 135 | * If the BIOS did not assign the BAR, zero out the |
136 | * resource so the kernel doesn't attmept to assign | 136 | * resource so the kernel doesn't attempt to assign |
137 | * it later on in pci_assign_unassigned_resources | 137 | * it later on in pci_assign_unassigned_resources |
138 | */ | 138 | */ |
139 | for (bar = 0; bar <= PCI_STD_RESOURCE_END; bar++) { | 139 | for (bar = 0; bar <= PCI_STD_RESOURCE_END; bar++) { |
diff --git a/arch/x86/pci/vmd.c b/arch/x86/pci/vmd.c index 613cac7395c4..e88b4176260f 100644 --- a/arch/x86/pci/vmd.c +++ b/arch/x86/pci/vmd.c | |||
@@ -119,10 +119,11 @@ static void vmd_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) | |||
119 | static void vmd_irq_enable(struct irq_data *data) | 119 | static void vmd_irq_enable(struct irq_data *data) |
120 | { | 120 | { |
121 | struct vmd_irq *vmdirq = data->chip_data; | 121 | struct vmd_irq *vmdirq = data->chip_data; |
122 | unsigned long flags; | ||
122 | 123 | ||
123 | raw_spin_lock(&list_lock); | 124 | raw_spin_lock_irqsave(&list_lock, flags); |
124 | list_add_tail_rcu(&vmdirq->node, &vmdirq->irq->irq_list); | 125 | list_add_tail_rcu(&vmdirq->node, &vmdirq->irq->irq_list); |
125 | raw_spin_unlock(&list_lock); | 126 | raw_spin_unlock_irqrestore(&list_lock, flags); |
126 | 127 | ||
127 | data->chip->irq_unmask(data); | 128 | data->chip->irq_unmask(data); |
128 | } | 129 | } |
@@ -130,12 +131,14 @@ static void vmd_irq_enable(struct irq_data *data) | |||
130 | static void vmd_irq_disable(struct irq_data *data) | 131 | static void vmd_irq_disable(struct irq_data *data) |
131 | { | 132 | { |
132 | struct vmd_irq *vmdirq = data->chip_data; | 133 | struct vmd_irq *vmdirq = data->chip_data; |
134 | unsigned long flags; | ||
133 | 135 | ||
134 | data->chip->irq_mask(data); | 136 | data->chip->irq_mask(data); |
135 | 137 | ||
136 | raw_spin_lock(&list_lock); | 138 | raw_spin_lock_irqsave(&list_lock, flags); |
137 | list_del_rcu(&vmdirq->node); | 139 | list_del_rcu(&vmdirq->node); |
138 | raw_spin_unlock(&list_lock); | 140 | INIT_LIST_HEAD_RCU(&vmdirq->node); |
141 | raw_spin_unlock_irqrestore(&list_lock, flags); | ||
139 | } | 142 | } |
140 | 143 | ||
141 | /* | 144 | /* |
@@ -166,16 +169,20 @@ static irq_hw_number_t vmd_get_hwirq(struct msi_domain_info *info, | |||
166 | * XXX: We can be even smarter selecting the best IRQ once we solve the | 169 | * XXX: We can be even smarter selecting the best IRQ once we solve the |
167 | * affinity problem. | 170 | * affinity problem. |
168 | */ | 171 | */ |
169 | static struct vmd_irq_list *vmd_next_irq(struct vmd_dev *vmd) | 172 | static struct vmd_irq_list *vmd_next_irq(struct vmd_dev *vmd, struct msi_desc *desc) |
170 | { | 173 | { |
171 | int i, best = 0; | 174 | int i, best = 1; |
175 | unsigned long flags; | ||
172 | 176 | ||
173 | raw_spin_lock(&list_lock); | 177 | if (!desc->msi_attrib.is_msix || vmd->msix_count == 1) |
178 | return &vmd->irqs[0]; | ||
179 | |||
180 | raw_spin_lock_irqsave(&list_lock, flags); | ||
174 | for (i = 1; i < vmd->msix_count; i++) | 181 | for (i = 1; i < vmd->msix_count; i++) |
175 | if (vmd->irqs[i].count < vmd->irqs[best].count) | 182 | if (vmd->irqs[i].count < vmd->irqs[best].count) |
176 | best = i; | 183 | best = i; |
177 | vmd->irqs[best].count++; | 184 | vmd->irqs[best].count++; |
178 | raw_spin_unlock(&list_lock); | 185 | raw_spin_unlock_irqrestore(&list_lock, flags); |
179 | 186 | ||
180 | return &vmd->irqs[best]; | 187 | return &vmd->irqs[best]; |
181 | } | 188 | } |
@@ -184,14 +191,15 @@ static int vmd_msi_init(struct irq_domain *domain, struct msi_domain_info *info, | |||
184 | unsigned int virq, irq_hw_number_t hwirq, | 191 | unsigned int virq, irq_hw_number_t hwirq, |
185 | msi_alloc_info_t *arg) | 192 | msi_alloc_info_t *arg) |
186 | { | 193 | { |
187 | struct vmd_dev *vmd = vmd_from_bus(msi_desc_to_pci_dev(arg->desc)->bus); | 194 | struct msi_desc *desc = arg->desc; |
195 | struct vmd_dev *vmd = vmd_from_bus(msi_desc_to_pci_dev(desc)->bus); | ||
188 | struct vmd_irq *vmdirq = kzalloc(sizeof(*vmdirq), GFP_KERNEL); | 196 | struct vmd_irq *vmdirq = kzalloc(sizeof(*vmdirq), GFP_KERNEL); |
189 | 197 | ||
190 | if (!vmdirq) | 198 | if (!vmdirq) |
191 | return -ENOMEM; | 199 | return -ENOMEM; |
192 | 200 | ||
193 | INIT_LIST_HEAD(&vmdirq->node); | 201 | INIT_LIST_HEAD(&vmdirq->node); |
194 | vmdirq->irq = vmd_next_irq(vmd); | 202 | vmdirq->irq = vmd_next_irq(vmd, desc); |
195 | vmdirq->virq = virq; | 203 | vmdirq->virq = virq; |
196 | 204 | ||
197 | irq_domain_set_info(domain, virq, vmdirq->irq->vmd_vector, info->chip, | 205 | irq_domain_set_info(domain, virq, vmdirq->irq->vmd_vector, info->chip, |
@@ -203,11 +211,12 @@ static void vmd_msi_free(struct irq_domain *domain, | |||
203 | struct msi_domain_info *info, unsigned int virq) | 211 | struct msi_domain_info *info, unsigned int virq) |
204 | { | 212 | { |
205 | struct vmd_irq *vmdirq = irq_get_chip_data(virq); | 213 | struct vmd_irq *vmdirq = irq_get_chip_data(virq); |
214 | unsigned long flags; | ||
206 | 215 | ||
207 | /* XXX: Potential optimization to rebalance */ | 216 | /* XXX: Potential optimization to rebalance */ |
208 | raw_spin_lock(&list_lock); | 217 | raw_spin_lock_irqsave(&list_lock, flags); |
209 | vmdirq->irq->count--; | 218 | vmdirq->irq->count--; |
210 | raw_spin_unlock(&list_lock); | 219 | raw_spin_unlock_irqrestore(&list_lock, flags); |
211 | 220 | ||
212 | kfree_rcu(vmdirq, rcu); | 221 | kfree_rcu(vmdirq, rcu); |
213 | } | 222 | } |
@@ -261,7 +270,7 @@ static struct device *to_vmd_dev(struct device *dev) | |||
261 | 270 | ||
262 | static struct dma_map_ops *vmd_dma_ops(struct device *dev) | 271 | static struct dma_map_ops *vmd_dma_ops(struct device *dev) |
263 | { | 272 | { |
264 | return to_vmd_dev(dev)->archdata.dma_ops; | 273 | return get_dma_ops(to_vmd_dev(dev)); |
265 | } | 274 | } |
266 | 275 | ||
267 | static void *vmd_alloc(struct device *dev, size_t size, dma_addr_t *addr, | 276 | static void *vmd_alloc(struct device *dev, size_t size, dma_addr_t *addr, |
@@ -367,7 +376,7 @@ static void vmd_teardown_dma_ops(struct vmd_dev *vmd) | |||
367 | { | 376 | { |
368 | struct dma_domain *domain = &vmd->dma_domain; | 377 | struct dma_domain *domain = &vmd->dma_domain; |
369 | 378 | ||
370 | if (vmd->dev->dev.archdata.dma_ops) | 379 | if (get_dma_ops(&vmd->dev->dev)) |
371 | del_dma_domain(domain); | 380 | del_dma_domain(domain); |
372 | } | 381 | } |
373 | 382 | ||
@@ -379,7 +388,7 @@ static void vmd_teardown_dma_ops(struct vmd_dev *vmd) | |||
379 | 388 | ||
380 | static void vmd_setup_dma_ops(struct vmd_dev *vmd) | 389 | static void vmd_setup_dma_ops(struct vmd_dev *vmd) |
381 | { | 390 | { |
382 | const struct dma_map_ops *source = vmd->dev->dev.archdata.dma_ops; | 391 | const struct dma_map_ops *source = get_dma_ops(&vmd->dev->dev); |
383 | struct dma_map_ops *dest = &vmd->dma_ops; | 392 | struct dma_map_ops *dest = &vmd->dma_ops; |
384 | struct dma_domain *domain = &vmd->dma_domain; | 393 | struct dma_domain *domain = &vmd->dma_domain; |
385 | 394 | ||
@@ -594,7 +603,7 @@ static int vmd_enable_domain(struct vmd_dev *vmd) | |||
594 | sd->node = pcibus_to_node(vmd->dev->bus); | 603 | sd->node = pcibus_to_node(vmd->dev->bus); |
595 | 604 | ||
596 | vmd->irq_domain = pci_msi_create_irq_domain(NULL, &vmd_msi_domain_info, | 605 | vmd->irq_domain = pci_msi_create_irq_domain(NULL, &vmd_msi_domain_info, |
597 | NULL); | 606 | x86_vector_domain); |
598 | if (!vmd->irq_domain) | 607 | if (!vmd->irq_domain) |
599 | return -ENODEV; | 608 | return -ENODEV; |
600 | 609 | ||
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index aebd944bdaa1..445ce28475b3 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -221,6 +221,9 @@ config ACPI_PROCESSOR_IDLE | |||
221 | bool | 221 | bool |
222 | select CPU_IDLE | 222 | select CPU_IDLE |
223 | 223 | ||
224 | config ACPI_MCFG | ||
225 | bool | ||
226 | |||
224 | config ACPI_CPPC_LIB | 227 | config ACPI_CPPC_LIB |
225 | bool | 228 | bool |
226 | depends on ACPI_PROCESSOR | 229 | depends on ACPI_PROCESSOR |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 35a6ccbe3025..5ae9d85c5159 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -40,6 +40,7 @@ acpi-$(CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC) += processor_pdc.o | |||
40 | acpi-y += ec.o | 40 | acpi-y += ec.o |
41 | acpi-$(CONFIG_ACPI_DOCK) += dock.o | 41 | acpi-$(CONFIG_ACPI_DOCK) += dock.o |
42 | acpi-y += pci_root.o pci_link.o pci_irq.o | 42 | acpi-y += pci_root.o pci_link.o pci_irq.o |
43 | obj-$(CONFIG_ACPI_MCFG) += pci_mcfg.o | ||
43 | acpi-y += acpi_lpss.o acpi_apd.o | 44 | acpi-y += acpi_lpss.o acpi_apd.o |
44 | acpi-y += acpi_platform.o | 45 | acpi-y += acpi_platform.o |
45 | acpi-y += acpi_pnp.o | 46 | acpi-y += acpi_pnp.o |
diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c new file mode 100644 index 000000000000..b5b376e081f5 --- /dev/null +++ b/drivers/acpi/pci_mcfg.c | |||
@@ -0,0 +1,92 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2016 Broadcom | ||
3 | * Author: Jayachandran C <jchandra@broadcom.com> | ||
4 | * Copyright (C) 2016 Semihalf | ||
5 | * Author: Tomasz Nowicki <tn@semihalf.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License, version 2, as | ||
9 | * published by the Free Software Foundation (the "GPL"). | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License version 2 (GPLv2) for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * version 2 (GPLv2) along with this source code. | ||
18 | */ | ||
19 | |||
20 | #define pr_fmt(fmt) "ACPI: " fmt | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/pci.h> | ||
24 | #include <linux/pci-acpi.h> | ||
25 | |||
26 | /* Structure to hold entries from the MCFG table */ | ||
27 | struct mcfg_entry { | ||
28 | struct list_head list; | ||
29 | phys_addr_t addr; | ||
30 | u16 segment; | ||
31 | u8 bus_start; | ||
32 | u8 bus_end; | ||
33 | }; | ||
34 | |||
35 | /* List to save MCFG entries */ | ||
36 | static LIST_HEAD(pci_mcfg_list); | ||
37 | |||
38 | phys_addr_t pci_mcfg_lookup(u16 seg, struct resource *bus_res) | ||
39 | { | ||
40 | struct mcfg_entry *e; | ||
41 | |||
42 | /* | ||
43 | * We expect exact match, unless MCFG entry end bus covers more than | ||
44 | * specified by caller. | ||
45 | */ | ||
46 | list_for_each_entry(e, &pci_mcfg_list, list) { | ||
47 | if (e->segment == seg && e->bus_start == bus_res->start && | ||
48 | e->bus_end >= bus_res->end) | ||
49 | return e->addr; | ||
50 | } | ||
51 | |||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | static __init int pci_mcfg_parse(struct acpi_table_header *header) | ||
56 | { | ||
57 | struct acpi_table_mcfg *mcfg; | ||
58 | struct acpi_mcfg_allocation *mptr; | ||
59 | struct mcfg_entry *e, *arr; | ||
60 | int i, n; | ||
61 | |||
62 | if (header->length < sizeof(struct acpi_table_mcfg)) | ||
63 | return -EINVAL; | ||
64 | |||
65 | n = (header->length - sizeof(struct acpi_table_mcfg)) / | ||
66 | sizeof(struct acpi_mcfg_allocation); | ||
67 | mcfg = (struct acpi_table_mcfg *)header; | ||
68 | mptr = (struct acpi_mcfg_allocation *) &mcfg[1]; | ||
69 | |||
70 | arr = kcalloc(n, sizeof(*arr), GFP_KERNEL); | ||
71 | if (!arr) | ||
72 | return -ENOMEM; | ||
73 | |||
74 | for (i = 0, e = arr; i < n; i++, mptr++, e++) { | ||
75 | e->segment = mptr->pci_segment; | ||
76 | e->addr = mptr->address; | ||
77 | e->bus_start = mptr->start_bus_number; | ||
78 | e->bus_end = mptr->end_bus_number; | ||
79 | list_add(&e->list, &pci_mcfg_list); | ||
80 | } | ||
81 | |||
82 | pr_info("MCFG table detected, %d entries\n", n); | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | /* Interface called by ACPI - parse and save MCFG table */ | ||
87 | void __init pci_mmcfg_late_init(void) | ||
88 | { | ||
89 | int err = acpi_table_parse(ACPI_SIG_MCFG, pci_mcfg_parse); | ||
90 | if (err) | ||
91 | pr_err("Failed to parse MCFG (%d)\n", err); | ||
92 | } | ||
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index ae3fe4e64203..d144168d4ef9 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -720,6 +720,36 @@ next: | |||
720 | } | 720 | } |
721 | } | 721 | } |
722 | 722 | ||
723 | static void acpi_pci_root_remap_iospace(struct resource_entry *entry) | ||
724 | { | ||
725 | #ifdef PCI_IOBASE | ||
726 | struct resource *res = entry->res; | ||
727 | resource_size_t cpu_addr = res->start; | ||
728 | resource_size_t pci_addr = cpu_addr - entry->offset; | ||
729 | resource_size_t length = resource_size(res); | ||
730 | unsigned long port; | ||
731 | |||
732 | if (pci_register_io_range(cpu_addr, length)) | ||
733 | goto err; | ||
734 | |||
735 | port = pci_address_to_pio(cpu_addr); | ||
736 | if (port == (unsigned long)-1) | ||
737 | goto err; | ||
738 | |||
739 | res->start = port; | ||
740 | res->end = port + length - 1; | ||
741 | entry->offset = port - pci_addr; | ||
742 | |||
743 | if (pci_remap_iospace(res, cpu_addr) < 0) | ||
744 | goto err; | ||
745 | |||
746 | pr_info("Remapped I/O %pa to %pR\n", &cpu_addr, res); | ||
747 | return; | ||
748 | err: | ||
749 | res->flags |= IORESOURCE_DISABLED; | ||
750 | #endif | ||
751 | } | ||
752 | |||
723 | int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info) | 753 | int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info) |
724 | { | 754 | { |
725 | int ret; | 755 | int ret; |
@@ -740,6 +770,9 @@ int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info) | |||
740 | "no IO and memory resources present in _CRS\n"); | 770 | "no IO and memory resources present in _CRS\n"); |
741 | else { | 771 | else { |
742 | resource_list_for_each_entry_safe(entry, tmp, list) { | 772 | resource_list_for_each_entry_safe(entry, tmp, list) { |
773 | if (entry->res->flags & IORESOURCE_IO) | ||
774 | acpi_pci_root_remap_iospace(entry); | ||
775 | |||
743 | if (entry->res->flags & IORESOURCE_DISABLED) | 776 | if (entry->res->flags & IORESOURCE_DISABLED) |
744 | resource_list_destroy_entry(entry); | 777 | resource_list_destroy_entry(entry); |
745 | else | 778 | else |
@@ -811,6 +844,8 @@ static void acpi_pci_root_release_info(struct pci_host_bridge *bridge) | |||
811 | 844 | ||
812 | resource_list_for_each_entry(entry, &bridge->windows) { | 845 | resource_list_for_each_entry(entry, &bridge->windows) { |
813 | res = entry->res; | 846 | res = entry->res; |
847 | if (res->flags & IORESOURCE_IO) | ||
848 | pci_unmap_iospace(res); | ||
814 | if (res->parent && | 849 | if (res->parent && |
815 | (res->flags & (IORESOURCE_MEM | IORESOURCE_IO))) | 850 | (res->flags & (IORESOURCE_MEM | IORESOURCE_IO))) |
816 | release_resource(res); | 851 | release_resource(res); |
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 5495a5ba8039..7f8728984f44 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig | |||
@@ -21,9 +21,9 @@ config ARM_GIC_MAX_NR | |||
21 | 21 | ||
22 | config ARM_GIC_V2M | 22 | config ARM_GIC_V2M |
23 | bool | 23 | bool |
24 | depends on ARM_GIC | 24 | depends on PCI |
25 | depends on PCI && PCI_MSI | 25 | select ARM_GIC |
26 | select PCI_MSI_IRQ_DOMAIN | 26 | select PCI_MSI |
27 | 27 | ||
28 | config GIC_NON_BANKED | 28 | config GIC_NON_BANKED |
29 | bool | 29 | bool |
@@ -37,7 +37,8 @@ config ARM_GIC_V3 | |||
37 | 37 | ||
38 | config ARM_GIC_V3_ITS | 38 | config ARM_GIC_V3_ITS |
39 | bool | 39 | bool |
40 | select PCI_MSI_IRQ_DOMAIN | 40 | depends on PCI |
41 | depends on PCI_MSI | ||
41 | 42 | ||
42 | config ARM_NVIC | 43 | config ARM_NVIC |
43 | bool | 44 | bool |
@@ -62,13 +63,13 @@ config ARM_VIC_NR | |||
62 | config ARMADA_370_XP_IRQ | 63 | config ARMADA_370_XP_IRQ |
63 | bool | 64 | bool |
64 | select GENERIC_IRQ_CHIP | 65 | select GENERIC_IRQ_CHIP |
65 | select PCI_MSI_IRQ_DOMAIN if PCI_MSI | 66 | select PCI_MSI if PCI |
66 | 67 | ||
67 | config ALPINE_MSI | 68 | config ALPINE_MSI |
68 | bool | 69 | bool |
69 | depends on PCI && PCI_MSI | 70 | depends on PCI |
71 | select PCI_MSI | ||
70 | select GENERIC_IRQ_CHIP | 72 | select GENERIC_IRQ_CHIP |
71 | select PCI_MSI_IRQ_DOMAIN | ||
72 | 73 | ||
73 | config ATMEL_AIC_IRQ | 74 | config ATMEL_AIC_IRQ |
74 | bool | 75 | bool |
@@ -117,7 +118,6 @@ config HISILICON_IRQ_MBIGEN | |||
117 | bool | 118 | bool |
118 | select ARM_GIC_V3 | 119 | select ARM_GIC_V3 |
119 | select ARM_GIC_V3_ITS | 120 | select ARM_GIC_V3_ITS |
120 | select GENERIC_MSI_IRQ_DOMAIN | ||
121 | 121 | ||
122 | config IMGPDC_IRQ | 122 | config IMGPDC_IRQ |
123 | bool | 123 | bool |
@@ -250,12 +250,10 @@ config IRQ_MXS | |||
250 | 250 | ||
251 | config MVEBU_ODMI | 251 | config MVEBU_ODMI |
252 | bool | 252 | bool |
253 | select GENERIC_MSI_IRQ_DOMAIN | ||
254 | 253 | ||
255 | config LS_SCFG_MSI | 254 | config LS_SCFG_MSI |
256 | def_bool y if SOC_LS1021A || ARCH_LAYERSCAPE | 255 | def_bool y if SOC_LS1021A || ARCH_LAYERSCAPE |
257 | depends on PCI && PCI_MSI | 256 | depends on PCI && PCI_MSI |
258 | select PCI_MSI_IRQ_DOMAIN | ||
259 | 257 | ||
260 | config PARTITION_PERCPU | 258 | config PARTITION_PERCPU |
261 | bool | 259 | bool |
diff --git a/drivers/misc/genwqe/card_base.c b/drivers/misc/genwqe/card_base.c index 4cf8f82cfca2..a70b853fa2c9 100644 --- a/drivers/misc/genwqe/card_base.c +++ b/drivers/misc/genwqe/card_base.c | |||
@@ -182,7 +182,7 @@ static void genwqe_dev_free(struct genwqe_dev *cd) | |||
182 | */ | 182 | */ |
183 | static int genwqe_bus_reset(struct genwqe_dev *cd) | 183 | static int genwqe_bus_reset(struct genwqe_dev *cd) |
184 | { | 184 | { |
185 | int bars, rc = 0; | 185 | int rc = 0; |
186 | struct pci_dev *pci_dev = cd->pci_dev; | 186 | struct pci_dev *pci_dev = cd->pci_dev; |
187 | void __iomem *mmio; | 187 | void __iomem *mmio; |
188 | 188 | ||
@@ -193,8 +193,7 @@ static int genwqe_bus_reset(struct genwqe_dev *cd) | |||
193 | cd->mmio = NULL; | 193 | cd->mmio = NULL; |
194 | pci_iounmap(pci_dev, mmio); | 194 | pci_iounmap(pci_dev, mmio); |
195 | 195 | ||
196 | bars = pci_select_bars(pci_dev, IORESOURCE_MEM); | 196 | pci_release_mem_regions(pci_dev); |
197 | pci_release_selected_regions(pci_dev, bars); | ||
198 | 197 | ||
199 | /* | 198 | /* |
200 | * Firmware/BIOS might change memory mapping during bus reset. | 199 | * Firmware/BIOS might change memory mapping during bus reset. |
@@ -218,7 +217,7 @@ static int genwqe_bus_reset(struct genwqe_dev *cd) | |||
218 | GENWQE_INJECT_GFIR_FATAL | | 217 | GENWQE_INJECT_GFIR_FATAL | |
219 | GENWQE_INJECT_GFIR_INFO); | 218 | GENWQE_INJECT_GFIR_INFO); |
220 | 219 | ||
221 | rc = pci_request_selected_regions(pci_dev, bars, genwqe_driver_name); | 220 | rc = pci_request_mem_regions(pci_dev, genwqe_driver_name); |
222 | if (rc) { | 221 | if (rc) { |
223 | dev_err(&pci_dev->dev, | 222 | dev_err(&pci_dev->dev, |
224 | "[%s] err: request bars failed (%d)\n", __func__, rc); | 223 | "[%s] err: request bars failed (%d)\n", __func__, rc); |
@@ -1068,10 +1067,9 @@ static int genwqe_health_check_stop(struct genwqe_dev *cd) | |||
1068 | */ | 1067 | */ |
1069 | static int genwqe_pci_setup(struct genwqe_dev *cd) | 1068 | static int genwqe_pci_setup(struct genwqe_dev *cd) |
1070 | { | 1069 | { |
1071 | int err, bars; | 1070 | int err; |
1072 | struct pci_dev *pci_dev = cd->pci_dev; | 1071 | struct pci_dev *pci_dev = cd->pci_dev; |
1073 | 1072 | ||
1074 | bars = pci_select_bars(pci_dev, IORESOURCE_MEM); | ||
1075 | err = pci_enable_device_mem(pci_dev); | 1073 | err = pci_enable_device_mem(pci_dev); |
1076 | if (err) { | 1074 | if (err) { |
1077 | dev_err(&pci_dev->dev, | 1075 | dev_err(&pci_dev->dev, |
@@ -1080,7 +1078,7 @@ static int genwqe_pci_setup(struct genwqe_dev *cd) | |||
1080 | } | 1078 | } |
1081 | 1079 | ||
1082 | /* Reserve PCI I/O and memory resources */ | 1080 | /* Reserve PCI I/O and memory resources */ |
1083 | err = pci_request_selected_regions(pci_dev, bars, genwqe_driver_name); | 1081 | err = pci_request_mem_regions(pci_dev, genwqe_driver_name); |
1084 | if (err) { | 1082 | if (err) { |
1085 | dev_err(&pci_dev->dev, | 1083 | dev_err(&pci_dev->dev, |
1086 | "[%s] err: request bars failed (%d)\n", __func__, err); | 1084 | "[%s] err: request bars failed (%d)\n", __func__, err); |
@@ -1142,7 +1140,7 @@ static int genwqe_pci_setup(struct genwqe_dev *cd) | |||
1142 | out_iounmap: | 1140 | out_iounmap: |
1143 | pci_iounmap(pci_dev, cd->mmio); | 1141 | pci_iounmap(pci_dev, cd->mmio); |
1144 | out_release_resources: | 1142 | out_release_resources: |
1145 | pci_release_selected_regions(pci_dev, bars); | 1143 | pci_release_mem_regions(pci_dev); |
1146 | err_disable_device: | 1144 | err_disable_device: |
1147 | pci_disable_device(pci_dev); | 1145 | pci_disable_device(pci_dev); |
1148 | err_out: | 1146 | err_out: |
@@ -1154,14 +1152,12 @@ static int genwqe_pci_setup(struct genwqe_dev *cd) | |||
1154 | */ | 1152 | */ |
1155 | static void genwqe_pci_remove(struct genwqe_dev *cd) | 1153 | static void genwqe_pci_remove(struct genwqe_dev *cd) |
1156 | { | 1154 | { |
1157 | int bars; | ||
1158 | struct pci_dev *pci_dev = cd->pci_dev; | 1155 | struct pci_dev *pci_dev = cd->pci_dev; |
1159 | 1156 | ||
1160 | if (cd->mmio) | 1157 | if (cd->mmio) |
1161 | pci_iounmap(pci_dev, cd->mmio); | 1158 | pci_iounmap(pci_dev, cd->mmio); |
1162 | 1159 | ||
1163 | bars = pci_select_bars(pci_dev, IORESOURCE_MEM); | 1160 | pci_release_mem_regions(pci_dev); |
1164 | pci_release_selected_regions(pci_dev, bars); | ||
1165 | pci_disable_device(pci_dev); | 1161 | pci_disable_device(pci_dev); |
1166 | } | 1162 | } |
1167 | 1163 | ||
diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c index e708e360a9e3..6453148d066a 100644 --- a/drivers/net/ethernet/atheros/alx/main.c +++ b/drivers/net/ethernet/atheros/alx/main.c | |||
@@ -1251,7 +1251,7 @@ static int alx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1251 | struct alx_priv *alx; | 1251 | struct alx_priv *alx; |
1252 | struct alx_hw *hw; | 1252 | struct alx_hw *hw; |
1253 | bool phy_configured; | 1253 | bool phy_configured; |
1254 | int bars, err; | 1254 | int err; |
1255 | 1255 | ||
1256 | err = pci_enable_device_mem(pdev); | 1256 | err = pci_enable_device_mem(pdev); |
1257 | if (err) | 1257 | if (err) |
@@ -1271,11 +1271,10 @@ static int alx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1271 | } | 1271 | } |
1272 | } | 1272 | } |
1273 | 1273 | ||
1274 | bars = pci_select_bars(pdev, IORESOURCE_MEM); | 1274 | err = pci_request_mem_regions(pdev, alx_drv_name); |
1275 | err = pci_request_selected_regions(pdev, bars, alx_drv_name); | ||
1276 | if (err) { | 1275 | if (err) { |
1277 | dev_err(&pdev->dev, | 1276 | dev_err(&pdev->dev, |
1278 | "pci_request_selected_regions failed(bars:%d)\n", bars); | 1277 | "pci_request_mem_regions failed\n"); |
1279 | goto out_pci_disable; | 1278 | goto out_pci_disable; |
1280 | } | 1279 | } |
1281 | 1280 | ||
@@ -1401,7 +1400,7 @@ out_unmap: | |||
1401 | out_free_netdev: | 1400 | out_free_netdev: |
1402 | free_netdev(netdev); | 1401 | free_netdev(netdev); |
1403 | out_pci_release: | 1402 | out_pci_release: |
1404 | pci_release_selected_regions(pdev, bars); | 1403 | pci_release_mem_regions(pdev); |
1405 | out_pci_disable: | 1404 | out_pci_disable: |
1406 | pci_disable_device(pdev); | 1405 | pci_disable_device(pdev); |
1407 | return err; | 1406 | return err; |
@@ -1420,8 +1419,7 @@ static void alx_remove(struct pci_dev *pdev) | |||
1420 | 1419 | ||
1421 | unregister_netdev(alx->dev); | 1420 | unregister_netdev(alx->dev); |
1422 | iounmap(hw->hw_addr); | 1421 | iounmap(hw->hw_addr); |
1423 | pci_release_selected_regions(pdev, | 1422 | pci_release_mem_regions(pdev); |
1424 | pci_select_bars(pdev, IORESOURCE_MEM)); | ||
1425 | 1423 | ||
1426 | pci_disable_pcie_error_reporting(pdev); | 1424 | pci_disable_pcie_error_reporting(pdev); |
1427 | pci_disable_device(pdev); | 1425 | pci_disable_device(pdev); |
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 41f32c0b341e..02f443958f31 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c | |||
@@ -7330,8 +7330,7 @@ err_flashmap: | |||
7330 | err_ioremap: | 7330 | err_ioremap: |
7331 | free_netdev(netdev); | 7331 | free_netdev(netdev); |
7332 | err_alloc_etherdev: | 7332 | err_alloc_etherdev: |
7333 | pci_release_selected_regions(pdev, | 7333 | pci_release_mem_regions(pdev); |
7334 | pci_select_bars(pdev, IORESOURCE_MEM)); | ||
7335 | err_pci_reg: | 7334 | err_pci_reg: |
7336 | err_dma: | 7335 | err_dma: |
7337 | pci_disable_device(pdev); | 7336 | pci_disable_device(pdev); |
@@ -7398,8 +7397,7 @@ static void e1000_remove(struct pci_dev *pdev) | |||
7398 | if ((adapter->hw.flash_address) && | 7397 | if ((adapter->hw.flash_address) && |
7399 | (adapter->hw.mac.type < e1000_pch_spt)) | 7398 | (adapter->hw.mac.type < e1000_pch_spt)) |
7400 | iounmap(adapter->hw.flash_address); | 7399 | iounmap(adapter->hw.flash_address); |
7401 | pci_release_selected_regions(pdev, | 7400 | pci_release_mem_regions(pdev); |
7402 | pci_select_bars(pdev, IORESOURCE_MEM)); | ||
7403 | 7401 | ||
7404 | free_netdev(netdev); | 7402 | free_netdev(netdev); |
7405 | 7403 | ||
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c index b8245c734c96..774a5654bf42 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c | |||
@@ -1963,10 +1963,7 @@ static int fm10k_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1963 | goto err_dma; | 1963 | goto err_dma; |
1964 | } | 1964 | } |
1965 | 1965 | ||
1966 | err = pci_request_selected_regions(pdev, | 1966 | err = pci_request_mem_regions(pdev, fm10k_driver_name); |
1967 | pci_select_bars(pdev, | ||
1968 | IORESOURCE_MEM), | ||
1969 | fm10k_driver_name); | ||
1970 | if (err) { | 1967 | if (err) { |
1971 | dev_err(&pdev->dev, | 1968 | dev_err(&pdev->dev, |
1972 | "pci_request_selected_regions failed: %d\n", err); | 1969 | "pci_request_selected_regions failed: %d\n", err); |
@@ -2070,8 +2067,7 @@ err_sw_init: | |||
2070 | err_ioremap: | 2067 | err_ioremap: |
2071 | free_netdev(netdev); | 2068 | free_netdev(netdev); |
2072 | err_alloc_netdev: | 2069 | err_alloc_netdev: |
2073 | pci_release_selected_regions(pdev, | 2070 | pci_release_mem_regions(pdev); |
2074 | pci_select_bars(pdev, IORESOURCE_MEM)); | ||
2075 | err_pci_reg: | 2071 | err_pci_reg: |
2076 | err_dma: | 2072 | err_dma: |
2077 | pci_disable_device(pdev); | 2073 | pci_disable_device(pdev); |
@@ -2119,8 +2115,7 @@ static void fm10k_remove(struct pci_dev *pdev) | |||
2119 | 2115 | ||
2120 | free_netdev(netdev); | 2116 | free_netdev(netdev); |
2121 | 2117 | ||
2122 | pci_release_selected_regions(pdev, | 2118 | pci_release_mem_regions(pdev); |
2123 | pci_select_bars(pdev, IORESOURCE_MEM)); | ||
2124 | 2119 | ||
2125 | pci_disable_pcie_error_reporting(pdev); | 2120 | pci_disable_pcie_error_reporting(pdev); |
2126 | 2121 | ||
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 339d99be4702..81c99e1be708 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c | |||
@@ -10710,8 +10710,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
10710 | } | 10710 | } |
10711 | 10711 | ||
10712 | /* set up pci connections */ | 10712 | /* set up pci connections */ |
10713 | err = pci_request_selected_regions(pdev, pci_select_bars(pdev, | 10713 | err = pci_request_mem_regions(pdev, i40e_driver_name); |
10714 | IORESOURCE_MEM), i40e_driver_name); | ||
10715 | if (err) { | 10714 | if (err) { |
10716 | dev_info(&pdev->dev, | 10715 | dev_info(&pdev->dev, |
10717 | "pci_request_selected_regions failed %d\n", err); | 10716 | "pci_request_selected_regions failed %d\n", err); |
@@ -11208,8 +11207,7 @@ err_ioremap: | |||
11208 | kfree(pf); | 11207 | kfree(pf); |
11209 | err_pf_alloc: | 11208 | err_pf_alloc: |
11210 | pci_disable_pcie_error_reporting(pdev); | 11209 | pci_disable_pcie_error_reporting(pdev); |
11211 | pci_release_selected_regions(pdev, | 11210 | pci_release_mem_regions(pdev); |
11212 | pci_select_bars(pdev, IORESOURCE_MEM)); | ||
11213 | err_pci_reg: | 11211 | err_pci_reg: |
11214 | err_dma: | 11212 | err_dma: |
11215 | pci_disable_device(pdev); | 11213 | pci_disable_device(pdev); |
@@ -11320,8 +11318,7 @@ static void i40e_remove(struct pci_dev *pdev) | |||
11320 | 11318 | ||
11321 | iounmap(hw->hw_addr); | 11319 | iounmap(hw->hw_addr); |
11322 | kfree(pf); | 11320 | kfree(pf); |
11323 | pci_release_selected_regions(pdev, | 11321 | pci_release_mem_regions(pdev); |
11324 | pci_select_bars(pdev, IORESOURCE_MEM)); | ||
11325 | 11322 | ||
11326 | pci_disable_pcie_error_reporting(pdev); | 11323 | pci_disable_pcie_error_reporting(pdev); |
11327 | pci_disable_device(pdev); | 11324 | pci_disable_device(pdev); |
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 9bcba42abb91..942a89fb0090 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c | |||
@@ -2324,9 +2324,7 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2324 | } | 2324 | } |
2325 | } | 2325 | } |
2326 | 2326 | ||
2327 | err = pci_request_selected_regions(pdev, pci_select_bars(pdev, | 2327 | err = pci_request_mem_regions(pdev, igb_driver_name); |
2328 | IORESOURCE_MEM), | ||
2329 | igb_driver_name); | ||
2330 | if (err) | 2328 | if (err) |
2331 | goto err_pci_reg; | 2329 | goto err_pci_reg; |
2332 | 2330 | ||
@@ -2750,8 +2748,7 @@ err_sw_init: | |||
2750 | err_ioremap: | 2748 | err_ioremap: |
2751 | free_netdev(netdev); | 2749 | free_netdev(netdev); |
2752 | err_alloc_etherdev: | 2750 | err_alloc_etherdev: |
2753 | pci_release_selected_regions(pdev, | 2751 | pci_release_mem_regions(pdev); |
2754 | pci_select_bars(pdev, IORESOURCE_MEM)); | ||
2755 | err_pci_reg: | 2752 | err_pci_reg: |
2756 | err_dma: | 2753 | err_dma: |
2757 | pci_disable_device(pdev); | 2754 | pci_disable_device(pdev); |
@@ -2916,8 +2913,7 @@ static void igb_remove(struct pci_dev *pdev) | |||
2916 | pci_iounmap(pdev, adapter->io_addr); | 2913 | pci_iounmap(pdev, adapter->io_addr); |
2917 | if (hw->flash_address) | 2914 | if (hw->flash_address) |
2918 | iounmap(hw->flash_address); | 2915 | iounmap(hw->flash_address); |
2919 | pci_release_selected_regions(pdev, | 2916 | pci_release_mem_regions(pdev); |
2920 | pci_select_bars(pdev, IORESOURCE_MEM)); | ||
2921 | 2917 | ||
2922 | kfree(adapter->shadow_vfta); | 2918 | kfree(adapter->shadow_vfta); |
2923 | free_netdev(netdev); | 2919 | free_netdev(netdev); |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 7871f538f0ad..5418c69a7463 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | |||
@@ -9353,8 +9353,7 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
9353 | pci_using_dac = 0; | 9353 | pci_using_dac = 0; |
9354 | } | 9354 | } |
9355 | 9355 | ||
9356 | err = pci_request_selected_regions(pdev, pci_select_bars(pdev, | 9356 | err = pci_request_mem_regions(pdev, ixgbe_driver_name); |
9357 | IORESOURCE_MEM), ixgbe_driver_name); | ||
9358 | if (err) { | 9357 | if (err) { |
9359 | dev_err(&pdev->dev, | 9358 | dev_err(&pdev->dev, |
9360 | "pci_request_selected_regions failed 0x%x\n", err); | 9359 | "pci_request_selected_regions failed 0x%x\n", err); |
@@ -9740,8 +9739,7 @@ err_ioremap: | |||
9740 | disable_dev = !test_and_set_bit(__IXGBE_DISABLED, &adapter->state); | 9739 | disable_dev = !test_and_set_bit(__IXGBE_DISABLED, &adapter->state); |
9741 | free_netdev(netdev); | 9740 | free_netdev(netdev); |
9742 | err_alloc_etherdev: | 9741 | err_alloc_etherdev: |
9743 | pci_release_selected_regions(pdev, | 9742 | pci_release_mem_regions(pdev); |
9744 | pci_select_bars(pdev, IORESOURCE_MEM)); | ||
9745 | err_pci_reg: | 9743 | err_pci_reg: |
9746 | err_dma: | 9744 | err_dma: |
9747 | if (!adapter || disable_dev) | 9745 | if (!adapter || disable_dev) |
@@ -9808,8 +9806,7 @@ static void ixgbe_remove(struct pci_dev *pdev) | |||
9808 | 9806 | ||
9809 | #endif | 9807 | #endif |
9810 | iounmap(adapter->io_addr); | 9808 | iounmap(adapter->io_addr); |
9811 | pci_release_selected_regions(pdev, pci_select_bars(pdev, | 9809 | pci_release_mem_regions(pdev); |
9812 | IORESOURCE_MEM)); | ||
9813 | 9810 | ||
9814 | e_dev_info("complete\n"); | 9811 | e_dev_info("complete\n"); |
9815 | 9812 | ||
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 4cb9b156cab7..d7c33f9361aa 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c | |||
@@ -1661,14 +1661,9 @@ static int nvme_pci_enable(struct nvme_dev *dev) | |||
1661 | 1661 | ||
1662 | static void nvme_dev_unmap(struct nvme_dev *dev) | 1662 | static void nvme_dev_unmap(struct nvme_dev *dev) |
1663 | { | 1663 | { |
1664 | struct pci_dev *pdev = to_pci_dev(dev->dev); | ||
1665 | int bars; | ||
1666 | |||
1667 | if (dev->bar) | 1664 | if (dev->bar) |
1668 | iounmap(dev->bar); | 1665 | iounmap(dev->bar); |
1669 | 1666 | pci_release_mem_regions(to_pci_dev(dev->dev)); | |
1670 | bars = pci_select_bars(pdev, IORESOURCE_MEM); | ||
1671 | pci_release_selected_regions(pdev, bars); | ||
1672 | } | 1667 | } |
1673 | 1668 | ||
1674 | static void nvme_pci_disable(struct nvme_dev *dev) | 1669 | static void nvme_pci_disable(struct nvme_dev *dev) |
@@ -1897,13 +1892,9 @@ static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = { | |||
1897 | 1892 | ||
1898 | static int nvme_dev_map(struct nvme_dev *dev) | 1893 | static int nvme_dev_map(struct nvme_dev *dev) |
1899 | { | 1894 | { |
1900 | int bars; | ||
1901 | struct pci_dev *pdev = to_pci_dev(dev->dev); | 1895 | struct pci_dev *pdev = to_pci_dev(dev->dev); |
1902 | 1896 | ||
1903 | bars = pci_select_bars(pdev, IORESOURCE_MEM); | 1897 | if (pci_request_mem_regions(pdev, "nvme")) |
1904 | if (!bars) | ||
1905 | return -ENODEV; | ||
1906 | if (pci_request_selected_regions(pdev, bars, "nvme")) | ||
1907 | return -ENODEV; | 1898 | return -ENODEV; |
1908 | 1899 | ||
1909 | dev->bar = ioremap(pci_resource_start(pdev, 0), 8192); | 1900 | dev->bar = ioremap(pci_resource_start(pdev, 0), 8192); |
@@ -1912,7 +1903,7 @@ static int nvme_dev_map(struct nvme_dev *dev) | |||
1912 | 1903 | ||
1913 | return 0; | 1904 | return 0; |
1914 | release: | 1905 | release: |
1915 | pci_release_selected_regions(pdev, bars); | 1906 | pci_release_mem_regions(pdev); |
1916 | return -ENODEV; | 1907 | return -ENODEV; |
1917 | } | 1908 | } |
1918 | 1909 | ||
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 56389be5d08b..67f9916ff14d 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig | |||
@@ -25,7 +25,7 @@ config PCI_MSI | |||
25 | If you don't know what to do here, say Y. | 25 | If you don't know what to do here, say Y. |
26 | 26 | ||
27 | config PCI_MSI_IRQ_DOMAIN | 27 | config PCI_MSI_IRQ_DOMAIN |
28 | bool | 28 | def_bool ARM || ARM64 || X86 |
29 | depends on PCI_MSI | 29 | depends on PCI_MSI |
30 | select GENERIC_MSI_IRQ_DOMAIN | 30 | select GENERIC_MSI_IRQ_DOMAIN |
31 | 31 | ||
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index dd7cdbee8029..c288e5a52575 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -91,6 +91,35 @@ void pci_bus_remove_resources(struct pci_bus *bus) | |||
91 | } | 91 | } |
92 | } | 92 | } |
93 | 93 | ||
94 | int devm_request_pci_bus_resources(struct device *dev, | ||
95 | struct list_head *resources) | ||
96 | { | ||
97 | struct resource_entry *win; | ||
98 | struct resource *parent, *res; | ||
99 | int err; | ||
100 | |||
101 | resource_list_for_each_entry(win, resources) { | ||
102 | res = win->res; | ||
103 | switch (resource_type(res)) { | ||
104 | case IORESOURCE_IO: | ||
105 | parent = &ioport_resource; | ||
106 | break; | ||
107 | case IORESOURCE_MEM: | ||
108 | parent = &iomem_resource; | ||
109 | break; | ||
110 | default: | ||
111 | continue; | ||
112 | } | ||
113 | |||
114 | err = devm_request_resource(dev, parent, res); | ||
115 | if (err) | ||
116 | return err; | ||
117 | } | ||
118 | |||
119 | return 0; | ||
120 | } | ||
121 | EXPORT_SYMBOL_GPL(devm_request_pci_bus_resources); | ||
122 | |||
94 | static struct pci_bus_region pci_32_bit = {0, 0xffffffffULL}; | 123 | static struct pci_bus_region pci_32_bit = {0, 0xffffffffULL}; |
95 | #ifdef CONFIG_PCI_BUS_ADDR_T_64BIT | 124 | #ifdef CONFIG_PCI_BUS_ADDR_T_64BIT |
96 | static struct pci_bus_region pci_64_bit = {0, | 125 | static struct pci_bus_region pci_64_bit = {0, |
@@ -291,6 +320,7 @@ void pci_bus_add_device(struct pci_dev *dev) | |||
291 | pci_fixup_device(pci_fixup_final, dev); | 320 | pci_fixup_device(pci_fixup_final, dev); |
292 | pci_create_sysfs_dev_files(dev); | 321 | pci_create_sysfs_dev_files(dev); |
293 | pci_proc_attach_device(dev); | 322 | pci_proc_attach_device(dev); |
323 | pci_bridge_d3_device_changed(dev); | ||
294 | 324 | ||
295 | dev->match_driver = true; | 325 | dev->match_driver = true; |
296 | retval = device_attach(&dev->dev); | 326 | retval = device_attach(&dev->dev); |
@@ -397,4 +427,3 @@ void pci_bus_put(struct pci_bus *bus) | |||
397 | put_device(&bus->dev); | 427 | put_device(&bus->dev); |
398 | } | 428 | } |
399 | EXPORT_SYMBOL(pci_bus_put); | 429 | EXPORT_SYMBOL(pci_bus_put); |
400 | |||
diff --git a/drivers/pci/ecam.c b/drivers/pci/ecam.c index f9832ad8efe2..66e0d718472f 100644 --- a/drivers/pci/ecam.c +++ b/drivers/pci/ecam.c | |||
@@ -19,10 +19,9 @@ | |||
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
22 | #include <linux/pci-ecam.h> | ||
22 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
23 | 24 | ||
24 | #include "ecam.h" | ||
25 | |||
26 | /* | 25 | /* |
27 | * On 64-bit systems, we do a single ioremap for the whole config space | 26 | * On 64-bit systems, we do a single ioremap for the whole config space |
28 | * since we have enough virtual address range available. On 32-bit, we | 27 | * since we have enough virtual address range available. On 32-bit, we |
@@ -52,6 +51,7 @@ struct pci_config_window *pci_ecam_create(struct device *dev, | |||
52 | if (!cfg) | 51 | if (!cfg) |
53 | return ERR_PTR(-ENOMEM); | 52 | return ERR_PTR(-ENOMEM); |
54 | 53 | ||
54 | cfg->parent = dev; | ||
55 | cfg->ops = ops; | 55 | cfg->ops = ops; |
56 | cfg->busr.start = busr->start; | 56 | cfg->busr.start = busr->start; |
57 | cfg->busr.end = busr->end; | 57 | cfg->busr.end = busr->end; |
@@ -95,7 +95,7 @@ struct pci_config_window *pci_ecam_create(struct device *dev, | |||
95 | } | 95 | } |
96 | 96 | ||
97 | if (ops->init) { | 97 | if (ops->init) { |
98 | err = ops->init(dev, cfg); | 98 | err = ops->init(cfg); |
99 | if (err) | 99 | if (err) |
100 | goto err_exit; | 100 | goto err_exit; |
101 | } | 101 | } |
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index 5d2374e4ee7f..9b485d873b0d 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig | |||
@@ -3,8 +3,9 @@ menu "PCI host controller drivers" | |||
3 | 3 | ||
4 | config PCI_DRA7XX | 4 | config PCI_DRA7XX |
5 | bool "TI DRA7xx PCIe controller" | 5 | bool "TI DRA7xx PCIe controller" |
6 | select PCIE_DW | ||
7 | depends on OF && HAS_IOMEM && TI_PIPE3 | 6 | depends on OF && HAS_IOMEM && TI_PIPE3 |
7 | depends on PCI_MSI_IRQ_DOMAIN | ||
8 | select PCIE_DW | ||
8 | help | 9 | help |
9 | Enables support for the PCIe controller in the DRA7xx SoC. There | 10 | Enables support for the PCIe controller in the DRA7xx SoC. There |
10 | are two instances of PCIe controller in DRA7xx. This controller can | 11 | are two instances of PCIe controller in DRA7xx. This controller can |
@@ -16,11 +17,20 @@ config PCI_MVEBU | |||
16 | depends on ARM | 17 | depends on ARM |
17 | depends on OF | 18 | depends on OF |
18 | 19 | ||
20 | config PCI_AARDVARK | ||
21 | bool "Aardvark PCIe controller" | ||
22 | depends on ARCH_MVEBU && ARM64 | ||
23 | depends on OF | ||
24 | depends on PCI_MSI_IRQ_DOMAIN | ||
25 | help | ||
26 | Add support for Aardvark 64bit PCIe Host Controller. This | ||
27 | controller is part of the South Bridge of the Marvel Armada | ||
28 | 3700 SoC. | ||
19 | 29 | ||
20 | config PCIE_XILINX_NWL | 30 | config PCIE_XILINX_NWL |
21 | bool "NWL PCIe Core" | 31 | bool "NWL PCIe Core" |
22 | depends on ARCH_ZYNQMP | 32 | depends on ARCH_ZYNQMP |
23 | select PCI_MSI_IRQ_DOMAIN if PCI_MSI | 33 | depends on PCI_MSI_IRQ_DOMAIN |
24 | help | 34 | help |
25 | Say 'Y' here if you want kernel support for Xilinx | 35 | Say 'Y' here if you want kernel support for Xilinx |
26 | NWL PCIe controller. The controller can act as Root Port | 36 | NWL PCIe controller. The controller can act as Root Port |
@@ -29,6 +39,7 @@ config PCIE_XILINX_NWL | |||
29 | 39 | ||
30 | config PCIE_DW_PLAT | 40 | config PCIE_DW_PLAT |
31 | bool "Platform bus based DesignWare PCIe Controller" | 41 | bool "Platform bus based DesignWare PCIe Controller" |
42 | depends on PCI_MSI_IRQ_DOMAIN | ||
32 | select PCIE_DW | 43 | select PCIE_DW |
33 | ---help--- | 44 | ---help--- |
34 | This selects the DesignWare PCIe controller support. Select this if | 45 | This selects the DesignWare PCIe controller support. Select this if |
@@ -40,16 +51,19 @@ config PCIE_DW_PLAT | |||
40 | 51 | ||
41 | config PCIE_DW | 52 | config PCIE_DW |
42 | bool | 53 | bool |
54 | depends on PCI_MSI_IRQ_DOMAIN | ||
43 | 55 | ||
44 | config PCI_EXYNOS | 56 | config PCI_EXYNOS |
45 | bool "Samsung Exynos PCIe controller" | 57 | bool "Samsung Exynos PCIe controller" |
46 | depends on SOC_EXYNOS5440 | 58 | depends on SOC_EXYNOS5440 |
59 | depends on PCI_MSI_IRQ_DOMAIN | ||
47 | select PCIEPORTBUS | 60 | select PCIEPORTBUS |
48 | select PCIE_DW | 61 | select PCIE_DW |
49 | 62 | ||
50 | config PCI_IMX6 | 63 | config PCI_IMX6 |
51 | bool "Freescale i.MX6 PCIe controller" | 64 | bool "Freescale i.MX6 PCIe controller" |
52 | depends on SOC_IMX6Q | 65 | depends on SOC_IMX6Q |
66 | depends on PCI_MSI_IRQ_DOMAIN | ||
53 | select PCIEPORTBUS | 67 | select PCIEPORTBUS |
54 | select PCIE_DW | 68 | select PCIE_DW |
55 | 69 | ||
@@ -72,8 +86,7 @@ config PCI_RCAR_GEN2 | |||
72 | config PCIE_RCAR | 86 | config PCIE_RCAR |
73 | bool "Renesas R-Car PCIe controller" | 87 | bool "Renesas R-Car PCIe controller" |
74 | depends on ARCH_RENESAS || (ARM && COMPILE_TEST) | 88 | depends on ARCH_RENESAS || (ARM && COMPILE_TEST) |
75 | select PCI_MSI | 89 | depends on PCI_MSI_IRQ_DOMAIN |
76 | select PCI_MSI_IRQ_DOMAIN | ||
77 | help | 90 | help |
78 | Say Y here if you want PCIe controller support on R-Car SoCs. | 91 | Say Y here if you want PCIe controller support on R-Car SoCs. |
79 | 92 | ||
@@ -85,6 +98,7 @@ config PCI_HOST_GENERIC | |||
85 | bool "Generic PCI host controller" | 98 | bool "Generic PCI host controller" |
86 | depends on (ARM || ARM64) && OF | 99 | depends on (ARM || ARM64) && OF |
87 | select PCI_HOST_COMMON | 100 | select PCI_HOST_COMMON |
101 | select IRQ_DOMAIN | ||
88 | help | 102 | help |
89 | Say Y here if you want to support a simple generic PCI host | 103 | Say Y here if you want to support a simple generic PCI host |
90 | controller, such as the one emulated by kvmtool. | 104 | controller, such as the one emulated by kvmtool. |
@@ -92,6 +106,7 @@ config PCI_HOST_GENERIC | |||
92 | config PCIE_SPEAR13XX | 106 | config PCIE_SPEAR13XX |
93 | bool "STMicroelectronics SPEAr PCIe controller" | 107 | bool "STMicroelectronics SPEAr PCIe controller" |
94 | depends on ARCH_SPEAR13XX | 108 | depends on ARCH_SPEAR13XX |
109 | depends on PCI_MSI_IRQ_DOMAIN | ||
95 | select PCIEPORTBUS | 110 | select PCIEPORTBUS |
96 | select PCIE_DW | 111 | select PCIE_DW |
97 | help | 112 | help |
@@ -100,6 +115,7 @@ config PCIE_SPEAR13XX | |||
100 | config PCI_KEYSTONE | 115 | config PCI_KEYSTONE |
101 | bool "TI Keystone PCIe controller" | 116 | bool "TI Keystone PCIe controller" |
102 | depends on ARCH_KEYSTONE | 117 | depends on ARCH_KEYSTONE |
118 | depends on PCI_MSI_IRQ_DOMAIN | ||
103 | select PCIE_DW | 119 | select PCIE_DW |
104 | select PCIEPORTBUS | 120 | select PCIEPORTBUS |
105 | help | 121 | help |
@@ -120,7 +136,6 @@ config PCI_XGENE | |||
120 | depends on ARCH_XGENE | 136 | depends on ARCH_XGENE |
121 | depends on OF | 137 | depends on OF |
122 | select PCIEPORTBUS | 138 | select PCIEPORTBUS |
123 | select PCI_MSI_IRQ_DOMAIN if PCI_MSI | ||
124 | help | 139 | help |
125 | Say Y here if you want internal PCI support on APM X-Gene SoC. | 140 | Say Y here if you want internal PCI support on APM X-Gene SoC. |
126 | There are 5 internal PCIe ports available. Each port is GEN3 capable | 141 | There are 5 internal PCIe ports available. Each port is GEN3 capable |
@@ -128,7 +143,8 @@ config PCI_XGENE | |||
128 | 143 | ||
129 | config PCI_XGENE_MSI | 144 | config PCI_XGENE_MSI |
130 | bool "X-Gene v1 PCIe MSI feature" | 145 | bool "X-Gene v1 PCIe MSI feature" |
131 | depends on PCI_XGENE && PCI_MSI | 146 | depends on PCI_XGENE |
147 | depends on PCI_MSI_IRQ_DOMAIN | ||
132 | default y | 148 | default y |
133 | help | 149 | help |
134 | Say Y here if you want PCIe MSI support for the APM X-Gene v1 SoC. | 150 | Say Y here if you want PCIe MSI support for the APM X-Gene v1 SoC. |
@@ -137,6 +153,7 @@ config PCI_XGENE_MSI | |||
137 | config PCI_LAYERSCAPE | 153 | config PCI_LAYERSCAPE |
138 | bool "Freescale Layerscape PCIe controller" | 154 | bool "Freescale Layerscape PCIe controller" |
139 | depends on OF && (ARM || ARCH_LAYERSCAPE) | 155 | depends on OF && (ARM || ARCH_LAYERSCAPE) |
156 | depends on PCI_MSI_IRQ_DOMAIN | ||
140 | select PCIE_DW | 157 | select PCIE_DW |
141 | select MFD_SYSCON | 158 | select MFD_SYSCON |
142 | help | 159 | help |
@@ -177,8 +194,7 @@ config PCIE_IPROC_BCMA | |||
177 | config PCIE_IPROC_MSI | 194 | config PCIE_IPROC_MSI |
178 | bool "Broadcom iProc PCIe MSI support" | 195 | bool "Broadcom iProc PCIe MSI support" |
179 | depends on PCIE_IPROC_PLATFORM || PCIE_IPROC_BCMA | 196 | depends on PCIE_IPROC_PLATFORM || PCIE_IPROC_BCMA |
180 | depends on PCI_MSI | 197 | depends on PCI_MSI_IRQ_DOMAIN |
181 | select PCI_MSI_IRQ_DOMAIN | ||
182 | default ARCH_BCM_IPROC | 198 | default ARCH_BCM_IPROC |
183 | help | 199 | help |
184 | Say Y here if you want to enable MSI support for Broadcom's iProc | 200 | Say Y here if you want to enable MSI support for Broadcom's iProc |
@@ -195,8 +211,8 @@ config PCIE_ALTERA | |||
195 | 211 | ||
196 | config PCIE_ALTERA_MSI | 212 | config PCIE_ALTERA_MSI |
197 | bool "Altera PCIe MSI feature" | 213 | bool "Altera PCIe MSI feature" |
198 | depends on PCIE_ALTERA && PCI_MSI | 214 | depends on PCIE_ALTERA |
199 | select PCI_MSI_IRQ_DOMAIN | 215 | depends on PCI_MSI_IRQ_DOMAIN |
200 | help | 216 | help |
201 | Say Y here if you want PCIe MSI support for the Altera FPGA. | 217 | Say Y here if you want PCIe MSI support for the Altera FPGA. |
202 | This MSI driver supports Altera MSI to GIC controller IP. | 218 | This MSI driver supports Altera MSI to GIC controller IP. |
@@ -204,6 +220,7 @@ config PCIE_ALTERA_MSI | |||
204 | config PCI_HISI | 220 | config PCI_HISI |
205 | depends on OF && ARM64 | 221 | depends on OF && ARM64 |
206 | bool "HiSilicon Hip05 and Hip06 SoCs PCIe controllers" | 222 | bool "HiSilicon Hip05 and Hip06 SoCs PCIe controllers" |
223 | depends on PCI_MSI_IRQ_DOMAIN | ||
207 | select PCIEPORTBUS | 224 | select PCIEPORTBUS |
208 | select PCIE_DW | 225 | select PCIE_DW |
209 | help | 226 | help |
@@ -213,6 +230,7 @@ config PCI_HISI | |||
213 | config PCIE_QCOM | 230 | config PCIE_QCOM |
214 | bool "Qualcomm PCIe controller" | 231 | bool "Qualcomm PCIe controller" |
215 | depends on ARCH_QCOM && OF | 232 | depends on ARCH_QCOM && OF |
233 | depends on PCI_MSI_IRQ_DOMAIN | ||
216 | select PCIE_DW | 234 | select PCIE_DW |
217 | select PCIEPORTBUS | 235 | select PCIEPORTBUS |
218 | help | 236 | help |
@@ -237,6 +255,7 @@ config PCI_HOST_THUNDER_ECAM | |||
237 | config PCIE_ARMADA_8K | 255 | config PCIE_ARMADA_8K |
238 | bool "Marvell Armada-8K PCIe controller" | 256 | bool "Marvell Armada-8K PCIe controller" |
239 | depends on ARCH_MVEBU | 257 | depends on ARCH_MVEBU |
258 | depends on PCI_MSI_IRQ_DOMAIN | ||
240 | select PCIE_DW | 259 | select PCIE_DW |
241 | select PCIEPORTBUS | 260 | select PCIEPORTBUS |
242 | help | 261 | help |
@@ -245,4 +264,14 @@ config PCIE_ARMADA_8K | |||
245 | Designware hardware and therefore the driver re-uses the | 264 | Designware hardware and therefore the driver re-uses the |
246 | Designware core functions to implement the driver. | 265 | Designware core functions to implement the driver. |
247 | 266 | ||
267 | config PCIE_ARTPEC6 | ||
268 | bool "Axis ARTPEC-6 PCIe controller" | ||
269 | depends on MACH_ARTPEC6 | ||
270 | depends on PCI_MSI_IRQ_DOMAIN | ||
271 | select PCIE_DW | ||
272 | select PCIEPORTBUS | ||
273 | help | ||
274 | Say Y here to enable PCIe controller support on Axis ARTPEC-6 | ||
275 | SoCs. This PCIe controller uses the DesignWare core. | ||
276 | |||
248 | endmenu | 277 | endmenu |
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index 9c8698e89e96..88434101e4c4 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile | |||
@@ -5,6 +5,7 @@ obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o | |||
5 | obj-$(CONFIG_PCI_IMX6) += pci-imx6.o | 5 | obj-$(CONFIG_PCI_IMX6) += pci-imx6.o |
6 | obj-$(CONFIG_PCI_HYPERV) += pci-hyperv.o | 6 | obj-$(CONFIG_PCI_HYPERV) += pci-hyperv.o |
7 | obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o | 7 | obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o |
8 | obj-$(CONFIG_PCI_AARDVARK) += pci-aardvark.o | ||
8 | obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o | 9 | obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o |
9 | obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o | 10 | obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o |
10 | obj-$(CONFIG_PCIE_RCAR) += pcie-rcar.o | 11 | obj-$(CONFIG_PCIE_RCAR) += pcie-rcar.o |
@@ -29,3 +30,4 @@ obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o | |||
29 | obj-$(CONFIG_PCI_HOST_THUNDER_ECAM) += pci-thunder-ecam.o | 30 | obj-$(CONFIG_PCI_HOST_THUNDER_ECAM) += pci-thunder-ecam.o |
30 | obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o | 31 | obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o |
31 | obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o | 32 | obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o |
33 | obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o | ||
diff --git a/drivers/pci/host/pci-aardvark.c b/drivers/pci/host/pci-aardvark.c new file mode 100644 index 000000000000..ef9893fa3176 --- /dev/null +++ b/drivers/pci/host/pci-aardvark.c | |||
@@ -0,0 +1,1001 @@ | |||
1 | /* | ||
2 | * Driver for the Aardvark PCIe controller, used on Marvell Armada | ||
3 | * 3700. | ||
4 | * | ||
5 | * Copyright (C) 2016 Marvell | ||
6 | * | ||
7 | * Author: Hezi Shahmoon <hezi.shahmoon@marvell.com> | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | #include <linux/delay.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/irq.h> | ||
17 | #include <linux/irqdomain.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/pci.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/of_address.h> | ||
23 | #include <linux/of_pci.h> | ||
24 | |||
25 | /* PCIe core registers */ | ||
26 | #define PCIE_CORE_CMD_STATUS_REG 0x4 | ||
27 | #define PCIE_CORE_CMD_IO_ACCESS_EN BIT(0) | ||
28 | #define PCIE_CORE_CMD_MEM_ACCESS_EN BIT(1) | ||
29 | #define PCIE_CORE_CMD_MEM_IO_REQ_EN BIT(2) | ||
30 | #define PCIE_CORE_DEV_CTRL_STATS_REG 0xc8 | ||
31 | #define PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE (0 << 4) | ||
32 | #define PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT 5 | ||
33 | #define PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE (0 << 11) | ||
34 | #define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT 12 | ||
35 | #define PCIE_CORE_LINK_CTRL_STAT_REG 0xd0 | ||
36 | #define PCIE_CORE_LINK_L0S_ENTRY BIT(0) | ||
37 | #define PCIE_CORE_LINK_TRAINING BIT(5) | ||
38 | #define PCIE_CORE_LINK_WIDTH_SHIFT 20 | ||
39 | #define PCIE_CORE_ERR_CAPCTL_REG 0x118 | ||
40 | #define PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX BIT(5) | ||
41 | #define PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX_EN BIT(6) | ||
42 | #define PCIE_CORE_ERR_CAPCTL_ECRC_CHCK BIT(7) | ||
43 | #define PCIE_CORE_ERR_CAPCTL_ECRC_CHCK_RCV BIT(8) | ||
44 | |||
45 | /* PIO registers base address and register offsets */ | ||
46 | #define PIO_BASE_ADDR 0x4000 | ||
47 | #define PIO_CTRL (PIO_BASE_ADDR + 0x0) | ||
48 | #define PIO_CTRL_TYPE_MASK GENMASK(3, 0) | ||
49 | #define PIO_CTRL_ADDR_WIN_DISABLE BIT(24) | ||
50 | #define PIO_STAT (PIO_BASE_ADDR + 0x4) | ||
51 | #define PIO_COMPLETION_STATUS_SHIFT 7 | ||
52 | #define PIO_COMPLETION_STATUS_MASK GENMASK(9, 7) | ||
53 | #define PIO_COMPLETION_STATUS_OK 0 | ||
54 | #define PIO_COMPLETION_STATUS_UR 1 | ||
55 | #define PIO_COMPLETION_STATUS_CRS 2 | ||
56 | #define PIO_COMPLETION_STATUS_CA 4 | ||
57 | #define PIO_NON_POSTED_REQ BIT(0) | ||
58 | #define PIO_ADDR_LS (PIO_BASE_ADDR + 0x8) | ||
59 | #define PIO_ADDR_MS (PIO_BASE_ADDR + 0xc) | ||
60 | #define PIO_WR_DATA (PIO_BASE_ADDR + 0x10) | ||
61 | #define PIO_WR_DATA_STRB (PIO_BASE_ADDR + 0x14) | ||
62 | #define PIO_RD_DATA (PIO_BASE_ADDR + 0x18) | ||
63 | #define PIO_START (PIO_BASE_ADDR + 0x1c) | ||
64 | #define PIO_ISR (PIO_BASE_ADDR + 0x20) | ||
65 | #define PIO_ISRM (PIO_BASE_ADDR + 0x24) | ||
66 | |||
67 | /* Aardvark Control registers */ | ||
68 | #define CONTROL_BASE_ADDR 0x4800 | ||
69 | #define PCIE_CORE_CTRL0_REG (CONTROL_BASE_ADDR + 0x0) | ||
70 | #define PCIE_GEN_SEL_MSK 0x3 | ||
71 | #define PCIE_GEN_SEL_SHIFT 0x0 | ||
72 | #define SPEED_GEN_1 0 | ||
73 | #define SPEED_GEN_2 1 | ||
74 | #define SPEED_GEN_3 2 | ||
75 | #define IS_RC_MSK 1 | ||
76 | #define IS_RC_SHIFT 2 | ||
77 | #define LANE_CNT_MSK 0x18 | ||
78 | #define LANE_CNT_SHIFT 0x3 | ||
79 | #define LANE_COUNT_1 (0 << LANE_CNT_SHIFT) | ||
80 | #define LANE_COUNT_2 (1 << LANE_CNT_SHIFT) | ||
81 | #define LANE_COUNT_4 (2 << LANE_CNT_SHIFT) | ||
82 | #define LANE_COUNT_8 (3 << LANE_CNT_SHIFT) | ||
83 | #define LINK_TRAINING_EN BIT(6) | ||
84 | #define LEGACY_INTA BIT(28) | ||
85 | #define LEGACY_INTB BIT(29) | ||
86 | #define LEGACY_INTC BIT(30) | ||
87 | #define LEGACY_INTD BIT(31) | ||
88 | #define PCIE_CORE_CTRL1_REG (CONTROL_BASE_ADDR + 0x4) | ||
89 | #define HOT_RESET_GEN BIT(0) | ||
90 | #define PCIE_CORE_CTRL2_REG (CONTROL_BASE_ADDR + 0x8) | ||
91 | #define PCIE_CORE_CTRL2_RESERVED 0x7 | ||
92 | #define PCIE_CORE_CTRL2_TD_ENABLE BIT(4) | ||
93 | #define PCIE_CORE_CTRL2_STRICT_ORDER_ENABLE BIT(5) | ||
94 | #define PCIE_CORE_CTRL2_OB_WIN_ENABLE BIT(6) | ||
95 | #define PCIE_CORE_CTRL2_MSI_ENABLE BIT(10) | ||
96 | #define PCIE_ISR0_REG (CONTROL_BASE_ADDR + 0x40) | ||
97 | #define PCIE_ISR0_MASK_REG (CONTROL_BASE_ADDR + 0x44) | ||
98 | #define PCIE_ISR0_MSI_INT_PENDING BIT(24) | ||
99 | #define PCIE_ISR0_INTX_ASSERT(val) BIT(16 + (val)) | ||
100 | #define PCIE_ISR0_INTX_DEASSERT(val) BIT(20 + (val)) | ||
101 | #define PCIE_ISR0_ALL_MASK GENMASK(26, 0) | ||
102 | #define PCIE_ISR1_REG (CONTROL_BASE_ADDR + 0x48) | ||
103 | #define PCIE_ISR1_MASK_REG (CONTROL_BASE_ADDR + 0x4C) | ||
104 | #define PCIE_ISR1_POWER_STATE_CHANGE BIT(4) | ||
105 | #define PCIE_ISR1_FLUSH BIT(5) | ||
106 | #define PCIE_ISR1_ALL_MASK GENMASK(5, 4) | ||
107 | #define PCIE_MSI_ADDR_LOW_REG (CONTROL_BASE_ADDR + 0x50) | ||
108 | #define PCIE_MSI_ADDR_HIGH_REG (CONTROL_BASE_ADDR + 0x54) | ||
109 | #define PCIE_MSI_STATUS_REG (CONTROL_BASE_ADDR + 0x58) | ||
110 | #define PCIE_MSI_MASK_REG (CONTROL_BASE_ADDR + 0x5C) | ||
111 | #define PCIE_MSI_PAYLOAD_REG (CONTROL_BASE_ADDR + 0x9C) | ||
112 | |||
113 | /* PCIe window configuration */ | ||
114 | #define OB_WIN_BASE_ADDR 0x4c00 | ||
115 | #define OB_WIN_BLOCK_SIZE 0x20 | ||
116 | #define OB_WIN_REG_ADDR(win, offset) (OB_WIN_BASE_ADDR + \ | ||
117 | OB_WIN_BLOCK_SIZE * (win) + \ | ||
118 | (offset)) | ||
119 | #define OB_WIN_MATCH_LS(win) OB_WIN_REG_ADDR(win, 0x00) | ||
120 | #define OB_WIN_MATCH_MS(win) OB_WIN_REG_ADDR(win, 0x04) | ||
121 | #define OB_WIN_REMAP_LS(win) OB_WIN_REG_ADDR(win, 0x08) | ||
122 | #define OB_WIN_REMAP_MS(win) OB_WIN_REG_ADDR(win, 0x0c) | ||
123 | #define OB_WIN_MASK_LS(win) OB_WIN_REG_ADDR(win, 0x10) | ||
124 | #define OB_WIN_MASK_MS(win) OB_WIN_REG_ADDR(win, 0x14) | ||
125 | #define OB_WIN_ACTIONS(win) OB_WIN_REG_ADDR(win, 0x18) | ||
126 | |||
127 | /* PCIe window types */ | ||
128 | #define OB_PCIE_MEM 0x0 | ||
129 | #define OB_PCIE_IO 0x4 | ||
130 | |||
131 | /* LMI registers base address and register offsets */ | ||
132 | #define LMI_BASE_ADDR 0x6000 | ||
133 | #define CFG_REG (LMI_BASE_ADDR + 0x0) | ||
134 | #define LTSSM_SHIFT 24 | ||
135 | #define LTSSM_MASK 0x3f | ||
136 | #define LTSSM_L0 0x10 | ||
137 | #define RC_BAR_CONFIG 0x300 | ||
138 | |||
139 | /* PCIe core controller registers */ | ||
140 | #define CTRL_CORE_BASE_ADDR 0x18000 | ||
141 | #define CTRL_CONFIG_REG (CTRL_CORE_BASE_ADDR + 0x0) | ||
142 | #define CTRL_MODE_SHIFT 0x0 | ||
143 | #define CTRL_MODE_MASK 0x1 | ||
144 | #define PCIE_CORE_MODE_DIRECT 0x0 | ||
145 | #define PCIE_CORE_MODE_COMMAND 0x1 | ||
146 | |||
147 | /* PCIe Central Interrupts Registers */ | ||
148 | #define CENTRAL_INT_BASE_ADDR 0x1b000 | ||
149 | #define HOST_CTRL_INT_STATUS_REG (CENTRAL_INT_BASE_ADDR + 0x0) | ||
150 | #define HOST_CTRL_INT_MASK_REG (CENTRAL_INT_BASE_ADDR + 0x4) | ||
151 | #define PCIE_IRQ_CMDQ_INT BIT(0) | ||
152 | #define PCIE_IRQ_MSI_STATUS_INT BIT(1) | ||
153 | #define PCIE_IRQ_CMD_SENT_DONE BIT(3) | ||
154 | #define PCIE_IRQ_DMA_INT BIT(4) | ||
155 | #define PCIE_IRQ_IB_DXFERDONE BIT(5) | ||
156 | #define PCIE_IRQ_OB_DXFERDONE BIT(6) | ||
157 | #define PCIE_IRQ_OB_RXFERDONE BIT(7) | ||
158 | #define PCIE_IRQ_COMPQ_INT BIT(12) | ||
159 | #define PCIE_IRQ_DIR_RD_DDR_DET BIT(13) | ||
160 | #define PCIE_IRQ_DIR_WR_DDR_DET BIT(14) | ||
161 | #define PCIE_IRQ_CORE_INT BIT(16) | ||
162 | #define PCIE_IRQ_CORE_INT_PIO BIT(17) | ||
163 | #define PCIE_IRQ_DPMU_INT BIT(18) | ||
164 | #define PCIE_IRQ_PCIE_MIS_INT BIT(19) | ||
165 | #define PCIE_IRQ_MSI_INT1_DET BIT(20) | ||
166 | #define PCIE_IRQ_MSI_INT2_DET BIT(21) | ||
167 | #define PCIE_IRQ_RC_DBELL_DET BIT(22) | ||
168 | #define PCIE_IRQ_EP_STATUS BIT(23) | ||
169 | #define PCIE_IRQ_ALL_MASK 0xfff0fb | ||
170 | #define PCIE_IRQ_ENABLE_INTS_MASK PCIE_IRQ_CORE_INT | ||
171 | |||
172 | /* Transaction types */ | ||
173 | #define PCIE_CONFIG_RD_TYPE0 0x8 | ||
174 | #define PCIE_CONFIG_RD_TYPE1 0x9 | ||
175 | #define PCIE_CONFIG_WR_TYPE0 0xa | ||
176 | #define PCIE_CONFIG_WR_TYPE1 0xb | ||
177 | |||
178 | /* PCI_BDF shifts 8bit, so we need extra 4bit shift */ | ||
179 | #define PCIE_BDF(dev) (dev << 4) | ||
180 | #define PCIE_CONF_BUS(bus) (((bus) & 0xff) << 20) | ||
181 | #define PCIE_CONF_DEV(dev) (((dev) & 0x1f) << 15) | ||
182 | #define PCIE_CONF_FUNC(fun) (((fun) & 0x7) << 12) | ||
183 | #define PCIE_CONF_REG(reg) ((reg) & 0xffc) | ||
184 | #define PCIE_CONF_ADDR(bus, devfn, where) \ | ||
185 | (PCIE_CONF_BUS(bus) | PCIE_CONF_DEV(PCI_SLOT(devfn)) | \ | ||
186 | PCIE_CONF_FUNC(PCI_FUNC(devfn)) | PCIE_CONF_REG(where)) | ||
187 | |||
188 | #define PIO_TIMEOUT_MS 1 | ||
189 | |||
190 | #define LINK_WAIT_MAX_RETRIES 10 | ||
191 | #define LINK_WAIT_USLEEP_MIN 90000 | ||
192 | #define LINK_WAIT_USLEEP_MAX 100000 | ||
193 | |||
194 | #define LEGACY_IRQ_NUM 4 | ||
195 | #define MSI_IRQ_NUM 32 | ||
196 | |||
197 | struct advk_pcie { | ||
198 | struct platform_device *pdev; | ||
199 | void __iomem *base; | ||
200 | struct list_head resources; | ||
201 | struct irq_domain *irq_domain; | ||
202 | struct irq_chip irq_chip; | ||
203 | struct msi_controller msi; | ||
204 | struct irq_domain *msi_domain; | ||
205 | struct irq_chip msi_irq_chip; | ||
206 | DECLARE_BITMAP(msi_irq_in_use, MSI_IRQ_NUM); | ||
207 | struct mutex msi_used_lock; | ||
208 | u16 msi_msg; | ||
209 | int root_bus_nr; | ||
210 | }; | ||
211 | |||
212 | static inline void advk_writel(struct advk_pcie *pcie, u32 val, u64 reg) | ||
213 | { | ||
214 | writel(val, pcie->base + reg); | ||
215 | } | ||
216 | |||
217 | static inline u32 advk_readl(struct advk_pcie *pcie, u64 reg) | ||
218 | { | ||
219 | return readl(pcie->base + reg); | ||
220 | } | ||
221 | |||
222 | static int advk_pcie_link_up(struct advk_pcie *pcie) | ||
223 | { | ||
224 | u32 val, ltssm_state; | ||
225 | |||
226 | val = advk_readl(pcie, CFG_REG); | ||
227 | ltssm_state = (val >> LTSSM_SHIFT) & LTSSM_MASK; | ||
228 | return ltssm_state >= LTSSM_L0; | ||
229 | } | ||
230 | |||
231 | static int advk_pcie_wait_for_link(struct advk_pcie *pcie) | ||
232 | { | ||
233 | int retries; | ||
234 | |||
235 | /* check if the link is up or not */ | ||
236 | for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) { | ||
237 | if (advk_pcie_link_up(pcie)) { | ||
238 | dev_info(&pcie->pdev->dev, "link up\n"); | ||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX); | ||
243 | } | ||
244 | |||
245 | dev_err(&pcie->pdev->dev, "link never came up\n"); | ||
246 | |||
247 | return -ETIMEDOUT; | ||
248 | } | ||
249 | |||
250 | /* | ||
251 | * Set PCIe address window register which could be used for memory | ||
252 | * mapping. | ||
253 | */ | ||
254 | static void advk_pcie_set_ob_win(struct advk_pcie *pcie, | ||
255 | u32 win_num, u32 match_ms, | ||
256 | u32 match_ls, u32 mask_ms, | ||
257 | u32 mask_ls, u32 remap_ms, | ||
258 | u32 remap_ls, u32 action) | ||
259 | { | ||
260 | advk_writel(pcie, match_ls, OB_WIN_MATCH_LS(win_num)); | ||
261 | advk_writel(pcie, match_ms, OB_WIN_MATCH_MS(win_num)); | ||
262 | advk_writel(pcie, mask_ms, OB_WIN_MASK_MS(win_num)); | ||
263 | advk_writel(pcie, mask_ls, OB_WIN_MASK_LS(win_num)); | ||
264 | advk_writel(pcie, remap_ms, OB_WIN_REMAP_MS(win_num)); | ||
265 | advk_writel(pcie, remap_ls, OB_WIN_REMAP_LS(win_num)); | ||
266 | advk_writel(pcie, action, OB_WIN_ACTIONS(win_num)); | ||
267 | advk_writel(pcie, match_ls | BIT(0), OB_WIN_MATCH_LS(win_num)); | ||
268 | } | ||
269 | |||
270 | static void advk_pcie_setup_hw(struct advk_pcie *pcie) | ||
271 | { | ||
272 | u32 reg; | ||
273 | int i; | ||
274 | |||
275 | /* Point PCIe unit MBUS decode windows to DRAM space */ | ||
276 | for (i = 0; i < 8; i++) | ||
277 | advk_pcie_set_ob_win(pcie, i, 0, 0, 0, 0, 0, 0, 0); | ||
278 | |||
279 | /* Set to Direct mode */ | ||
280 | reg = advk_readl(pcie, CTRL_CONFIG_REG); | ||
281 | reg &= ~(CTRL_MODE_MASK << CTRL_MODE_SHIFT); | ||
282 | reg |= ((PCIE_CORE_MODE_DIRECT & CTRL_MODE_MASK) << CTRL_MODE_SHIFT); | ||
283 | advk_writel(pcie, reg, CTRL_CONFIG_REG); | ||
284 | |||
285 | /* Set PCI global control register to RC mode */ | ||
286 | reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); | ||
287 | reg |= (IS_RC_MSK << IS_RC_SHIFT); | ||
288 | advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); | ||
289 | |||
290 | /* Set Advanced Error Capabilities and Control PF0 register */ | ||
291 | reg = PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX | | ||
292 | PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX_EN | | ||
293 | PCIE_CORE_ERR_CAPCTL_ECRC_CHCK | | ||
294 | PCIE_CORE_ERR_CAPCTL_ECRC_CHCK_RCV; | ||
295 | advk_writel(pcie, reg, PCIE_CORE_ERR_CAPCTL_REG); | ||
296 | |||
297 | /* Set PCIe Device Control and Status 1 PF0 register */ | ||
298 | reg = PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE | | ||
299 | (7 << PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT) | | ||
300 | PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE | | ||
301 | PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT; | ||
302 | advk_writel(pcie, reg, PCIE_CORE_DEV_CTRL_STATS_REG); | ||
303 | |||
304 | /* Program PCIe Control 2 to disable strict ordering */ | ||
305 | reg = PCIE_CORE_CTRL2_RESERVED | | ||
306 | PCIE_CORE_CTRL2_TD_ENABLE; | ||
307 | advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG); | ||
308 | |||
309 | /* Set GEN2 */ | ||
310 | reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); | ||
311 | reg &= ~PCIE_GEN_SEL_MSK; | ||
312 | reg |= SPEED_GEN_2; | ||
313 | advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); | ||
314 | |||
315 | /* Set lane X1 */ | ||
316 | reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); | ||
317 | reg &= ~LANE_CNT_MSK; | ||
318 | reg |= LANE_COUNT_1; | ||
319 | advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); | ||
320 | |||
321 | /* Enable link training */ | ||
322 | reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); | ||
323 | reg |= LINK_TRAINING_EN; | ||
324 | advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); | ||
325 | |||
326 | /* Enable MSI */ | ||
327 | reg = advk_readl(pcie, PCIE_CORE_CTRL2_REG); | ||
328 | reg |= PCIE_CORE_CTRL2_MSI_ENABLE; | ||
329 | advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG); | ||
330 | |||
331 | /* Clear all interrupts */ | ||
332 | advk_writel(pcie, PCIE_ISR0_ALL_MASK, PCIE_ISR0_REG); | ||
333 | advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_REG); | ||
334 | advk_writel(pcie, PCIE_IRQ_ALL_MASK, HOST_CTRL_INT_STATUS_REG); | ||
335 | |||
336 | /* Disable All ISR0/1 Sources */ | ||
337 | reg = PCIE_ISR0_ALL_MASK; | ||
338 | reg &= ~PCIE_ISR0_MSI_INT_PENDING; | ||
339 | advk_writel(pcie, reg, PCIE_ISR0_MASK_REG); | ||
340 | |||
341 | advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_MASK_REG); | ||
342 | |||
343 | /* Unmask all MSI's */ | ||
344 | advk_writel(pcie, 0, PCIE_MSI_MASK_REG); | ||
345 | |||
346 | /* Enable summary interrupt for GIC SPI source */ | ||
347 | reg = PCIE_IRQ_ALL_MASK & (~PCIE_IRQ_ENABLE_INTS_MASK); | ||
348 | advk_writel(pcie, reg, HOST_CTRL_INT_MASK_REG); | ||
349 | |||
350 | reg = advk_readl(pcie, PCIE_CORE_CTRL2_REG); | ||
351 | reg |= PCIE_CORE_CTRL2_OB_WIN_ENABLE; | ||
352 | advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG); | ||
353 | |||
354 | /* Bypass the address window mapping for PIO */ | ||
355 | reg = advk_readl(pcie, PIO_CTRL); | ||
356 | reg |= PIO_CTRL_ADDR_WIN_DISABLE; | ||
357 | advk_writel(pcie, reg, PIO_CTRL); | ||
358 | |||
359 | /* Start link training */ | ||
360 | reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG); | ||
361 | reg |= PCIE_CORE_LINK_TRAINING; | ||
362 | advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG); | ||
363 | |||
364 | advk_pcie_wait_for_link(pcie); | ||
365 | |||
366 | reg = PCIE_CORE_LINK_L0S_ENTRY | | ||
367 | (1 << PCIE_CORE_LINK_WIDTH_SHIFT); | ||
368 | advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG); | ||
369 | |||
370 | reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); | ||
371 | reg |= PCIE_CORE_CMD_MEM_ACCESS_EN | | ||
372 | PCIE_CORE_CMD_IO_ACCESS_EN | | ||
373 | PCIE_CORE_CMD_MEM_IO_REQ_EN; | ||
374 | advk_writel(pcie, reg, PCIE_CORE_CMD_STATUS_REG); | ||
375 | } | ||
376 | |||
377 | static void advk_pcie_check_pio_status(struct advk_pcie *pcie) | ||
378 | { | ||
379 | u32 reg; | ||
380 | unsigned int status; | ||
381 | char *strcomp_status, *str_posted; | ||
382 | |||
383 | reg = advk_readl(pcie, PIO_STAT); | ||
384 | status = (reg & PIO_COMPLETION_STATUS_MASK) >> | ||
385 | PIO_COMPLETION_STATUS_SHIFT; | ||
386 | |||
387 | if (!status) | ||
388 | return; | ||
389 | |||
390 | switch (status) { | ||
391 | case PIO_COMPLETION_STATUS_UR: | ||
392 | strcomp_status = "UR"; | ||
393 | break; | ||
394 | case PIO_COMPLETION_STATUS_CRS: | ||
395 | strcomp_status = "CRS"; | ||
396 | break; | ||
397 | case PIO_COMPLETION_STATUS_CA: | ||
398 | strcomp_status = "CA"; | ||
399 | break; | ||
400 | default: | ||
401 | strcomp_status = "Unknown"; | ||
402 | break; | ||
403 | } | ||
404 | |||
405 | if (reg & PIO_NON_POSTED_REQ) | ||
406 | str_posted = "Non-posted"; | ||
407 | else | ||
408 | str_posted = "Posted"; | ||
409 | |||
410 | dev_err(&pcie->pdev->dev, "%s PIO Response Status: %s, %#x @ %#x\n", | ||
411 | str_posted, strcomp_status, reg, advk_readl(pcie, PIO_ADDR_LS)); | ||
412 | } | ||
413 | |||
414 | static int advk_pcie_wait_pio(struct advk_pcie *pcie) | ||
415 | { | ||
416 | unsigned long timeout; | ||
417 | |||
418 | timeout = jiffies + msecs_to_jiffies(PIO_TIMEOUT_MS); | ||
419 | |||
420 | while (time_before(jiffies, timeout)) { | ||
421 | u32 start, isr; | ||
422 | |||
423 | start = advk_readl(pcie, PIO_START); | ||
424 | isr = advk_readl(pcie, PIO_ISR); | ||
425 | if (!start && isr) | ||
426 | return 0; | ||
427 | } | ||
428 | |||
429 | dev_err(&pcie->pdev->dev, "config read/write timed out\n"); | ||
430 | return -ETIMEDOUT; | ||
431 | } | ||
432 | |||
433 | static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn, | ||
434 | int where, int size, u32 *val) | ||
435 | { | ||
436 | struct advk_pcie *pcie = bus->sysdata; | ||
437 | u32 reg; | ||
438 | int ret; | ||
439 | |||
440 | if (PCI_SLOT(devfn) != 0) { | ||
441 | *val = 0xffffffff; | ||
442 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
443 | } | ||
444 | |||
445 | /* Start PIO */ | ||
446 | advk_writel(pcie, 0, PIO_START); | ||
447 | advk_writel(pcie, 1, PIO_ISR); | ||
448 | |||
449 | /* Program the control register */ | ||
450 | reg = advk_readl(pcie, PIO_CTRL); | ||
451 | reg &= ~PIO_CTRL_TYPE_MASK; | ||
452 | if (bus->number == pcie->root_bus_nr) | ||
453 | reg |= PCIE_CONFIG_RD_TYPE0; | ||
454 | else | ||
455 | reg |= PCIE_CONFIG_RD_TYPE1; | ||
456 | advk_writel(pcie, reg, PIO_CTRL); | ||
457 | |||
458 | /* Program the address registers */ | ||
459 | reg = PCIE_BDF(devfn) | PCIE_CONF_REG(where); | ||
460 | advk_writel(pcie, reg, PIO_ADDR_LS); | ||
461 | advk_writel(pcie, 0, PIO_ADDR_MS); | ||
462 | |||
463 | /* Program the data strobe */ | ||
464 | advk_writel(pcie, 0xf, PIO_WR_DATA_STRB); | ||
465 | |||
466 | /* Start the transfer */ | ||
467 | advk_writel(pcie, 1, PIO_START); | ||
468 | |||
469 | ret = advk_pcie_wait_pio(pcie); | ||
470 | if (ret < 0) | ||
471 | return PCIBIOS_SET_FAILED; | ||
472 | |||
473 | advk_pcie_check_pio_status(pcie); | ||
474 | |||
475 | /* Get the read result */ | ||
476 | *val = advk_readl(pcie, PIO_RD_DATA); | ||
477 | if (size == 1) | ||
478 | *val = (*val >> (8 * (where & 3))) & 0xff; | ||
479 | else if (size == 2) | ||
480 | *val = (*val >> (8 * (where & 3))) & 0xffff; | ||
481 | |||
482 | return PCIBIOS_SUCCESSFUL; | ||
483 | } | ||
484 | |||
485 | static int advk_pcie_wr_conf(struct pci_bus *bus, u32 devfn, | ||
486 | int where, int size, u32 val) | ||
487 | { | ||
488 | struct advk_pcie *pcie = bus->sysdata; | ||
489 | u32 reg; | ||
490 | u32 data_strobe = 0x0; | ||
491 | int offset; | ||
492 | int ret; | ||
493 | |||
494 | if (PCI_SLOT(devfn) != 0) | ||
495 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
496 | |||
497 | if (where % size) | ||
498 | return PCIBIOS_SET_FAILED; | ||
499 | |||
500 | /* Start PIO */ | ||
501 | advk_writel(pcie, 0, PIO_START); | ||
502 | advk_writel(pcie, 1, PIO_ISR); | ||
503 | |||
504 | /* Program the control register */ | ||
505 | reg = advk_readl(pcie, PIO_CTRL); | ||
506 | reg &= ~PIO_CTRL_TYPE_MASK; | ||
507 | if (bus->number == pcie->root_bus_nr) | ||
508 | reg |= PCIE_CONFIG_WR_TYPE0; | ||
509 | else | ||
510 | reg |= PCIE_CONFIG_WR_TYPE1; | ||
511 | advk_writel(pcie, reg, PIO_CTRL); | ||
512 | |||
513 | /* Program the address registers */ | ||
514 | reg = PCIE_CONF_ADDR(bus->number, devfn, where); | ||
515 | advk_writel(pcie, reg, PIO_ADDR_LS); | ||
516 | advk_writel(pcie, 0, PIO_ADDR_MS); | ||
517 | |||
518 | /* Calculate the write strobe */ | ||
519 | offset = where & 0x3; | ||
520 | reg = val << (8 * offset); | ||
521 | data_strobe = GENMASK(size - 1, 0) << offset; | ||
522 | |||
523 | /* Program the data register */ | ||
524 | advk_writel(pcie, reg, PIO_WR_DATA); | ||
525 | |||
526 | /* Program the data strobe */ | ||
527 | advk_writel(pcie, data_strobe, PIO_WR_DATA_STRB); | ||
528 | |||
529 | /* Start the transfer */ | ||
530 | advk_writel(pcie, 1, PIO_START); | ||
531 | |||
532 | ret = advk_pcie_wait_pio(pcie); | ||
533 | if (ret < 0) | ||
534 | return PCIBIOS_SET_FAILED; | ||
535 | |||
536 | advk_pcie_check_pio_status(pcie); | ||
537 | |||
538 | return PCIBIOS_SUCCESSFUL; | ||
539 | } | ||
540 | |||
541 | static struct pci_ops advk_pcie_ops = { | ||
542 | .read = advk_pcie_rd_conf, | ||
543 | .write = advk_pcie_wr_conf, | ||
544 | }; | ||
545 | |||
546 | static int advk_pcie_alloc_msi(struct advk_pcie *pcie) | ||
547 | { | ||
548 | int hwirq; | ||
549 | |||
550 | mutex_lock(&pcie->msi_used_lock); | ||
551 | hwirq = find_first_zero_bit(pcie->msi_irq_in_use, MSI_IRQ_NUM); | ||
552 | if (hwirq >= MSI_IRQ_NUM) | ||
553 | hwirq = -ENOSPC; | ||
554 | else | ||
555 | set_bit(hwirq, pcie->msi_irq_in_use); | ||
556 | mutex_unlock(&pcie->msi_used_lock); | ||
557 | |||
558 | return hwirq; | ||
559 | } | ||
560 | |||
561 | static void advk_pcie_free_msi(struct advk_pcie *pcie, int hwirq) | ||
562 | { | ||
563 | mutex_lock(&pcie->msi_used_lock); | ||
564 | if (!test_bit(hwirq, pcie->msi_irq_in_use)) | ||
565 | dev_err(&pcie->pdev->dev, "trying to free unused MSI#%d\n", | ||
566 | hwirq); | ||
567 | else | ||
568 | clear_bit(hwirq, pcie->msi_irq_in_use); | ||
569 | mutex_unlock(&pcie->msi_used_lock); | ||
570 | } | ||
571 | |||
572 | static int advk_pcie_setup_msi_irq(struct msi_controller *chip, | ||
573 | struct pci_dev *pdev, | ||
574 | struct msi_desc *desc) | ||
575 | { | ||
576 | struct advk_pcie *pcie = pdev->bus->sysdata; | ||
577 | struct msi_msg msg; | ||
578 | int virq, hwirq; | ||
579 | phys_addr_t msi_msg_phys; | ||
580 | |||
581 | /* We support MSI, but not MSI-X */ | ||
582 | if (desc->msi_attrib.is_msix) | ||
583 | return -EINVAL; | ||
584 | |||
585 | hwirq = advk_pcie_alloc_msi(pcie); | ||
586 | if (hwirq < 0) | ||
587 | return hwirq; | ||
588 | |||
589 | virq = irq_create_mapping(pcie->msi_domain, hwirq); | ||
590 | if (!virq) { | ||
591 | advk_pcie_free_msi(pcie, hwirq); | ||
592 | return -EINVAL; | ||
593 | } | ||
594 | |||
595 | irq_set_msi_desc(virq, desc); | ||
596 | |||
597 | msi_msg_phys = virt_to_phys(&pcie->msi_msg); | ||
598 | |||
599 | msg.address_lo = lower_32_bits(msi_msg_phys); | ||
600 | msg.address_hi = upper_32_bits(msi_msg_phys); | ||
601 | msg.data = virq; | ||
602 | |||
603 | pci_write_msi_msg(virq, &msg); | ||
604 | |||
605 | return 0; | ||
606 | } | ||
607 | |||
608 | static void advk_pcie_teardown_msi_irq(struct msi_controller *chip, | ||
609 | unsigned int irq) | ||
610 | { | ||
611 | struct irq_data *d = irq_get_irq_data(irq); | ||
612 | struct msi_desc *msi = irq_data_get_msi_desc(d); | ||
613 | struct advk_pcie *pcie = msi_desc_to_pci_sysdata(msi); | ||
614 | unsigned long hwirq = d->hwirq; | ||
615 | |||
616 | irq_dispose_mapping(irq); | ||
617 | advk_pcie_free_msi(pcie, hwirq); | ||
618 | } | ||
619 | |||
620 | static int advk_pcie_msi_map(struct irq_domain *domain, | ||
621 | unsigned int virq, irq_hw_number_t hw) | ||
622 | { | ||
623 | struct advk_pcie *pcie = domain->host_data; | ||
624 | |||
625 | irq_set_chip_and_handler(virq, &pcie->msi_irq_chip, | ||
626 | handle_simple_irq); | ||
627 | |||
628 | return 0; | ||
629 | } | ||
630 | |||
631 | static const struct irq_domain_ops advk_pcie_msi_irq_ops = { | ||
632 | .map = advk_pcie_msi_map, | ||
633 | }; | ||
634 | |||
635 | static void advk_pcie_irq_mask(struct irq_data *d) | ||
636 | { | ||
637 | struct advk_pcie *pcie = d->domain->host_data; | ||
638 | irq_hw_number_t hwirq = irqd_to_hwirq(d); | ||
639 | u32 mask; | ||
640 | |||
641 | mask = advk_readl(pcie, PCIE_ISR0_MASK_REG); | ||
642 | mask |= PCIE_ISR0_INTX_ASSERT(hwirq); | ||
643 | advk_writel(pcie, mask, PCIE_ISR0_MASK_REG); | ||
644 | } | ||
645 | |||
646 | static void advk_pcie_irq_unmask(struct irq_data *d) | ||
647 | { | ||
648 | struct advk_pcie *pcie = d->domain->host_data; | ||
649 | irq_hw_number_t hwirq = irqd_to_hwirq(d); | ||
650 | u32 mask; | ||
651 | |||
652 | mask = advk_readl(pcie, PCIE_ISR0_MASK_REG); | ||
653 | mask &= ~PCIE_ISR0_INTX_ASSERT(hwirq); | ||
654 | advk_writel(pcie, mask, PCIE_ISR0_MASK_REG); | ||
655 | } | ||
656 | |||
657 | static int advk_pcie_irq_map(struct irq_domain *h, | ||
658 | unsigned int virq, irq_hw_number_t hwirq) | ||
659 | { | ||
660 | struct advk_pcie *pcie = h->host_data; | ||
661 | |||
662 | advk_pcie_irq_mask(irq_get_irq_data(virq)); | ||
663 | irq_set_status_flags(virq, IRQ_LEVEL); | ||
664 | irq_set_chip_and_handler(virq, &pcie->irq_chip, | ||
665 | handle_level_irq); | ||
666 | irq_set_chip_data(virq, pcie); | ||
667 | |||
668 | return 0; | ||
669 | } | ||
670 | |||
671 | static const struct irq_domain_ops advk_pcie_irq_domain_ops = { | ||
672 | .map = advk_pcie_irq_map, | ||
673 | .xlate = irq_domain_xlate_onecell, | ||
674 | }; | ||
675 | |||
676 | static int advk_pcie_init_msi_irq_domain(struct advk_pcie *pcie) | ||
677 | { | ||
678 | struct device *dev = &pcie->pdev->dev; | ||
679 | struct device_node *node = dev->of_node; | ||
680 | struct irq_chip *msi_irq_chip; | ||
681 | struct msi_controller *msi; | ||
682 | phys_addr_t msi_msg_phys; | ||
683 | int ret; | ||
684 | |||
685 | msi_irq_chip = &pcie->msi_irq_chip; | ||
686 | |||
687 | msi_irq_chip->name = devm_kasprintf(dev, GFP_KERNEL, "%s-msi", | ||
688 | dev_name(dev)); | ||
689 | if (!msi_irq_chip->name) | ||
690 | return -ENOMEM; | ||
691 | |||
692 | msi_irq_chip->irq_enable = pci_msi_unmask_irq; | ||
693 | msi_irq_chip->irq_disable = pci_msi_mask_irq; | ||
694 | msi_irq_chip->irq_mask = pci_msi_mask_irq; | ||
695 | msi_irq_chip->irq_unmask = pci_msi_unmask_irq; | ||
696 | |||
697 | msi = &pcie->msi; | ||
698 | |||
699 | msi->setup_irq = advk_pcie_setup_msi_irq; | ||
700 | msi->teardown_irq = advk_pcie_teardown_msi_irq; | ||
701 | msi->of_node = node; | ||
702 | |||
703 | mutex_init(&pcie->msi_used_lock); | ||
704 | |||
705 | msi_msg_phys = virt_to_phys(&pcie->msi_msg); | ||
706 | |||
707 | advk_writel(pcie, lower_32_bits(msi_msg_phys), | ||
708 | PCIE_MSI_ADDR_LOW_REG); | ||
709 | advk_writel(pcie, upper_32_bits(msi_msg_phys), | ||
710 | PCIE_MSI_ADDR_HIGH_REG); | ||
711 | |||
712 | pcie->msi_domain = | ||
713 | irq_domain_add_linear(NULL, MSI_IRQ_NUM, | ||
714 | &advk_pcie_msi_irq_ops, pcie); | ||
715 | if (!pcie->msi_domain) | ||
716 | return -ENOMEM; | ||
717 | |||
718 | ret = of_pci_msi_chip_add(msi); | ||
719 | if (ret < 0) { | ||
720 | irq_domain_remove(pcie->msi_domain); | ||
721 | return ret; | ||
722 | } | ||
723 | |||
724 | return 0; | ||
725 | } | ||
726 | |||
727 | static void advk_pcie_remove_msi_irq_domain(struct advk_pcie *pcie) | ||
728 | { | ||
729 | of_pci_msi_chip_remove(&pcie->msi); | ||
730 | irq_domain_remove(pcie->msi_domain); | ||
731 | } | ||
732 | |||
733 | static int advk_pcie_init_irq_domain(struct advk_pcie *pcie) | ||
734 | { | ||
735 | struct device *dev = &pcie->pdev->dev; | ||
736 | struct device_node *node = dev->of_node; | ||
737 | struct device_node *pcie_intc_node; | ||
738 | struct irq_chip *irq_chip; | ||
739 | |||
740 | pcie_intc_node = of_get_next_child(node, NULL); | ||
741 | if (!pcie_intc_node) { | ||
742 | dev_err(dev, "No PCIe Intc node found\n"); | ||
743 | return -ENODEV; | ||
744 | } | ||
745 | |||
746 | irq_chip = &pcie->irq_chip; | ||
747 | |||
748 | irq_chip->name = devm_kasprintf(dev, GFP_KERNEL, "%s-irq", | ||
749 | dev_name(dev)); | ||
750 | if (!irq_chip->name) { | ||
751 | of_node_put(pcie_intc_node); | ||
752 | return -ENOMEM; | ||
753 | } | ||
754 | |||
755 | irq_chip->irq_mask = advk_pcie_irq_mask; | ||
756 | irq_chip->irq_mask_ack = advk_pcie_irq_mask; | ||
757 | irq_chip->irq_unmask = advk_pcie_irq_unmask; | ||
758 | |||
759 | pcie->irq_domain = | ||
760 | irq_domain_add_linear(pcie_intc_node, LEGACY_IRQ_NUM, | ||
761 | &advk_pcie_irq_domain_ops, pcie); | ||
762 | if (!pcie->irq_domain) { | ||
763 | dev_err(dev, "Failed to get a INTx IRQ domain\n"); | ||
764 | of_node_put(pcie_intc_node); | ||
765 | return -ENOMEM; | ||
766 | } | ||
767 | |||
768 | return 0; | ||
769 | } | ||
770 | |||
771 | static void advk_pcie_remove_irq_domain(struct advk_pcie *pcie) | ||
772 | { | ||
773 | irq_domain_remove(pcie->irq_domain); | ||
774 | } | ||
775 | |||
776 | static void advk_pcie_handle_msi(struct advk_pcie *pcie) | ||
777 | { | ||
778 | u32 msi_val, msi_mask, msi_status, msi_idx; | ||
779 | u16 msi_data; | ||
780 | |||
781 | msi_mask = advk_readl(pcie, PCIE_MSI_MASK_REG); | ||
782 | msi_val = advk_readl(pcie, PCIE_MSI_STATUS_REG); | ||
783 | msi_status = msi_val & ~msi_mask; | ||
784 | |||
785 | for (msi_idx = 0; msi_idx < MSI_IRQ_NUM; msi_idx++) { | ||
786 | if (!(BIT(msi_idx) & msi_status)) | ||
787 | continue; | ||
788 | |||
789 | advk_writel(pcie, BIT(msi_idx), PCIE_MSI_STATUS_REG); | ||
790 | msi_data = advk_readl(pcie, PCIE_MSI_PAYLOAD_REG) & 0xFF; | ||
791 | generic_handle_irq(msi_data); | ||
792 | } | ||
793 | |||
794 | advk_writel(pcie, PCIE_ISR0_MSI_INT_PENDING, | ||
795 | PCIE_ISR0_REG); | ||
796 | } | ||
797 | |||
798 | static void advk_pcie_handle_int(struct advk_pcie *pcie) | ||
799 | { | ||
800 | u32 val, mask, status; | ||
801 | int i, virq; | ||
802 | |||
803 | val = advk_readl(pcie, PCIE_ISR0_REG); | ||
804 | mask = advk_readl(pcie, PCIE_ISR0_MASK_REG); | ||
805 | status = val & ((~mask) & PCIE_ISR0_ALL_MASK); | ||
806 | |||
807 | if (!status) { | ||
808 | advk_writel(pcie, val, PCIE_ISR0_REG); | ||
809 | return; | ||
810 | } | ||
811 | |||
812 | /* Process MSI interrupts */ | ||
813 | if (status & PCIE_ISR0_MSI_INT_PENDING) | ||
814 | advk_pcie_handle_msi(pcie); | ||
815 | |||
816 | /* Process legacy interrupts */ | ||
817 | for (i = 0; i < LEGACY_IRQ_NUM; i++) { | ||
818 | if (!(status & PCIE_ISR0_INTX_ASSERT(i))) | ||
819 | continue; | ||
820 | |||
821 | advk_writel(pcie, PCIE_ISR0_INTX_ASSERT(i), | ||
822 | PCIE_ISR0_REG); | ||
823 | |||
824 | virq = irq_find_mapping(pcie->irq_domain, i); | ||
825 | generic_handle_irq(virq); | ||
826 | } | ||
827 | } | ||
828 | |||
829 | static irqreturn_t advk_pcie_irq_handler(int irq, void *arg) | ||
830 | { | ||
831 | struct advk_pcie *pcie = arg; | ||
832 | u32 status; | ||
833 | |||
834 | status = advk_readl(pcie, HOST_CTRL_INT_STATUS_REG); | ||
835 | if (!(status & PCIE_IRQ_CORE_INT)) | ||
836 | return IRQ_NONE; | ||
837 | |||
838 | advk_pcie_handle_int(pcie); | ||
839 | |||
840 | /* Clear interrupt */ | ||
841 | advk_writel(pcie, PCIE_IRQ_CORE_INT, HOST_CTRL_INT_STATUS_REG); | ||
842 | |||
843 | return IRQ_HANDLED; | ||
844 | } | ||
845 | |||
846 | static int advk_pcie_parse_request_of_pci_ranges(struct advk_pcie *pcie) | ||
847 | { | ||
848 | int err, res_valid = 0; | ||
849 | struct device *dev = &pcie->pdev->dev; | ||
850 | struct device_node *np = dev->of_node; | ||
851 | struct resource_entry *win; | ||
852 | resource_size_t iobase; | ||
853 | |||
854 | INIT_LIST_HEAD(&pcie->resources); | ||
855 | |||
856 | err = of_pci_get_host_bridge_resources(np, 0, 0xff, &pcie->resources, | ||
857 | &iobase); | ||
858 | if (err) | ||
859 | return err; | ||
860 | |||
861 | err = devm_request_pci_bus_resources(dev, &pcie->resources); | ||
862 | if (err) | ||
863 | goto out_release_res; | ||
864 | |||
865 | resource_list_for_each_entry(win, &pcie->resources) { | ||
866 | struct resource *res = win->res; | ||
867 | |||
868 | switch (resource_type(res)) { | ||
869 | case IORESOURCE_IO: | ||
870 | advk_pcie_set_ob_win(pcie, 1, | ||
871 | upper_32_bits(res->start), | ||
872 | lower_32_bits(res->start), | ||
873 | 0, 0xF8000000, 0, | ||
874 | lower_32_bits(res->start), | ||
875 | OB_PCIE_IO); | ||
876 | err = pci_remap_iospace(res, iobase); | ||
877 | if (err) | ||
878 | dev_warn(dev, "error %d: failed to map resource %pR\n", | ||
879 | err, res); | ||
880 | break; | ||
881 | case IORESOURCE_MEM: | ||
882 | advk_pcie_set_ob_win(pcie, 0, | ||
883 | upper_32_bits(res->start), | ||
884 | lower_32_bits(res->start), | ||
885 | 0x0, 0xF8000000, 0, | ||
886 | lower_32_bits(res->start), | ||
887 | (2 << 20) | OB_PCIE_MEM); | ||
888 | res_valid |= !(res->flags & IORESOURCE_PREFETCH); | ||
889 | break; | ||
890 | case IORESOURCE_BUS: | ||
891 | pcie->root_bus_nr = res->start; | ||
892 | break; | ||
893 | } | ||
894 | } | ||
895 | |||
896 | if (!res_valid) { | ||
897 | dev_err(dev, "non-prefetchable memory resource required\n"); | ||
898 | err = -EINVAL; | ||
899 | goto out_release_res; | ||
900 | } | ||
901 | |||
902 | return 0; | ||
903 | |||
904 | out_release_res: | ||
905 | pci_free_resource_list(&pcie->resources); | ||
906 | return err; | ||
907 | } | ||
908 | |||
909 | static int advk_pcie_probe(struct platform_device *pdev) | ||
910 | { | ||
911 | struct advk_pcie *pcie; | ||
912 | struct resource *res; | ||
913 | struct pci_bus *bus, *child; | ||
914 | struct msi_controller *msi; | ||
915 | struct device_node *msi_node; | ||
916 | int ret, irq; | ||
917 | |||
918 | pcie = devm_kzalloc(&pdev->dev, sizeof(struct advk_pcie), | ||
919 | GFP_KERNEL); | ||
920 | if (!pcie) | ||
921 | return -ENOMEM; | ||
922 | |||
923 | pcie->pdev = pdev; | ||
924 | platform_set_drvdata(pdev, pcie); | ||
925 | |||
926 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
927 | pcie->base = devm_ioremap_resource(&pdev->dev, res); | ||
928 | if (IS_ERR(pcie->base)) { | ||
929 | dev_err(&pdev->dev, "Failed to map registers\n"); | ||
930 | return PTR_ERR(pcie->base); | ||
931 | } | ||
932 | |||
933 | irq = platform_get_irq(pdev, 0); | ||
934 | ret = devm_request_irq(&pdev->dev, irq, advk_pcie_irq_handler, | ||
935 | IRQF_SHARED | IRQF_NO_THREAD, "advk-pcie", | ||
936 | pcie); | ||
937 | if (ret) { | ||
938 | dev_err(&pdev->dev, "Failed to register interrupt\n"); | ||
939 | return ret; | ||
940 | } | ||
941 | |||
942 | ret = advk_pcie_parse_request_of_pci_ranges(pcie); | ||
943 | if (ret) { | ||
944 | dev_err(&pdev->dev, "Failed to parse resources\n"); | ||
945 | return ret; | ||
946 | } | ||
947 | |||
948 | advk_pcie_setup_hw(pcie); | ||
949 | |||
950 | ret = advk_pcie_init_irq_domain(pcie); | ||
951 | if (ret) { | ||
952 | dev_err(&pdev->dev, "Failed to initialize irq\n"); | ||
953 | return ret; | ||
954 | } | ||
955 | |||
956 | ret = advk_pcie_init_msi_irq_domain(pcie); | ||
957 | if (ret) { | ||
958 | dev_err(&pdev->dev, "Failed to initialize irq\n"); | ||
959 | advk_pcie_remove_irq_domain(pcie); | ||
960 | return ret; | ||
961 | } | ||
962 | |||
963 | msi_node = of_parse_phandle(pdev->dev.of_node, "msi-parent", 0); | ||
964 | if (msi_node) | ||
965 | msi = of_pci_find_msi_chip_by_node(msi_node); | ||
966 | else | ||
967 | msi = NULL; | ||
968 | |||
969 | bus = pci_scan_root_bus_msi(&pdev->dev, 0, &advk_pcie_ops, | ||
970 | pcie, &pcie->resources, &pcie->msi); | ||
971 | if (!bus) { | ||
972 | advk_pcie_remove_msi_irq_domain(pcie); | ||
973 | advk_pcie_remove_irq_domain(pcie); | ||
974 | return -ENOMEM; | ||
975 | } | ||
976 | |||
977 | pci_bus_assign_resources(bus); | ||
978 | |||
979 | list_for_each_entry(child, &bus->children, node) | ||
980 | pcie_bus_configure_settings(child); | ||
981 | |||
982 | pci_bus_add_devices(bus); | ||
983 | |||
984 | return 0; | ||
985 | } | ||
986 | |||
987 | static const struct of_device_id advk_pcie_of_match_table[] = { | ||
988 | { .compatible = "marvell,armada-3700-pcie", }, | ||
989 | {}, | ||
990 | }; | ||
991 | |||
992 | static struct platform_driver advk_pcie_driver = { | ||
993 | .driver = { | ||
994 | .name = "advk-pcie", | ||
995 | .of_match_table = advk_pcie_of_match_table, | ||
996 | /* Driver unloading/unbinding currently not supported */ | ||
997 | .suppress_bind_attrs = true, | ||
998 | }, | ||
999 | .probe = advk_pcie_probe, | ||
1000 | }; | ||
1001 | builtin_platform_driver(advk_pcie_driver); | ||
diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c index f441130407e7..81b3949a26db 100644 --- a/drivers/pci/host/pci-dra7xx.c +++ b/drivers/pci/host/pci-dra7xx.c | |||
@@ -181,14 +181,14 @@ static int dra7xx_pcie_init_irq_domain(struct pcie_port *pp) | |||
181 | 181 | ||
182 | if (!pcie_intc_node) { | 182 | if (!pcie_intc_node) { |
183 | dev_err(dev, "No PCIe Intc node found\n"); | 183 | dev_err(dev, "No PCIe Intc node found\n"); |
184 | return PTR_ERR(pcie_intc_node); | 184 | return -ENODEV; |
185 | } | 185 | } |
186 | 186 | ||
187 | pp->irq_domain = irq_domain_add_linear(pcie_intc_node, 4, | 187 | pp->irq_domain = irq_domain_add_linear(pcie_intc_node, 4, |
188 | &intx_domain_ops, pp); | 188 | &intx_domain_ops, pp); |
189 | if (!pp->irq_domain) { | 189 | if (!pp->irq_domain) { |
190 | dev_err(dev, "Failed to get a INTx IRQ domain\n"); | 190 | dev_err(dev, "Failed to get a INTx IRQ domain\n"); |
191 | return PTR_ERR(pp->irq_domain); | 191 | return -ENODEV; |
192 | } | 192 | } |
193 | 193 | ||
194 | return 0; | 194 | return 0; |
diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c index 8cba7ab73df9..9d9d34e959b6 100644 --- a/drivers/pci/host/pci-host-common.c +++ b/drivers/pci/host/pci-host-common.c | |||
@@ -20,10 +20,9 @@ | |||
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/of_address.h> | 21 | #include <linux/of_address.h> |
22 | #include <linux/of_pci.h> | 22 | #include <linux/of_pci.h> |
23 | #include <linux/pci-ecam.h> | ||
23 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
24 | 25 | ||
25 | #include "../ecam.h" | ||
26 | |||
27 | static int gen_pci_parse_request_of_pci_ranges(struct device *dev, | 26 | static int gen_pci_parse_request_of_pci_ranges(struct device *dev, |
28 | struct list_head *resources, struct resource **bus_range) | 27 | struct list_head *resources, struct resource **bus_range) |
29 | { | 28 | { |
@@ -36,44 +35,34 @@ static int gen_pci_parse_request_of_pci_ranges(struct device *dev, | |||
36 | if (err) | 35 | if (err) |
37 | return err; | 36 | return err; |
38 | 37 | ||
38 | err = devm_request_pci_bus_resources(dev, resources); | ||
39 | if (err) | ||
40 | return err; | ||
41 | |||
39 | resource_list_for_each_entry(win, resources) { | 42 | resource_list_for_each_entry(win, resources) { |
40 | struct resource *parent, *res = win->res; | 43 | struct resource *res = win->res; |
41 | 44 | ||
42 | switch (resource_type(res)) { | 45 | switch (resource_type(res)) { |
43 | case IORESOURCE_IO: | 46 | case IORESOURCE_IO: |
44 | parent = &ioport_resource; | ||
45 | err = pci_remap_iospace(res, iobase); | 47 | err = pci_remap_iospace(res, iobase); |
46 | if (err) { | 48 | if (err) |
47 | dev_warn(dev, "error %d: failed to map resource %pR\n", | 49 | dev_warn(dev, "error %d: failed to map resource %pR\n", |
48 | err, res); | 50 | err, res); |
49 | continue; | ||
50 | } | ||
51 | break; | 51 | break; |
52 | case IORESOURCE_MEM: | 52 | case IORESOURCE_MEM: |
53 | parent = &iomem_resource; | ||
54 | res_valid |= !(res->flags & IORESOURCE_PREFETCH); | 53 | res_valid |= !(res->flags & IORESOURCE_PREFETCH); |
55 | break; | 54 | break; |
56 | case IORESOURCE_BUS: | 55 | case IORESOURCE_BUS: |
57 | *bus_range = res; | 56 | *bus_range = res; |
58 | default: | 57 | break; |
59 | continue; | ||
60 | } | 58 | } |
61 | |||
62 | err = devm_request_resource(dev, parent, res); | ||
63 | if (err) | ||
64 | goto out_release_res; | ||
65 | } | ||
66 | |||
67 | if (!res_valid) { | ||
68 | dev_err(dev, "non-prefetchable memory resource required\n"); | ||
69 | err = -EINVAL; | ||
70 | goto out_release_res; | ||
71 | } | 59 | } |
72 | 60 | ||
73 | return 0; | 61 | if (res_valid) |
62 | return 0; | ||
74 | 63 | ||
75 | out_release_res: | 64 | dev_err(dev, "non-prefetchable memory resource required\n"); |
76 | return err; | 65 | return -EINVAL; |
77 | } | 66 | } |
78 | 67 | ||
79 | static void gen_pci_unmap_cfg(void *ptr) | 68 | static void gen_pci_unmap_cfg(void *ptr) |
@@ -155,7 +144,14 @@ int pci_host_common_probe(struct platform_device *pdev, | |||
155 | 144 | ||
156 | pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci); | 145 | pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci); |
157 | 146 | ||
158 | if (!pci_has_flag(PCI_PROBE_ONLY)) { | 147 | /* |
148 | * We insert PCI resources into the iomem_resource and | ||
149 | * ioport_resource trees in either pci_bus_claim_resources() | ||
150 | * or pci_bus_assign_resources(). | ||
151 | */ | ||
152 | if (pci_has_flag(PCI_PROBE_ONLY)) { | ||
153 | pci_bus_claim_resources(bus); | ||
154 | } else { | ||
159 | pci_bus_size_bridges(bus); | 155 | pci_bus_size_bridges(bus); |
160 | pci_bus_assign_resources(bus); | 156 | pci_bus_assign_resources(bus); |
161 | 157 | ||
diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c index 6eaceab1bf04..c05ea9d72f69 100644 --- a/drivers/pci/host/pci-host-generic.c +++ b/drivers/pci/host/pci-host-generic.c | |||
@@ -20,13 +20,12 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/module.h> | 23 | #include <linux/init.h> |
24 | #include <linux/of_address.h> | 24 | #include <linux/of_address.h> |
25 | #include <linux/of_pci.h> | 25 | #include <linux/of_pci.h> |
26 | #include <linux/pci-ecam.h> | ||
26 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
27 | 28 | ||
28 | #include "../ecam.h" | ||
29 | |||
30 | static struct pci_ecam_ops gen_pci_cfg_cam_bus_ops = { | 29 | static struct pci_ecam_ops gen_pci_cfg_cam_bus_ops = { |
31 | .bus_shift = 16, | 30 | .bus_shift = 16, |
32 | .pci_ops = { | 31 | .pci_ops = { |
@@ -46,8 +45,6 @@ static const struct of_device_id gen_pci_of_match[] = { | |||
46 | { }, | 45 | { }, |
47 | }; | 46 | }; |
48 | 47 | ||
49 | MODULE_DEVICE_TABLE(of, gen_pci_of_match); | ||
50 | |||
51 | static int gen_pci_probe(struct platform_device *pdev) | 48 | static int gen_pci_probe(struct platform_device *pdev) |
52 | { | 49 | { |
53 | const struct of_device_id *of_id; | 50 | const struct of_device_id *of_id; |
@@ -66,8 +63,4 @@ static struct platform_driver gen_pci_driver = { | |||
66 | }, | 63 | }, |
67 | .probe = gen_pci_probe, | 64 | .probe = gen_pci_probe, |
68 | }; | 65 | }; |
69 | module_platform_driver(gen_pci_driver); | 66 | builtin_platform_driver(gen_pci_driver); |
70 | |||
71 | MODULE_DESCRIPTION("Generic PCI host driver"); | ||
72 | MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>"); | ||
73 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c index 7e9b2de2aa24..6955ffdb89f3 100644 --- a/drivers/pci/host/pci-hyperv.c +++ b/drivers/pci/host/pci-hyperv.c | |||
@@ -732,16 +732,18 @@ static void hv_msi_free(struct irq_domain *domain, struct msi_domain_info *info, | |||
732 | 732 | ||
733 | pdev = msi_desc_to_pci_dev(msi); | 733 | pdev = msi_desc_to_pci_dev(msi); |
734 | hbus = info->data; | 734 | hbus = info->data; |
735 | hpdev = get_pcichild_wslot(hbus, devfn_to_wslot(pdev->devfn)); | 735 | int_desc = irq_data_get_irq_chip_data(irq_data); |
736 | if (!hpdev) | 736 | if (!int_desc) |
737 | return; | 737 | return; |
738 | 738 | ||
739 | int_desc = irq_data_get_irq_chip_data(irq_data); | 739 | irq_data->chip_data = NULL; |
740 | if (int_desc) { | 740 | hpdev = get_pcichild_wslot(hbus, devfn_to_wslot(pdev->devfn)); |
741 | irq_data->chip_data = NULL; | 741 | if (!hpdev) { |
742 | hv_int_desc_free(hpdev, int_desc); | 742 | kfree(int_desc); |
743 | return; | ||
743 | } | 744 | } |
744 | 745 | ||
746 | hv_int_desc_free(hpdev, int_desc); | ||
745 | put_pcichild(hpdev, hv_pcidev_ref_by_slot); | 747 | put_pcichild(hpdev, hv_pcidev_ref_by_slot); |
746 | } | 748 | } |
747 | 749 | ||
@@ -1657,14 +1659,16 @@ static void hv_pci_onchannelcallback(void *context) | |||
1657 | continue; | 1659 | continue; |
1658 | } | 1660 | } |
1659 | 1661 | ||
1662 | /* Zero length indicates there are no more packets. */ | ||
1663 | if (ret || !bytes_recvd) | ||
1664 | break; | ||
1665 | |||
1660 | /* | 1666 | /* |
1661 | * All incoming packets must be at least as large as a | 1667 | * All incoming packets must be at least as large as a |
1662 | * response. | 1668 | * response. |
1663 | */ | 1669 | */ |
1664 | if (bytes_recvd <= sizeof(struct pci_response)) { | 1670 | if (bytes_recvd <= sizeof(struct pci_response)) |
1665 | kfree(buffer); | 1671 | continue; |
1666 | return; | ||
1667 | } | ||
1668 | desc = (struct vmpacket_descriptor *)buffer; | 1672 | desc = (struct vmpacket_descriptor *)buffer; |
1669 | 1673 | ||
1670 | switch (desc->type) { | 1674 | switch (desc->type) { |
@@ -1679,8 +1683,7 @@ static void hv_pci_onchannelcallback(void *context) | |||
1679 | comp_packet->completion_func(comp_packet->compl_ctxt, | 1683 | comp_packet->completion_func(comp_packet->compl_ctxt, |
1680 | response, | 1684 | response, |
1681 | bytes_recvd); | 1685 | bytes_recvd); |
1682 | kfree(buffer); | 1686 | break; |
1683 | return; | ||
1684 | 1687 | ||
1685 | case VM_PKT_DATA_INBAND: | 1688 | case VM_PKT_DATA_INBAND: |
1686 | 1689 | ||
@@ -1727,8 +1730,9 @@ static void hv_pci_onchannelcallback(void *context) | |||
1727 | desc->type, req_id, bytes_recvd); | 1730 | desc->type, req_id, bytes_recvd); |
1728 | break; | 1731 | break; |
1729 | } | 1732 | } |
1730 | break; | ||
1731 | } | 1733 | } |
1734 | |||
1735 | kfree(buffer); | ||
1732 | } | 1736 | } |
1733 | 1737 | ||
1734 | /** | 1738 | /** |
diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c index 6b8301ef21ca..8ba28834d470 100644 --- a/drivers/pci/host/pci-keystone.c +++ b/drivers/pci/host/pci-keystone.c | |||
@@ -17,7 +17,7 @@ | |||
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/irqdomain.h> | 19 | #include <linux/irqdomain.h> |
20 | #include <linux/module.h> | 20 | #include <linux/init.h> |
21 | #include <linux/msi.h> | 21 | #include <linux/msi.h> |
22 | #include <linux/of_irq.h> | 22 | #include <linux/of_irq.h> |
23 | #include <linux/of.h> | 23 | #include <linux/of.h> |
@@ -360,7 +360,6 @@ static const struct of_device_id ks_pcie_of_match[] = { | |||
360 | }, | 360 | }, |
361 | { }, | 361 | { }, |
362 | }; | 362 | }; |
363 | MODULE_DEVICE_TABLE(of, ks_pcie_of_match); | ||
364 | 363 | ||
365 | static int __exit ks_pcie_remove(struct platform_device *pdev) | 364 | static int __exit ks_pcie_remove(struct platform_device *pdev) |
366 | { | 365 | { |
@@ -439,9 +438,4 @@ static struct platform_driver ks_pcie_driver __refdata = { | |||
439 | .of_match_table = of_match_ptr(ks_pcie_of_match), | 438 | .of_match_table = of_match_ptr(ks_pcie_of_match), |
440 | }, | 439 | }, |
441 | }; | 440 | }; |
442 | 441 | builtin_platform_driver(ks_pcie_driver); | |
443 | module_platform_driver(ks_pcie_driver); | ||
444 | |||
445 | MODULE_AUTHOR("Murali Karicheri <m-karicheri2@ti.com>"); | ||
446 | MODULE_DESCRIPTION("Keystone PCIe host controller driver"); | ||
447 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c index a21e229d95e0..114ba819277a 100644 --- a/drivers/pci/host/pci-layerscape.c +++ b/drivers/pci/host/pci-layerscape.c | |||
@@ -12,7 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
15 | #include <linux/module.h> | 15 | #include <linux/init.h> |
16 | #include <linux/of_pci.h> | 16 | #include <linux/of_pci.h> |
17 | #include <linux/of_platform.h> | 17 | #include <linux/of_platform.h> |
18 | #include <linux/of_irq.h> | 18 | #include <linux/of_irq.h> |
@@ -211,7 +211,6 @@ static const struct of_device_id ls_pcie_of_match[] = { | |||
211 | { .compatible = "fsl,ls2085a-pcie", .data = &ls2080_drvdata }, | 211 | { .compatible = "fsl,ls2085a-pcie", .data = &ls2080_drvdata }, |
212 | { }, | 212 | { }, |
213 | }; | 213 | }; |
214 | MODULE_DEVICE_TABLE(of, ls_pcie_of_match); | ||
215 | 214 | ||
216 | static int __init ls_add_pcie_port(struct pcie_port *pp, | 215 | static int __init ls_add_pcie_port(struct pcie_port *pp, |
217 | struct platform_device *pdev) | 216 | struct platform_device *pdev) |
@@ -275,9 +274,4 @@ static struct platform_driver ls_pcie_driver = { | |||
275 | .of_match_table = ls_pcie_of_match, | 274 | .of_match_table = ls_pcie_of_match, |
276 | }, | 275 | }, |
277 | }; | 276 | }; |
278 | 277 | builtin_platform_driver_probe(ls_pcie_driver, ls_pcie_probe); | |
279 | module_platform_driver_probe(ls_pcie_driver, ls_pcie_probe); | ||
280 | |||
281 | MODULE_AUTHOR("Minghuan Lian <Minghuan.Lian@freescale.com>"); | ||
282 | MODULE_DESCRIPTION("Freescale Layerscape PCIe host controller driver"); | ||
283 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index 6b451df6502c..307f81d6b479 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c | |||
@@ -1,6 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * PCIe driver for Marvell Armada 370 and Armada XP SoCs | 2 | * PCIe driver for Marvell Armada 370 and Armada XP SoCs |
3 | * | 3 | * |
4 | * Author: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
5 | * | ||
4 | * This file is licensed under the terms of the GNU General Public | 6 | * This file is licensed under the terms of the GNU General Public |
5 | * License version 2. This program is licensed "as is" without any | 7 | * License version 2. This program is licensed "as is" without any |
6 | * warranty of any kind, whether express or implied. | 8 | * warranty of any kind, whether express or implied. |
@@ -11,7 +13,7 @@ | |||
11 | #include <linux/clk.h> | 13 | #include <linux/clk.h> |
12 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
13 | #include <linux/gpio.h> | 15 | #include <linux/gpio.h> |
14 | #include <linux/module.h> | 16 | #include <linux/init.h> |
15 | #include <linux/mbus.h> | 17 | #include <linux/mbus.h> |
16 | #include <linux/msi.h> | 18 | #include <linux/msi.h> |
17 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
@@ -839,25 +841,22 @@ static struct pci_ops mvebu_pcie_ops = { | |||
839 | static int mvebu_pcie_setup(int nr, struct pci_sys_data *sys) | 841 | static int mvebu_pcie_setup(int nr, struct pci_sys_data *sys) |
840 | { | 842 | { |
841 | struct mvebu_pcie *pcie = sys_to_pcie(sys); | 843 | struct mvebu_pcie *pcie = sys_to_pcie(sys); |
842 | int i; | 844 | int err, i; |
843 | 845 | ||
844 | pcie->mem.name = "PCI MEM"; | 846 | pcie->mem.name = "PCI MEM"; |
845 | pcie->realio.name = "PCI I/O"; | 847 | pcie->realio.name = "PCI I/O"; |
846 | 848 | ||
847 | if (request_resource(&iomem_resource, &pcie->mem)) | 849 | if (resource_size(&pcie->realio) != 0) |
848 | return 0; | ||
849 | |||
850 | if (resource_size(&pcie->realio) != 0) { | ||
851 | if (request_resource(&ioport_resource, &pcie->realio)) { | ||
852 | release_resource(&pcie->mem); | ||
853 | return 0; | ||
854 | } | ||
855 | pci_add_resource_offset(&sys->resources, &pcie->realio, | 850 | pci_add_resource_offset(&sys->resources, &pcie->realio, |
856 | sys->io_offset); | 851 | sys->io_offset); |
857 | } | 852 | |
858 | pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset); | 853 | pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset); |
859 | pci_add_resource(&sys->resources, &pcie->busn); | 854 | pci_add_resource(&sys->resources, &pcie->busn); |
860 | 855 | ||
856 | err = devm_request_pci_bus_resources(&pcie->pdev->dev, &sys->resources); | ||
857 | if (err) | ||
858 | return 0; | ||
859 | |||
861 | for (i = 0; i < pcie->nports; i++) { | 860 | for (i = 0; i < pcie->nports; i++) { |
862 | struct mvebu_pcie_port *port = &pcie->ports[i]; | 861 | struct mvebu_pcie_port *port = &pcie->ports[i]; |
863 | 862 | ||
@@ -1298,7 +1297,6 @@ static const struct of_device_id mvebu_pcie_of_match_table[] = { | |||
1298 | { .compatible = "marvell,kirkwood-pcie", }, | 1297 | { .compatible = "marvell,kirkwood-pcie", }, |
1299 | {}, | 1298 | {}, |
1300 | }; | 1299 | }; |
1301 | MODULE_DEVICE_TABLE(of, mvebu_pcie_of_match_table); | ||
1302 | 1300 | ||
1303 | static const struct dev_pm_ops mvebu_pcie_pm_ops = { | 1301 | static const struct dev_pm_ops mvebu_pcie_pm_ops = { |
1304 | SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mvebu_pcie_suspend, mvebu_pcie_resume) | 1302 | SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mvebu_pcie_suspend, mvebu_pcie_resume) |
@@ -1314,8 +1312,4 @@ static struct platform_driver mvebu_pcie_driver = { | |||
1314 | }, | 1312 | }, |
1315 | .probe = mvebu_pcie_probe, | 1313 | .probe = mvebu_pcie_probe, |
1316 | }; | 1314 | }; |
1317 | module_platform_driver(mvebu_pcie_driver); | 1315 | builtin_platform_driver(mvebu_pcie_driver); |
1318 | |||
1319 | MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>"); | ||
1320 | MODULE_DESCRIPTION("Marvell EBU PCIe driver"); | ||
1321 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pci-rcar-gen2.c b/drivers/pci/host/pci-rcar-gen2.c index 9980a4bdae7e..597566f96f5e 100644 --- a/drivers/pci/host/pci-rcar-gen2.c +++ b/drivers/pci/host/pci-rcar-gen2.c | |||
@@ -4,6 +4,8 @@ | |||
4 | * Copyright (C) 2013 Renesas Solutions Corp. | 4 | * Copyright (C) 2013 Renesas Solutions Corp. |
5 | * Copyright (C) 2013 Cogent Embedded, Inc. | 5 | * Copyright (C) 2013 Cogent Embedded, Inc. |
6 | * | 6 | * |
7 | * Author: Valentine Barshak <valentine.barshak@cogentembedded.com> | ||
8 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
9 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. |
@@ -14,7 +16,6 @@ | |||
14 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
15 | #include <linux/io.h> | 17 | #include <linux/io.h> |
16 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
17 | #include <linux/module.h> | ||
18 | #include <linux/of_address.h> | 19 | #include <linux/of_address.h> |
19 | #include <linux/of_pci.h> | 20 | #include <linux/of_pci.h> |
20 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
@@ -97,7 +98,6 @@ | |||
97 | struct rcar_pci_priv { | 98 | struct rcar_pci_priv { |
98 | struct device *dev; | 99 | struct device *dev; |
99 | void __iomem *reg; | 100 | void __iomem *reg; |
100 | struct resource io_res; | ||
101 | struct resource mem_res; | 101 | struct resource mem_res; |
102 | struct resource *cfg_res; | 102 | struct resource *cfg_res; |
103 | unsigned busnr; | 103 | unsigned busnr; |
@@ -194,6 +194,7 @@ static int rcar_pci_setup(int nr, struct pci_sys_data *sys) | |||
194 | struct rcar_pci_priv *priv = sys->private_data; | 194 | struct rcar_pci_priv *priv = sys->private_data; |
195 | void __iomem *reg = priv->reg; | 195 | void __iomem *reg = priv->reg; |
196 | u32 val; | 196 | u32 val; |
197 | int ret; | ||
197 | 198 | ||
198 | pm_runtime_enable(priv->dev); | 199 | pm_runtime_enable(priv->dev); |
199 | pm_runtime_get_sync(priv->dev); | 200 | pm_runtime_get_sync(priv->dev); |
@@ -273,8 +274,10 @@ static int rcar_pci_setup(int nr, struct pci_sys_data *sys) | |||
273 | rcar_pci_setup_errirq(priv); | 274 | rcar_pci_setup_errirq(priv); |
274 | 275 | ||
275 | /* Add PCI resources */ | 276 | /* Add PCI resources */ |
276 | pci_add_resource(&sys->resources, &priv->io_res); | ||
277 | pci_add_resource(&sys->resources, &priv->mem_res); | 277 | pci_add_resource(&sys->resources, &priv->mem_res); |
278 | ret = devm_request_pci_bus_resources(priv->dev, &sys->resources); | ||
279 | if (ret < 0) | ||
280 | return ret; | ||
278 | 281 | ||
279 | /* Setup bus number based on platform device id / of bus-range */ | 282 | /* Setup bus number based on platform device id / of bus-range */ |
280 | sys->busnr = priv->busnr; | 283 | sys->busnr = priv->busnr; |
@@ -371,14 +374,6 @@ static int rcar_pci_probe(struct platform_device *pdev) | |||
371 | return -ENOMEM; | 374 | return -ENOMEM; |
372 | 375 | ||
373 | priv->mem_res = *mem_res; | 376 | priv->mem_res = *mem_res; |
374 | /* | ||
375 | * The controller does not support/use port I/O, | ||
376 | * so setup a dummy port I/O region here. | ||
377 | */ | ||
378 | priv->io_res.start = priv->mem_res.start; | ||
379 | priv->io_res.end = priv->mem_res.end; | ||
380 | priv->io_res.flags = IORESOURCE_IO; | ||
381 | |||
382 | priv->cfg_res = cfg_res; | 377 | priv->cfg_res = cfg_res; |
383 | 378 | ||
384 | priv->irq = platform_get_irq(pdev, 0); | 379 | priv->irq = platform_get_irq(pdev, 0); |
@@ -421,6 +416,7 @@ static int rcar_pci_probe(struct platform_device *pdev) | |||
421 | hw_private[0] = priv; | 416 | hw_private[0] = priv; |
422 | memset(&hw, 0, sizeof(hw)); | 417 | memset(&hw, 0, sizeof(hw)); |
423 | hw.nr_controllers = ARRAY_SIZE(hw_private); | 418 | hw.nr_controllers = ARRAY_SIZE(hw_private); |
419 | hw.io_optional = 1; | ||
424 | hw.private_data = hw_private; | 420 | hw.private_data = hw_private; |
425 | hw.map_irq = rcar_pci_map_irq; | 421 | hw.map_irq = rcar_pci_map_irq; |
426 | hw.ops = &rcar_pci_ops; | 422 | hw.ops = &rcar_pci_ops; |
@@ -437,8 +433,6 @@ static struct of_device_id rcar_pci_of_match[] = { | |||
437 | { }, | 433 | { }, |
438 | }; | 434 | }; |
439 | 435 | ||
440 | MODULE_DEVICE_TABLE(of, rcar_pci_of_match); | ||
441 | |||
442 | static struct platform_driver rcar_pci_driver = { | 436 | static struct platform_driver rcar_pci_driver = { |
443 | .driver = { | 437 | .driver = { |
444 | .name = "pci-rcar-gen2", | 438 | .name = "pci-rcar-gen2", |
@@ -447,9 +441,4 @@ static struct platform_driver rcar_pci_driver = { | |||
447 | }, | 441 | }, |
448 | .probe = rcar_pci_probe, | 442 | .probe = rcar_pci_probe, |
449 | }; | 443 | }; |
450 | 444 | builtin_platform_driver(rcar_pci_driver); | |
451 | module_platform_driver(rcar_pci_driver); | ||
452 | |||
453 | MODULE_LICENSE("GPL v2"); | ||
454 | MODULE_DESCRIPTION("Renesas R-Car Gen2 internal PCI"); | ||
455 | MODULE_AUTHOR("Valentine Barshak <valentine.barshak@cogentembedded.com>"); | ||
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index c388468c202a..6de0757b11e4 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c | |||
@@ -9,6 +9,8 @@ | |||
9 | * | 9 | * |
10 | * Bits taken from arch/arm/mach-dove/pcie.c | 10 | * Bits taken from arch/arm/mach-dove/pcie.c |
11 | * | 11 | * |
12 | * Author: Thierry Reding <treding@nvidia.com> | ||
13 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | 14 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of the GNU General Public License as published by | 15 | * it under the terms of the GNU General Public License as published by |
14 | * the Free Software Foundation; either version 2 of the License, or | 16 | * the Free Software Foundation; either version 2 of the License, or |
@@ -32,7 +34,7 @@ | |||
32 | #include <linux/irq.h> | 34 | #include <linux/irq.h> |
33 | #include <linux/irqdomain.h> | 35 | #include <linux/irqdomain.h> |
34 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
35 | #include <linux/module.h> | 37 | #include <linux/init.h> |
36 | #include <linux/msi.h> | 38 | #include <linux/msi.h> |
37 | #include <linux/of_address.h> | 39 | #include <linux/of_address.h> |
38 | #include <linux/of_pci.h> | 40 | #include <linux/of_pci.h> |
@@ -183,26 +185,26 @@ | |||
183 | 185 | ||
184 | #define AFI_PEXBIAS_CTRL_0 0x168 | 186 | #define AFI_PEXBIAS_CTRL_0 0x168 |
185 | 187 | ||
186 | #define RP_VEND_XP 0x00000F00 | 188 | #define RP_VEND_XP 0x00000f00 |
187 | #define RP_VEND_XP_DL_UP (1 << 30) | 189 | #define RP_VEND_XP_DL_UP (1 << 30) |
188 | 190 | ||
189 | #define RP_PRIV_MISC 0x00000FE0 | 191 | #define RP_PRIV_MISC 0x00000fe0 |
190 | #define RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT (0xE << 0) | 192 | #define RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT (0xe << 0) |
191 | #define RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT (0xF << 0) | 193 | #define RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT (0xf << 0) |
192 | 194 | ||
193 | #define RP_LINK_CONTROL_STATUS 0x00000090 | 195 | #define RP_LINK_CONTROL_STATUS 0x00000090 |
194 | #define RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE 0x20000000 | 196 | #define RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE 0x20000000 |
195 | #define RP_LINK_CONTROL_STATUS_LINKSTAT_MASK 0x3fff0000 | 197 | #define RP_LINK_CONTROL_STATUS_LINKSTAT_MASK 0x3fff0000 |
196 | 198 | ||
197 | #define PADS_CTL_SEL 0x0000009C | 199 | #define PADS_CTL_SEL 0x0000009c |
198 | 200 | ||
199 | #define PADS_CTL 0x000000A0 | 201 | #define PADS_CTL 0x000000a0 |
200 | #define PADS_CTL_IDDQ_1L (1 << 0) | 202 | #define PADS_CTL_IDDQ_1L (1 << 0) |
201 | #define PADS_CTL_TX_DATA_EN_1L (1 << 6) | 203 | #define PADS_CTL_TX_DATA_EN_1L (1 << 6) |
202 | #define PADS_CTL_RX_DATA_EN_1L (1 << 10) | 204 | #define PADS_CTL_RX_DATA_EN_1L (1 << 10) |
203 | 205 | ||
204 | #define PADS_PLL_CTL_TEGRA20 0x000000B8 | 206 | #define PADS_PLL_CTL_TEGRA20 0x000000b8 |
205 | #define PADS_PLL_CTL_TEGRA30 0x000000B4 | 207 | #define PADS_PLL_CTL_TEGRA30 0x000000b4 |
206 | #define PADS_PLL_CTL_RST_B4SM (1 << 1) | 208 | #define PADS_PLL_CTL_RST_B4SM (1 << 1) |
207 | #define PADS_PLL_CTL_LOCKDET (1 << 8) | 209 | #define PADS_PLL_CTL_LOCKDET (1 << 8) |
208 | #define PADS_PLL_CTL_REFCLK_MASK (0x3 << 16) | 210 | #define PADS_PLL_CTL_REFCLK_MASK (0x3 << 16) |
@@ -214,9 +216,9 @@ | |||
214 | #define PADS_PLL_CTL_TXCLKREF_DIV5 (1 << 20) | 216 | #define PADS_PLL_CTL_TXCLKREF_DIV5 (1 << 20) |
215 | #define PADS_PLL_CTL_TXCLKREF_BUF_EN (1 << 22) | 217 | #define PADS_PLL_CTL_TXCLKREF_BUF_EN (1 << 22) |
216 | 218 | ||
217 | #define PADS_REFCLK_CFG0 0x000000C8 | 219 | #define PADS_REFCLK_CFG0 0x000000c8 |
218 | #define PADS_REFCLK_CFG1 0x000000CC | 220 | #define PADS_REFCLK_CFG1 0x000000cc |
219 | #define PADS_REFCLK_BIAS 0x000000D0 | 221 | #define PADS_REFCLK_BIAS 0x000000d0 |
220 | 222 | ||
221 | /* | 223 | /* |
222 | * Fields in PADS_REFCLK_CFG*. Those registers form an array of 16-bit | 224 | * Fields in PADS_REFCLK_CFG*. Those registers form an array of 16-bit |
@@ -228,15 +230,6 @@ | |||
228 | #define PADS_REFCLK_CFG_PREDI_SHIFT 8 /* 11:8 */ | 230 | #define PADS_REFCLK_CFG_PREDI_SHIFT 8 /* 11:8 */ |
229 | #define PADS_REFCLK_CFG_DRVI_SHIFT 12 /* 15:12 */ | 231 | #define PADS_REFCLK_CFG_DRVI_SHIFT 12 /* 15:12 */ |
230 | 232 | ||
231 | /* Default value provided by HW engineering is 0xfa5c */ | ||
232 | #define PADS_REFCLK_CFG_VALUE \ | ||
233 | ( \ | ||
234 | (0x17 << PADS_REFCLK_CFG_TERM_SHIFT) | \ | ||
235 | (0 << PADS_REFCLK_CFG_E_TERM_SHIFT) | \ | ||
236 | (0xa << PADS_REFCLK_CFG_PREDI_SHIFT) | \ | ||
237 | (0xf << PADS_REFCLK_CFG_DRVI_SHIFT) \ | ||
238 | ) | ||
239 | |||
240 | struct tegra_msi { | 233 | struct tegra_msi { |
241 | struct msi_controller chip; | 234 | struct msi_controller chip; |
242 | DECLARE_BITMAP(used, INT_PCI_MSI_NR); | 235 | DECLARE_BITMAP(used, INT_PCI_MSI_NR); |
@@ -252,6 +245,8 @@ struct tegra_pcie_soc_data { | |||
252 | unsigned int msi_base_shift; | 245 | unsigned int msi_base_shift; |
253 | u32 pads_pll_ctl; | 246 | u32 pads_pll_ctl; |
254 | u32 tx_ref_sel; | 247 | u32 tx_ref_sel; |
248 | u32 pads_refclk_cfg0; | ||
249 | u32 pads_refclk_cfg1; | ||
255 | bool has_pex_clkreq_en; | 250 | bool has_pex_clkreq_en; |
256 | bool has_pex_bias_ctrl; | 251 | bool has_pex_bias_ctrl; |
257 | bool has_intr_prsnt_sense; | 252 | bool has_intr_prsnt_sense; |
@@ -274,7 +269,6 @@ struct tegra_pcie { | |||
274 | struct list_head buses; | 269 | struct list_head buses; |
275 | struct resource *cs; | 270 | struct resource *cs; |
276 | 271 | ||
277 | struct resource all; | ||
278 | struct resource io; | 272 | struct resource io; |
279 | struct resource pio; | 273 | struct resource pio; |
280 | struct resource mem; | 274 | struct resource mem; |
@@ -623,30 +617,21 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) | |||
623 | sys->mem_offset = pcie->offset.mem; | 617 | sys->mem_offset = pcie->offset.mem; |
624 | sys->io_offset = pcie->offset.io; | 618 | sys->io_offset = pcie->offset.io; |
625 | 619 | ||
626 | err = devm_request_resource(pcie->dev, &pcie->all, &pcie->io); | 620 | err = devm_request_resource(pcie->dev, &iomem_resource, &pcie->io); |
627 | if (err < 0) | ||
628 | return err; | ||
629 | |||
630 | err = devm_request_resource(pcie->dev, &ioport_resource, &pcie->pio); | ||
631 | if (err < 0) | ||
632 | return err; | ||
633 | |||
634 | err = devm_request_resource(pcie->dev, &pcie->all, &pcie->mem); | ||
635 | if (err < 0) | 621 | if (err < 0) |
636 | return err; | 622 | return err; |
637 | 623 | ||
638 | err = devm_request_resource(pcie->dev, &pcie->all, &pcie->prefetch); | ||
639 | if (err) | ||
640 | return err; | ||
641 | |||
642 | pci_add_resource_offset(&sys->resources, &pcie->pio, sys->io_offset); | 624 | pci_add_resource_offset(&sys->resources, &pcie->pio, sys->io_offset); |
643 | pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset); | 625 | pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset); |
644 | pci_add_resource_offset(&sys->resources, &pcie->prefetch, | 626 | pci_add_resource_offset(&sys->resources, &pcie->prefetch, |
645 | sys->mem_offset); | 627 | sys->mem_offset); |
646 | pci_add_resource(&sys->resources, &pcie->busn); | 628 | pci_add_resource(&sys->resources, &pcie->busn); |
647 | 629 | ||
648 | pci_ioremap_io(pcie->pio.start, pcie->io.start); | 630 | err = devm_request_pci_bus_resources(pcie->dev, &sys->resources); |
631 | if (err < 0) | ||
632 | return err; | ||
649 | 633 | ||
634 | pci_remap_iospace(&pcie->pio, pcie->io.start); | ||
650 | return 1; | 635 | return 1; |
651 | } | 636 | } |
652 | 637 | ||
@@ -838,12 +823,6 @@ static int tegra_pcie_phy_enable(struct tegra_pcie *pcie) | |||
838 | value |= PADS_PLL_CTL_RST_B4SM; | 823 | value |= PADS_PLL_CTL_RST_B4SM; |
839 | pads_writel(pcie, value, soc->pads_pll_ctl); | 824 | pads_writel(pcie, value, soc->pads_pll_ctl); |
840 | 825 | ||
841 | /* Configure the reference clock driver */ | ||
842 | value = PADS_REFCLK_CFG_VALUE | (PADS_REFCLK_CFG_VALUE << 16); | ||
843 | pads_writel(pcie, value, PADS_REFCLK_CFG0); | ||
844 | if (soc->num_ports > 2) | ||
845 | pads_writel(pcie, PADS_REFCLK_CFG_VALUE, PADS_REFCLK_CFG1); | ||
846 | |||
847 | /* wait for the PLL to lock */ | 826 | /* wait for the PLL to lock */ |
848 | err = tegra_pcie_pll_wait(pcie, 500); | 827 | err = tegra_pcie_pll_wait(pcie, 500); |
849 | if (err < 0) { | 828 | if (err < 0) { |
@@ -927,6 +906,7 @@ static int tegra_pcie_port_phy_power_off(struct tegra_pcie_port *port) | |||
927 | 906 | ||
928 | static int tegra_pcie_phy_power_on(struct tegra_pcie *pcie) | 907 | static int tegra_pcie_phy_power_on(struct tegra_pcie *pcie) |
929 | { | 908 | { |
909 | const struct tegra_pcie_soc_data *soc = pcie->soc_data; | ||
930 | struct tegra_pcie_port *port; | 910 | struct tegra_pcie_port *port; |
931 | int err; | 911 | int err; |
932 | 912 | ||
@@ -952,6 +932,12 @@ static int tegra_pcie_phy_power_on(struct tegra_pcie *pcie) | |||
952 | } | 932 | } |
953 | } | 933 | } |
954 | 934 | ||
935 | /* Configure the reference clock driver */ | ||
936 | pads_writel(pcie, soc->pads_refclk_cfg0, PADS_REFCLK_CFG0); | ||
937 | |||
938 | if (soc->num_ports > 2) | ||
939 | pads_writel(pcie, soc->pads_refclk_cfg1, PADS_REFCLK_CFG1); | ||
940 | |||
955 | return 0; | 941 | return 0; |
956 | } | 942 | } |
957 | 943 | ||
@@ -1822,12 +1808,6 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie) | |||
1822 | struct resource res; | 1808 | struct resource res; |
1823 | int err; | 1809 | int err; |
1824 | 1810 | ||
1825 | memset(&pcie->all, 0, sizeof(pcie->all)); | ||
1826 | pcie->all.flags = IORESOURCE_MEM; | ||
1827 | pcie->all.name = np->full_name; | ||
1828 | pcie->all.start = ~0; | ||
1829 | pcie->all.end = 0; | ||
1830 | |||
1831 | if (of_pci_range_parser_init(&parser, np)) { | 1811 | if (of_pci_range_parser_init(&parser, np)) { |
1832 | dev_err(pcie->dev, "missing \"ranges\" property\n"); | 1812 | dev_err(pcie->dev, "missing \"ranges\" property\n"); |
1833 | return -EINVAL; | 1813 | return -EINVAL; |
@@ -1880,18 +1860,8 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie) | |||
1880 | } | 1860 | } |
1881 | break; | 1861 | break; |
1882 | } | 1862 | } |
1883 | |||
1884 | if (res.start <= pcie->all.start) | ||
1885 | pcie->all.start = res.start; | ||
1886 | |||
1887 | if (res.end >= pcie->all.end) | ||
1888 | pcie->all.end = res.end; | ||
1889 | } | 1863 | } |
1890 | 1864 | ||
1891 | err = devm_request_resource(pcie->dev, &iomem_resource, &pcie->all); | ||
1892 | if (err < 0) | ||
1893 | return err; | ||
1894 | |||
1895 | err = of_pci_parse_bus_range(np, &pcie->busn); | 1865 | err = of_pci_parse_bus_range(np, &pcie->busn); |
1896 | if (err < 0) { | 1866 | if (err < 0) { |
1897 | dev_err(pcie->dev, "failed to parse ranges property: %d\n", | 1867 | dev_err(pcie->dev, "failed to parse ranges property: %d\n", |
@@ -2078,6 +2048,7 @@ static const struct tegra_pcie_soc_data tegra20_pcie_data = { | |||
2078 | .msi_base_shift = 0, | 2048 | .msi_base_shift = 0, |
2079 | .pads_pll_ctl = PADS_PLL_CTL_TEGRA20, | 2049 | .pads_pll_ctl = PADS_PLL_CTL_TEGRA20, |
2080 | .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_DIV10, | 2050 | .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_DIV10, |
2051 | .pads_refclk_cfg0 = 0xfa5cfa5c, | ||
2081 | .has_pex_clkreq_en = false, | 2052 | .has_pex_clkreq_en = false, |
2082 | .has_pex_bias_ctrl = false, | 2053 | .has_pex_bias_ctrl = false, |
2083 | .has_intr_prsnt_sense = false, | 2054 | .has_intr_prsnt_sense = false, |
@@ -2090,6 +2061,8 @@ static const struct tegra_pcie_soc_data tegra30_pcie_data = { | |||
2090 | .msi_base_shift = 8, | 2061 | .msi_base_shift = 8, |
2091 | .pads_pll_ctl = PADS_PLL_CTL_TEGRA30, | 2062 | .pads_pll_ctl = PADS_PLL_CTL_TEGRA30, |
2092 | .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN, | 2063 | .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN, |
2064 | .pads_refclk_cfg0 = 0xfa5cfa5c, | ||
2065 | .pads_refclk_cfg1 = 0xfa5cfa5c, | ||
2093 | .has_pex_clkreq_en = true, | 2066 | .has_pex_clkreq_en = true, |
2094 | .has_pex_bias_ctrl = true, | 2067 | .has_pex_bias_ctrl = true, |
2095 | .has_intr_prsnt_sense = true, | 2068 | .has_intr_prsnt_sense = true, |
@@ -2102,6 +2075,7 @@ static const struct tegra_pcie_soc_data tegra124_pcie_data = { | |||
2102 | .msi_base_shift = 8, | 2075 | .msi_base_shift = 8, |
2103 | .pads_pll_ctl = PADS_PLL_CTL_TEGRA30, | 2076 | .pads_pll_ctl = PADS_PLL_CTL_TEGRA30, |
2104 | .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN, | 2077 | .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN, |
2078 | .pads_refclk_cfg0 = 0x44ac44ac, | ||
2105 | .has_pex_clkreq_en = true, | 2079 | .has_pex_clkreq_en = true, |
2106 | .has_pex_bias_ctrl = true, | 2080 | .has_pex_bias_ctrl = true, |
2107 | .has_intr_prsnt_sense = true, | 2081 | .has_intr_prsnt_sense = true, |
@@ -2115,7 +2089,6 @@ static const struct of_device_id tegra_pcie_of_match[] = { | |||
2115 | { .compatible = "nvidia,tegra20-pcie", .data = &tegra20_pcie_data }, | 2089 | { .compatible = "nvidia,tegra20-pcie", .data = &tegra20_pcie_data }, |
2116 | { }, | 2090 | { }, |
2117 | }; | 2091 | }; |
2118 | MODULE_DEVICE_TABLE(of, tegra_pcie_of_match); | ||
2119 | 2092 | ||
2120 | static void *tegra_pcie_ports_seq_start(struct seq_file *s, loff_t *pos) | 2093 | static void *tegra_pcie_ports_seq_start(struct seq_file *s, loff_t *pos) |
2121 | { | 2094 | { |
@@ -2249,8 +2222,6 @@ static int tegra_pcie_probe(struct platform_device *pdev) | |||
2249 | if (err < 0) | 2222 | if (err < 0) |
2250 | return err; | 2223 | return err; |
2251 | 2224 | ||
2252 | pcibios_min_mem = 0; | ||
2253 | |||
2254 | err = tegra_pcie_get_resources(pcie); | 2225 | err = tegra_pcie_get_resources(pcie); |
2255 | if (err < 0) { | 2226 | if (err < 0) { |
2256 | dev_err(&pdev->dev, "failed to request resources: %d\n", err); | 2227 | dev_err(&pdev->dev, "failed to request resources: %d\n", err); |
@@ -2306,8 +2277,4 @@ static struct platform_driver tegra_pcie_driver = { | |||
2306 | }, | 2277 | }, |
2307 | .probe = tegra_pcie_probe, | 2278 | .probe = tegra_pcie_probe, |
2308 | }; | 2279 | }; |
2309 | module_platform_driver(tegra_pcie_driver); | 2280 | builtin_platform_driver(tegra_pcie_driver); |
2310 | |||
2311 | MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>"); | ||
2312 | MODULE_DESCRIPTION("NVIDIA Tegra PCIe driver"); | ||
2313 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pci-thunder-ecam.c b/drivers/pci/host/pci-thunder-ecam.c index 540d030613eb..d50a3dc2d8db 100644 --- a/drivers/pci/host/pci-thunder-ecam.c +++ b/drivers/pci/host/pci-thunder-ecam.c | |||
@@ -7,14 +7,13 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
10 | #include <linux/module.h> | 10 | #include <linux/init.h> |
11 | #include <linux/ioport.h> | 11 | #include <linux/ioport.h> |
12 | #include <linux/of_pci.h> | 12 | #include <linux/of_pci.h> |
13 | #include <linux/of.h> | 13 | #include <linux/of.h> |
14 | #include <linux/pci-ecam.h> | ||
14 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
15 | 16 | ||
16 | #include "../ecam.h" | ||
17 | |||
18 | static void set_val(u32 v, int where, int size, u32 *val) | 17 | static void set_val(u32 v, int where, int size, u32 *val) |
19 | { | 18 | { |
20 | int shift = (where & 3) * 8; | 19 | int shift = (where & 3) * 8; |
@@ -360,7 +359,6 @@ static const struct of_device_id thunder_ecam_of_match[] = { | |||
360 | { .compatible = "cavium,pci-host-thunder-ecam" }, | 359 | { .compatible = "cavium,pci-host-thunder-ecam" }, |
361 | { }, | 360 | { }, |
362 | }; | 361 | }; |
363 | MODULE_DEVICE_TABLE(of, thunder_ecam_of_match); | ||
364 | 362 | ||
365 | static int thunder_ecam_probe(struct platform_device *pdev) | 363 | static int thunder_ecam_probe(struct platform_device *pdev) |
366 | { | 364 | { |
@@ -374,7 +372,4 @@ static struct platform_driver thunder_ecam_driver = { | |||
374 | }, | 372 | }, |
375 | .probe = thunder_ecam_probe, | 373 | .probe = thunder_ecam_probe, |
376 | }; | 374 | }; |
377 | module_platform_driver(thunder_ecam_driver); | 375 | builtin_platform_driver(thunder_ecam_driver); |
378 | |||
379 | MODULE_DESCRIPTION("Thunder ECAM PCI host driver"); | ||
380 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pci-thunder-pem.c b/drivers/pci/host/pci-thunder-pem.c index 9b8ab94f3c8c..6abaf80ffb39 100644 --- a/drivers/pci/host/pci-thunder-pem.c +++ b/drivers/pci/host/pci-thunder-pem.c | |||
@@ -15,13 +15,12 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/module.h> | 18 | #include <linux/init.h> |
19 | #include <linux/of_address.h> | 19 | #include <linux/of_address.h> |
20 | #include <linux/of_pci.h> | 20 | #include <linux/of_pci.h> |
21 | #include <linux/pci-ecam.h> | ||
21 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
22 | 23 | ||
23 | #include "../ecam.h" | ||
24 | |||
25 | #define PEM_CFG_WR 0x28 | 24 | #define PEM_CFG_WR 0x28 |
26 | #define PEM_CFG_RD 0x30 | 25 | #define PEM_CFG_RD 0x30 |
27 | 26 | ||
@@ -285,8 +284,9 @@ static int thunder_pem_config_write(struct pci_bus *bus, unsigned int devfn, | |||
285 | return pci_generic_config_write(bus, devfn, where, size, val); | 284 | return pci_generic_config_write(bus, devfn, where, size, val); |
286 | } | 285 | } |
287 | 286 | ||
288 | static int thunder_pem_init(struct device *dev, struct pci_config_window *cfg) | 287 | static int thunder_pem_init(struct pci_config_window *cfg) |
289 | { | 288 | { |
289 | struct device *dev = cfg->parent; | ||
290 | resource_size_t bar4_start; | 290 | resource_size_t bar4_start; |
291 | struct resource *res_pem; | 291 | struct resource *res_pem; |
292 | struct thunder_pem_pci *pem_pci; | 292 | struct thunder_pem_pci *pem_pci; |
@@ -346,7 +346,6 @@ static const struct of_device_id thunder_pem_of_match[] = { | |||
346 | { .compatible = "cavium,pci-host-thunder-pem" }, | 346 | { .compatible = "cavium,pci-host-thunder-pem" }, |
347 | { }, | 347 | { }, |
348 | }; | 348 | }; |
349 | MODULE_DEVICE_TABLE(of, thunder_pem_of_match); | ||
350 | 349 | ||
351 | static int thunder_pem_probe(struct platform_device *pdev) | 350 | static int thunder_pem_probe(struct platform_device *pdev) |
352 | { | 351 | { |
@@ -360,7 +359,4 @@ static struct platform_driver thunder_pem_driver = { | |||
360 | }, | 359 | }, |
361 | .probe = thunder_pem_probe, | 360 | .probe = thunder_pem_probe, |
362 | }; | 361 | }; |
363 | module_platform_driver(thunder_pem_driver); | 362 | builtin_platform_driver(thunder_pem_driver); |
364 | |||
365 | MODULE_DESCRIPTION("Thunder PEM PCIe host driver"); | ||
366 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pci-versatile.c b/drivers/pci/host/pci-versatile.c index f843a72dc51c..f234405770ab 100644 --- a/drivers/pci/host/pci-versatile.c +++ b/drivers/pci/host/pci-versatile.c | |||
@@ -80,21 +80,21 @@ static int versatile_pci_parse_request_of_pci_ranges(struct device *dev, | |||
80 | if (err) | 80 | if (err) |
81 | return err; | 81 | return err; |
82 | 82 | ||
83 | err = devm_request_pci_bus_resources(dev, res); | ||
84 | if (err) | ||
85 | goto out_release_res; | ||
86 | |||
83 | resource_list_for_each_entry(win, res) { | 87 | resource_list_for_each_entry(win, res) { |
84 | struct resource *parent, *res = win->res; | 88 | struct resource *res = win->res; |
85 | 89 | ||
86 | switch (resource_type(res)) { | 90 | switch (resource_type(res)) { |
87 | case IORESOURCE_IO: | 91 | case IORESOURCE_IO: |
88 | parent = &ioport_resource; | ||
89 | err = pci_remap_iospace(res, iobase); | 92 | err = pci_remap_iospace(res, iobase); |
90 | if (err) { | 93 | if (err) |
91 | dev_warn(dev, "error %d: failed to map resource %pR\n", | 94 | dev_warn(dev, "error %d: failed to map resource %pR\n", |
92 | err, res); | 95 | err, res); |
93 | continue; | ||
94 | } | ||
95 | break; | 96 | break; |
96 | case IORESOURCE_MEM: | 97 | case IORESOURCE_MEM: |
97 | parent = &iomem_resource; | ||
98 | res_valid |= !(res->flags & IORESOURCE_PREFETCH); | 98 | res_valid |= !(res->flags & IORESOURCE_PREFETCH); |
99 | 99 | ||
100 | writel(res->start >> 28, PCI_IMAP(mem)); | 100 | writel(res->start >> 28, PCI_IMAP(mem)); |
@@ -102,23 +102,14 @@ static int versatile_pci_parse_request_of_pci_ranges(struct device *dev, | |||
102 | mem++; | 102 | mem++; |
103 | 103 | ||
104 | break; | 104 | break; |
105 | case IORESOURCE_BUS: | ||
106 | default: | ||
107 | continue; | ||
108 | } | 105 | } |
109 | |||
110 | err = devm_request_resource(dev, parent, res); | ||
111 | if (err) | ||
112 | goto out_release_res; | ||
113 | } | 106 | } |
114 | 107 | ||
115 | if (!res_valid) { | 108 | if (res_valid) |
116 | dev_err(dev, "non-prefetchable memory resource required\n"); | 109 | return 0; |
117 | err = -EINVAL; | ||
118 | goto out_release_res; | ||
119 | } | ||
120 | 110 | ||
121 | return 0; | 111 | dev_err(dev, "non-prefetchable memory resource required\n"); |
112 | err = -EINVAL; | ||
122 | 113 | ||
123 | out_release_res: | 114 | out_release_res: |
124 | pci_free_resource_list(res); | 115 | pci_free_resource_list(res); |
diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c index ae00ce22d5a6..a81273c23341 100644 --- a/drivers/pci/host/pci-xgene.c +++ b/drivers/pci/host/pci-xgene.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
22 | #include <linux/jiffies.h> | 22 | #include <linux/jiffies.h> |
23 | #include <linux/memblock.h> | 23 | #include <linux/memblock.h> |
24 | #include <linux/module.h> | 24 | #include <linux/init.h> |
25 | #include <linux/of.h> | 25 | #include <linux/of.h> |
26 | #include <linux/of_address.h> | 26 | #include <linux/of_address.h> |
27 | #include <linux/of_irq.h> | 27 | #include <linux/of_irq.h> |
@@ -540,14 +540,20 @@ static int xgene_pcie_probe_bridge(struct platform_device *pdev) | |||
540 | if (ret) | 540 | if (ret) |
541 | return ret; | 541 | return ret; |
542 | 542 | ||
543 | ret = devm_request_pci_bus_resources(&pdev->dev, &res); | ||
544 | if (ret) | ||
545 | goto error; | ||
546 | |||
543 | ret = xgene_pcie_setup(port, &res, iobase); | 547 | ret = xgene_pcie_setup(port, &res, iobase); |
544 | if (ret) | 548 | if (ret) |
545 | return ret; | 549 | goto error; |
546 | 550 | ||
547 | bus = pci_create_root_bus(&pdev->dev, 0, | 551 | bus = pci_create_root_bus(&pdev->dev, 0, |
548 | &xgene_pcie_ops, port, &res); | 552 | &xgene_pcie_ops, port, &res); |
549 | if (!bus) | 553 | if (!bus) { |
550 | return -ENOMEM; | 554 | ret = -ENOMEM; |
555 | goto error; | ||
556 | } | ||
551 | 557 | ||
552 | pci_scan_child_bus(bus); | 558 | pci_scan_child_bus(bus); |
553 | pci_assign_unassigned_bus_resources(bus); | 559 | pci_assign_unassigned_bus_resources(bus); |
@@ -555,6 +561,10 @@ static int xgene_pcie_probe_bridge(struct platform_device *pdev) | |||
555 | 561 | ||
556 | platform_set_drvdata(pdev, port); | 562 | platform_set_drvdata(pdev, port); |
557 | return 0; | 563 | return 0; |
564 | |||
565 | error: | ||
566 | pci_free_resource_list(&res); | ||
567 | return ret; | ||
558 | } | 568 | } |
559 | 569 | ||
560 | static const struct of_device_id xgene_pcie_match_table[] = { | 570 | static const struct of_device_id xgene_pcie_match_table[] = { |
@@ -569,8 +579,4 @@ static struct platform_driver xgene_pcie_driver = { | |||
569 | }, | 579 | }, |
570 | .probe = xgene_pcie_probe_bridge, | 580 | .probe = xgene_pcie_probe_bridge, |
571 | }; | 581 | }; |
572 | module_platform_driver(xgene_pcie_driver); | 582 | builtin_platform_driver(xgene_pcie_driver); |
573 | |||
574 | MODULE_AUTHOR("Tanmay Inamdar <tinamdar@apm.com>"); | ||
575 | MODULE_DESCRIPTION("APM X-Gene PCIe driver"); | ||
576 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c index dbac6fb3f0bd..2b7837650db8 100644 --- a/drivers/pci/host/pcie-altera.c +++ b/drivers/pci/host/pcie-altera.c | |||
@@ -61,6 +61,8 @@ | |||
61 | #define TLP_LOOP 500 | 61 | #define TLP_LOOP 500 |
62 | #define RP_DEVFN 0 | 62 | #define RP_DEVFN 0 |
63 | 63 | ||
64 | #define LINK_UP_TIMEOUT 5000 | ||
65 | |||
64 | #define INTX_NUM 4 | 66 | #define INTX_NUM 4 |
65 | 67 | ||
66 | #define DWORD_MASK 3 | 68 | #define DWORD_MASK 3 |
@@ -81,9 +83,30 @@ struct tlp_rp_regpair_t { | |||
81 | u32 reg1; | 83 | u32 reg1; |
82 | }; | 84 | }; |
83 | 85 | ||
86 | static inline void cra_writel(struct altera_pcie *pcie, const u32 value, | ||
87 | const u32 reg) | ||
88 | { | ||
89 | writel_relaxed(value, pcie->cra_base + reg); | ||
90 | } | ||
91 | |||
92 | static inline u32 cra_readl(struct altera_pcie *pcie, const u32 reg) | ||
93 | { | ||
94 | return readl_relaxed(pcie->cra_base + reg); | ||
95 | } | ||
96 | |||
97 | static bool altera_pcie_link_is_up(struct altera_pcie *pcie) | ||
98 | { | ||
99 | return !!((cra_readl(pcie, RP_LTSSM) & RP_LTSSM_MASK) == LTSSM_L0); | ||
100 | } | ||
101 | |||
84 | static void altera_pcie_retrain(struct pci_dev *dev) | 102 | static void altera_pcie_retrain(struct pci_dev *dev) |
85 | { | 103 | { |
86 | u16 linkcap, linkstat; | 104 | u16 linkcap, linkstat; |
105 | struct altera_pcie *pcie = dev->bus->sysdata; | ||
106 | int timeout = 0; | ||
107 | |||
108 | if (!altera_pcie_link_is_up(pcie)) | ||
109 | return; | ||
87 | 110 | ||
88 | /* | 111 | /* |
89 | * Set the retrain bit if the PCIe rootport support > 2.5GB/s, but | 112 | * Set the retrain bit if the PCIe rootport support > 2.5GB/s, but |
@@ -95,9 +118,16 @@ static void altera_pcie_retrain(struct pci_dev *dev) | |||
95 | return; | 118 | return; |
96 | 119 | ||
97 | pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &linkstat); | 120 | pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &linkstat); |
98 | if ((linkstat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB) | 121 | if ((linkstat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB) { |
99 | pcie_capability_set_word(dev, PCI_EXP_LNKCTL, | 122 | pcie_capability_set_word(dev, PCI_EXP_LNKCTL, |
100 | PCI_EXP_LNKCTL_RL); | 123 | PCI_EXP_LNKCTL_RL); |
124 | while (!altera_pcie_link_is_up(pcie)) { | ||
125 | timeout++; | ||
126 | if (timeout > LINK_UP_TIMEOUT) | ||
127 | break; | ||
128 | udelay(5); | ||
129 | } | ||
130 | } | ||
101 | } | 131 | } |
102 | DECLARE_PCI_FIXUP_EARLY(0x1172, PCI_ANY_ID, altera_pcie_retrain); | 132 | DECLARE_PCI_FIXUP_EARLY(0x1172, PCI_ANY_ID, altera_pcie_retrain); |
103 | 133 | ||
@@ -120,17 +150,6 @@ static bool altera_pcie_hide_rc_bar(struct pci_bus *bus, unsigned int devfn, | |||
120 | return false; | 150 | return false; |
121 | } | 151 | } |
122 | 152 | ||
123 | static inline void cra_writel(struct altera_pcie *pcie, const u32 value, | ||
124 | const u32 reg) | ||
125 | { | ||
126 | writel_relaxed(value, pcie->cra_base + reg); | ||
127 | } | ||
128 | |||
129 | static inline u32 cra_readl(struct altera_pcie *pcie, const u32 reg) | ||
130 | { | ||
131 | return readl_relaxed(pcie->cra_base + reg); | ||
132 | } | ||
133 | |||
134 | static void tlp_write_tx(struct altera_pcie *pcie, | 153 | static void tlp_write_tx(struct altera_pcie *pcie, |
135 | struct tlp_rp_regpair_t *tlp_rp_regdata) | 154 | struct tlp_rp_regpair_t *tlp_rp_regdata) |
136 | { | 155 | { |
@@ -139,11 +158,6 @@ static void tlp_write_tx(struct altera_pcie *pcie, | |||
139 | cra_writel(pcie, tlp_rp_regdata->ctrl, RP_TX_CNTRL); | 158 | cra_writel(pcie, tlp_rp_regdata->ctrl, RP_TX_CNTRL); |
140 | } | 159 | } |
141 | 160 | ||
142 | static bool altera_pcie_link_is_up(struct altera_pcie *pcie) | ||
143 | { | ||
144 | return !!((cra_readl(pcie, RP_LTSSM) & RP_LTSSM_MASK) == LTSSM_L0); | ||
145 | } | ||
146 | |||
147 | static bool altera_pcie_valid_config(struct altera_pcie *pcie, | 161 | static bool altera_pcie_valid_config(struct altera_pcie *pcie, |
148 | struct pci_bus *bus, int dev) | 162 | struct pci_bus *bus, int dev) |
149 | { | 163 | { |
@@ -415,11 +429,6 @@ static void altera_pcie_isr(struct irq_desc *desc) | |||
415 | chained_irq_exit(chip, desc); | 429 | chained_irq_exit(chip, desc); |
416 | } | 430 | } |
417 | 431 | ||
418 | static void altera_pcie_release_of_pci_ranges(struct altera_pcie *pcie) | ||
419 | { | ||
420 | pci_free_resource_list(&pcie->resources); | ||
421 | } | ||
422 | |||
423 | static int altera_pcie_parse_request_of_pci_ranges(struct altera_pcie *pcie) | 432 | static int altera_pcie_parse_request_of_pci_ranges(struct altera_pcie *pcie) |
424 | { | 433 | { |
425 | int err, res_valid = 0; | 434 | int err, res_valid = 0; |
@@ -432,33 +441,25 @@ static int altera_pcie_parse_request_of_pci_ranges(struct altera_pcie *pcie) | |||
432 | if (err) | 441 | if (err) |
433 | return err; | 442 | return err; |
434 | 443 | ||
444 | err = devm_request_pci_bus_resources(dev, &pcie->resources); | ||
445 | if (err) | ||
446 | goto out_release_res; | ||
447 | |||
435 | resource_list_for_each_entry(win, &pcie->resources) { | 448 | resource_list_for_each_entry(win, &pcie->resources) { |
436 | struct resource *parent, *res = win->res; | 449 | struct resource *res = win->res; |
437 | 450 | ||
438 | switch (resource_type(res)) { | 451 | if (resource_type(res) == IORESOURCE_MEM) |
439 | case IORESOURCE_MEM: | ||
440 | parent = &iomem_resource; | ||
441 | res_valid |= !(res->flags & IORESOURCE_PREFETCH); | 452 | res_valid |= !(res->flags & IORESOURCE_PREFETCH); |
442 | break; | ||
443 | default: | ||
444 | continue; | ||
445 | } | ||
446 | |||
447 | err = devm_request_resource(dev, parent, res); | ||
448 | if (err) | ||
449 | goto out_release_res; | ||
450 | } | 453 | } |
451 | 454 | ||
452 | if (!res_valid) { | 455 | if (res_valid) |
453 | dev_err(dev, "non-prefetchable memory resource required\n"); | 456 | return 0; |
454 | err = -EINVAL; | ||
455 | goto out_release_res; | ||
456 | } | ||
457 | 457 | ||
458 | return 0; | 458 | dev_err(dev, "non-prefetchable memory resource required\n"); |
459 | err = -EINVAL; | ||
459 | 460 | ||
460 | out_release_res: | 461 | out_release_res: |
461 | altera_pcie_release_of_pci_ranges(pcie); | 462 | pci_free_resource_list(&pcie->resources); |
462 | return err; | 463 | return err; |
463 | } | 464 | } |
464 | 465 | ||
diff --git a/drivers/pci/host/pcie-armada8k.c b/drivers/pci/host/pcie-armada8k.c index 55723567b5d4..0f4f570068e3 100644 --- a/drivers/pci/host/pcie-armada8k.c +++ b/drivers/pci/host/pcie-armada8k.c | |||
@@ -5,6 +5,9 @@ | |||
5 | * | 5 | * |
6 | * Copyright (C) 2016 Marvell Technology Group Ltd. | 6 | * Copyright (C) 2016 Marvell Technology Group Ltd. |
7 | * | 7 | * |
8 | * Author: Yehuda Yitshak <yehuday@marvell.com> | ||
9 | * Author: Shadi Ammouri <shadi@marvell.com> | ||
10 | * | ||
8 | * This file is licensed under the terms of the GNU General Public | 11 | * This file is licensed under the terms of the GNU General Public |
9 | * License version 2. This program is licensed "as is" without any | 12 | * License version 2. This program is licensed "as is" without any |
10 | * warranty of any kind, whether express or implied. | 13 | * warranty of any kind, whether express or implied. |
@@ -14,7 +17,7 @@ | |||
14 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
15 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
16 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
17 | #include <linux/module.h> | 20 | #include <linux/init.h> |
18 | #include <linux/of.h> | 21 | #include <linux/of.h> |
19 | #include <linux/pci.h> | 22 | #include <linux/pci.h> |
20 | #include <linux/phy/phy.h> | 23 | #include <linux/phy/phy.h> |
@@ -244,7 +247,6 @@ static const struct of_device_id armada8k_pcie_of_match[] = { | |||
244 | { .compatible = "marvell,armada8k-pcie", }, | 247 | { .compatible = "marvell,armada8k-pcie", }, |
245 | {}, | 248 | {}, |
246 | }; | 249 | }; |
247 | MODULE_DEVICE_TABLE(of, armada8k_pcie_of_match); | ||
248 | 250 | ||
249 | static struct platform_driver armada8k_pcie_driver = { | 251 | static struct platform_driver armada8k_pcie_driver = { |
250 | .probe = armada8k_pcie_probe, | 252 | .probe = armada8k_pcie_probe, |
@@ -253,10 +255,4 @@ static struct platform_driver armada8k_pcie_driver = { | |||
253 | .of_match_table = of_match_ptr(armada8k_pcie_of_match), | 255 | .of_match_table = of_match_ptr(armada8k_pcie_of_match), |
254 | }, | 256 | }, |
255 | }; | 257 | }; |
256 | 258 | builtin_platform_driver(armada8k_pcie_driver); | |
257 | module_platform_driver(armada8k_pcie_driver); | ||
258 | |||
259 | MODULE_DESCRIPTION("Armada 8k PCIe host controller driver"); | ||
260 | MODULE_AUTHOR("Yehuda Yitshak <yehuday@marvell.com>"); | ||
261 | MODULE_AUTHOR("Shadi Ammouri <shadi@marvell.com>"); | ||
262 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pcie-artpec6.c b/drivers/pci/host/pcie-artpec6.c new file mode 100644 index 000000000000..16ba70b7ec65 --- /dev/null +++ b/drivers/pci/host/pcie-artpec6.c | |||
@@ -0,0 +1,280 @@ | |||
1 | /* | ||
2 | * PCIe host controller driver for Axis ARTPEC-6 SoC | ||
3 | * | ||
4 | * Author: Niklas Cassel <niklas.cassel@axis.com> | ||
5 | * | ||
6 | * Based on work done by Phil Edworthy <phil@edworthys.org> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/delay.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/pci.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/resource.h> | ||
19 | #include <linux/signal.h> | ||
20 | #include <linux/types.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/mfd/syscon.h> | ||
23 | #include <linux/regmap.h> | ||
24 | |||
25 | #include "pcie-designware.h" | ||
26 | |||
27 | #define to_artpec6_pcie(x) container_of(x, struct artpec6_pcie, pp) | ||
28 | |||
29 | struct artpec6_pcie { | ||
30 | struct pcie_port pp; | ||
31 | struct regmap *regmap; | ||
32 | void __iomem *phy_base; | ||
33 | }; | ||
34 | |||
35 | /* PCIe Port Logic registers (memory-mapped) */ | ||
36 | #define PL_OFFSET 0x700 | ||
37 | #define PCIE_PHY_DEBUG_R0 (PL_OFFSET + 0x28) | ||
38 | #define PCIE_PHY_DEBUG_R1 (PL_OFFSET + 0x2c) | ||
39 | |||
40 | #define MISC_CONTROL_1_OFF (PL_OFFSET + 0x1bc) | ||
41 | #define DBI_RO_WR_EN 1 | ||
42 | |||
43 | /* ARTPEC-6 specific registers */ | ||
44 | #define PCIECFG 0x18 | ||
45 | #define PCIECFG_DBG_OEN (1 << 24) | ||
46 | #define PCIECFG_CORE_RESET_REQ (1 << 21) | ||
47 | #define PCIECFG_LTSSM_ENABLE (1 << 20) | ||
48 | #define PCIECFG_CLKREQ_B (1 << 11) | ||
49 | #define PCIECFG_REFCLK_ENABLE (1 << 10) | ||
50 | #define PCIECFG_PLL_ENABLE (1 << 9) | ||
51 | #define PCIECFG_PCLK_ENABLE (1 << 8) | ||
52 | #define PCIECFG_RISRCREN (1 << 4) | ||
53 | #define PCIECFG_MODE_TX_DRV_EN (1 << 3) | ||
54 | #define PCIECFG_CISRREN (1 << 2) | ||
55 | #define PCIECFG_MACRO_ENABLE (1 << 0) | ||
56 | |||
57 | #define NOCCFG 0x40 | ||
58 | #define NOCCFG_ENABLE_CLK_PCIE (1 << 4) | ||
59 | #define NOCCFG_POWER_PCIE_IDLEACK (1 << 3) | ||
60 | #define NOCCFG_POWER_PCIE_IDLE (1 << 2) | ||
61 | #define NOCCFG_POWER_PCIE_IDLEREQ (1 << 1) | ||
62 | |||
63 | #define PHY_STATUS 0x118 | ||
64 | #define PHY_COSPLLLOCK (1 << 0) | ||
65 | |||
66 | #define ARTPEC6_CPU_TO_BUS_ADDR 0x0fffffff | ||
67 | |||
68 | static int artpec6_pcie_establish_link(struct pcie_port *pp) | ||
69 | { | ||
70 | struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pp); | ||
71 | u32 val; | ||
72 | unsigned int retries; | ||
73 | |||
74 | /* Hold DW core in reset */ | ||
75 | regmap_read(artpec6_pcie->regmap, PCIECFG, &val); | ||
76 | val |= PCIECFG_CORE_RESET_REQ; | ||
77 | regmap_write(artpec6_pcie->regmap, PCIECFG, val); | ||
78 | |||
79 | regmap_read(artpec6_pcie->regmap, PCIECFG, &val); | ||
80 | val |= PCIECFG_RISRCREN | /* Receiver term. 50 Ohm */ | ||
81 | PCIECFG_MODE_TX_DRV_EN | | ||
82 | PCIECFG_CISRREN | /* Reference clock term. 100 Ohm */ | ||
83 | PCIECFG_MACRO_ENABLE; | ||
84 | val |= PCIECFG_REFCLK_ENABLE; | ||
85 | val &= ~PCIECFG_DBG_OEN; | ||
86 | val &= ~PCIECFG_CLKREQ_B; | ||
87 | regmap_write(artpec6_pcie->regmap, PCIECFG, val); | ||
88 | usleep_range(5000, 6000); | ||
89 | |||
90 | regmap_read(artpec6_pcie->regmap, NOCCFG, &val); | ||
91 | val |= NOCCFG_ENABLE_CLK_PCIE; | ||
92 | regmap_write(artpec6_pcie->regmap, NOCCFG, val); | ||
93 | usleep_range(20, 30); | ||
94 | |||
95 | regmap_read(artpec6_pcie->regmap, PCIECFG, &val); | ||
96 | val |= PCIECFG_PCLK_ENABLE | PCIECFG_PLL_ENABLE; | ||
97 | regmap_write(artpec6_pcie->regmap, PCIECFG, val); | ||
98 | usleep_range(6000, 7000); | ||
99 | |||
100 | regmap_read(artpec6_pcie->regmap, NOCCFG, &val); | ||
101 | val &= ~NOCCFG_POWER_PCIE_IDLEREQ; | ||
102 | regmap_write(artpec6_pcie->regmap, NOCCFG, val); | ||
103 | |||
104 | retries = 50; | ||
105 | do { | ||
106 | usleep_range(1000, 2000); | ||
107 | regmap_read(artpec6_pcie->regmap, NOCCFG, &val); | ||
108 | retries--; | ||
109 | } while (retries && | ||
110 | (val & (NOCCFG_POWER_PCIE_IDLEACK | NOCCFG_POWER_PCIE_IDLE))); | ||
111 | |||
112 | retries = 50; | ||
113 | do { | ||
114 | usleep_range(1000, 2000); | ||
115 | val = readl(artpec6_pcie->phy_base + PHY_STATUS); | ||
116 | retries--; | ||
117 | } while (retries && !(val & PHY_COSPLLLOCK)); | ||
118 | |||
119 | /* Take DW core out of reset */ | ||
120 | regmap_read(artpec6_pcie->regmap, PCIECFG, &val); | ||
121 | val &= ~PCIECFG_CORE_RESET_REQ; | ||
122 | regmap_write(artpec6_pcie->regmap, PCIECFG, val); | ||
123 | usleep_range(100, 200); | ||
124 | |||
125 | /* | ||
126 | * Enable writing to config regs. This is required as the Synopsys | ||
127 | * driver changes the class code. That register needs DBI write enable. | ||
128 | */ | ||
129 | writel(DBI_RO_WR_EN, pp->dbi_base + MISC_CONTROL_1_OFF); | ||
130 | |||
131 | pp->io_base &= ARTPEC6_CPU_TO_BUS_ADDR; | ||
132 | pp->mem_base &= ARTPEC6_CPU_TO_BUS_ADDR; | ||
133 | pp->cfg0_base &= ARTPEC6_CPU_TO_BUS_ADDR; | ||
134 | pp->cfg1_base &= ARTPEC6_CPU_TO_BUS_ADDR; | ||
135 | |||
136 | /* setup root complex */ | ||
137 | dw_pcie_setup_rc(pp); | ||
138 | |||
139 | /* assert LTSSM enable */ | ||
140 | regmap_read(artpec6_pcie->regmap, PCIECFG, &val); | ||
141 | val |= PCIECFG_LTSSM_ENABLE; | ||
142 | regmap_write(artpec6_pcie->regmap, PCIECFG, val); | ||
143 | |||
144 | /* check if the link is up or not */ | ||
145 | if (!dw_pcie_wait_for_link(pp)) | ||
146 | return 0; | ||
147 | |||
148 | dev_dbg(pp->dev, "DEBUG_R0: 0x%08x, DEBUG_R1: 0x%08x\n", | ||
149 | readl(pp->dbi_base + PCIE_PHY_DEBUG_R0), | ||
150 | readl(pp->dbi_base + PCIE_PHY_DEBUG_R1)); | ||
151 | |||
152 | return -ETIMEDOUT; | ||
153 | } | ||
154 | |||
155 | static void artpec6_pcie_enable_interrupts(struct pcie_port *pp) | ||
156 | { | ||
157 | if (IS_ENABLED(CONFIG_PCI_MSI)) | ||
158 | dw_pcie_msi_init(pp); | ||
159 | } | ||
160 | |||
161 | static void artpec6_pcie_host_init(struct pcie_port *pp) | ||
162 | { | ||
163 | artpec6_pcie_establish_link(pp); | ||
164 | artpec6_pcie_enable_interrupts(pp); | ||
165 | } | ||
166 | |||
167 | static int artpec6_pcie_link_up(struct pcie_port *pp) | ||
168 | { | ||
169 | u32 rc; | ||
170 | |||
171 | /* | ||
172 | * Get status from Synopsys IP | ||
173 | * link is debug bit 36, debug register 1 starts at bit 32 | ||
174 | */ | ||
175 | rc = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1) & (0x1 << (36 - 32)); | ||
176 | if (rc) | ||
177 | return 1; | ||
178 | |||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static struct pcie_host_ops artpec6_pcie_host_ops = { | ||
183 | .link_up = artpec6_pcie_link_up, | ||
184 | .host_init = artpec6_pcie_host_init, | ||
185 | }; | ||
186 | |||
187 | static irqreturn_t artpec6_pcie_msi_handler(int irq, void *arg) | ||
188 | { | ||
189 | struct pcie_port *pp = arg; | ||
190 | |||
191 | return dw_handle_msi_irq(pp); | ||
192 | } | ||
193 | |||
194 | static int __init artpec6_add_pcie_port(struct pcie_port *pp, | ||
195 | struct platform_device *pdev) | ||
196 | { | ||
197 | int ret; | ||
198 | |||
199 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | ||
200 | pp->msi_irq = platform_get_irq_byname(pdev, "msi"); | ||
201 | if (pp->msi_irq <= 0) { | ||
202 | dev_err(&pdev->dev, "failed to get MSI irq\n"); | ||
203 | return -ENODEV; | ||
204 | } | ||
205 | |||
206 | ret = devm_request_irq(&pdev->dev, pp->msi_irq, | ||
207 | artpec6_pcie_msi_handler, | ||
208 | IRQF_SHARED | IRQF_NO_THREAD, | ||
209 | "artpec6-pcie-msi", pp); | ||
210 | if (ret) { | ||
211 | dev_err(&pdev->dev, "failed to request MSI irq\n"); | ||
212 | return ret; | ||
213 | } | ||
214 | } | ||
215 | |||
216 | pp->root_bus_nr = -1; | ||
217 | pp->ops = &artpec6_pcie_host_ops; | ||
218 | |||
219 | ret = dw_pcie_host_init(pp); | ||
220 | if (ret) { | ||
221 | dev_err(&pdev->dev, "failed to initialize host\n"); | ||
222 | return ret; | ||
223 | } | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | static int artpec6_pcie_probe(struct platform_device *pdev) | ||
229 | { | ||
230 | struct artpec6_pcie *artpec6_pcie; | ||
231 | struct pcie_port *pp; | ||
232 | struct resource *dbi_base; | ||
233 | struct resource *phy_base; | ||
234 | int ret; | ||
235 | |||
236 | artpec6_pcie = devm_kzalloc(&pdev->dev, sizeof(*artpec6_pcie), | ||
237 | GFP_KERNEL); | ||
238 | if (!artpec6_pcie) | ||
239 | return -ENOMEM; | ||
240 | |||
241 | pp = &artpec6_pcie->pp; | ||
242 | pp->dev = &pdev->dev; | ||
243 | |||
244 | dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi"); | ||
245 | pp->dbi_base = devm_ioremap_resource(&pdev->dev, dbi_base); | ||
246 | if (IS_ERR(pp->dbi_base)) | ||
247 | return PTR_ERR(pp->dbi_base); | ||
248 | |||
249 | phy_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy"); | ||
250 | artpec6_pcie->phy_base = devm_ioremap_resource(&pdev->dev, phy_base); | ||
251 | if (IS_ERR(artpec6_pcie->phy_base)) | ||
252 | return PTR_ERR(artpec6_pcie->phy_base); | ||
253 | |||
254 | artpec6_pcie->regmap = | ||
255 | syscon_regmap_lookup_by_phandle(pdev->dev.of_node, | ||
256 | "axis,syscon-pcie"); | ||
257 | if (IS_ERR(artpec6_pcie->regmap)) | ||
258 | return PTR_ERR(artpec6_pcie->regmap); | ||
259 | |||
260 | ret = artpec6_add_pcie_port(pp, pdev); | ||
261 | if (ret < 0) | ||
262 | return ret; | ||
263 | |||
264 | platform_set_drvdata(pdev, artpec6_pcie); | ||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | static const struct of_device_id artpec6_pcie_of_match[] = { | ||
269 | { .compatible = "axis,artpec6-pcie", }, | ||
270 | {}, | ||
271 | }; | ||
272 | |||
273 | static struct platform_driver artpec6_pcie_driver = { | ||
274 | .probe = artpec6_pcie_probe, | ||
275 | .driver = { | ||
276 | .name = "artpec6-pcie", | ||
277 | .of_match_table = artpec6_pcie_of_match, | ||
278 | }, | ||
279 | }; | ||
280 | builtin_platform_driver(artpec6_pcie_driver); | ||
diff --git a/drivers/pci/host/pcie-designware-plat.c b/drivers/pci/host/pcie-designware-plat.c index b3500994d08a..c8079dc81c10 100644 --- a/drivers/pci/host/pcie-designware-plat.c +++ b/drivers/pci/host/pcie-designware-plat.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/gpio.h> | 14 | #include <linux/gpio.h> |
15 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/module.h> | 17 | #include <linux/init.h> |
18 | #include <linux/of_gpio.h> | 18 | #include <linux/of_gpio.h> |
19 | #include <linux/pci.h> | 19 | #include <linux/pci.h> |
20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
@@ -121,7 +121,6 @@ static const struct of_device_id dw_plat_pcie_of_match[] = { | |||
121 | { .compatible = "snps,dw-pcie", }, | 121 | { .compatible = "snps,dw-pcie", }, |
122 | {}, | 122 | {}, |
123 | }; | 123 | }; |
124 | MODULE_DEVICE_TABLE(of, dw_plat_pcie_of_match); | ||
125 | 124 | ||
126 | static struct platform_driver dw_plat_pcie_driver = { | 125 | static struct platform_driver dw_plat_pcie_driver = { |
127 | .driver = { | 126 | .driver = { |
@@ -130,9 +129,4 @@ static struct platform_driver dw_plat_pcie_driver = { | |||
130 | }, | 129 | }, |
131 | .probe = dw_plat_pcie_probe, | 130 | .probe = dw_plat_pcie_probe, |
132 | }; | 131 | }; |
133 | 132 | builtin_platform_driver(dw_plat_pcie_driver); | |
134 | module_platform_driver(dw_plat_pcie_driver); | ||
135 | |||
136 | MODULE_AUTHOR("Joao Pinto <Joao.Pinto@synopsys.com>"); | ||
137 | MODULE_DESCRIPTION("Synopsys PCIe host controller glue platform driver"); | ||
138 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index aafd766546f3..12afce19890b 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c | |||
@@ -452,6 +452,10 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
452 | if (ret) | 452 | if (ret) |
453 | return ret; | 453 | return ret; |
454 | 454 | ||
455 | ret = devm_request_pci_bus_resources(&pdev->dev, &res); | ||
456 | if (ret) | ||
457 | goto error; | ||
458 | |||
455 | /* Get the I/O and memory ranges from DT */ | 459 | /* Get the I/O and memory ranges from DT */ |
456 | resource_list_for_each_entry(win, &res) { | 460 | resource_list_for_each_entry(win, &res) { |
457 | switch (resource_type(win->res)) { | 461 | switch (resource_type(win->res)) { |
@@ -461,11 +465,9 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
461 | pp->io_size = resource_size(pp->io); | 465 | pp->io_size = resource_size(pp->io); |
462 | pp->io_bus_addr = pp->io->start - win->offset; | 466 | pp->io_bus_addr = pp->io->start - win->offset; |
463 | ret = pci_remap_iospace(pp->io, pp->io_base); | 467 | ret = pci_remap_iospace(pp->io, pp->io_base); |
464 | if (ret) { | 468 | if (ret) |
465 | dev_warn(pp->dev, "error %d: failed to map resource %pR\n", | 469 | dev_warn(pp->dev, "error %d: failed to map resource %pR\n", |
466 | ret, pp->io); | 470 | ret, pp->io); |
467 | continue; | ||
468 | } | ||
469 | break; | 471 | break; |
470 | case IORESOURCE_MEM: | 472 | case IORESOURCE_MEM: |
471 | pp->mem = win->res; | 473 | pp->mem = win->res; |
@@ -483,8 +485,6 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
483 | case IORESOURCE_BUS: | 485 | case IORESOURCE_BUS: |
484 | pp->busn = win->res; | 486 | pp->busn = win->res; |
485 | break; | 487 | break; |
486 | default: | ||
487 | continue; | ||
488 | } | 488 | } |
489 | } | 489 | } |
490 | 490 | ||
@@ -493,7 +493,8 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
493 | resource_size(pp->cfg)); | 493 | resource_size(pp->cfg)); |
494 | if (!pp->dbi_base) { | 494 | if (!pp->dbi_base) { |
495 | dev_err(pp->dev, "error with ioremap\n"); | 495 | dev_err(pp->dev, "error with ioremap\n"); |
496 | return -ENOMEM; | 496 | ret = -ENOMEM; |
497 | goto error; | ||
497 | } | 498 | } |
498 | } | 499 | } |
499 | 500 | ||
@@ -504,7 +505,8 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
504 | pp->cfg0_size); | 505 | pp->cfg0_size); |
505 | if (!pp->va_cfg0_base) { | 506 | if (!pp->va_cfg0_base) { |
506 | dev_err(pp->dev, "error with ioremap in function\n"); | 507 | dev_err(pp->dev, "error with ioremap in function\n"); |
507 | return -ENOMEM; | 508 | ret = -ENOMEM; |
509 | goto error; | ||
508 | } | 510 | } |
509 | } | 511 | } |
510 | 512 | ||
@@ -513,7 +515,8 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
513 | pp->cfg1_size); | 515 | pp->cfg1_size); |
514 | if (!pp->va_cfg1_base) { | 516 | if (!pp->va_cfg1_base) { |
515 | dev_err(pp->dev, "error with ioremap\n"); | 517 | dev_err(pp->dev, "error with ioremap\n"); |
516 | return -ENOMEM; | 518 | ret = -ENOMEM; |
519 | goto error; | ||
517 | } | 520 | } |
518 | } | 521 | } |
519 | 522 | ||
@@ -528,7 +531,8 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
528 | &dw_pcie_msi_chip); | 531 | &dw_pcie_msi_chip); |
529 | if (!pp->irq_domain) { | 532 | if (!pp->irq_domain) { |
530 | dev_err(pp->dev, "irq domain init failed\n"); | 533 | dev_err(pp->dev, "irq domain init failed\n"); |
531 | return -ENXIO; | 534 | ret = -ENXIO; |
535 | goto error; | ||
532 | } | 536 | } |
533 | 537 | ||
534 | for (i = 0; i < MAX_MSI_IRQS; i++) | 538 | for (i = 0; i < MAX_MSI_IRQS; i++) |
@@ -536,7 +540,7 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
536 | } else { | 540 | } else { |
537 | ret = pp->ops->msi_host_init(pp, &dw_pcie_msi_chip); | 541 | ret = pp->ops->msi_host_init(pp, &dw_pcie_msi_chip); |
538 | if (ret < 0) | 542 | if (ret < 0) |
539 | return ret; | 543 | goto error; |
540 | } | 544 | } |
541 | } | 545 | } |
542 | 546 | ||
@@ -552,8 +556,10 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
552 | } else | 556 | } else |
553 | bus = pci_scan_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops, | 557 | bus = pci_scan_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops, |
554 | pp, &res); | 558 | pp, &res); |
555 | if (!bus) | 559 | if (!bus) { |
556 | return -ENOMEM; | 560 | ret = -ENOMEM; |
561 | goto error; | ||
562 | } | ||
557 | 563 | ||
558 | if (pp->ops->scan_bus) | 564 | if (pp->ops->scan_bus) |
559 | pp->ops->scan_bus(pp); | 565 | pp->ops->scan_bus(pp); |
@@ -571,6 +577,10 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
571 | 577 | ||
572 | pci_bus_add_devices(bus); | 578 | pci_bus_add_devices(bus); |
573 | return 0; | 579 | return 0; |
580 | |||
581 | error: | ||
582 | pci_free_resource_list(&res); | ||
583 | return ret; | ||
574 | } | 584 | } |
575 | 585 | ||
576 | static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, | 586 | static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, |
diff --git a/drivers/pci/host/pcie-hisi.c b/drivers/pci/host/pcie-hisi.c index 3e98d4edae2d..7ee9dfcc45fb 100644 --- a/drivers/pci/host/pcie-hisi.c +++ b/drivers/pci/host/pcie-hisi.c | |||
@@ -12,7 +12,7 @@ | |||
12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
13 | */ | 13 | */ |
14 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
15 | #include <linux/module.h> | 15 | #include <linux/init.h> |
16 | #include <linux/mfd/syscon.h> | 16 | #include <linux/mfd/syscon.h> |
17 | #include <linux/of_address.h> | 17 | #include <linux/of_address.h> |
18 | #include <linux/of_pci.h> | 18 | #include <linux/of_pci.h> |
@@ -235,9 +235,6 @@ static const struct of_device_id hisi_pcie_of_match[] = { | |||
235 | {}, | 235 | {}, |
236 | }; | 236 | }; |
237 | 237 | ||
238 | |||
239 | MODULE_DEVICE_TABLE(of, hisi_pcie_of_match); | ||
240 | |||
241 | static struct platform_driver hisi_pcie_driver = { | 238 | static struct platform_driver hisi_pcie_driver = { |
242 | .probe = hisi_pcie_probe, | 239 | .probe = hisi_pcie_probe, |
243 | .driver = { | 240 | .driver = { |
@@ -245,10 +242,4 @@ static struct platform_driver hisi_pcie_driver = { | |||
245 | .of_match_table = hisi_pcie_of_match, | 242 | .of_match_table = hisi_pcie_of_match, |
246 | }, | 243 | }, |
247 | }; | 244 | }; |
248 | 245 | builtin_platform_driver(hisi_pcie_driver); | |
249 | module_platform_driver(hisi_pcie_driver); | ||
250 | |||
251 | MODULE_AUTHOR("Zhou Wang <wangzhou1@hisilicon.com>"); | ||
252 | MODULE_AUTHOR("Dacai Zhu <zhudacai@hisilicon.com>"); | ||
253 | MODULE_AUTHOR("Gabriele Paoloni <gabriele.paoloni@huawei.com>"); | ||
254 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pcie-iproc.c b/drivers/pci/host/pcie-iproc.c index a576aeeb22da..e167b2f0098d 100644 --- a/drivers/pci/host/pcie-iproc.c +++ b/drivers/pci/host/pcie-iproc.c | |||
@@ -462,6 +462,10 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) | |||
462 | if (!pcie || !pcie->dev || !pcie->base) | 462 | if (!pcie || !pcie->dev || !pcie->base) |
463 | return -EINVAL; | 463 | return -EINVAL; |
464 | 464 | ||
465 | ret = devm_request_pci_bus_resources(pcie->dev, res); | ||
466 | if (ret) | ||
467 | return ret; | ||
468 | |||
465 | ret = phy_init(pcie->phy); | 469 | ret = phy_init(pcie->phy); |
466 | if (ret) { | 470 | if (ret) { |
467 | dev_err(pcie->dev, "unable to initialize PCIe PHY\n"); | 471 | dev_err(pcie->dev, "unable to initialize PCIe PHY\n"); |
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c index 35092188039b..65db7a221509 100644 --- a/drivers/pci/host/pcie-rcar.c +++ b/drivers/pci/host/pcie-rcar.c | |||
@@ -7,6 +7,8 @@ | |||
7 | * arch/sh/drivers/pci/ops-sh7786.c | 7 | * arch/sh/drivers/pci/ops-sh7786.c |
8 | * Copyright (C) 2009 - 2011 Paul Mundt | 8 | * Copyright (C) 2009 - 2011 Paul Mundt |
9 | * | 9 | * |
10 | * Author: Phil Edworthy <phil.edworthy@renesas.com> | ||
11 | * | ||
10 | * This file is licensed under the terms of the GNU General Public | 12 | * This file is licensed under the terms of the GNU General Public |
11 | * License version 2. This program is licensed "as is" without any | 13 | * License version 2. This program is licensed "as is" without any |
12 | * warranty of any kind, whether express or implied. | 14 | * warranty of any kind, whether express or implied. |
@@ -18,7 +20,7 @@ | |||
18 | #include <linux/irq.h> | 20 | #include <linux/irq.h> |
19 | #include <linux/irqdomain.h> | 21 | #include <linux/irqdomain.h> |
20 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
21 | #include <linux/module.h> | 23 | #include <linux/init.h> |
22 | #include <linux/msi.h> | 24 | #include <linux/msi.h> |
23 | #include <linux/of_address.h> | 25 | #include <linux/of_address.h> |
24 | #include <linux/of_irq.h> | 26 | #include <linux/of_irq.h> |
@@ -936,12 +938,6 @@ static const struct of_device_id rcar_pcie_of_match[] = { | |||
936 | { .compatible = "renesas,pcie-r8a7795", .data = rcar_pcie_hw_init }, | 938 | { .compatible = "renesas,pcie-r8a7795", .data = rcar_pcie_hw_init }, |
937 | {}, | 939 | {}, |
938 | }; | 940 | }; |
939 | MODULE_DEVICE_TABLE(of, rcar_pcie_of_match); | ||
940 | |||
941 | static void rcar_pcie_release_of_pci_ranges(struct rcar_pcie *pci) | ||
942 | { | ||
943 | pci_free_resource_list(&pci->resources); | ||
944 | } | ||
945 | 941 | ||
946 | static int rcar_pcie_parse_request_of_pci_ranges(struct rcar_pcie *pci) | 942 | static int rcar_pcie_parse_request_of_pci_ranges(struct rcar_pcie *pci) |
947 | { | 943 | { |
@@ -955,37 +951,25 @@ static int rcar_pcie_parse_request_of_pci_ranges(struct rcar_pcie *pci) | |||
955 | if (err) | 951 | if (err) |
956 | return err; | 952 | return err; |
957 | 953 | ||
954 | err = devm_request_pci_bus_resources(dev, &pci->resources); | ||
955 | if (err) | ||
956 | goto out_release_res; | ||
957 | |||
958 | resource_list_for_each_entry(win, &pci->resources) { | 958 | resource_list_for_each_entry(win, &pci->resources) { |
959 | struct resource *parent, *res = win->res; | 959 | struct resource *res = win->res; |
960 | 960 | ||
961 | switch (resource_type(res)) { | 961 | if (resource_type(res) == IORESOURCE_IO) { |
962 | case IORESOURCE_IO: | ||
963 | parent = &ioport_resource; | ||
964 | err = pci_remap_iospace(res, iobase); | 962 | err = pci_remap_iospace(res, iobase); |
965 | if (err) { | 963 | if (err) |
966 | dev_warn(dev, "error %d: failed to map resource %pR\n", | 964 | dev_warn(dev, "error %d: failed to map resource %pR\n", |
967 | err, res); | 965 | err, res); |
968 | continue; | ||
969 | } | ||
970 | break; | ||
971 | case IORESOURCE_MEM: | ||
972 | parent = &iomem_resource; | ||
973 | break; | ||
974 | |||
975 | case IORESOURCE_BUS: | ||
976 | default: | ||
977 | continue; | ||
978 | } | 966 | } |
979 | |||
980 | err = devm_request_resource(dev, parent, res); | ||
981 | if (err) | ||
982 | goto out_release_res; | ||
983 | } | 967 | } |
984 | 968 | ||
985 | return 0; | 969 | return 0; |
986 | 970 | ||
987 | out_release_res: | 971 | out_release_res: |
988 | rcar_pcie_release_of_pci_ranges(pci); | 972 | pci_free_resource_list(&pci->resources); |
989 | return err; | 973 | return err; |
990 | } | 974 | } |
991 | 975 | ||
@@ -1073,8 +1057,4 @@ static struct platform_driver rcar_pcie_driver = { | |||
1073 | }, | 1057 | }, |
1074 | .probe = rcar_pcie_probe, | 1058 | .probe = rcar_pcie_probe, |
1075 | }; | 1059 | }; |
1076 | module_platform_driver(rcar_pcie_driver); | 1060 | builtin_platform_driver(rcar_pcie_driver); |
1077 | |||
1078 | MODULE_AUTHOR("Phil Edworthy <phil.edworthy@renesas.com>"); | ||
1079 | MODULE_DESCRIPTION("Renesas R-Car PCIe driver"); | ||
1080 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pcie-xilinx-nwl.c b/drivers/pci/host/pcie-xilinx-nwl.c index 3479d30e2be8..0b597d9190b4 100644 --- a/drivers/pci/host/pcie-xilinx-nwl.c +++ b/drivers/pci/host/pcie-xilinx-nwl.c | |||
@@ -825,27 +825,33 @@ static int nwl_pcie_probe(struct platform_device *pdev) | |||
825 | 825 | ||
826 | err = of_pci_get_host_bridge_resources(node, 0, 0xff, &res, &iobase); | 826 | err = of_pci_get_host_bridge_resources(node, 0, 0xff, &res, &iobase); |
827 | if (err) { | 827 | if (err) { |
828 | pr_err("Getting bridge resources failed\n"); | 828 | dev_err(pcie->dev, "Getting bridge resources failed\n"); |
829 | return err; | 829 | return err; |
830 | } | 830 | } |
831 | 831 | ||
832 | err = devm_request_pci_bus_resources(pcie->dev, &res); | ||
833 | if (err) | ||
834 | goto error; | ||
835 | |||
832 | err = nwl_pcie_init_irq_domain(pcie); | 836 | err = nwl_pcie_init_irq_domain(pcie); |
833 | if (err) { | 837 | if (err) { |
834 | dev_err(pcie->dev, "Failed creating IRQ Domain\n"); | 838 | dev_err(pcie->dev, "Failed creating IRQ Domain\n"); |
835 | return err; | 839 | goto error; |
836 | } | 840 | } |
837 | 841 | ||
838 | bus = pci_create_root_bus(&pdev->dev, pcie->root_busno, | 842 | bus = pci_create_root_bus(&pdev->dev, pcie->root_busno, |
839 | &nwl_pcie_ops, pcie, &res); | 843 | &nwl_pcie_ops, pcie, &res); |
840 | if (!bus) | 844 | if (!bus) { |
841 | return -ENOMEM; | 845 | err = -ENOMEM; |
846 | goto error; | ||
847 | } | ||
842 | 848 | ||
843 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | 849 | if (IS_ENABLED(CONFIG_PCI_MSI)) { |
844 | err = nwl_pcie_enable_msi(pcie, bus); | 850 | err = nwl_pcie_enable_msi(pcie, bus); |
845 | if (err < 0) { | 851 | if (err < 0) { |
846 | dev_err(&pdev->dev, | 852 | dev_err(&pdev->dev, |
847 | "failed to enable MSI support: %d\n", err); | 853 | "failed to enable MSI support: %d\n", err); |
848 | return err; | 854 | goto error; |
849 | } | 855 | } |
850 | } | 856 | } |
851 | pci_scan_child_bus(bus); | 857 | pci_scan_child_bus(bus); |
@@ -855,6 +861,10 @@ static int nwl_pcie_probe(struct platform_device *pdev) | |||
855 | pci_bus_add_devices(bus); | 861 | pci_bus_add_devices(bus); |
856 | platform_set_drvdata(pdev, pcie); | 862 | platform_set_drvdata(pdev, pcie); |
857 | return 0; | 863 | return 0; |
864 | |||
865 | error: | ||
866 | pci_free_resource_list(&res); | ||
867 | return err; | ||
858 | } | 868 | } |
859 | 869 | ||
860 | static int nwl_pcie_remove(struct platform_device *pdev) | 870 | static int nwl_pcie_remove(struct platform_device *pdev) |
diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c index 65f0fe0c2eaf..a30e01639557 100644 --- a/drivers/pci/host/pcie-xilinx.c +++ b/drivers/pci/host/pcie-xilinx.c | |||
@@ -550,7 +550,7 @@ static int xilinx_pcie_init_irq_domain(struct xilinx_pcie_port *port) | |||
550 | pcie_intc_node = of_get_next_child(node, NULL); | 550 | pcie_intc_node = of_get_next_child(node, NULL); |
551 | if (!pcie_intc_node) { | 551 | if (!pcie_intc_node) { |
552 | dev_err(dev, "No PCIe Intc node found\n"); | 552 | dev_err(dev, "No PCIe Intc node found\n"); |
553 | return PTR_ERR(pcie_intc_node); | 553 | return -ENODEV; |
554 | } | 554 | } |
555 | 555 | ||
556 | port->irq_domain = irq_domain_add_linear(pcie_intc_node, 4, | 556 | port->irq_domain = irq_domain_add_linear(pcie_intc_node, 4, |
@@ -558,7 +558,7 @@ static int xilinx_pcie_init_irq_domain(struct xilinx_pcie_port *port) | |||
558 | port); | 558 | port); |
559 | if (!port->irq_domain) { | 559 | if (!port->irq_domain) { |
560 | dev_err(dev, "Failed to get a INTx IRQ domain\n"); | 560 | dev_err(dev, "Failed to get a INTx IRQ domain\n"); |
561 | return PTR_ERR(port->irq_domain); | 561 | return -ENODEV; |
562 | } | 562 | } |
563 | 563 | ||
564 | /* Setup MSI */ | 564 | /* Setup MSI */ |
@@ -569,7 +569,7 @@ static int xilinx_pcie_init_irq_domain(struct xilinx_pcie_port *port) | |||
569 | &xilinx_pcie_msi_chip); | 569 | &xilinx_pcie_msi_chip); |
570 | if (!port->irq_domain) { | 570 | if (!port->irq_domain) { |
571 | dev_err(dev, "Failed to get a MSI IRQ domain\n"); | 571 | dev_err(dev, "Failed to get a MSI IRQ domain\n"); |
572 | return PTR_ERR(port->irq_domain); | 572 | return -ENODEV; |
573 | } | 573 | } |
574 | 574 | ||
575 | xilinx_pcie_enable_msi(port); | 575 | xilinx_pcie_enable_msi(port); |
@@ -660,7 +660,6 @@ static int xilinx_pcie_probe(struct platform_device *pdev) | |||
660 | struct xilinx_pcie_port *port; | 660 | struct xilinx_pcie_port *port; |
661 | struct device *dev = &pdev->dev; | 661 | struct device *dev = &pdev->dev; |
662 | struct pci_bus *bus; | 662 | struct pci_bus *bus; |
663 | |||
664 | int err; | 663 | int err; |
665 | resource_size_t iobase = 0; | 664 | resource_size_t iobase = 0; |
666 | LIST_HEAD(res); | 665 | LIST_HEAD(res); |
@@ -694,10 +693,17 @@ static int xilinx_pcie_probe(struct platform_device *pdev) | |||
694 | dev_err(dev, "Getting bridge resources failed\n"); | 693 | dev_err(dev, "Getting bridge resources failed\n"); |
695 | return err; | 694 | return err; |
696 | } | 695 | } |
696 | |||
697 | err = devm_request_pci_bus_resources(dev, &res); | ||
698 | if (err) | ||
699 | goto error; | ||
700 | |||
697 | bus = pci_create_root_bus(&pdev->dev, 0, | 701 | bus = pci_create_root_bus(&pdev->dev, 0, |
698 | &xilinx_pcie_ops, port, &res); | 702 | &xilinx_pcie_ops, port, &res); |
699 | if (!bus) | 703 | if (!bus) { |
700 | return -ENOMEM; | 704 | err = -ENOMEM; |
705 | goto error; | ||
706 | } | ||
701 | 707 | ||
702 | #ifdef CONFIG_PCI_MSI | 708 | #ifdef CONFIG_PCI_MSI |
703 | xilinx_pcie_msi_chip.dev = port->dev; | 709 | xilinx_pcie_msi_chip.dev = port->dev; |
@@ -712,6 +718,10 @@ static int xilinx_pcie_probe(struct platform_device *pdev) | |||
712 | platform_set_drvdata(pdev, port); | 718 | platform_set_drvdata(pdev, port); |
713 | 719 | ||
714 | return 0; | 720 | return 0; |
721 | |||
722 | error: | ||
723 | pci_free_resource_list(&res); | ||
724 | return err; | ||
715 | } | 725 | } |
716 | 726 | ||
717 | /** | 727 | /** |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index fa49f9143b80..6a33ddcfa20b 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -675,6 +675,8 @@ static void acpiphp_check_bridge(struct acpiphp_bridge *bridge) | |||
675 | if (bridge->is_going_away) | 675 | if (bridge->is_going_away) |
676 | return; | 676 | return; |
677 | 677 | ||
678 | pm_runtime_get_sync(&bridge->pci_dev->dev); | ||
679 | |||
678 | list_for_each_entry(slot, &bridge->slots, node) { | 680 | list_for_each_entry(slot, &bridge->slots, node) { |
679 | struct pci_bus *bus = slot->bus; | 681 | struct pci_bus *bus = slot->bus; |
680 | struct pci_dev *dev, *tmp; | 682 | struct pci_dev *dev, *tmp; |
@@ -694,6 +696,8 @@ static void acpiphp_check_bridge(struct acpiphp_bridge *bridge) | |||
694 | disable_slot(slot); | 696 | disable_slot(slot); |
695 | } | 697 | } |
696 | } | 698 | } |
699 | |||
700 | pm_runtime_put(&bridge->pci_dev->dev); | ||
697 | } | 701 | } |
698 | 702 | ||
699 | /* | 703 | /* |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 5c24e938042f..08e84d61874e 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -546,6 +546,10 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) | |||
546 | u8 present; | 546 | u8 present; |
547 | bool link; | 547 | bool link; |
548 | 548 | ||
549 | /* Interrupts cannot originate from a controller that's asleep */ | ||
550 | if (pdev->current_state == PCI_D3cold) | ||
551 | return IRQ_NONE; | ||
552 | |||
549 | /* | 553 | /* |
550 | * In order to guarantee that all interrupt events are | 554 | * In order to guarantee that all interrupt events are |
551 | * serviced, we need to re-inspect Slot Status register after | 555 | * serviced, we need to re-inspect Slot Status register after |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index a080f4496fe2..a02981efdad5 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -4,6 +4,7 @@ | |||
4 | * | 4 | * |
5 | * Copyright (C) 2003-2004 Intel | 5 | * Copyright (C) 2003-2004 Intel |
6 | * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) | 6 | * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) |
7 | * Copyright (C) 2016 Christoph Hellwig. | ||
7 | */ | 8 | */ |
8 | 9 | ||
9 | #include <linux/err.h> | 10 | #include <linux/err.h> |
@@ -207,6 +208,12 @@ static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag) | |||
207 | desc->masked = __pci_msi_desc_mask_irq(desc, mask, flag); | 208 | desc->masked = __pci_msi_desc_mask_irq(desc, mask, flag); |
208 | } | 209 | } |
209 | 210 | ||
211 | static void __iomem *pci_msix_desc_addr(struct msi_desc *desc) | ||
212 | { | ||
213 | return desc->mask_base + | ||
214 | desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE; | ||
215 | } | ||
216 | |||
210 | /* | 217 | /* |
211 | * This internal function does not flush PCI writes to the device. | 218 | * This internal function does not flush PCI writes to the device. |
212 | * All users must ensure that they read from the device before either | 219 | * All users must ensure that they read from the device before either |
@@ -217,8 +224,6 @@ static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag) | |||
217 | u32 __pci_msix_desc_mask_irq(struct msi_desc *desc, u32 flag) | 224 | u32 __pci_msix_desc_mask_irq(struct msi_desc *desc, u32 flag) |
218 | { | 225 | { |
219 | u32 mask_bits = desc->masked; | 226 | u32 mask_bits = desc->masked; |
220 | unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + | ||
221 | PCI_MSIX_ENTRY_VECTOR_CTRL; | ||
222 | 227 | ||
223 | if (pci_msi_ignore_mask) | 228 | if (pci_msi_ignore_mask) |
224 | return 0; | 229 | return 0; |
@@ -226,7 +231,7 @@ u32 __pci_msix_desc_mask_irq(struct msi_desc *desc, u32 flag) | |||
226 | mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; | 231 | mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; |
227 | if (flag) | 232 | if (flag) |
228 | mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT; | 233 | mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT; |
229 | writel(mask_bits, desc->mask_base + offset); | 234 | writel(mask_bits, pci_msix_desc_addr(desc) + PCI_MSIX_ENTRY_VECTOR_CTRL); |
230 | 235 | ||
231 | return mask_bits; | 236 | return mask_bits; |
232 | } | 237 | } |
@@ -284,8 +289,7 @@ void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg) | |||
284 | BUG_ON(dev->current_state != PCI_D0); | 289 | BUG_ON(dev->current_state != PCI_D0); |
285 | 290 | ||
286 | if (entry->msi_attrib.is_msix) { | 291 | if (entry->msi_attrib.is_msix) { |
287 | void __iomem *base = entry->mask_base + | 292 | void __iomem *base = pci_msix_desc_addr(entry); |
288 | entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE; | ||
289 | 293 | ||
290 | msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR); | 294 | msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR); |
291 | msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR); | 295 | msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR); |
@@ -315,9 +319,7 @@ void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg) | |||
315 | if (dev->current_state != PCI_D0) { | 319 | if (dev->current_state != PCI_D0) { |
316 | /* Don't touch the hardware now */ | 320 | /* Don't touch the hardware now */ |
317 | } else if (entry->msi_attrib.is_msix) { | 321 | } else if (entry->msi_attrib.is_msix) { |
318 | void __iomem *base; | 322 | void __iomem *base = pci_msix_desc_addr(entry); |
319 | base = entry->mask_base + | ||
320 | entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE; | ||
321 | 323 | ||
322 | writel(msg->address_lo, base + PCI_MSIX_ENTRY_LOWER_ADDR); | 324 | writel(msg->address_lo, base + PCI_MSIX_ENTRY_LOWER_ADDR); |
323 | writel(msg->address_hi, base + PCI_MSIX_ENTRY_UPPER_ADDR); | 325 | writel(msg->address_hi, base + PCI_MSIX_ENTRY_UPPER_ADDR); |
@@ -567,6 +569,7 @@ static struct msi_desc *msi_setup_entry(struct pci_dev *dev, int nvec) | |||
567 | entry->msi_attrib.multi_cap = (control & PCI_MSI_FLAGS_QMASK) >> 1; | 569 | entry->msi_attrib.multi_cap = (control & PCI_MSI_FLAGS_QMASK) >> 1; |
568 | entry->msi_attrib.multiple = ilog2(__roundup_pow_of_two(nvec)); | 570 | entry->msi_attrib.multiple = ilog2(__roundup_pow_of_two(nvec)); |
569 | entry->nvec_used = nvec; | 571 | entry->nvec_used = nvec; |
572 | entry->affinity = dev->irq_affinity; | ||
570 | 573 | ||
571 | if (control & PCI_MSI_FLAGS_64BIT) | 574 | if (control & PCI_MSI_FLAGS_64BIT) |
572 | entry->mask_pos = dev->msi_cap + PCI_MSI_MASK_64; | 575 | entry->mask_pos = dev->msi_cap + PCI_MSI_MASK_64; |
@@ -678,10 +681,18 @@ static void __iomem *msix_map_region(struct pci_dev *dev, unsigned nr_entries) | |||
678 | static int msix_setup_entries(struct pci_dev *dev, void __iomem *base, | 681 | static int msix_setup_entries(struct pci_dev *dev, void __iomem *base, |
679 | struct msix_entry *entries, int nvec) | 682 | struct msix_entry *entries, int nvec) |
680 | { | 683 | { |
684 | const struct cpumask *mask = NULL; | ||
681 | struct msi_desc *entry; | 685 | struct msi_desc *entry; |
682 | int i; | 686 | int cpu = -1, i; |
683 | 687 | ||
684 | for (i = 0; i < nvec; i++) { | 688 | for (i = 0; i < nvec; i++) { |
689 | if (dev->irq_affinity) { | ||
690 | cpu = cpumask_next(cpu, dev->irq_affinity); | ||
691 | if (cpu >= nr_cpu_ids) | ||
692 | cpu = cpumask_first(dev->irq_affinity); | ||
693 | mask = cpumask_of(cpu); | ||
694 | } | ||
695 | |||
685 | entry = alloc_msi_entry(&dev->dev); | 696 | entry = alloc_msi_entry(&dev->dev); |
686 | if (!entry) { | 697 | if (!entry) { |
687 | if (!i) | 698 | if (!i) |
@@ -694,10 +705,14 @@ static int msix_setup_entries(struct pci_dev *dev, void __iomem *base, | |||
694 | 705 | ||
695 | entry->msi_attrib.is_msix = 1; | 706 | entry->msi_attrib.is_msix = 1; |
696 | entry->msi_attrib.is_64 = 1; | 707 | entry->msi_attrib.is_64 = 1; |
697 | entry->msi_attrib.entry_nr = entries[i].entry; | 708 | if (entries) |
709 | entry->msi_attrib.entry_nr = entries[i].entry; | ||
710 | else | ||
711 | entry->msi_attrib.entry_nr = i; | ||
698 | entry->msi_attrib.default_irq = dev->irq; | 712 | entry->msi_attrib.default_irq = dev->irq; |
699 | entry->mask_base = base; | 713 | entry->mask_base = base; |
700 | entry->nvec_used = 1; | 714 | entry->nvec_used = 1; |
715 | entry->affinity = mask; | ||
701 | 716 | ||
702 | list_add_tail(&entry->list, dev_to_msi_list(&dev->dev)); | 717 | list_add_tail(&entry->list, dev_to_msi_list(&dev->dev)); |
703 | } | 718 | } |
@@ -712,13 +727,11 @@ static void msix_program_entries(struct pci_dev *dev, | |||
712 | int i = 0; | 727 | int i = 0; |
713 | 728 | ||
714 | for_each_pci_msi_entry(entry, dev) { | 729 | for_each_pci_msi_entry(entry, dev) { |
715 | int offset = entries[i].entry * PCI_MSIX_ENTRY_SIZE + | 730 | if (entries) |
716 | PCI_MSIX_ENTRY_VECTOR_CTRL; | 731 | entries[i++].vector = entry->irq; |
717 | 732 | entry->masked = readl(pci_msix_desc_addr(entry) + | |
718 | entries[i].vector = entry->irq; | 733 | PCI_MSIX_ENTRY_VECTOR_CTRL); |
719 | entry->masked = readl(entry->mask_base + offset); | ||
720 | msix_mask_irq(entry, 1); | 734 | msix_mask_irq(entry, 1); |
721 | i++; | ||
722 | } | 735 | } |
723 | } | 736 | } |
724 | 737 | ||
@@ -931,7 +944,7 @@ EXPORT_SYMBOL(pci_msix_vec_count); | |||
931 | /** | 944 | /** |
932 | * pci_enable_msix - configure device's MSI-X capability structure | 945 | * pci_enable_msix - configure device's MSI-X capability structure |
933 | * @dev: pointer to the pci_dev data structure of MSI-X device function | 946 | * @dev: pointer to the pci_dev data structure of MSI-X device function |
934 | * @entries: pointer to an array of MSI-X entries | 947 | * @entries: pointer to an array of MSI-X entries (optional) |
935 | * @nvec: number of MSI-X irqs requested for allocation by device driver | 948 | * @nvec: number of MSI-X irqs requested for allocation by device driver |
936 | * | 949 | * |
937 | * Setup the MSI-X capability structure of device function with the number | 950 | * Setup the MSI-X capability structure of device function with the number |
@@ -951,22 +964,21 @@ int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec) | |||
951 | if (!pci_msi_supported(dev, nvec)) | 964 | if (!pci_msi_supported(dev, nvec)) |
952 | return -EINVAL; | 965 | return -EINVAL; |
953 | 966 | ||
954 | if (!entries) | ||
955 | return -EINVAL; | ||
956 | |||
957 | nr_entries = pci_msix_vec_count(dev); | 967 | nr_entries = pci_msix_vec_count(dev); |
958 | if (nr_entries < 0) | 968 | if (nr_entries < 0) |
959 | return nr_entries; | 969 | return nr_entries; |
960 | if (nvec > nr_entries) | 970 | if (nvec > nr_entries) |
961 | return nr_entries; | 971 | return nr_entries; |
962 | 972 | ||
963 | /* Check for any invalid entries */ | 973 | if (entries) { |
964 | for (i = 0; i < nvec; i++) { | 974 | /* Check for any invalid entries */ |
965 | if (entries[i].entry >= nr_entries) | 975 | for (i = 0; i < nvec; i++) { |
966 | return -EINVAL; /* invalid entry */ | 976 | if (entries[i].entry >= nr_entries) |
967 | for (j = i + 1; j < nvec; j++) { | 977 | return -EINVAL; /* invalid entry */ |
968 | if (entries[i].entry == entries[j].entry) | 978 | for (j = i + 1; j < nvec; j++) { |
969 | return -EINVAL; /* duplicate entry */ | 979 | if (entries[i].entry == entries[j].entry) |
980 | return -EINVAL; /* duplicate entry */ | ||
981 | } | ||
970 | } | 982 | } |
971 | } | 983 | } |
972 | WARN_ON(!!dev->msix_enabled); | 984 | WARN_ON(!!dev->msix_enabled); |
@@ -1026,19 +1038,8 @@ int pci_msi_enabled(void) | |||
1026 | } | 1038 | } |
1027 | EXPORT_SYMBOL(pci_msi_enabled); | 1039 | EXPORT_SYMBOL(pci_msi_enabled); |
1028 | 1040 | ||
1029 | /** | 1041 | static int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec, |
1030 | * pci_enable_msi_range - configure device's MSI capability structure | 1042 | unsigned int flags) |
1031 | * @dev: device to configure | ||
1032 | * @minvec: minimal number of interrupts to configure | ||
1033 | * @maxvec: maximum number of interrupts to configure | ||
1034 | * | ||
1035 | * This function tries to allocate a maximum possible number of interrupts in a | ||
1036 | * range between @minvec and @maxvec. It returns a negative errno if an error | ||
1037 | * occurs. If it succeeds, it returns the actual number of interrupts allocated | ||
1038 | * and updates the @dev's irq member to the lowest new interrupt number; | ||
1039 | * the other interrupt numbers allocated to this device are consecutive. | ||
1040 | **/ | ||
1041 | int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec) | ||
1042 | { | 1043 | { |
1043 | int nvec; | 1044 | int nvec; |
1044 | int rc; | 1045 | int rc; |
@@ -1061,25 +1062,85 @@ int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec) | |||
1061 | nvec = pci_msi_vec_count(dev); | 1062 | nvec = pci_msi_vec_count(dev); |
1062 | if (nvec < 0) | 1063 | if (nvec < 0) |
1063 | return nvec; | 1064 | return nvec; |
1064 | else if (nvec < minvec) | 1065 | if (nvec < minvec) |
1065 | return -EINVAL; | 1066 | return -EINVAL; |
1066 | else if (nvec > maxvec) | 1067 | |
1068 | if (nvec > maxvec) | ||
1067 | nvec = maxvec; | 1069 | nvec = maxvec; |
1068 | 1070 | ||
1069 | do { | 1071 | for (;;) { |
1072 | if (!(flags & PCI_IRQ_NOAFFINITY)) { | ||
1073 | dev->irq_affinity = irq_create_affinity_mask(&nvec); | ||
1074 | if (nvec < minvec) | ||
1075 | return -ENOSPC; | ||
1076 | } | ||
1077 | |||
1070 | rc = msi_capability_init(dev, nvec); | 1078 | rc = msi_capability_init(dev, nvec); |
1071 | if (rc < 0) { | 1079 | if (rc == 0) |
1080 | return nvec; | ||
1081 | |||
1082 | kfree(dev->irq_affinity); | ||
1083 | dev->irq_affinity = NULL; | ||
1084 | |||
1085 | if (rc < 0) | ||
1072 | return rc; | 1086 | return rc; |
1073 | } else if (rc > 0) { | 1087 | if (rc < minvec) |
1074 | if (rc < minvec) | 1088 | return -ENOSPC; |
1089 | |||
1090 | nvec = rc; | ||
1091 | } | ||
1092 | } | ||
1093 | |||
1094 | /** | ||
1095 | * pci_enable_msi_range - configure device's MSI capability structure | ||
1096 | * @dev: device to configure | ||
1097 | * @minvec: minimal number of interrupts to configure | ||
1098 | * @maxvec: maximum number of interrupts to configure | ||
1099 | * | ||
1100 | * This function tries to allocate a maximum possible number of interrupts in a | ||
1101 | * range between @minvec and @maxvec. It returns a negative errno if an error | ||
1102 | * occurs. If it succeeds, it returns the actual number of interrupts allocated | ||
1103 | * and updates the @dev's irq member to the lowest new interrupt number; | ||
1104 | * the other interrupt numbers allocated to this device are consecutive. | ||
1105 | **/ | ||
1106 | int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec) | ||
1107 | { | ||
1108 | return __pci_enable_msi_range(dev, minvec, maxvec, PCI_IRQ_NOAFFINITY); | ||
1109 | } | ||
1110 | EXPORT_SYMBOL(pci_enable_msi_range); | ||
1111 | |||
1112 | static int __pci_enable_msix_range(struct pci_dev *dev, | ||
1113 | struct msix_entry *entries, int minvec, int maxvec, | ||
1114 | unsigned int flags) | ||
1115 | { | ||
1116 | int nvec = maxvec; | ||
1117 | int rc; | ||
1118 | |||
1119 | if (maxvec < minvec) | ||
1120 | return -ERANGE; | ||
1121 | |||
1122 | for (;;) { | ||
1123 | if (!(flags & PCI_IRQ_NOAFFINITY)) { | ||
1124 | dev->irq_affinity = irq_create_affinity_mask(&nvec); | ||
1125 | if (nvec < minvec) | ||
1075 | return -ENOSPC; | 1126 | return -ENOSPC; |
1076 | nvec = rc; | ||
1077 | } | 1127 | } |
1078 | } while (rc); | ||
1079 | 1128 | ||
1080 | return nvec; | 1129 | rc = pci_enable_msix(dev, entries, nvec); |
1130 | if (rc == 0) | ||
1131 | return nvec; | ||
1132 | |||
1133 | kfree(dev->irq_affinity); | ||
1134 | dev->irq_affinity = NULL; | ||
1135 | |||
1136 | if (rc < 0) | ||
1137 | return rc; | ||
1138 | if (rc < minvec) | ||
1139 | return -ENOSPC; | ||
1140 | |||
1141 | nvec = rc; | ||
1142 | } | ||
1081 | } | 1143 | } |
1082 | EXPORT_SYMBOL(pci_enable_msi_range); | ||
1083 | 1144 | ||
1084 | /** | 1145 | /** |
1085 | * pci_enable_msix_range - configure device's MSI-X capability structure | 1146 | * pci_enable_msix_range - configure device's MSI-X capability structure |
@@ -1097,28 +1158,101 @@ EXPORT_SYMBOL(pci_enable_msi_range); | |||
1097 | * with new allocated MSI-X interrupts. | 1158 | * with new allocated MSI-X interrupts. |
1098 | **/ | 1159 | **/ |
1099 | int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, | 1160 | int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, |
1100 | int minvec, int maxvec) | 1161 | int minvec, int maxvec) |
1101 | { | 1162 | { |
1102 | int nvec = maxvec; | 1163 | return __pci_enable_msix_range(dev, entries, minvec, maxvec, |
1103 | int rc; | 1164 | PCI_IRQ_NOAFFINITY); |
1165 | } | ||
1166 | EXPORT_SYMBOL(pci_enable_msix_range); | ||
1104 | 1167 | ||
1105 | if (maxvec < minvec) | 1168 | /** |
1106 | return -ERANGE; | 1169 | * pci_alloc_irq_vectors - allocate multiple IRQs for a device |
1170 | * @dev: PCI device to operate on | ||
1171 | * @min_vecs: minimum number of vectors required (must be >= 1) | ||
1172 | * @max_vecs: maximum (desired) number of vectors | ||
1173 | * @flags: flags or quirks for the allocation | ||
1174 | * | ||
1175 | * Allocate up to @max_vecs interrupt vectors for @dev, using MSI-X or MSI | ||
1176 | * vectors if available, and fall back to a single legacy vector | ||
1177 | * if neither is available. Return the number of vectors allocated, | ||
1178 | * (which might be smaller than @max_vecs) if successful, or a negative | ||
1179 | * error code on error. If less than @min_vecs interrupt vectors are | ||
1180 | * available for @dev the function will fail with -ENOSPC. | ||
1181 | * | ||
1182 | * To get the Linux IRQ number used for a vector that can be passed to | ||
1183 | * request_irq() use the pci_irq_vector() helper. | ||
1184 | */ | ||
1185 | int pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs, | ||
1186 | unsigned int max_vecs, unsigned int flags) | ||
1187 | { | ||
1188 | int vecs = -ENOSPC; | ||
1107 | 1189 | ||
1108 | do { | 1190 | if (!(flags & PCI_IRQ_NOMSIX)) { |
1109 | rc = pci_enable_msix(dev, entries, nvec); | 1191 | vecs = __pci_enable_msix_range(dev, NULL, min_vecs, max_vecs, |
1110 | if (rc < 0) { | 1192 | flags); |
1111 | return rc; | 1193 | if (vecs > 0) |
1112 | } else if (rc > 0) { | 1194 | return vecs; |
1113 | if (rc < minvec) | 1195 | } |
1114 | return -ENOSPC; | 1196 | |
1115 | nvec = rc; | 1197 | if (!(flags & PCI_IRQ_NOMSI)) { |
1198 | vecs = __pci_enable_msi_range(dev, min_vecs, max_vecs, flags); | ||
1199 | if (vecs > 0) | ||
1200 | return vecs; | ||
1201 | } | ||
1202 | |||
1203 | /* use legacy irq if allowed */ | ||
1204 | if (!(flags & PCI_IRQ_NOLEGACY) && min_vecs == 1) | ||
1205 | return 1; | ||
1206 | return vecs; | ||
1207 | } | ||
1208 | EXPORT_SYMBOL(pci_alloc_irq_vectors); | ||
1209 | |||
1210 | /** | ||
1211 | * pci_free_irq_vectors - free previously allocated IRQs for a device | ||
1212 | * @dev: PCI device to operate on | ||
1213 | * | ||
1214 | * Undoes the allocations and enabling in pci_alloc_irq_vectors(). | ||
1215 | */ | ||
1216 | void pci_free_irq_vectors(struct pci_dev *dev) | ||
1217 | { | ||
1218 | pci_disable_msix(dev); | ||
1219 | pci_disable_msi(dev); | ||
1220 | } | ||
1221 | EXPORT_SYMBOL(pci_free_irq_vectors); | ||
1222 | |||
1223 | /** | ||
1224 | * pci_irq_vector - return Linux IRQ number of a device vector | ||
1225 | * @dev: PCI device to operate on | ||
1226 | * @nr: device-relative interrupt vector index (0-based). | ||
1227 | */ | ||
1228 | int pci_irq_vector(struct pci_dev *dev, unsigned int nr) | ||
1229 | { | ||
1230 | if (dev->msix_enabled) { | ||
1231 | struct msi_desc *entry; | ||
1232 | int i = 0; | ||
1233 | |||
1234 | for_each_pci_msi_entry(entry, dev) { | ||
1235 | if (i == nr) | ||
1236 | return entry->irq; | ||
1237 | i++; | ||
1116 | } | 1238 | } |
1117 | } while (rc); | 1239 | WARN_ON_ONCE(1); |
1240 | return -EINVAL; | ||
1241 | } | ||
1118 | 1242 | ||
1119 | return nvec; | 1243 | if (dev->msi_enabled) { |
1244 | struct msi_desc *entry = first_pci_msi_entry(dev); | ||
1245 | |||
1246 | if (WARN_ON_ONCE(nr >= entry->nvec_used)) | ||
1247 | return -EINVAL; | ||
1248 | } else { | ||
1249 | if (WARN_ON_ONCE(nr > 0)) | ||
1250 | return -EINVAL; | ||
1251 | } | ||
1252 | |||
1253 | return dev->irq + nr; | ||
1120 | } | 1254 | } |
1121 | EXPORT_SYMBOL(pci_enable_msix_range); | 1255 | EXPORT_SYMBOL(pci_irq_vector); |
1122 | 1256 | ||
1123 | struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc) | 1257 | struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc) |
1124 | { | 1258 | { |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index d7ffd66814bb..e39a67c8ef39 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -777,7 +777,7 @@ static int pci_pm_suspend_noirq(struct device *dev) | |||
777 | 777 | ||
778 | if (!pci_dev->state_saved) { | 778 | if (!pci_dev->state_saved) { |
779 | pci_save_state(pci_dev); | 779 | pci_save_state(pci_dev); |
780 | if (!pci_has_subordinate(pci_dev)) | 780 | if (pci_power_manageable(pci_dev)) |
781 | pci_prepare_to_sleep(pci_dev); | 781 | pci_prepare_to_sleep(pci_dev); |
782 | } | 782 | } |
783 | 783 | ||
@@ -1144,7 +1144,6 @@ static int pci_pm_runtime_suspend(struct device *dev) | |||
1144 | return -ENOSYS; | 1144 | return -ENOSYS; |
1145 | 1145 | ||
1146 | pci_dev->state_saved = false; | 1146 | pci_dev->state_saved = false; |
1147 | pci_dev->no_d3cold = false; | ||
1148 | error = pm->runtime_suspend(dev); | 1147 | error = pm->runtime_suspend(dev); |
1149 | if (error) { | 1148 | if (error) { |
1150 | /* | 1149 | /* |
@@ -1161,8 +1160,6 @@ static int pci_pm_runtime_suspend(struct device *dev) | |||
1161 | 1160 | ||
1162 | return error; | 1161 | return error; |
1163 | } | 1162 | } |
1164 | if (!pci_dev->d3cold_allowed) | ||
1165 | pci_dev->no_d3cold = true; | ||
1166 | 1163 | ||
1167 | pci_fixup_device(pci_fixup_suspend, pci_dev); | 1164 | pci_fixup_device(pci_fixup_suspend, pci_dev); |
1168 | 1165 | ||
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index d319a9ca9b7b..bcd10c795284 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -406,6 +406,11 @@ static ssize_t d3cold_allowed_store(struct device *dev, | |||
406 | return -EINVAL; | 406 | return -EINVAL; |
407 | 407 | ||
408 | pdev->d3cold_allowed = !!val; | 408 | pdev->d3cold_allowed = !!val; |
409 | if (pdev->d3cold_allowed) | ||
410 | pci_d3cold_enable(pdev); | ||
411 | else | ||
412 | pci_d3cold_disable(pdev); | ||
413 | |||
409 | pm_runtime_resume(dev); | 414 | pm_runtime_resume(dev); |
410 | 415 | ||
411 | return count; | 416 | return count; |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index badbddc683f0..aab9d5115a5f 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -7,8 +7,10 @@ | |||
7 | * Copyright 1997 -- 2000 Martin Mares <mj@ucw.cz> | 7 | * Copyright 1997 -- 2000 Martin Mares <mj@ucw.cz> |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/acpi.h> | ||
10 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
11 | #include <linux/delay.h> | 12 | #include <linux/delay.h> |
13 | #include <linux/dmi.h> | ||
12 | #include <linux/init.h> | 14 | #include <linux/init.h> |
13 | #include <linux/of.h> | 15 | #include <linux/of.h> |
14 | #include <linux/of_pci.h> | 16 | #include <linux/of_pci.h> |
@@ -25,7 +27,9 @@ | |||
25 | #include <linux/device.h> | 27 | #include <linux/device.h> |
26 | #include <linux/pm_runtime.h> | 28 | #include <linux/pm_runtime.h> |
27 | #include <linux/pci_hotplug.h> | 29 | #include <linux/pci_hotplug.h> |
30 | #include <linux/vmalloc.h> | ||
28 | #include <asm/setup.h> | 31 | #include <asm/setup.h> |
32 | #include <asm/dma.h> | ||
29 | #include <linux/aer.h> | 33 | #include <linux/aer.h> |
30 | #include "pci.h" | 34 | #include "pci.h" |
31 | 35 | ||
@@ -81,6 +85,9 @@ unsigned long pci_cardbus_mem_size = DEFAULT_CARDBUS_MEM_SIZE; | |||
81 | unsigned long pci_hotplug_io_size = DEFAULT_HOTPLUG_IO_SIZE; | 85 | unsigned long pci_hotplug_io_size = DEFAULT_HOTPLUG_IO_SIZE; |
82 | unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_SIZE; | 86 | unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_SIZE; |
83 | 87 | ||
88 | #define DEFAULT_HOTPLUG_BUS_SIZE 1 | ||
89 | unsigned long pci_hotplug_bus_size = DEFAULT_HOTPLUG_BUS_SIZE; | ||
90 | |||
84 | enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_DEFAULT; | 91 | enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_DEFAULT; |
85 | 92 | ||
86 | /* | 93 | /* |
@@ -101,6 +108,21 @@ unsigned int pcibios_max_latency = 255; | |||
101 | /* If set, the PCIe ARI capability will not be used. */ | 108 | /* If set, the PCIe ARI capability will not be used. */ |
102 | static bool pcie_ari_disabled; | 109 | static bool pcie_ari_disabled; |
103 | 110 | ||
111 | /* Disable bridge_d3 for all PCIe ports */ | ||
112 | static bool pci_bridge_d3_disable; | ||
113 | /* Force bridge_d3 for all PCIe ports */ | ||
114 | static bool pci_bridge_d3_force; | ||
115 | |||
116 | static int __init pcie_port_pm_setup(char *str) | ||
117 | { | ||
118 | if (!strcmp(str, "off")) | ||
119 | pci_bridge_d3_disable = true; | ||
120 | else if (!strcmp(str, "force")) | ||
121 | pci_bridge_d3_force = true; | ||
122 | return 1; | ||
123 | } | ||
124 | __setup("pcie_port_pm=", pcie_port_pm_setup); | ||
125 | |||
104 | /** | 126 | /** |
105 | * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children | 127 | * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children |
106 | * @bus: pointer to PCI bus structure to search | 128 | * @bus: pointer to PCI bus structure to search |
@@ -2156,6 +2178,164 @@ void pci_config_pm_runtime_put(struct pci_dev *pdev) | |||
2156 | } | 2178 | } |
2157 | 2179 | ||
2158 | /** | 2180 | /** |
2181 | * pci_bridge_d3_possible - Is it possible to put the bridge into D3 | ||
2182 | * @bridge: Bridge to check | ||
2183 | * | ||
2184 | * This function checks if it is possible to move the bridge to D3. | ||
2185 | * Currently we only allow D3 for recent enough PCIe ports. | ||
2186 | */ | ||
2187 | static bool pci_bridge_d3_possible(struct pci_dev *bridge) | ||
2188 | { | ||
2189 | unsigned int year; | ||
2190 | |||
2191 | if (!pci_is_pcie(bridge)) | ||
2192 | return false; | ||
2193 | |||
2194 | switch (pci_pcie_type(bridge)) { | ||
2195 | case PCI_EXP_TYPE_ROOT_PORT: | ||
2196 | case PCI_EXP_TYPE_UPSTREAM: | ||
2197 | case PCI_EXP_TYPE_DOWNSTREAM: | ||
2198 | if (pci_bridge_d3_disable) | ||
2199 | return false; | ||
2200 | if (pci_bridge_d3_force) | ||
2201 | return true; | ||
2202 | |||
2203 | /* | ||
2204 | * It should be safe to put PCIe ports from 2015 or newer | ||
2205 | * to D3. | ||
2206 | */ | ||
2207 | if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && | ||
2208 | year >= 2015) { | ||
2209 | return true; | ||
2210 | } | ||
2211 | break; | ||
2212 | } | ||
2213 | |||
2214 | return false; | ||
2215 | } | ||
2216 | |||
2217 | static int pci_dev_check_d3cold(struct pci_dev *dev, void *data) | ||
2218 | { | ||
2219 | bool *d3cold_ok = data; | ||
2220 | bool no_d3cold; | ||
2221 | |||
2222 | /* | ||
2223 | * The device needs to be allowed to go D3cold and if it is wake | ||
2224 | * capable to do so from D3cold. | ||
2225 | */ | ||
2226 | no_d3cold = dev->no_d3cold || !dev->d3cold_allowed || | ||
2227 | (device_may_wakeup(&dev->dev) && !pci_pme_capable(dev, PCI_D3cold)) || | ||
2228 | !pci_power_manageable(dev); | ||
2229 | |||
2230 | *d3cold_ok = !no_d3cold; | ||
2231 | |||
2232 | return no_d3cold; | ||
2233 | } | ||
2234 | |||
2235 | /* | ||
2236 | * pci_bridge_d3_update - Update bridge D3 capabilities | ||
2237 | * @dev: PCI device which is changed | ||
2238 | * @remove: Is the device being removed | ||
2239 | * | ||
2240 | * Update upstream bridge PM capabilities accordingly depending on if the | ||
2241 | * device PM configuration was changed or the device is being removed. The | ||
2242 | * change is also propagated upstream. | ||
2243 | */ | ||
2244 | static void pci_bridge_d3_update(struct pci_dev *dev, bool remove) | ||
2245 | { | ||
2246 | struct pci_dev *bridge; | ||
2247 | bool d3cold_ok = true; | ||
2248 | |||
2249 | bridge = pci_upstream_bridge(dev); | ||
2250 | if (!bridge || !pci_bridge_d3_possible(bridge)) | ||
2251 | return; | ||
2252 | |||
2253 | pci_dev_get(bridge); | ||
2254 | /* | ||
2255 | * If the device is removed we do not care about its D3cold | ||
2256 | * capabilities. | ||
2257 | */ | ||
2258 | if (!remove) | ||
2259 | pci_dev_check_d3cold(dev, &d3cold_ok); | ||
2260 | |||
2261 | if (d3cold_ok) { | ||
2262 | /* | ||
2263 | * We need to go through all children to find out if all of | ||
2264 | * them can still go to D3cold. | ||
2265 | */ | ||
2266 | pci_walk_bus(bridge->subordinate, pci_dev_check_d3cold, | ||
2267 | &d3cold_ok); | ||
2268 | } | ||
2269 | |||
2270 | if (bridge->bridge_d3 != d3cold_ok) { | ||
2271 | bridge->bridge_d3 = d3cold_ok; | ||
2272 | /* Propagate change to upstream bridges */ | ||
2273 | pci_bridge_d3_update(bridge, false); | ||
2274 | } | ||
2275 | |||
2276 | pci_dev_put(bridge); | ||
2277 | } | ||
2278 | |||
2279 | /** | ||
2280 | * pci_bridge_d3_device_changed - Update bridge D3 capabilities on change | ||
2281 | * @dev: PCI device that was changed | ||
2282 | * | ||
2283 | * If a device is added or its PM configuration, such as is it allowed to | ||
2284 | * enter D3cold, is changed this function updates upstream bridge PM | ||
2285 | * capabilities accordingly. | ||
2286 | */ | ||
2287 | void pci_bridge_d3_device_changed(struct pci_dev *dev) | ||
2288 | { | ||
2289 | pci_bridge_d3_update(dev, false); | ||
2290 | } | ||
2291 | |||
2292 | /** | ||
2293 | * pci_bridge_d3_device_removed - Update bridge D3 capabilities on remove | ||
2294 | * @dev: PCI device being removed | ||
2295 | * | ||
2296 | * Function updates upstream bridge PM capabilities based on other devices | ||
2297 | * still left on the bus. | ||
2298 | */ | ||
2299 | void pci_bridge_d3_device_removed(struct pci_dev *dev) | ||
2300 | { | ||
2301 | pci_bridge_d3_update(dev, true); | ||
2302 | } | ||
2303 | |||
2304 | /** | ||
2305 | * pci_d3cold_enable - Enable D3cold for device | ||
2306 | * @dev: PCI device to handle | ||
2307 | * | ||
2308 | * This function can be used in drivers to enable D3cold from the device | ||
2309 | * they handle. It also updates upstream PCI bridge PM capabilities | ||
2310 | * accordingly. | ||
2311 | */ | ||
2312 | void pci_d3cold_enable(struct pci_dev *dev) | ||
2313 | { | ||
2314 | if (dev->no_d3cold) { | ||
2315 | dev->no_d3cold = false; | ||
2316 | pci_bridge_d3_device_changed(dev); | ||
2317 | } | ||
2318 | } | ||
2319 | EXPORT_SYMBOL_GPL(pci_d3cold_enable); | ||
2320 | |||
2321 | /** | ||
2322 | * pci_d3cold_disable - Disable D3cold for device | ||
2323 | * @dev: PCI device to handle | ||
2324 | * | ||
2325 | * This function can be used in drivers to disable D3cold from the device | ||
2326 | * they handle. It also updates upstream PCI bridge PM capabilities | ||
2327 | * accordingly. | ||
2328 | */ | ||
2329 | void pci_d3cold_disable(struct pci_dev *dev) | ||
2330 | { | ||
2331 | if (!dev->no_d3cold) { | ||
2332 | dev->no_d3cold = true; | ||
2333 | pci_bridge_d3_device_changed(dev); | ||
2334 | } | ||
2335 | } | ||
2336 | EXPORT_SYMBOL_GPL(pci_d3cold_disable); | ||
2337 | |||
2338 | /** | ||
2159 | * pci_pm_init - Initialize PM functions of given PCI device | 2339 | * pci_pm_init - Initialize PM functions of given PCI device |
2160 | * @dev: PCI device to handle. | 2340 | * @dev: PCI device to handle. |
2161 | */ | 2341 | */ |
@@ -2189,6 +2369,7 @@ void pci_pm_init(struct pci_dev *dev) | |||
2189 | dev->pm_cap = pm; | 2369 | dev->pm_cap = pm; |
2190 | dev->d3_delay = PCI_PM_D3_WAIT; | 2370 | dev->d3_delay = PCI_PM_D3_WAIT; |
2191 | dev->d3cold_delay = PCI_PM_D3COLD_WAIT; | 2371 | dev->d3cold_delay = PCI_PM_D3COLD_WAIT; |
2372 | dev->bridge_d3 = pci_bridge_d3_possible(dev); | ||
2192 | dev->d3cold_allowed = true; | 2373 | dev->d3cold_allowed = true; |
2193 | 2374 | ||
2194 | dev->d1_support = false; | 2375 | dev->d1_support = false; |
@@ -3165,6 +3346,23 @@ int __weak pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr) | |||
3165 | #endif | 3346 | #endif |
3166 | } | 3347 | } |
3167 | 3348 | ||
3349 | /** | ||
3350 | * pci_unmap_iospace - Unmap the memory mapped I/O space | ||
3351 | * @res: resource to be unmapped | ||
3352 | * | ||
3353 | * Unmap the CPU virtual address @res from virtual address space. | ||
3354 | * Only architectures that have memory mapped IO functions defined | ||
3355 | * (and the PCI_IOBASE value defined) should call this function. | ||
3356 | */ | ||
3357 | void pci_unmap_iospace(struct resource *res) | ||
3358 | { | ||
3359 | #if defined(PCI_IOBASE) && defined(CONFIG_MMU) | ||
3360 | unsigned long vaddr = (unsigned long)PCI_IOBASE + res->start; | ||
3361 | |||
3362 | unmap_kernel_range(vaddr, resource_size(res)); | ||
3363 | #endif | ||
3364 | } | ||
3365 | |||
3168 | static void __pci_set_master(struct pci_dev *dev, bool enable) | 3366 | static void __pci_set_master(struct pci_dev *dev, bool enable) |
3169 | { | 3367 | { |
3170 | u16 old_cmd, cmd; | 3368 | u16 old_cmd, cmd; |
@@ -4755,6 +4953,7 @@ static DEFINE_SPINLOCK(resource_alignment_lock); | |||
4755 | static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev) | 4953 | static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev) |
4756 | { | 4954 | { |
4757 | int seg, bus, slot, func, align_order, count; | 4955 | int seg, bus, slot, func, align_order, count; |
4956 | unsigned short vendor, device, subsystem_vendor, subsystem_device; | ||
4758 | resource_size_t align = 0; | 4957 | resource_size_t align = 0; |
4759 | char *p; | 4958 | char *p; |
4760 | 4959 | ||
@@ -4768,28 +4967,55 @@ static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev) | |||
4768 | } else { | 4967 | } else { |
4769 | align_order = -1; | 4968 | align_order = -1; |
4770 | } | 4969 | } |
4771 | if (sscanf(p, "%x:%x:%x.%x%n", | 4970 | if (strncmp(p, "pci:", 4) == 0) { |
4772 | &seg, &bus, &slot, &func, &count) != 4) { | 4971 | /* PCI vendor/device (subvendor/subdevice) ids are specified */ |
4773 | seg = 0; | 4972 | p += 4; |
4774 | if (sscanf(p, "%x:%x.%x%n", | 4973 | if (sscanf(p, "%hx:%hx:%hx:%hx%n", |
4775 | &bus, &slot, &func, &count) != 3) { | 4974 | &vendor, &device, &subsystem_vendor, &subsystem_device, &count) != 4) { |
4776 | /* Invalid format */ | 4975 | if (sscanf(p, "%hx:%hx%n", &vendor, &device, &count) != 2) { |
4777 | printk(KERN_ERR "PCI: Can't parse resource_alignment parameter: %s\n", | 4976 | printk(KERN_ERR "PCI: Can't parse resource_alignment parameter: pci:%s\n", |
4778 | p); | 4977 | p); |
4978 | break; | ||
4979 | } | ||
4980 | subsystem_vendor = subsystem_device = 0; | ||
4981 | } | ||
4982 | p += count; | ||
4983 | if ((!vendor || (vendor == dev->vendor)) && | ||
4984 | (!device || (device == dev->device)) && | ||
4985 | (!subsystem_vendor || (subsystem_vendor == dev->subsystem_vendor)) && | ||
4986 | (!subsystem_device || (subsystem_device == dev->subsystem_device))) { | ||
4987 | if (align_order == -1) | ||
4988 | align = PAGE_SIZE; | ||
4989 | else | ||
4990 | align = 1 << align_order; | ||
4991 | /* Found */ | ||
4779 | break; | 4992 | break; |
4780 | } | 4993 | } |
4781 | } | 4994 | } |
4782 | p += count; | 4995 | else { |
4783 | if (seg == pci_domain_nr(dev->bus) && | 4996 | if (sscanf(p, "%x:%x:%x.%x%n", |
4784 | bus == dev->bus->number && | 4997 | &seg, &bus, &slot, &func, &count) != 4) { |
4785 | slot == PCI_SLOT(dev->devfn) && | 4998 | seg = 0; |
4786 | func == PCI_FUNC(dev->devfn)) { | 4999 | if (sscanf(p, "%x:%x.%x%n", |
4787 | if (align_order == -1) | 5000 | &bus, &slot, &func, &count) != 3) { |
4788 | align = PAGE_SIZE; | 5001 | /* Invalid format */ |
4789 | else | 5002 | printk(KERN_ERR "PCI: Can't parse resource_alignment parameter: %s\n", |
4790 | align = 1 << align_order; | 5003 | p); |
4791 | /* Found */ | 5004 | break; |
4792 | break; | 5005 | } |
5006 | } | ||
5007 | p += count; | ||
5008 | if (seg == pci_domain_nr(dev->bus) && | ||
5009 | bus == dev->bus->number && | ||
5010 | slot == PCI_SLOT(dev->devfn) && | ||
5011 | func == PCI_FUNC(dev->devfn)) { | ||
5012 | if (align_order == -1) | ||
5013 | align = PAGE_SIZE; | ||
5014 | else | ||
5015 | align = 1 << align_order; | ||
5016 | /* Found */ | ||
5017 | break; | ||
5018 | } | ||
4793 | } | 5019 | } |
4794 | if (*p != ';' && *p != ',') { | 5020 | if (*p != ';' && *p != ',') { |
4795 | /* End of param or invalid format */ | 5021 | /* End of param or invalid format */ |
@@ -4897,7 +5123,7 @@ static ssize_t pci_resource_alignment_store(struct bus_type *bus, | |||
4897 | return pci_set_resource_alignment_param(buf, count); | 5123 | return pci_set_resource_alignment_param(buf, count); |
4898 | } | 5124 | } |
4899 | 5125 | ||
4900 | BUS_ATTR(resource_alignment, 0644, pci_resource_alignment_show, | 5126 | static BUS_ATTR(resource_alignment, 0644, pci_resource_alignment_show, |
4901 | pci_resource_alignment_store); | 5127 | pci_resource_alignment_store); |
4902 | 5128 | ||
4903 | static int __init pci_resource_alignment_sysfs_init(void) | 5129 | static int __init pci_resource_alignment_sysfs_init(void) |
@@ -4923,7 +5149,7 @@ int pci_get_new_domain_nr(void) | |||
4923 | } | 5149 | } |
4924 | 5150 | ||
4925 | #ifdef CONFIG_PCI_DOMAINS_GENERIC | 5151 | #ifdef CONFIG_PCI_DOMAINS_GENERIC |
4926 | void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent) | 5152 | static int of_pci_bus_find_domain_nr(struct device *parent) |
4927 | { | 5153 | { |
4928 | static int use_dt_domains = -1; | 5154 | static int use_dt_domains = -1; |
4929 | int domain = -1; | 5155 | int domain = -1; |
@@ -4967,7 +5193,13 @@ void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent) | |||
4967 | domain = -1; | 5193 | domain = -1; |
4968 | } | 5194 | } |
4969 | 5195 | ||
4970 | bus->domain_nr = domain; | 5196 | return domain; |
5197 | } | ||
5198 | |||
5199 | int pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent) | ||
5200 | { | ||
5201 | return acpi_disabled ? of_pci_bus_find_domain_nr(parent) : | ||
5202 | acpi_pci_bus_find_domain_nr(bus); | ||
4971 | } | 5203 | } |
4972 | #endif | 5204 | #endif |
4973 | #endif | 5205 | #endif |
@@ -5021,6 +5253,11 @@ static int __init pci_setup(char *str) | |||
5021 | pci_hotplug_io_size = memparse(str + 9, &str); | 5253 | pci_hotplug_io_size = memparse(str + 9, &str); |
5022 | } else if (!strncmp(str, "hpmemsize=", 10)) { | 5254 | } else if (!strncmp(str, "hpmemsize=", 10)) { |
5023 | pci_hotplug_mem_size = memparse(str + 10, &str); | 5255 | pci_hotplug_mem_size = memparse(str + 10, &str); |
5256 | } else if (!strncmp(str, "hpbussize=", 10)) { | ||
5257 | pci_hotplug_bus_size = | ||
5258 | simple_strtoul(str + 10, &str, 0); | ||
5259 | if (pci_hotplug_bus_size > 0xff) | ||
5260 | pci_hotplug_bus_size = DEFAULT_HOTPLUG_BUS_SIZE; | ||
5024 | } else if (!strncmp(str, "pcie_bus_tune_off", 17)) { | 5261 | } else if (!strncmp(str, "pcie_bus_tune_off", 17)) { |
5025 | pcie_bus_config = PCIE_BUS_TUNE_OFF; | 5262 | pcie_bus_config = PCIE_BUS_TUNE_OFF; |
5026 | } else if (!strncmp(str, "pcie_bus_safe", 13)) { | 5263 | } else if (!strncmp(str, "pcie_bus_safe", 13)) { |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index a814bbb80fcb..9730c474b016 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -82,6 +82,8 @@ void pci_pm_init(struct pci_dev *dev); | |||
82 | void pci_ea_init(struct pci_dev *dev); | 82 | void pci_ea_init(struct pci_dev *dev); |
83 | void pci_allocate_cap_save_buffers(struct pci_dev *dev); | 83 | void pci_allocate_cap_save_buffers(struct pci_dev *dev); |
84 | void pci_free_cap_save_buffers(struct pci_dev *dev); | 84 | void pci_free_cap_save_buffers(struct pci_dev *dev); |
85 | void pci_bridge_d3_device_changed(struct pci_dev *dev); | ||
86 | void pci_bridge_d3_device_removed(struct pci_dev *dev); | ||
85 | 87 | ||
86 | static inline void pci_wakeup_event(struct pci_dev *dev) | 88 | static inline void pci_wakeup_event(struct pci_dev *dev) |
87 | { | 89 | { |
@@ -94,6 +96,15 @@ static inline bool pci_has_subordinate(struct pci_dev *pci_dev) | |||
94 | return !!(pci_dev->subordinate); | 96 | return !!(pci_dev->subordinate); |
95 | } | 97 | } |
96 | 98 | ||
99 | static inline bool pci_power_manageable(struct pci_dev *pci_dev) | ||
100 | { | ||
101 | /* | ||
102 | * Currently we allow normal PCI devices and PCI bridges transition | ||
103 | * into D3 if their bridge_d3 is set. | ||
104 | */ | ||
105 | return !pci_has_subordinate(pci_dev) || pci_dev->bridge_d3; | ||
106 | } | ||
107 | |||
97 | struct pci_vpd_ops { | 108 | struct pci_vpd_ops { |
98 | ssize_t (*read)(struct pci_dev *dev, loff_t pos, size_t count, void *buf); | 109 | ssize_t (*read)(struct pci_dev *dev, loff_t pos, size_t count, void *buf); |
99 | ssize_t (*write)(struct pci_dev *dev, loff_t pos, size_t count, const void *buf); | 110 | ssize_t (*write)(struct pci_dev *dev, loff_t pos, size_t count, const void *buf); |
diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig index 22ca6412bd15..7fcea75afa4c 100644 --- a/drivers/pci/pcie/Kconfig +++ b/drivers/pci/pcie/Kconfig | |||
@@ -83,7 +83,7 @@ config PCIE_PME | |||
83 | depends on PCIEPORTBUS && PM | 83 | depends on PCIEPORTBUS && PM |
84 | 84 | ||
85 | config PCIE_DPC | 85 | config PCIE_DPC |
86 | tristate "PCIe Downstream Port Containment support" | 86 | bool "PCIe Downstream Port Containment support" |
87 | depends on PCIEPORTBUS | 87 | depends on PCIEPORTBUS |
88 | default n | 88 | default n |
89 | help | 89 | help |
@@ -92,6 +92,3 @@ config PCIE_DPC | |||
92 | will be handled by the DPC driver. If your system doesn't | 92 | will be handled by the DPC driver. If your system doesn't |
93 | have this capability or you do not want to use this feature, | 93 | have this capability or you do not want to use this feature, |
94 | it is safe to answer N. | 94 | it is safe to answer N. |
95 | |||
96 | To compile this driver as a module, choose M here: the module | ||
97 | will be called pcie-dpc. | ||
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 2dfe7fdb77e7..0ec649d961d7 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
@@ -139,7 +139,7 @@ static void pcie_set_clkpm_nocheck(struct pcie_link_state *link, int enable) | |||
139 | static void pcie_set_clkpm(struct pcie_link_state *link, int enable) | 139 | static void pcie_set_clkpm(struct pcie_link_state *link, int enable) |
140 | { | 140 | { |
141 | /* Don't enable Clock PM if the link is not Clock PM capable */ | 141 | /* Don't enable Clock PM if the link is not Clock PM capable */ |
142 | if (!link->clkpm_capable && enable) | 142 | if (!link->clkpm_capable) |
143 | enable = 0; | 143 | enable = 0; |
144 | /* Need nothing if the specified equals to current state */ | 144 | /* Need nothing if the specified equals to current state */ |
145 | if (link->clkpm_enabled == enable) | 145 | if (link->clkpm_enabled == enable) |
diff --git a/drivers/pci/pcie/pcie-dpc.c b/drivers/pci/pcie/pcie-dpc.c index ab552f1bc08f..250f87861786 100644 --- a/drivers/pci/pcie/pcie-dpc.c +++ b/drivers/pci/pcie/pcie-dpc.c | |||
@@ -15,8 +15,8 @@ | |||
15 | 15 | ||
16 | struct dpc_dev { | 16 | struct dpc_dev { |
17 | struct pcie_device *dev; | 17 | struct pcie_device *dev; |
18 | struct work_struct work; | 18 | struct work_struct work; |
19 | int cap_pos; | 19 | int cap_pos; |
20 | }; | 20 | }; |
21 | 21 | ||
22 | static void dpc_wait_link_inactive(struct pci_dev *pdev) | 22 | static void dpc_wait_link_inactive(struct pci_dev *pdev) |
@@ -89,7 +89,7 @@ static int dpc_probe(struct pcie_device *dev) | |||
89 | int status; | 89 | int status; |
90 | u16 ctl, cap; | 90 | u16 ctl, cap; |
91 | 91 | ||
92 | dpc = kzalloc(sizeof(*dpc), GFP_KERNEL); | 92 | dpc = devm_kzalloc(&dev->device, sizeof(*dpc), GFP_KERNEL); |
93 | if (!dpc) | 93 | if (!dpc) |
94 | return -ENOMEM; | 94 | return -ENOMEM; |
95 | 95 | ||
@@ -98,11 +98,12 @@ static int dpc_probe(struct pcie_device *dev) | |||
98 | INIT_WORK(&dpc->work, interrupt_event_handler); | 98 | INIT_WORK(&dpc->work, interrupt_event_handler); |
99 | set_service_data(dev, dpc); | 99 | set_service_data(dev, dpc); |
100 | 100 | ||
101 | status = request_irq(dev->irq, dpc_irq, IRQF_SHARED, "pcie-dpc", dpc); | 101 | status = devm_request_irq(&dev->device, dev->irq, dpc_irq, IRQF_SHARED, |
102 | "pcie-dpc", dpc); | ||
102 | if (status) { | 103 | if (status) { |
103 | dev_warn(&dev->device, "request IRQ%d failed: %d\n", dev->irq, | 104 | dev_warn(&dev->device, "request IRQ%d failed: %d\n", dev->irq, |
104 | status); | 105 | status); |
105 | goto out; | 106 | return status; |
106 | } | 107 | } |
107 | 108 | ||
108 | pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CAP, &cap); | 109 | pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CAP, &cap); |
@@ -117,9 +118,6 @@ static int dpc_probe(struct pcie_device *dev) | |||
117 | FLAG(cap, PCI_EXP_DPC_CAP_SW_TRIGGER), (cap >> 8) & 0xf, | 118 | FLAG(cap, PCI_EXP_DPC_CAP_SW_TRIGGER), (cap >> 8) & 0xf, |
118 | FLAG(cap, PCI_EXP_DPC_CAP_DL_ACTIVE)); | 119 | FLAG(cap, PCI_EXP_DPC_CAP_DL_ACTIVE)); |
119 | return status; | 120 | return status; |
120 | out: | ||
121 | kfree(dpc); | ||
122 | return status; | ||
123 | } | 121 | } |
124 | 122 | ||
125 | static void dpc_remove(struct pcie_device *dev) | 123 | static void dpc_remove(struct pcie_device *dev) |
@@ -131,14 +129,11 @@ static void dpc_remove(struct pcie_device *dev) | |||
131 | pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CTL, &ctl); | 129 | pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CTL, &ctl); |
132 | ctl &= ~(PCI_EXP_DPC_CTL_EN_NONFATAL | PCI_EXP_DPC_CTL_INT_EN); | 130 | ctl &= ~(PCI_EXP_DPC_CTL_EN_NONFATAL | PCI_EXP_DPC_CTL_INT_EN); |
133 | pci_write_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CTL, ctl); | 131 | pci_write_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CTL, ctl); |
134 | |||
135 | free_irq(dev->irq, dpc); | ||
136 | kfree(dpc); | ||
137 | } | 132 | } |
138 | 133 | ||
139 | static struct pcie_port_service_driver dpcdriver = { | 134 | static struct pcie_port_service_driver dpcdriver = { |
140 | .name = "dpc", | 135 | .name = "dpc", |
141 | .port_type = PCI_EXP_TYPE_ROOT_PORT | PCI_EXP_TYPE_DOWNSTREAM, | 136 | .port_type = PCIE_ANY_PORT, |
142 | .service = PCIE_PORT_SERVICE_DPC, | 137 | .service = PCIE_PORT_SERVICE_DPC, |
143 | .probe = dpc_probe, | 138 | .probe = dpc_probe, |
144 | .remove = dpc_remove, | 139 | .remove = dpc_remove, |
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 32d4d0a3d20e..e9270b4026f3 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
13 | #include <linux/pm.h> | 13 | #include <linux/pm.h> |
14 | #include <linux/pm_runtime.h> | ||
14 | #include <linux/string.h> | 15 | #include <linux/string.h> |
15 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
16 | #include <linux/pcieport_if.h> | 17 | #include <linux/pcieport_if.h> |
@@ -342,6 +343,8 @@ static int pcie_device_init(struct pci_dev *pdev, int service, int irq) | |||
342 | return retval; | 343 | return retval; |
343 | } | 344 | } |
344 | 345 | ||
346 | pm_runtime_no_callbacks(device); | ||
347 | |||
345 | return 0; | 348 | return 0; |
346 | } | 349 | } |
347 | 350 | ||
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index be35da2e105e..70d7ad8c6d17 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -93,6 +93,26 @@ static int pcie_port_resume_noirq(struct device *dev) | |||
93 | return 0; | 93 | return 0; |
94 | } | 94 | } |
95 | 95 | ||
96 | static int pcie_port_runtime_suspend(struct device *dev) | ||
97 | { | ||
98 | return to_pci_dev(dev)->bridge_d3 ? 0 : -EBUSY; | ||
99 | } | ||
100 | |||
101 | static int pcie_port_runtime_resume(struct device *dev) | ||
102 | { | ||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | static int pcie_port_runtime_idle(struct device *dev) | ||
107 | { | ||
108 | /* | ||
109 | * Assume the PCI core has set bridge_d3 whenever it thinks the port | ||
110 | * should be good to go to D3. Everything else, including moving | ||
111 | * the port to D3, is handled by the PCI core. | ||
112 | */ | ||
113 | return to_pci_dev(dev)->bridge_d3 ? 0 : -EBUSY; | ||
114 | } | ||
115 | |||
96 | static const struct dev_pm_ops pcie_portdrv_pm_ops = { | 116 | static const struct dev_pm_ops pcie_portdrv_pm_ops = { |
97 | .suspend = pcie_port_device_suspend, | 117 | .suspend = pcie_port_device_suspend, |
98 | .resume = pcie_port_device_resume, | 118 | .resume = pcie_port_device_resume, |
@@ -101,6 +121,9 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = { | |||
101 | .poweroff = pcie_port_device_suspend, | 121 | .poweroff = pcie_port_device_suspend, |
102 | .restore = pcie_port_device_resume, | 122 | .restore = pcie_port_device_resume, |
103 | .resume_noirq = pcie_port_resume_noirq, | 123 | .resume_noirq = pcie_port_resume_noirq, |
124 | .runtime_suspend = pcie_port_runtime_suspend, | ||
125 | .runtime_resume = pcie_port_runtime_resume, | ||
126 | .runtime_idle = pcie_port_runtime_idle, | ||
104 | }; | 127 | }; |
105 | 128 | ||
106 | #define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops) | 129 | #define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops) |
@@ -134,16 +157,39 @@ static int pcie_portdrv_probe(struct pci_dev *dev, | |||
134 | return status; | 157 | return status; |
135 | 158 | ||
136 | pci_save_state(dev); | 159 | pci_save_state(dev); |
160 | |||
137 | /* | 161 | /* |
138 | * D3cold may not work properly on some PCIe port, so disable | 162 | * Prevent runtime PM if the port is advertising support for PCIe |
139 | * it by default. | 163 | * hotplug. Otherwise the BIOS hotplug SMI code might not be able |
164 | * to enumerate devices behind this port properly (the port is | ||
165 | * powered down preventing all config space accesses to the | ||
166 | * subordinate devices). We can't be sure for native PCIe hotplug | ||
167 | * either so prevent that as well. | ||
140 | */ | 168 | */ |
141 | dev->d3cold_allowed = false; | 169 | if (!dev->is_hotplug_bridge) { |
170 | /* | ||
171 | * Keep the port resumed 100ms to make sure things like | ||
172 | * config space accesses from userspace (lspci) will not | ||
173 | * cause the port to repeatedly suspend and resume. | ||
174 | */ | ||
175 | pm_runtime_set_autosuspend_delay(&dev->dev, 100); | ||
176 | pm_runtime_use_autosuspend(&dev->dev); | ||
177 | pm_runtime_mark_last_busy(&dev->dev); | ||
178 | pm_runtime_put_autosuspend(&dev->dev); | ||
179 | pm_runtime_allow(&dev->dev); | ||
180 | } | ||
181 | |||
142 | return 0; | 182 | return 0; |
143 | } | 183 | } |
144 | 184 | ||
145 | static void pcie_portdrv_remove(struct pci_dev *dev) | 185 | static void pcie_portdrv_remove(struct pci_dev *dev) |
146 | { | 186 | { |
187 | if (!dev->is_hotplug_bridge) { | ||
188 | pm_runtime_forbid(&dev->dev); | ||
189 | pm_runtime_get_noresume(&dev->dev); | ||
190 | pm_runtime_dont_use_autosuspend(&dev->dev); | ||
191 | } | ||
192 | |||
147 | pcie_port_device_remove(dev); | 193 | pcie_port_device_remove(dev); |
148 | } | 194 | } |
149 | 195 | ||
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 8e3ef720997d..93f280df3428 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/aer.h> | 16 | #include <linux/aer.h> |
17 | #include <linux/acpi.h> | 17 | #include <linux/acpi.h> |
18 | #include <linux/irqdomain.h> | 18 | #include <linux/irqdomain.h> |
19 | #include <linux/pm_runtime.h> | ||
19 | #include "pci.h" | 20 | #include "pci.h" |
20 | 21 | ||
21 | #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ | 22 | #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ |
@@ -832,6 +833,12 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass) | |||
832 | u8 primary, secondary, subordinate; | 833 | u8 primary, secondary, subordinate; |
833 | int broken = 0; | 834 | int broken = 0; |
834 | 835 | ||
836 | /* | ||
837 | * Make sure the bridge is powered on to be able to access config | ||
838 | * space of devices below it. | ||
839 | */ | ||
840 | pm_runtime_get_sync(&dev->dev); | ||
841 | |||
835 | pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); | 842 | pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); |
836 | primary = buses & 0xFF; | 843 | primary = buses & 0xFF; |
837 | secondary = (buses >> 8) & 0xFF; | 844 | secondary = (buses >> 8) & 0xFF; |
@@ -1012,6 +1019,8 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass) | |||
1012 | out: | 1019 | out: |
1013 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bctl); | 1020 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bctl); |
1014 | 1021 | ||
1022 | pm_runtime_put(&dev->dev); | ||
1023 | |||
1015 | return max; | 1024 | return max; |
1016 | } | 1025 | } |
1017 | EXPORT_SYMBOL(pci_scan_bridge); | 1026 | EXPORT_SYMBOL(pci_scan_bridge); |
@@ -2077,6 +2086,15 @@ unsigned int pci_scan_child_bus(struct pci_bus *bus) | |||
2077 | } | 2086 | } |
2078 | 2087 | ||
2079 | /* | 2088 | /* |
2089 | * Make sure a hotplug bridge has at least the minimum requested | ||
2090 | * number of buses. | ||
2091 | */ | ||
2092 | if (bus->self && bus->self->is_hotplug_bridge && pci_hotplug_bus_size) { | ||
2093 | if (max - bus->busn_res.start < pci_hotplug_bus_size - 1) | ||
2094 | max = bus->busn_res.start + pci_hotplug_bus_size - 1; | ||
2095 | } | ||
2096 | |||
2097 | /* | ||
2080 | * We've scanned the bus and so we know all about what's on | 2098 | * We've scanned the bus and so we know all about what's on |
2081 | * the other side of any bridges that may be on this bus plus | 2099 | * the other side of any bridges that may be on this bus plus |
2082 | * any devices. | 2100 | * any devices. |
@@ -2127,7 +2145,9 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | |||
2127 | b->sysdata = sysdata; | 2145 | b->sysdata = sysdata; |
2128 | b->ops = ops; | 2146 | b->ops = ops; |
2129 | b->number = b->busn_res.start = bus; | 2147 | b->number = b->busn_res.start = bus; |
2130 | pci_bus_assign_domain_nr(b, parent); | 2148 | #ifdef CONFIG_PCI_DOMAINS_GENERIC |
2149 | b->domain_nr = pci_bus_find_domain_nr(b, parent); | ||
2150 | #endif | ||
2131 | b2 = pci_find_bus(pci_domain_nr(b), bus); | 2151 | b2 = pci_find_bus(pci_domain_nr(b), bus); |
2132 | if (b2) { | 2152 | if (b2) { |
2133 | /* If we already got to this bus through a different bridge, ignore it */ | 2153 | /* If we already got to this bus through a different bridge, ignore it */ |
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 3f155e78513f..2408abe4ee8c 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c | |||
@@ -231,7 +231,7 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma) | |||
231 | { | 231 | { |
232 | struct pci_dev *dev = PDE_DATA(file_inode(file)); | 232 | struct pci_dev *dev = PDE_DATA(file_inode(file)); |
233 | struct pci_filp_private *fpriv = file->private_data; | 233 | struct pci_filp_private *fpriv = file->private_data; |
234 | int i, ret; | 234 | int i, ret, write_combine; |
235 | 235 | ||
236 | if (!capable(CAP_SYS_RAWIO)) | 236 | if (!capable(CAP_SYS_RAWIO)) |
237 | return -EPERM; | 237 | return -EPERM; |
@@ -245,9 +245,12 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma) | |||
245 | if (i >= PCI_ROM_RESOURCE) | 245 | if (i >= PCI_ROM_RESOURCE) |
246 | return -ENODEV; | 246 | return -ENODEV; |
247 | 247 | ||
248 | if (fpriv->mmap_state == pci_mmap_mem) | ||
249 | write_combine = fpriv->write_combine; | ||
250 | else | ||
251 | write_combine = 0; | ||
248 | ret = pci_mmap_page_range(dev, vma, | 252 | ret = pci_mmap_page_range(dev, vma, |
249 | fpriv->mmap_state, | 253 | fpriv->mmap_state, write_combine); |
250 | fpriv->write_combine); | ||
251 | if (ret < 0) | 254 | if (ret < 0) |
252 | return ret; | 255 | return ret; |
253 | 256 | ||
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index ee72ebe18f4b..37ff0158e45f 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -3189,13 +3189,15 @@ static void quirk_no_bus_reset(struct pci_dev *dev) | |||
3189 | } | 3189 | } |
3190 | 3190 | ||
3191 | /* | 3191 | /* |
3192 | * Atheros AR93xx chips do not behave after a bus reset. The device will | 3192 | * Some Atheros AR9xxx and QCA988x chips do not behave after a bus reset. |
3193 | * throw a Link Down error on AER-capable systems and regardless of AER, | 3193 | * The device will throw a Link Down error on AER-capable systems and |
3194 | * config space of the device is never accessible again and typically | 3194 | * regardless of AER, config space of the device is never accessible again |
3195 | * causes the system to hang or reset when access is attempted. | 3195 | * and typically causes the system to hang or reset when access is attempted. |
3196 | * http://www.spinics.net/lists/linux-pci/msg34797.html | 3196 | * http://www.spinics.net/lists/linux-pci/msg34797.html |
3197 | */ | 3197 | */ |
3198 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0030, quirk_no_bus_reset); | 3198 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0030, quirk_no_bus_reset); |
3199 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0032, quirk_no_bus_reset); | ||
3200 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x003c, quirk_no_bus_reset); | ||
3199 | 3201 | ||
3200 | static void quirk_no_pm_reset(struct pci_dev *dev) | 3202 | static void quirk_no_pm_reset(struct pci_dev *dev) |
3201 | { | 3203 | { |
@@ -3711,6 +3713,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9172, | |||
3711 | /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c59 */ | 3713 | /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c59 */ |
3712 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x917a, | 3714 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x917a, |
3713 | quirk_dma_func1_alias); | 3715 | quirk_dma_func1_alias); |
3716 | /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c78 */ | ||
3717 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9182, | ||
3718 | quirk_dma_func1_alias); | ||
3714 | /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c46 */ | 3719 | /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c46 */ |
3715 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x91a0, | 3720 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x91a0, |
3716 | quirk_dma_func1_alias); | 3721 | quirk_dma_func1_alias); |
@@ -3747,6 +3752,9 @@ static const struct pci_device_id fixed_dma_alias_tbl[] = { | |||
3747 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x0285, | 3752 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x0285, |
3748 | PCI_VENDOR_ID_ADAPTEC2, 0x02bb), /* Adaptec 3405 */ | 3753 | PCI_VENDOR_ID_ADAPTEC2, 0x02bb), /* Adaptec 3405 */ |
3749 | .driver_data = PCI_DEVFN(1, 0) }, | 3754 | .driver_data = PCI_DEVFN(1, 0) }, |
3755 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x0285, | ||
3756 | PCI_VENDOR_ID_ADAPTEC2, 0x02bc), /* Adaptec 3805 */ | ||
3757 | .driver_data = PCI_DEVFN(1, 0) }, | ||
3750 | { 0 } | 3758 | { 0 } |
3751 | }; | 3759 | }; |
3752 | 3760 | ||
@@ -4087,6 +4095,7 @@ static const struct pci_dev_acs_enabled { | |||
4087 | { PCI_VENDOR_ID_AMD, 0x7809, pci_quirk_amd_sb_acs }, | 4095 | { PCI_VENDOR_ID_AMD, 0x7809, pci_quirk_amd_sb_acs }, |
4088 | { PCI_VENDOR_ID_SOLARFLARE, 0x0903, pci_quirk_mf_endpoint_acs }, | 4096 | { PCI_VENDOR_ID_SOLARFLARE, 0x0903, pci_quirk_mf_endpoint_acs }, |
4089 | { PCI_VENDOR_ID_SOLARFLARE, 0x0923, pci_quirk_mf_endpoint_acs }, | 4097 | { PCI_VENDOR_ID_SOLARFLARE, 0x0923, pci_quirk_mf_endpoint_acs }, |
4098 | { PCI_VENDOR_ID_SOLARFLARE, 0x0A03, pci_quirk_mf_endpoint_acs }, | ||
4090 | { PCI_VENDOR_ID_INTEL, 0x10C6, pci_quirk_mf_endpoint_acs }, | 4099 | { PCI_VENDOR_ID_INTEL, 0x10C6, pci_quirk_mf_endpoint_acs }, |
4091 | { PCI_VENDOR_ID_INTEL, 0x10DB, pci_quirk_mf_endpoint_acs }, | 4100 | { PCI_VENDOR_ID_INTEL, 0x10DB, pci_quirk_mf_endpoint_acs }, |
4092 | { PCI_VENDOR_ID_INTEL, 0x10DD, pci_quirk_mf_endpoint_acs }, | 4101 | { PCI_VENDOR_ID_INTEL, 0x10DD, pci_quirk_mf_endpoint_acs }, |
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 8982026637d5..d1ef7acf6930 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c | |||
@@ -96,6 +96,8 @@ static void pci_remove_bus_device(struct pci_dev *dev) | |||
96 | dev->subordinate = NULL; | 96 | dev->subordinate = NULL; |
97 | } | 97 | } |
98 | 98 | ||
99 | pci_bridge_d3_device_removed(dev); | ||
100 | |||
99 | pci_destroy_dev(dev); | 101 | pci_destroy_dev(dev); |
100 | } | 102 | } |
101 | 103 | ||
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index d678c46e5f03..c74059e10a6d 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -1428,6 +1428,74 @@ void pci_bus_assign_resources(const struct pci_bus *bus) | |||
1428 | } | 1428 | } |
1429 | EXPORT_SYMBOL(pci_bus_assign_resources); | 1429 | EXPORT_SYMBOL(pci_bus_assign_resources); |
1430 | 1430 | ||
1431 | static void pci_claim_device_resources(struct pci_dev *dev) | ||
1432 | { | ||
1433 | int i; | ||
1434 | |||
1435 | for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) { | ||
1436 | struct resource *r = &dev->resource[i]; | ||
1437 | |||
1438 | if (!r->flags || r->parent) | ||
1439 | continue; | ||
1440 | |||
1441 | pci_claim_resource(dev, i); | ||
1442 | } | ||
1443 | } | ||
1444 | |||
1445 | static void pci_claim_bridge_resources(struct pci_dev *dev) | ||
1446 | { | ||
1447 | int i; | ||
1448 | |||
1449 | for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) { | ||
1450 | struct resource *r = &dev->resource[i]; | ||
1451 | |||
1452 | if (!r->flags || r->parent) | ||
1453 | continue; | ||
1454 | |||
1455 | pci_claim_bridge_resource(dev, i); | ||
1456 | } | ||
1457 | } | ||
1458 | |||
1459 | static void pci_bus_allocate_dev_resources(struct pci_bus *b) | ||
1460 | { | ||
1461 | struct pci_dev *dev; | ||
1462 | struct pci_bus *child; | ||
1463 | |||
1464 | list_for_each_entry(dev, &b->devices, bus_list) { | ||
1465 | pci_claim_device_resources(dev); | ||
1466 | |||
1467 | child = dev->subordinate; | ||
1468 | if (child) | ||
1469 | pci_bus_allocate_dev_resources(child); | ||
1470 | } | ||
1471 | } | ||
1472 | |||
1473 | static void pci_bus_allocate_resources(struct pci_bus *b) | ||
1474 | { | ||
1475 | struct pci_bus *child; | ||
1476 | |||
1477 | /* | ||
1478 | * Carry out a depth-first search on the PCI bus | ||
1479 | * tree to allocate bridge apertures. Read the | ||
1480 | * programmed bridge bases and recursively claim | ||
1481 | * the respective bridge resources. | ||
1482 | */ | ||
1483 | if (b->self) { | ||
1484 | pci_read_bridge_bases(b); | ||
1485 | pci_claim_bridge_resources(b->self); | ||
1486 | } | ||
1487 | |||
1488 | list_for_each_entry(child, &b->children, node) | ||
1489 | pci_bus_allocate_resources(child); | ||
1490 | } | ||
1491 | |||
1492 | void pci_bus_claim_resources(struct pci_bus *b) | ||
1493 | { | ||
1494 | pci_bus_allocate_resources(b); | ||
1495 | pci_bus_allocate_dev_resources(b); | ||
1496 | } | ||
1497 | EXPORT_SYMBOL(pci_bus_claim_resources); | ||
1498 | |||
1431 | static void __pci_bridge_assign_resources(const struct pci_dev *bridge, | 1499 | static void __pci_bridge_assign_resources(const struct pci_dev *bridge, |
1432 | struct list_head *add_head, | 1500 | struct list_head *add_head, |
1433 | struct list_head *fail_head) | 1501 | struct list_head *fail_head) |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index adf61b43eb70..734a0428ef0e 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -4854,20 +4854,17 @@ static int | |||
4854 | lpfc_enable_pci_dev(struct lpfc_hba *phba) | 4854 | lpfc_enable_pci_dev(struct lpfc_hba *phba) |
4855 | { | 4855 | { |
4856 | struct pci_dev *pdev; | 4856 | struct pci_dev *pdev; |
4857 | int bars = 0; | ||
4858 | 4857 | ||
4859 | /* Obtain PCI device reference */ | 4858 | /* Obtain PCI device reference */ |
4860 | if (!phba->pcidev) | 4859 | if (!phba->pcidev) |
4861 | goto out_error; | 4860 | goto out_error; |
4862 | else | 4861 | else |
4863 | pdev = phba->pcidev; | 4862 | pdev = phba->pcidev; |
4864 | /* Select PCI BARs */ | ||
4865 | bars = pci_select_bars(pdev, IORESOURCE_MEM); | ||
4866 | /* Enable PCI device */ | 4863 | /* Enable PCI device */ |
4867 | if (pci_enable_device_mem(pdev)) | 4864 | if (pci_enable_device_mem(pdev)) |
4868 | goto out_error; | 4865 | goto out_error; |
4869 | /* Request PCI resource for the device */ | 4866 | /* Request PCI resource for the device */ |
4870 | if (pci_request_selected_regions(pdev, bars, LPFC_DRIVER_NAME)) | 4867 | if (pci_request_mem_regions(pdev, LPFC_DRIVER_NAME)) |
4871 | goto out_disable_device; | 4868 | goto out_disable_device; |
4872 | /* Set up device as PCI master and save state for EEH */ | 4869 | /* Set up device as PCI master and save state for EEH */ |
4873 | pci_set_master(pdev); | 4870 | pci_set_master(pdev); |
@@ -4884,7 +4881,7 @@ out_disable_device: | |||
4884 | pci_disable_device(pdev); | 4881 | pci_disable_device(pdev); |
4885 | out_error: | 4882 | out_error: |
4886 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 4883 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
4887 | "1401 Failed to enable pci device, bars:x%x\n", bars); | 4884 | "1401 Failed to enable pci device\n"); |
4888 | return -ENODEV; | 4885 | return -ENODEV; |
4889 | } | 4886 | } |
4890 | 4887 | ||
@@ -4899,17 +4896,14 @@ static void | |||
4899 | lpfc_disable_pci_dev(struct lpfc_hba *phba) | 4896 | lpfc_disable_pci_dev(struct lpfc_hba *phba) |
4900 | { | 4897 | { |
4901 | struct pci_dev *pdev; | 4898 | struct pci_dev *pdev; |
4902 | int bars; | ||
4903 | 4899 | ||
4904 | /* Obtain PCI device reference */ | 4900 | /* Obtain PCI device reference */ |
4905 | if (!phba->pcidev) | 4901 | if (!phba->pcidev) |
4906 | return; | 4902 | return; |
4907 | else | 4903 | else |
4908 | pdev = phba->pcidev; | 4904 | pdev = phba->pcidev; |
4909 | /* Select PCI BARs */ | ||
4910 | bars = pci_select_bars(pdev, IORESOURCE_MEM); | ||
4911 | /* Release PCI resource and disable PCI device */ | 4905 | /* Release PCI resource and disable PCI device */ |
4912 | pci_release_selected_regions(pdev, bars); | 4906 | pci_release_mem_regions(pdev); |
4913 | pci_disable_device(pdev); | 4907 | pci_disable_device(pdev); |
4914 | 4908 | ||
4915 | return; | 4909 | return; |
@@ -9811,7 +9805,6 @@ lpfc_pci_remove_one_s3(struct pci_dev *pdev) | |||
9811 | struct lpfc_vport **vports; | 9805 | struct lpfc_vport **vports; |
9812 | struct lpfc_hba *phba = vport->phba; | 9806 | struct lpfc_hba *phba = vport->phba; |
9813 | int i; | 9807 | int i; |
9814 | int bars = pci_select_bars(pdev, IORESOURCE_MEM); | ||
9815 | 9808 | ||
9816 | spin_lock_irq(&phba->hbalock); | 9809 | spin_lock_irq(&phba->hbalock); |
9817 | vport->load_flag |= FC_UNLOADING; | 9810 | vport->load_flag |= FC_UNLOADING; |
@@ -9886,7 +9879,7 @@ lpfc_pci_remove_one_s3(struct pci_dev *pdev) | |||
9886 | 9879 | ||
9887 | lpfc_hba_free(phba); | 9880 | lpfc_hba_free(phba); |
9888 | 9881 | ||
9889 | pci_release_selected_regions(pdev, bars); | 9882 | pci_release_mem_regions(pdev); |
9890 | pci_disable_device(pdev); | 9883 | pci_disable_device(pdev); |
9891 | } | 9884 | } |
9892 | 9885 | ||
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index c10972fcc8e4..4fd041bec332 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
@@ -387,7 +387,7 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) | |||
387 | * need to have the registers polled during D3, so avoid D3cold. | 387 | * need to have the registers polled during D3, so avoid D3cold. |
388 | */ | 388 | */ |
389 | if (xhci->quirks & XHCI_COMP_MODE_QUIRK) | 389 | if (xhci->quirks & XHCI_COMP_MODE_QUIRK) |
390 | pdev->no_d3cold = true; | 390 | pci_d3cold_disable(pdev); |
391 | 391 | ||
392 | if (xhci->quirks & XHCI_PME_STUCK_QUIRK) | 392 | if (xhci->quirks & XHCI_PME_STUCK_QUIRK) |
393 | xhci_pme_quirk(hcd); | 393 | xhci_pme_quirk(hcd); |
diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h index 89ab0572dbc6..7d63a66e8ed4 100644 --- a/include/linux/pci-acpi.h +++ b/include/linux/pci-acpi.h | |||
@@ -24,6 +24,8 @@ static inline acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev) | |||
24 | } | 24 | } |
25 | extern phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle); | 25 | extern phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle); |
26 | 26 | ||
27 | extern phys_addr_t pci_mcfg_lookup(u16 domain, struct resource *bus_res); | ||
28 | |||
27 | static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev) | 29 | static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev) |
28 | { | 30 | { |
29 | struct pci_bus *pbus = pdev->bus; | 31 | struct pci_bus *pbus = pdev->bus; |
diff --git a/drivers/pci/ecam.h b/include/linux/pci-ecam.h index 9878bebd45bb..7adad206b1f4 100644 --- a/drivers/pci/ecam.h +++ b/include/linux/pci-ecam.h | |||
@@ -27,8 +27,7 @@ struct pci_config_window; | |||
27 | struct pci_ecam_ops { | 27 | struct pci_ecam_ops { |
28 | unsigned int bus_shift; | 28 | unsigned int bus_shift; |
29 | struct pci_ops pci_ops; | 29 | struct pci_ops pci_ops; |
30 | int (*init)(struct device *, | 30 | int (*init)(struct pci_config_window *); |
31 | struct pci_config_window *); | ||
32 | }; | 31 | }; |
33 | 32 | ||
34 | /* | 33 | /* |
@@ -45,6 +44,7 @@ struct pci_config_window { | |||
45 | void __iomem *win; /* 64-bit single mapping */ | 44 | void __iomem *win; /* 64-bit single mapping */ |
46 | void __iomem **winp; /* 32-bit per-bus mapping */ | 45 | void __iomem **winp; /* 32-bit per-bus mapping */ |
47 | }; | 46 | }; |
47 | struct device *parent;/* ECAM res was from this dev */ | ||
48 | }; | 48 | }; |
49 | 49 | ||
50 | /* create and free pci_config_window */ | 50 | /* create and free pci_config_window */ |
diff --git a/include/linux/pci.h b/include/linux/pci.h index c40ac910cce4..2599a980340f 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -101,6 +101,10 @@ enum { | |||
101 | DEVICE_COUNT_RESOURCE = PCI_NUM_RESOURCES, | 101 | DEVICE_COUNT_RESOURCE = PCI_NUM_RESOURCES, |
102 | }; | 102 | }; |
103 | 103 | ||
104 | /* | ||
105 | * pci_power_t values must match the bits in the Capabilities PME_Support | ||
106 | * and Control/Status PowerState fields in the Power Management capability. | ||
107 | */ | ||
104 | typedef int __bitwise pci_power_t; | 108 | typedef int __bitwise pci_power_t; |
105 | 109 | ||
106 | #define PCI_D0 ((pci_power_t __force) 0) | 110 | #define PCI_D0 ((pci_power_t __force) 0) |
@@ -116,7 +120,7 @@ extern const char *pci_power_names[]; | |||
116 | 120 | ||
117 | static inline const char *pci_power_name(pci_power_t state) | 121 | static inline const char *pci_power_name(pci_power_t state) |
118 | { | 122 | { |
119 | return pci_power_names[1 + (int) state]; | 123 | return pci_power_names[1 + (__force int) state]; |
120 | } | 124 | } |
121 | 125 | ||
122 | #define PCI_PM_D2_DELAY 200 | 126 | #define PCI_PM_D2_DELAY 200 |
@@ -294,6 +298,7 @@ struct pci_dev { | |||
294 | unsigned int d2_support:1; /* Low power state D2 is supported */ | 298 | unsigned int d2_support:1; /* Low power state D2 is supported */ |
295 | unsigned int no_d1d2:1; /* D1 and D2 are forbidden */ | 299 | unsigned int no_d1d2:1; /* D1 and D2 are forbidden */ |
296 | unsigned int no_d3cold:1; /* D3cold is forbidden */ | 300 | unsigned int no_d3cold:1; /* D3cold is forbidden */ |
301 | unsigned int bridge_d3:1; /* Allow D3 for bridge */ | ||
297 | unsigned int d3cold_allowed:1; /* D3cold is allowed by user */ | 302 | unsigned int d3cold_allowed:1; /* D3cold is allowed by user */ |
298 | unsigned int mmio_always_on:1; /* disallow turning off io/mem | 303 | unsigned int mmio_always_on:1; /* disallow turning off io/mem |
299 | decoding during bar sizing */ | 304 | decoding during bar sizing */ |
@@ -320,6 +325,7 @@ struct pci_dev { | |||
320 | * directly, use the values stored here. They might be different! | 325 | * directly, use the values stored here. They might be different! |
321 | */ | 326 | */ |
322 | unsigned int irq; | 327 | unsigned int irq; |
328 | struct cpumask *irq_affinity; | ||
323 | struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */ | 329 | struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */ |
324 | 330 | ||
325 | bool match_driver; /* Skip attaching driver */ | 331 | bool match_driver; /* Skip attaching driver */ |
@@ -1084,6 +1090,8 @@ int pci_back_from_sleep(struct pci_dev *dev); | |||
1084 | bool pci_dev_run_wake(struct pci_dev *dev); | 1090 | bool pci_dev_run_wake(struct pci_dev *dev); |
1085 | bool pci_check_pme_status(struct pci_dev *dev); | 1091 | bool pci_check_pme_status(struct pci_dev *dev); |
1086 | void pci_pme_wakeup_bus(struct pci_bus *bus); | 1092 | void pci_pme_wakeup_bus(struct pci_bus *bus); |
1093 | void pci_d3cold_enable(struct pci_dev *dev); | ||
1094 | void pci_d3cold_disable(struct pci_dev *dev); | ||
1087 | 1095 | ||
1088 | static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, | 1096 | static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, |
1089 | bool enable) | 1097 | bool enable) |
@@ -1115,6 +1123,7 @@ int pci_set_vpd_size(struct pci_dev *dev, size_t len); | |||
1115 | /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */ | 1123 | /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */ |
1116 | resource_size_t pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx); | 1124 | resource_size_t pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx); |
1117 | void pci_bus_assign_resources(const struct pci_bus *bus); | 1125 | void pci_bus_assign_resources(const struct pci_bus *bus); |
1126 | void pci_bus_claim_resources(struct pci_bus *bus); | ||
1118 | void pci_bus_size_bridges(struct pci_bus *bus); | 1127 | void pci_bus_size_bridges(struct pci_bus *bus); |
1119 | int pci_claim_resource(struct pci_dev *, int); | 1128 | int pci_claim_resource(struct pci_dev *, int); |
1120 | int pci_claim_bridge_resource(struct pci_dev *bridge, int i); | 1129 | int pci_claim_bridge_resource(struct pci_dev *bridge, int i); |
@@ -1144,9 +1153,12 @@ void pci_add_resource(struct list_head *resources, struct resource *res); | |||
1144 | void pci_add_resource_offset(struct list_head *resources, struct resource *res, | 1153 | void pci_add_resource_offset(struct list_head *resources, struct resource *res, |
1145 | resource_size_t offset); | 1154 | resource_size_t offset); |
1146 | void pci_free_resource_list(struct list_head *resources); | 1155 | void pci_free_resource_list(struct list_head *resources); |
1147 | void pci_bus_add_resource(struct pci_bus *bus, struct resource *res, unsigned int flags); | 1156 | void pci_bus_add_resource(struct pci_bus *bus, struct resource *res, |
1157 | unsigned int flags); | ||
1148 | struct resource *pci_bus_resource_n(const struct pci_bus *bus, int n); | 1158 | struct resource *pci_bus_resource_n(const struct pci_bus *bus, int n); |
1149 | void pci_bus_remove_resources(struct pci_bus *bus); | 1159 | void pci_bus_remove_resources(struct pci_bus *bus); |
1160 | int devm_request_pci_bus_resources(struct device *dev, | ||
1161 | struct list_head *resources); | ||
1150 | 1162 | ||
1151 | #define pci_bus_for_each_resource(bus, res, i) \ | 1163 | #define pci_bus_for_each_resource(bus, res, i) \ |
1152 | for (i = 0; \ | 1164 | for (i = 0; \ |
@@ -1168,6 +1180,7 @@ int pci_register_io_range(phys_addr_t addr, resource_size_t size); | |||
1168 | unsigned long pci_address_to_pio(phys_addr_t addr); | 1180 | unsigned long pci_address_to_pio(phys_addr_t addr); |
1169 | phys_addr_t pci_pio_to_address(unsigned long pio); | 1181 | phys_addr_t pci_pio_to_address(unsigned long pio); |
1170 | int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr); | 1182 | int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr); |
1183 | void pci_unmap_iospace(struct resource *res); | ||
1171 | 1184 | ||
1172 | static inline pci_bus_addr_t pci_bus_address(struct pci_dev *pdev, int bar) | 1185 | static inline pci_bus_addr_t pci_bus_address(struct pci_dev *pdev, int bar) |
1173 | { | 1186 | { |
@@ -1238,6 +1251,11 @@ resource_size_t pcibios_iov_resource_alignment(struct pci_dev *dev, int resno); | |||
1238 | int pci_set_vga_state(struct pci_dev *pdev, bool decode, | 1251 | int pci_set_vga_state(struct pci_dev *pdev, bool decode, |
1239 | unsigned int command_bits, u32 flags); | 1252 | unsigned int command_bits, u32 flags); |
1240 | 1253 | ||
1254 | #define PCI_IRQ_NOLEGACY (1 << 0) /* don't use legacy interrupts */ | ||
1255 | #define PCI_IRQ_NOMSI (1 << 1) /* don't use MSI interrupts */ | ||
1256 | #define PCI_IRQ_NOMSIX (1 << 2) /* don't use MSI-X interrupts */ | ||
1257 | #define PCI_IRQ_NOAFFINITY (1 << 3) /* don't auto-assign affinity */ | ||
1258 | |||
1241 | /* kmem_cache style wrapper around pci_alloc_consistent() */ | 1259 | /* kmem_cache style wrapper around pci_alloc_consistent() */ |
1242 | 1260 | ||
1243 | #include <linux/pci-dma.h> | 1261 | #include <linux/pci-dma.h> |
@@ -1285,6 +1303,11 @@ static inline int pci_enable_msix_exact(struct pci_dev *dev, | |||
1285 | return rc; | 1303 | return rc; |
1286 | return 0; | 1304 | return 0; |
1287 | } | 1305 | } |
1306 | int pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs, | ||
1307 | unsigned int max_vecs, unsigned int flags); | ||
1308 | void pci_free_irq_vectors(struct pci_dev *dev); | ||
1309 | int pci_irq_vector(struct pci_dev *dev, unsigned int nr); | ||
1310 | |||
1288 | #else | 1311 | #else |
1289 | static inline int pci_msi_vec_count(struct pci_dev *dev) { return -ENOSYS; } | 1312 | static inline int pci_msi_vec_count(struct pci_dev *dev) { return -ENOSYS; } |
1290 | static inline void pci_msi_shutdown(struct pci_dev *dev) { } | 1313 | static inline void pci_msi_shutdown(struct pci_dev *dev) { } |
@@ -1308,6 +1331,24 @@ static inline int pci_enable_msix_range(struct pci_dev *dev, | |||
1308 | static inline int pci_enable_msix_exact(struct pci_dev *dev, | 1331 | static inline int pci_enable_msix_exact(struct pci_dev *dev, |
1309 | struct msix_entry *entries, int nvec) | 1332 | struct msix_entry *entries, int nvec) |
1310 | { return -ENOSYS; } | 1333 | { return -ENOSYS; } |
1334 | static inline int pci_alloc_irq_vectors(struct pci_dev *dev, | ||
1335 | unsigned int min_vecs, unsigned int max_vecs, | ||
1336 | unsigned int flags) | ||
1337 | { | ||
1338 | if (min_vecs > 1) | ||
1339 | return -EINVAL; | ||
1340 | return 1; | ||
1341 | } | ||
1342 | static inline void pci_free_irq_vectors(struct pci_dev *dev) | ||
1343 | { | ||
1344 | } | ||
1345 | |||
1346 | static inline int pci_irq_vector(struct pci_dev *dev, unsigned int nr) | ||
1347 | { | ||
1348 | if (WARN_ON_ONCE(nr > 0)) | ||
1349 | return -EINVAL; | ||
1350 | return dev->irq; | ||
1351 | } | ||
1311 | #endif | 1352 | #endif |
1312 | 1353 | ||
1313 | #ifdef CONFIG_PCIEPORTBUS | 1354 | #ifdef CONFIG_PCIEPORTBUS |
@@ -1390,12 +1431,13 @@ static inline int pci_domain_nr(struct pci_bus *bus) | |||
1390 | { | 1431 | { |
1391 | return bus->domain_nr; | 1432 | return bus->domain_nr; |
1392 | } | 1433 | } |
1393 | void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent); | 1434 | #ifdef CONFIG_ACPI |
1435 | int acpi_pci_bus_find_domain_nr(struct pci_bus *bus); | ||
1394 | #else | 1436 | #else |
1395 | static inline void pci_bus_assign_domain_nr(struct pci_bus *bus, | 1437 | static inline int acpi_pci_bus_find_domain_nr(struct pci_bus *bus) |
1396 | struct device *parent) | 1438 | { return 0; } |
1397 | { | 1439 | #endif |
1398 | } | 1440 | int pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent); |
1399 | #endif | 1441 | #endif |
1400 | 1442 | ||
1401 | /* some architectures require additional setup to direct VGA traffic */ | 1443 | /* some architectures require additional setup to direct VGA traffic */ |
@@ -1403,6 +1445,34 @@ typedef int (*arch_set_vga_state_t)(struct pci_dev *pdev, bool decode, | |||
1403 | unsigned int command_bits, u32 flags); | 1445 | unsigned int command_bits, u32 flags); |
1404 | void pci_register_set_vga_state(arch_set_vga_state_t func); | 1446 | void pci_register_set_vga_state(arch_set_vga_state_t func); |
1405 | 1447 | ||
1448 | static inline int | ||
1449 | pci_request_io_regions(struct pci_dev *pdev, const char *name) | ||
1450 | { | ||
1451 | return pci_request_selected_regions(pdev, | ||
1452 | pci_select_bars(pdev, IORESOURCE_IO), name); | ||
1453 | } | ||
1454 | |||
1455 | static inline void | ||
1456 | pci_release_io_regions(struct pci_dev *pdev) | ||
1457 | { | ||
1458 | return pci_release_selected_regions(pdev, | ||
1459 | pci_select_bars(pdev, IORESOURCE_IO)); | ||
1460 | } | ||
1461 | |||
1462 | static inline int | ||
1463 | pci_request_mem_regions(struct pci_dev *pdev, const char *name) | ||
1464 | { | ||
1465 | return pci_request_selected_regions(pdev, | ||
1466 | pci_select_bars(pdev, IORESOURCE_MEM), name); | ||
1467 | } | ||
1468 | |||
1469 | static inline void | ||
1470 | pci_release_mem_regions(struct pci_dev *pdev) | ||
1471 | { | ||
1472 | return pci_release_selected_regions(pdev, | ||
1473 | pci_select_bars(pdev, IORESOURCE_MEM)); | ||
1474 | } | ||
1475 | |||
1406 | #else /* CONFIG_PCI is not enabled */ | 1476 | #else /* CONFIG_PCI is not enabled */ |
1407 | 1477 | ||
1408 | static inline void pci_set_flags(int flags) { } | 1478 | static inline void pci_set_flags(int flags) { } |
@@ -1555,7 +1625,11 @@ static inline const char *pci_name(const struct pci_dev *pdev) | |||
1555 | /* Some archs don't want to expose struct resource to userland as-is | 1625 | /* Some archs don't want to expose struct resource to userland as-is |
1556 | * in sysfs and /proc | 1626 | * in sysfs and /proc |
1557 | */ | 1627 | */ |
1558 | #ifndef HAVE_ARCH_PCI_RESOURCE_TO_USER | 1628 | #ifdef HAVE_ARCH_PCI_RESOURCE_TO_USER |
1629 | void pci_resource_to_user(const struct pci_dev *dev, int bar, | ||
1630 | const struct resource *rsrc, | ||
1631 | resource_size_t *start, resource_size_t *end); | ||
1632 | #else | ||
1559 | static inline void pci_resource_to_user(const struct pci_dev *dev, int bar, | 1633 | static inline void pci_resource_to_user(const struct pci_dev *dev, int bar, |
1560 | const struct resource *rsrc, resource_size_t *start, | 1634 | const struct resource *rsrc, resource_size_t *start, |
1561 | resource_size_t *end) | 1635 | resource_size_t *end) |
@@ -1707,6 +1781,7 @@ extern u8 pci_cache_line_size; | |||
1707 | 1781 | ||
1708 | extern unsigned long pci_hotplug_io_size; | 1782 | extern unsigned long pci_hotplug_io_size; |
1709 | extern unsigned long pci_hotplug_mem_size; | 1783 | extern unsigned long pci_hotplug_mem_size; |
1784 | extern unsigned long pci_hotplug_bus_size; | ||
1710 | 1785 | ||
1711 | /* Architecture-specific versions may override these (weak) */ | 1786 | /* Architecture-specific versions may override these (weak) */ |
1712 | void pcibios_disable_device(struct pci_dev *dev); | 1787 | void pcibios_disable_device(struct pci_dev *dev); |
@@ -1723,7 +1798,7 @@ void pcibios_free_irq(struct pci_dev *dev); | |||
1723 | extern struct dev_pm_ops pcibios_pm_ops; | 1798 | extern struct dev_pm_ops pcibios_pm_ops; |
1724 | #endif | 1799 | #endif |
1725 | 1800 | ||
1726 | #ifdef CONFIG_PCI_MMCONFIG | 1801 | #if defined(CONFIG_PCI_MMCONFIG) || defined(CONFIG_ACPI_MCFG) |
1727 | void __init pci_mmcfg_early_init(void); | 1802 | void __init pci_mmcfg_early_init(void); |
1728 | void __init pci_mmcfg_late_init(void); | 1803 | void __init pci_mmcfg_late_init(void); |
1729 | #else | 1804 | #else |