2005-04-17 02:20:36 +04:00
/*
* This file is subject to the terms and conditions of the GNU General Public
* License . See the file " COPYING " in the main directory of this archive
* for more details .
*
* Copyright ( C ) 2000 , 2001 Keith M Wesolowski
* Copyright ( C ) 2004 by Ralf Baechle ( ralf @ linux - mips . org )
*/
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/interrupt.h>
# include <linux/pci.h>
# include <linux/types.h>
# include <asm/ip32/mace.h>
# include <asm/ip32/ip32_ints.h>
# undef DEBUG_MACE_PCI
/*
* Handle errors from the bridge . This includes master and target aborts ,
* various command and address errors , and the interrupt test . This gets
* registered on the bridge error irq . It ' s conceivable that some of these
* conditions warrant a panic . Anybody care to say which ones ?
*/
2006-10-07 22:44:33 +04:00
static irqreturn_t macepci_error ( int irq , void * dev )
2005-04-17 02:20:36 +04:00
{
char s ;
unsigned int flags = mace - > pci . error ;
unsigned int addr = mace - > pci . error_addr ;
if ( flags & MACEPCI_ERROR_MEMORY_ADDR )
s = ' M ' ;
else if ( flags & MACEPCI_ERROR_CONFIG_ADDR )
s = ' C ' ;
else
s = ' X ' ;
if ( flags & MACEPCI_ERROR_MASTER_ABORT ) {
printk ( " MACEPCI: Master abort at 0x%08x (%c) \n " , addr , s ) ;
flags & = ~ MACEPCI_ERROR_MASTER_ABORT ;
}
if ( flags & MACEPCI_ERROR_TARGET_ABORT ) {
printk ( " MACEPCI: Target abort at 0x%08x (%c) \n " , addr , s ) ;
flags & = ~ MACEPCI_ERROR_TARGET_ABORT ;
}
if ( flags & MACEPCI_ERROR_DATA_PARITY_ERR ) {
printk ( " MACEPCI: Data parity error at 0x%08x (%c) \n " , addr , s ) ;
flags & = ~ MACEPCI_ERROR_DATA_PARITY_ERR ;
}
if ( flags & MACEPCI_ERROR_RETRY_ERR ) {
printk ( " MACEPCI: Retry error at 0x%08x (%c) \n " , addr , s ) ;
flags & = ~ MACEPCI_ERROR_RETRY_ERR ;
}
if ( flags & MACEPCI_ERROR_ILLEGAL_CMD ) {
printk ( " MACEPCI: Illegal command at 0x%08x (%c) \n " , addr , s ) ;
flags & = ~ MACEPCI_ERROR_ILLEGAL_CMD ;
}
if ( flags & MACEPCI_ERROR_SYSTEM_ERR ) {
printk ( " MACEPCI: System error at 0x%08x (%c) \n " , addr , s ) ;
flags & = ~ MACEPCI_ERROR_SYSTEM_ERR ;
}
if ( flags & MACEPCI_ERROR_PARITY_ERR ) {
printk ( " MACEPCI: Parity error at 0x%08x (%c) \n " , addr , s ) ;
flags & = ~ MACEPCI_ERROR_PARITY_ERR ;
}
if ( flags & MACEPCI_ERROR_OVERRUN ) {
printk ( " MACEPCI: Overrun error at 0x%08x (%c) \n " , addr , s ) ;
flags & = ~ MACEPCI_ERROR_OVERRUN ;
}
if ( flags & MACEPCI_ERROR_SIG_TABORT ) {
printk ( " MACEPCI: Signaled target abort (clearing) \n " ) ;
flags & = ~ MACEPCI_ERROR_SIG_TABORT ;
}
if ( flags & MACEPCI_ERROR_INTERRUPT_TEST ) {
printk ( " MACEPCI: Interrupt test triggered (clearing) \n " ) ;
flags & = ~ MACEPCI_ERROR_INTERRUPT_TEST ;
}
mace - > pci . error = flags ;
return IRQ_HANDLED ;
}
extern struct pci_ops mace_pci_ops ;
2005-09-04 02:56:16 +04:00
# ifdef CONFIG_64BIT
2005-04-17 02:20:36 +04:00
static struct resource mace_pci_mem_resource = {
. name = " SGI O2 PCI MEM " ,
. start = MACEPCI_HI_MEMORY ,
. end = 0x2FFFFFFFFUL ,
. flags = IORESOURCE_MEM ,
} ;
static struct resource mace_pci_io_resource = {
. name = " SGI O2 PCI IO " ,
. start = 0x00000000UL ,
. end = 0xffffffffUL ,
. flags = IORESOURCE_IO ,
} ;
# define MACE_PCI_MEM_OFFSET 0x200000000
# else
static struct resource mace_pci_mem_resource = {
. name = " SGI O2 PCI MEM " ,
. start = MACEPCI_LOW_MEMORY ,
. end = MACEPCI_LOW_MEMORY + 0x2000000 - 1 ,
. flags = IORESOURCE_MEM ,
} ;
static struct resource mace_pci_io_resource = {
. name = " SGI O2 PCI IO " ,
. start = 0x00000000 ,
. end = 0xFFFFFFFF ,
. flags = IORESOURCE_IO ,
} ;
# define MACE_PCI_MEM_OFFSET (MACEPCI_LOW_MEMORY - 0x80000000)
# endif
static struct pci_controller mace_pci_controller = {
. pci_ops = & mace_pci_ops ,
. mem_resource = & mace_pci_mem_resource ,
. io_resource = & mace_pci_io_resource ,
. iommu = 0 ,
. mem_offset = MACE_PCI_MEM_OFFSET ,
. io_offset = 0 ,
2008-01-05 14:13:11 +03:00
. io_map_base = CKSEG1ADDR ( MACEPCI_LOW_IO ) ,
2005-04-17 02:20:36 +04:00
} ;
static int __init mace_init ( void )
{
PCIBIOS_MIN_IO = 0x1000 ;
/* Clear any outstanding errors and enable interrupts */
mace - > pci . error_addr = 0 ;
mace - > pci . error = 0 ;
mace - > pci . control = 0xff008500 ;
printk ( " MACE PCI rev %d \n " , mace - > pci . rev ) ;
BUG_ON ( request_irq ( MACE_PCI_BRIDGE_IRQ , macepci_error , 0 ,
" MACE PCI error " , NULL ) ) ;
2008-01-05 14:13:11 +03:00
/* extend memory resources */
iomem_resource . end = mace_pci_mem_resource . end ;
2005-02-19 16:58:37 +03:00
ioport_resource = mace_pci_io_resource ;
2005-04-17 02:20:36 +04:00
register_pci_controller ( & mace_pci_controller ) ;
return 0 ;
}
arch_initcall ( mace_init ) ;