2007-11-22 16:29:10 +09:00
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/pci.h>
# include <linux/types.h>
2008-07-29 08:09:44 +09:00
# include <cpu/irq.h>
2007-11-22 16:29:10 +09:00
# include "pci-sh5.h"
2011-06-10 15:30:21 +01:00
int __init pcibios_map_platform_irq ( const struct pci_dev * dev , u8 slot , u8 pin )
2007-11-22 16:29:10 +09:00
{
int result = - 1 ;
/* The complication here is that the PCI IRQ lines from the Cayman's 2
5 V slots get into the CPU via a different path from the IRQ lines
from the 3 3.3 V slots . Thus , we have to detect whether the card ' s
interrupts go via the 5 V or 3.3 V path , i . e . the ' bridge swizzling '
at the point where we cross from 5 V to 3.3 V is not the normal case .
The added complication is that we don ' t know that the 5 V slots are
always bus 2 , because a card containing a PCI - PCI bridge may be
plugged into a 3.3 V slot , and this changes the bus numbering .
Also , the Cayman has an intermediate PCI bus that goes a custom
expansion board header ( and to the secondary bridge ) . This bus has
never been used in practice .
The 1 ary onboard PCI - PCI bridge is device 3 on bus 0
The 2 ary onboard PCI - PCI bridge is device 0 on the 2 ary bus of
the 1 ary bridge .
*/
struct slot_pin {
int slot ;
int pin ;
} path [ 4 ] ;
int i = 0 ;
while ( dev - > bus - > number > 0 ) {
slot = path [ i ] . slot = PCI_SLOT ( dev - > devfn ) ;
2008-12-09 16:12:32 -07:00
pin = path [ i ] . pin = pci_swizzle_interrupt_pin ( dev , pin ) ;
2007-11-22 16:29:10 +09:00
dev = dev - > bus - > self ;
i + + ;
if ( i > 3 ) panic ( " PCI path to root bus too long! \n " ) ;
}
slot = PCI_SLOT ( dev - > devfn ) ;
/* This is the slot on bus 0 through which the device is eventually
reachable . */
/* Now work back up. */
if ( ( slot < 3 ) | | ( i = = 0 ) ) {
/* Bus 0 (incl. PCI-PCI bridge itself) : perform the final
swizzle now . */
2008-12-09 16:12:32 -07:00
result = IRQ_INTA + pci_swizzle_interrupt_pin ( dev , pin ) - 1 ;
2007-11-22 16:29:10 +09:00
} else {
i - - ;
slot = path [ i ] . slot ;
pin = path [ i ] . pin ;
if ( slot > 0 ) {
panic ( " PCI expansion bus device found - not handled! \n " ) ;
} else {
if ( i > 0 ) {
/* 5V slots */
i - - ;
slot = path [ i ] . slot ;
pin = path [ i ] . pin ;
/* 'pin' was swizzled earlier wrt slot, don't do it again. */
result = IRQ_P2INTA + ( pin - 1 ) ;
} else {
/* IRQ for 2ary PCI-PCI bridge : unused */
result = - 1 ;
}
}
}
return result ;
}