X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Farm%2Fmach-iop3xx%2Fiq80321-pci.c;h=5d9624863e4ee753f1b58b91b742a15a81e24b11;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=7dce5dfa627eaf86839ee38b0c8ad8b31e11cde6;hpb=a2c21200f1c81b08cb55e417b68150bba439b646;p=linux-2.6.git diff --git a/arch/arm/mach-iop3xx/iq80321-pci.c b/arch/arm/mach-iop3xx/iq80321-pci.c index 7dce5dfa6..5d9624863 100644 --- a/arch/arm/mach-iop3xx/iq80321-pci.c +++ b/arch/arm/mach-iop3xx/iq80321-pci.c @@ -38,37 +38,79 @@ #define INTE IRQ_IQ80321_I82544 -typedef u8 irq_table[4]; - -static irq_table pci_irq_table[] = { - /* - * PCI IDSEL/INTPIN->INTLINE - * A B C D - */ - {INTE, INTE, INTE, INTE}, /* Gig-E */ - {INTD, INTC, INTD, INTA}, /* Unused */ - {INTC, INTD, INTA, INTB}, /* PCI-X Slot */ -}; - static inline int __init iq80321_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) { + static int pci_irq_table[][4] = { + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + {INTE, INTE, INTE, INTE}, /* Gig-E */ + {-1, -1, -1, -1}, /* Unused */ + {INTC, INTD, INTA, INTB}, /* PCI-X Slot */ + {-1, -1, -1, -1}, + }; + BUG_ON(pin < 1 || pin > 4); - return PCI_IRQ_TABLE_LOOKUP(2, 3); +// return PCI_IRQ_TABLE_LOOKUP(4, 7); + return pci_irq_table[idsel%4][pin-1]; } static int iq80321_setup(int nr, struct pci_sys_data *sys) { - switch (nr) { - case 0: - sys->map_irq = iq80321_map_irq; - break; - default: + struct resource *res; + + if(nr != 0) return 0; - } - return iop321_setup(nr, sys); + res = kmalloc(sizeof(struct resource) * 2, GFP_KERNEL); + if (!res) + panic("PCI: unable to alloc resources"); + + memset(res, 0, sizeof(struct resource) * 2); + + res[0].start = IQ80321_PCI_IO_BASE + IQ80321_PCI_IO_OFFSET; + res[0].end = IQ80321_PCI_IO_BASE + IQ80321_PCI_IO_SIZE - 1 + IQ80321_PCI_IO_OFFSET; + res[0].name = "IQ80321 PCI I/O Space"; + res[0].flags = IORESOURCE_IO; + + res[1].start = IQ80321_PCI_MEM_BASE; + res[1].end = IQ80321_PCI_MEM_BASE + IQ80321_PCI_MEM_SIZE; + res[1].name = "IQ80321 PCI Memory Space"; + res[1].flags = IORESOURCE_MEM; + + request_resource(&ioport_resource, &res[0]); + request_resource(&iomem_resource, &res[1]); + + /* + * Since the IQ80321 is a slave card on a PCI backplane, + * it uses BAR1 to reserve a portion of PCI memory space for + * use with the private devices on the secondary bus + * (GigE and PCI-X slot). We read BAR1 and configure + * our outbound translation windows to target that + * address range and assign all devices in that + * address range. W/O this, certain BIOSes will fail + * to boot as the IQ80321 claims addresses that are + * in use by other devices. + * + * Note that the same cannot be done with I/O space, + * so hopefully the host will stick to the lower 64K for + * PCI I/O and leave us alone. + */ + sys->mem_offset = IQ80321_PCI_MEM_BASE - + (*IOP321_IABAR1 & PCI_BASE_ADDRESS_MEM_MASK); + + sys->resource[0] = &res[0]; + sys->resource[1] = &res[1]; + sys->resource[2] = NULL; + sys->io_offset = IQ80321_PCI_IO_OFFSET; + + iop3xx_pcibios_min_io = IQ80321_PCI_IO_BASE; + iop3xx_pcibios_min_mem = IQ80321_PCI_MEM_BASE; + + return 1; } static void iq80321_preinit(void) @@ -82,6 +124,7 @@ static struct hw_pci iq80321_pci __initdata = { .setup = iq80321_setup, .scan = iop321_scan_bus, .preinit = iq80321_preinit, + .map_irq = iq80321_map_irq }; static int __init iq80321_pci_init(void)