2005-04-17 02:20:36 +04:00
/*
* drivers / pci / setup - irq . c
*
* Extruded from code written by
* Dave Rusling ( david . rusling @ reo . mts . dec . com )
* David Mosberger ( davidm @ cs . arizona . edu )
* David Miller ( davem @ redhat . com )
*
* Support routines for initializing a PCI subsystem .
*/
# include <linux/kernel.h>
# include <linux/pci.h>
# include <linux/errno.h>
# include <linux/ioport.h>
# include <linux/cache.h>
2017-06-28 23:14:02 +03:00
# include "pci.h"
2005-04-17 02:20:36 +04:00
2012-09-17 15:22:54 +04:00
void __weak pcibios_update_irq ( struct pci_dev * dev , int irq )
{
dev_dbg ( & dev - > dev , " assigning IRQ %02d \n " , irq ) ;
pci_write_config_byte ( dev , PCI_INTERRUPT_LINE , irq ) ;
}
2005-04-17 02:20:36 +04:00
2017-06-28 23:14:02 +03:00
void pci_assign_irq ( struct pci_dev * dev )
2005-04-17 02:20:36 +04:00
{
2017-06-28 23:14:02 +03:00
u8 pin ;
u8 slot = - 1 ;
2007-02-06 03:36:07 +03:00
int irq = 0 ;
2017-06-28 23:14:02 +03:00
struct pci_host_bridge * hbrg = pci_find_host_bridge ( dev - > bus ) ;
if ( ! ( hbrg - > map_irq ) ) {
dev_dbg ( & dev - > dev , " runtime IRQ mapping not provided by arch \n " ) ;
return ;
}
2005-04-17 02:20:36 +04:00
/* If this device is not on the primary bus, we need to figure out
which interrupt pin it will come in on . We know which slot it
will come in on ' cos that slot is where the bridge is . Each
time the interrupt line passes through a PCI - PCI bridge we must
apply the swizzle function . */
pci_read_config_byte ( dev , PCI_INTERRUPT_PIN , & pin ) ;
2007-02-06 03:36:07 +03:00
/* Cope with illegal. */
if ( pin > 4 )
2005-04-17 02:20:36 +04:00
pin = 1 ;
2017-06-28 23:14:02 +03:00
if ( pin ) {
2007-02-06 03:36:07 +03:00
/* Follow the chain of bridges, swizzling as we go. */
2017-06-28 23:14:02 +03:00
if ( hbrg - > swizzle_irq )
slot = ( * ( hbrg - > swizzle_irq ) ) ( dev , & pin ) ;
2005-04-17 02:20:36 +04:00
2017-06-28 23:14:02 +03:00
/*
* If a swizzling function is not used map_irq must
* ignore slot
*/
irq = ( * ( hbrg - > map_irq ) ) ( dev , slot , pin ) ;
2007-02-06 03:36:07 +03:00
if ( irq = = - 1 )
irq = 0 ;
}
2005-04-17 02:20:36 +04:00
dev - > irq = irq ;
2017-06-28 23:14:02 +03:00
dev_dbg ( & dev - > dev , " assign IRQ: got %d \n " , dev - > irq ) ;
2005-04-17 02:20:36 +04:00
/* Always tell the device, so the driver knows what is
the real IRQ to use ; the device does not use it . */
pcibios_update_irq ( dev , irq ) ;
}