ssb: Fix support for PCI devices behind a SSB->PCI bridge

We must pin all resources and make sure the PCI subsystem
won't relocate us, as the addresses are hardwired into hardware.

Signed-off-by: Michael Buesch <mb@bu3sch.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by Michael Buesch and committed by John W. Linville fc71acc8 5078ed50

+12 -5
+12 -5
drivers/ssb/driver_pcicore.c
··· 79 base = &ssb_pcicore_pcibus_iobase; 80 else 81 base = &ssb_pcicore_pcibus_membase; 82 if (res->end) { 83 size = res->end - res->start + 1; 84 if (*base & (size - 1)) ··· 102 103 static void __init ssb_fixup_pcibridge(struct pci_dev *dev) 104 { 105 if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) != 0) 106 return; 107 108 - ssb_printk(KERN_INFO "PCI: fixing up bridge\n"); 109 110 /* Enable PCI bridge bus mastering and memory space */ 111 pci_set_master(dev); ··· 117 pci_write_config_dword(dev, SSB_BAR1_CONTROL, 3); 118 119 /* Make sure our latency is high enough to handle the devices behind us */ 120 - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xa8); 121 } 122 DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ssb_fixup_pcibridge); 123 ··· 300 .name = "SSB PCIcore external memory", 301 .start = SSB_PCI_DMA, 302 .end = SSB_PCI_DMA + SSB_PCI_DMA_SZ - 1, 303 - .flags = IORESOURCE_MEM, 304 }; 305 306 static struct resource ssb_pcicore_io_resource = { 307 .name = "SSB PCIcore external I/O", 308 .start = 0x100, 309 .end = 0x7FF, 310 - .flags = IORESOURCE_IO, 311 }; 312 313 static struct pci_controller ssb_pcicore_controller = { ··· 374 /* Ok, ready to run, register it to the system. 375 * The following needs change, if we want to port hostmode 376 * to non-MIPS platform. */ 377 - set_io_port_base((unsigned long)ioremap_nocache(SSB_PCI_MEM, 0x04000000)); 378 /* Give some time to the PCI controller to configure itself with the new 379 * values. Not waiting at this point causes crashes of the machine. */ 380 mdelay(10);
··· 79 base = &ssb_pcicore_pcibus_iobase; 80 else 81 base = &ssb_pcicore_pcibus_membase; 82 + res->flags |= IORESOURCE_PCI_FIXED; 83 if (res->end) { 84 size = res->end - res->start + 1; 85 if (*base & (size - 1)) ··· 101 102 static void __init ssb_fixup_pcibridge(struct pci_dev *dev) 103 { 104 + u8 lat; 105 + 106 if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) != 0) 107 return; 108 109 + ssb_printk(KERN_INFO "PCI: Fixing up bridge %s\n", pci_name(dev)); 110 111 /* Enable PCI bridge bus mastering and memory space */ 112 pci_set_master(dev); ··· 114 pci_write_config_dword(dev, SSB_BAR1_CONTROL, 3); 115 116 /* Make sure our latency is high enough to handle the devices behind us */ 117 + lat = 168; 118 + ssb_printk(KERN_INFO "PCI: Fixing latency timer of device %s to %u\n", 119 + pci_name(dev), lat); 120 + pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); 121 } 122 DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ssb_fixup_pcibridge); 123 ··· 294 .name = "SSB PCIcore external memory", 295 .start = SSB_PCI_DMA, 296 .end = SSB_PCI_DMA + SSB_PCI_DMA_SZ - 1, 297 + .flags = IORESOURCE_MEM | IORESOURCE_PCI_FIXED, 298 }; 299 300 static struct resource ssb_pcicore_io_resource = { 301 .name = "SSB PCIcore external I/O", 302 .start = 0x100, 303 .end = 0x7FF, 304 + .flags = IORESOURCE_IO | IORESOURCE_PCI_FIXED, 305 }; 306 307 static struct pci_controller ssb_pcicore_controller = { ··· 368 /* Ok, ready to run, register it to the system. 369 * The following needs change, if we want to port hostmode 370 * to non-MIPS platform. */ 371 + ssb_pcicore_controller.io_map_base = (unsigned long)ioremap_nocache(SSB_PCI_MEM, 0x04000000); 372 + set_io_port_base(ssb_pcicore_controller.io_map_base); 373 /* Give some time to the PCI controller to configure itself with the new 374 * values. Not waiting at this point causes crashes of the machine. */ 375 mdelay(10);