++
++int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
++{
++ u8 irq;
++
++ if (dev->bus->number == 1)
++ return 2;
++
++ pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
++ return irq + 2;
++}
++
++u32 pci_iobase = 0x100;
++u32 pci_membase = SB_PCI_DMA;
++
++static void bcm47xx_fixup_device(struct pci_dev *d)
++{
++ struct resource *res;
++ int pos, size;
++ u32 *base;
++
++ if (d->bus->number == 0)
++ return;
++
++ printk("PCI: Fixing up device %s\n", pci_name(d));
++
++ /* Fix up resource bases */
++ for (pos = 0; pos < 6; pos++) {
++ res = &d->resource[pos];
++ base = ((res->flags & IORESOURCE_IO) ? &pci_iobase : &pci_membase);
++ if (res->end) {
++ size = res->end - res->start + 1;
++ if (*base & (size - 1))
++ *base = (*base + size) & ~(size - 1);
++ res->start = *base;
++ res->end = res->start + size - 1;
++ *base += size;
++ pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start);
++ }
++ /* Fix up PCI bridge BAR0 only */
++ if (d->bus->number == 1 && PCI_SLOT(d->devfn) == 0)
++ break;
++ }
++ /* Fix up interrupt lines */
++ if (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))
++ d->irq = (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))->irq;
++ pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
++}
++
++
++static void bcm47xx_fixup_bridge(struct pci_dev *dev)
++{
++ if (dev->bus->number != 1 || PCI_SLOT(dev->devfn) != 0)
++ return;
++
++ printk("PCI: fixing up bridge\n");
++
++ /* Enable PCI bridge bus mastering and memory space */
++ pci_set_master(dev);
++ pcibios_enable_device(dev, ~0);
++
++ /* Enable PCI bridge BAR1 prefetch and burst */
++ pci_write_config_dword(dev, PCI_BAR1_CONTROL, 3);
++}
++
++/* Do platform specific device initialization at pci_enable_device() time */
++int pcibios_plat_dev_init(struct pci_dev *dev)
++{
++ uint coreidx;
++ unsigned long flags;
++
++ bcm47xx_fixup_device(dev);
++
++ /* These cores come out of reset enabled */
++ if ((dev->bus->number != 0) ||
++ (dev->device == SB_MIPS) ||
++ (dev->device == SB_MIPS33) ||
++ (dev->device == SB_EXTIF) ||
++ (dev->device == SB_CC))
++ return 0;
++
++ /* Do a core reset */
++ spin_lock_irqsave(&sbh_lock, flags);
++ coreidx = sb_coreidx(sbh);
++ if (sb_setcoreidx(sbh, PCI_SLOT(dev->devfn)) && (sb_coreid(sbh) == SB_USB)) {
++ /*
++ * The USB core requires a special bit to be set during core
++ * reset to enable host (OHCI) mode. Resetting the SB core in
++ * pcibios_enable_device() is a hack for compatibility with
++ * vanilla usb-ohci so that it does not have to know about
++ * SB. A driver that wants to use the USB core in device mode
++ * should know about SB and should reset the bit back to 0
++ * after calling pcibios_enable_device().
++ */
++ sb_core_disable(sbh, sb_coreflags(sbh, 0, 0));
++ sb_core_reset(sbh, 1 << 29);
++ } else {
++ sb_core_reset(sbh, 0);
++ }
++ sb_setcoreidx(sbh, coreidx);
++ spin_unlock_irqrestore(&sbh_lock, flags);
++
++ return 0;
++}
++
++DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, bcm47xx_fixup_bridge);