On Thu, Feb 07, 2013 at 11:25:23PM +0000, Arnd Bergmann wrote: > > link@0 { > > reg = <0x800 0 0 0 0>; // Bus 0, Dev 0x10, Fn 0 > > interrupt-mask = <0x0 0 0 7>; > > interrupt-map = <0x0000 0 0 1 &mpic 58 // INTA > > 0x0000 0 0 2 &mpic 58 // INTB > > 0x0000 0 0 3 &mpic 58 // INTC > > 0x0000 0 0 4 &mpic 58>; // INTD > > } > > The interrupt-map property only makes sense for the host bridge, > not for bridges below it, which don't normally get represented > in the device tree. Linux scans up the PCI bus until it finds a PCI device with a matching OF node. It then constructs an interrupt map 'laddr' (ie the bus:dev.fn) for the child device of this OF node. If you don't have any DT PCI nodes then this should always fold down to doing a lookup with bus=0, and device representing the 'slot' in legacy PCI. However, as soon as you provide a node for a bridge in DT this halts the 'fold down' and goes to the interrupt-map with a device on the subordinate bus number of the bridge. This makes *lots* of sense, if you have bridges providing bus slots then you include the bridge in DT to stop the 'fold down' at that known bridge, giving you a chance to see the interrupt wiring behind the bridge. This matches the design of PCI - if you know how interrupts are hooked up then use that information, otherwise assume the INTx interrupts swizzle and search upward. This is how add-in cards with PCI bridges are supported. This behavior seems complex, but sane to me. I wouldn't change it as Andrew suggested. Thomas's problem is the presence of the static DT node for the root port bridge. Since the node is static you can't know what the runtime determined subordinate bus numbers will be, so there is no possible way to write an interrupt-map at the host bridge. Putting the map in the bridge's DT node seems elegant and correct to me - the map is describing the actual hardware - the root port bridge is actually terminating INTx from downstream devices and converting them to CPU interrupts. (FWIW discrete HT to PCIe bridges do something similar) If you imagine the case you alluded to, a PCI-E root port, connected to a PCI-E to PCI bridge, with 2 physical PCI bus slots. The interrupts for the 2 slots are routed to the CPU directly: link@0 { reg = </* Bus 0, Dev 0x10, Fn 0 */>; // Root Port bridge // Match on INTx (not used since the pci-bridge doesn't create inband INTx) interrupt-mask = <0x0 0 0 7>; interrupt-map = <0x0000 0 0 1 &pic 0 // Inband INTA 0x0000 0 0 2 &pic 1 // Inband INTB .. pci_bridge@0 { reg = </* Bus 1, Dev 0x10, Fn 0 */>; // PCIe to PCI bridge // Match on the device/slot and INTx pin interrupt-mask = <0x7f 0 0 7>; interrupt-map = <0x00xx 0 0 1 &pic 2 // Slot 0 physical INTA 0x00xx 0 0 1 &pic 3 // Slot 1 physical INTA .. } } To me, this seems to be a much more accurate description of how the hardware is constructed then trying to cram all this information into the host bridge's interrupt map. It shows clearly where inband INTA messages arriving at the root port are directed as well as where the slot by slot out-of-band interrupt wires on the PCI bus are directed. Jason -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html