Skip to content

Commit

Permalink
ssb: Fix support for PCI devices behind a SSB->PCI bridge
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Michael Buesch authored and linvjw committed Feb 21, 2008
1 parent 5078ed5 commit fc71acc
Showing 1 changed file with 12 additions and 5 deletions.
17 changes: 12 additions & 5 deletions drivers/ssb/driver_pcicore.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ int pcibios_plat_dev_init(struct pci_dev *d)
base = &ssb_pcicore_pcibus_iobase;
else
base = &ssb_pcicore_pcibus_membase;
res->flags |= IORESOURCE_PCI_FIXED;
if (res->end) {
size = res->end - res->start + 1;
if (*base & (size - 1))
Expand All @@ -101,10 +102,12 @@ int pcibios_plat_dev_init(struct pci_dev *d)

static void __init ssb_fixup_pcibridge(struct pci_dev *dev)
{
u8 lat;

if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) != 0)
return;

ssb_printk(KERN_INFO "PCI: fixing up bridge\n");
ssb_printk(KERN_INFO "PCI: Fixing up bridge %s\n", pci_name(dev));

/* Enable PCI bridge bus mastering and memory space */
pci_set_master(dev);
Expand All @@ -114,7 +117,10 @@ static void __init ssb_fixup_pcibridge(struct pci_dev *dev)
pci_write_config_dword(dev, SSB_BAR1_CONTROL, 3);

/* Make sure our latency is high enough to handle the devices behind us */
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xa8);
lat = 168;
ssb_printk(KERN_INFO "PCI: Fixing latency timer of device %s to %u\n",
pci_name(dev), lat);
pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
}
DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ssb_fixup_pcibridge);

Expand Down Expand Up @@ -294,14 +300,14 @@ static struct resource ssb_pcicore_mem_resource = {
.name = "SSB PCIcore external memory",
.start = SSB_PCI_DMA,
.end = SSB_PCI_DMA + SSB_PCI_DMA_SZ - 1,
.flags = IORESOURCE_MEM,
.flags = IORESOURCE_MEM | IORESOURCE_PCI_FIXED,
};

static struct resource ssb_pcicore_io_resource = {
.name = "SSB PCIcore external I/O",
.start = 0x100,
.end = 0x7FF,
.flags = IORESOURCE_IO,
.flags = IORESOURCE_IO | IORESOURCE_PCI_FIXED,
};

static struct pci_controller ssb_pcicore_controller = {
Expand Down Expand Up @@ -368,7 +374,8 @@ static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc)
/* Ok, ready to run, register it to the system.
* The following needs change, if we want to port hostmode
* to non-MIPS platform. */
set_io_port_base((unsigned long)ioremap_nocache(SSB_PCI_MEM, 0x04000000));
ssb_pcicore_controller.io_map_base = (unsigned long)ioremap_nocache(SSB_PCI_MEM, 0x04000000);
set_io_port_base(ssb_pcicore_controller.io_map_base);
/* Give some time to the PCI controller to configure itself with the new
* values. Not waiting at this point causes crashes of the machine. */
mdelay(10);
Expand Down

0 comments on commit fc71acc

Please sign in to comment.