diff options
Diffstat (limited to 'arch/arm/mach-versatile/pci.c')
-rw-r--r-- | arch/arm/mach-versatile/pci.c | 47 |
1 files changed, 30 insertions, 17 deletions
diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c index e92e5e0705bc..c97be4ea76d2 100644 --- a/arch/arm/mach-versatile/pci.c +++ b/arch/arm/mach-versatile/pci.c | |||
@@ -43,9 +43,9 @@ | |||
43 | #define PCI_IMAP0 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x0) | 43 | #define PCI_IMAP0 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x0) |
44 | #define PCI_IMAP1 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x4) | 44 | #define PCI_IMAP1 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x4) |
45 | #define PCI_IMAP2 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x8) | 45 | #define PCI_IMAP2 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x8) |
46 | #define PCI_SMAP0 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x10) | 46 | #define PCI_SMAP0 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x14) |
47 | #define PCI_SMAP1 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x14) | 47 | #define PCI_SMAP1 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x18) |
48 | #define PCI_SMAP2 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x18) | 48 | #define PCI_SMAP2 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x1c) |
49 | #define PCI_SELFID __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0xc) | 49 | #define PCI_SELFID __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0xc) |
50 | 50 | ||
51 | #define DEVICE_ID_OFFSET 0x00 | 51 | #define DEVICE_ID_OFFSET 0x00 |
@@ -170,8 +170,8 @@ static struct pci_ops pci_versatile_ops = { | |||
170 | .write = versatile_write_config, | 170 | .write = versatile_write_config, |
171 | }; | 171 | }; |
172 | 172 | ||
173 | static struct resource io_mem = { | 173 | static struct resource unused_mem = { |
174 | .name = "PCI I/O space", | 174 | .name = "PCI unused", |
175 | .start = VERSATILE_PCI_MEM_BASE0, | 175 | .start = VERSATILE_PCI_MEM_BASE0, |
176 | .end = VERSATILE_PCI_MEM_BASE0+VERSATILE_PCI_MEM_BASE0_SIZE-1, | 176 | .end = VERSATILE_PCI_MEM_BASE0+VERSATILE_PCI_MEM_BASE0_SIZE-1, |
177 | .flags = IORESOURCE_MEM, | 177 | .flags = IORESOURCE_MEM, |
@@ -195,9 +195,9 @@ static int __init pci_versatile_setup_resources(struct pci_sys_data *sys) | |||
195 | { | 195 | { |
196 | int ret = 0; | 196 | int ret = 0; |
197 | 197 | ||
198 | ret = request_resource(&iomem_resource, &io_mem); | 198 | ret = request_resource(&iomem_resource, &unused_mem); |
199 | if (ret) { | 199 | if (ret) { |
200 | printk(KERN_ERR "PCI: unable to allocate I/O " | 200 | printk(KERN_ERR "PCI: unable to allocate unused " |
201 | "memory region (%d)\n", ret); | 201 | "memory region (%d)\n", ret); |
202 | goto out; | 202 | goto out; |
203 | } | 203 | } |
@@ -205,7 +205,7 @@ static int __init pci_versatile_setup_resources(struct pci_sys_data *sys) | |||
205 | if (ret) { | 205 | if (ret) { |
206 | printk(KERN_ERR "PCI: unable to allocate non-prefetchable " | 206 | printk(KERN_ERR "PCI: unable to allocate non-prefetchable " |
207 | "memory region (%d)\n", ret); | 207 | "memory region (%d)\n", ret); |
208 | goto release_io_mem; | 208 | goto release_unused_mem; |
209 | } | 209 | } |
210 | ret = request_resource(&iomem_resource, &pre_mem); | 210 | ret = request_resource(&iomem_resource, &pre_mem); |
211 | if (ret) { | 211 | if (ret) { |
@@ -225,8 +225,8 @@ static int __init pci_versatile_setup_resources(struct pci_sys_data *sys) | |||
225 | 225 | ||
226 | release_non_mem: | 226 | release_non_mem: |
227 | release_resource(&non_mem); | 227 | release_resource(&non_mem); |
228 | release_io_mem: | 228 | release_unused_mem: |
229 | release_resource(&io_mem); | 229 | release_resource(&unused_mem); |
230 | out: | 230 | out: |
231 | return ret; | 231 | return ret; |
232 | } | 232 | } |
@@ -246,7 +246,7 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys) | |||
246 | goto out; | 246 | goto out; |
247 | } | 247 | } |
248 | 248 | ||
249 | ret = pci_ioremap_io(0, VERSATILE_PCI_MEM_BASE0); | 249 | ret = pci_ioremap_io(0, VERSATILE_PCI_IO_BASE); |
250 | if (ret) | 250 | if (ret) |
251 | goto out; | 251 | goto out; |
252 | 252 | ||
@@ -295,6 +295,19 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys) | |||
295 | __raw_writel(PHYS_OFFSET, local_pci_cfg_base + PCI_BASE_ADDRESS_2); | 295 | __raw_writel(PHYS_OFFSET, local_pci_cfg_base + PCI_BASE_ADDRESS_2); |
296 | 296 | ||
297 | /* | 297 | /* |
298 | * For many years the kernel and QEMU were symbiotically buggy | ||
299 | * in that they both assumed the same broken IRQ mapping. | ||
300 | * QEMU therefore attempts to auto-detect old broken kernels | ||
301 | * so that they still work on newer QEMU as they did on old | ||
302 | * QEMU. Since we now use the correct (ie matching-hardware) | ||
303 | * IRQ mapping we write a definitely different value to a | ||
304 | * PCI_INTERRUPT_LINE register to tell QEMU that we expect | ||
305 | * real hardware behaviour and it need not be backwards | ||
306 | * compatible for us. This write is harmless on real hardware. | ||
307 | */ | ||
308 | __raw_writel(0, VERSATILE_PCI_VIRT_BASE+PCI_INTERRUPT_LINE); | ||
309 | |||
310 | /* | ||
298 | * Do not to map Versatile FPGA PCI device into memory space | 311 | * Do not to map Versatile FPGA PCI device into memory space |
299 | */ | 312 | */ |
300 | pci_slot_ignore |= (1 << myslot); | 313 | pci_slot_ignore |= (1 << myslot); |
@@ -327,13 +340,13 @@ static int __init versatile_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |||
327 | { | 340 | { |
328 | int irq; | 341 | int irq; |
329 | 342 | ||
330 | /* slot, pin, irq | 343 | /* |
331 | * 24 1 IRQ_SIC_PCI0 | 344 | * Slot INTA INTB INTC INTD |
332 | * 25 1 IRQ_SIC_PCI1 | 345 | * 31 PCI1 PCI2 PCI3 PCI0 |
333 | * 26 1 IRQ_SIC_PCI2 | 346 | * 30 PCI0 PCI1 PCI2 PCI3 |
334 | * 27 1 IRQ_SIC_PCI3 | 347 | * 29 PCI3 PCI0 PCI1 PCI2 |
335 | */ | 348 | */ |
336 | irq = IRQ_SIC_PCI0 + ((slot - 24 + pin - 1) & 3); | 349 | irq = IRQ_SIC_PCI0 + ((slot + 2 + pin - 1) & 3); |
337 | 350 | ||
338 | return irq; | 351 | return irq; |
339 | } | 352 | } |