1 /* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 2000, 2001 Keith M Wesolowski 7 * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) 8 */ 9 #include <linux/kernel.h> 10 #include <linux/init.h> 11 #include <linux/interrupt.h> 12 #include <linux/pci.h> 13 #include <linux/types.h> 14 #include <asm/ip32/mace.h> 15 #include <asm/ip32/ip32_ints.h> 16 17 #undef DEBUG_MACE_PCI 18 19 /* 20 * Handle errors from the bridge. This includes master and target aborts, 21 * various command and address errors, and the interrupt test. This gets 22 * registered on the bridge error irq. It's conceivable that some of these 23 * conditions warrant a panic. Anybody care to say which ones? 24 */ 25 static irqreturn_t macepci_error(int irq, void *dev) 26 { 27 char s; 28 unsigned int flags = mace->pci.error; 29 unsigned int addr = mace->pci.error_addr; 30 31 if (flags & MACEPCI_ERROR_MEMORY_ADDR) 32 s = 'M'; 33 else if (flags & MACEPCI_ERROR_CONFIG_ADDR) 34 s = 'C'; 35 else 36 s = 'X'; 37 38 if (flags & MACEPCI_ERROR_MASTER_ABORT) { 39 printk("MACEPCI: Master abort at 0x%08x (%c)\n", addr, s); 40 flags &= ~MACEPCI_ERROR_MASTER_ABORT; 41 } 42 if (flags & MACEPCI_ERROR_TARGET_ABORT) { 43 printk("MACEPCI: Target abort at 0x%08x (%c)\n", addr, s); 44 flags &= ~MACEPCI_ERROR_TARGET_ABORT; 45 } 46 if (flags & MACEPCI_ERROR_DATA_PARITY_ERR) { 47 printk("MACEPCI: Data parity error at 0x%08x (%c)\n", addr, s); 48 flags &= ~MACEPCI_ERROR_DATA_PARITY_ERR; 49 } 50 if (flags & MACEPCI_ERROR_RETRY_ERR) { 51 printk("MACEPCI: Retry error at 0x%08x (%c)\n", addr, s); 52 flags &= ~MACEPCI_ERROR_RETRY_ERR; 53 } 54 if (flags & MACEPCI_ERROR_ILLEGAL_CMD) { 55 printk("MACEPCI: Illegal command at 0x%08x (%c)\n", addr, s); 56 flags &= ~MACEPCI_ERROR_ILLEGAL_CMD; 57 } 58 if (flags & MACEPCI_ERROR_SYSTEM_ERR) { 59 printk("MACEPCI: System error at 0x%08x (%c)\n", addr, s); 60 flags &= ~MACEPCI_ERROR_SYSTEM_ERR; 61 } 62 if (flags & MACEPCI_ERROR_PARITY_ERR) { 63 printk("MACEPCI: Parity error at 0x%08x (%c)\n", addr, s); 64 flags &= ~MACEPCI_ERROR_PARITY_ERR; 65 } 66 if (flags & MACEPCI_ERROR_OVERRUN) { 67 printk("MACEPCI: Overrun error at 0x%08x (%c)\n", addr, s); 68 flags &= ~MACEPCI_ERROR_OVERRUN; 69 } 70 if (flags & MACEPCI_ERROR_SIG_TABORT) { 71 printk("MACEPCI: Signaled target abort (clearing)\n"); 72 flags &= ~MACEPCI_ERROR_SIG_TABORT; 73 } 74 if (flags & MACEPCI_ERROR_INTERRUPT_TEST) { 75 printk("MACEPCI: Interrupt test triggered (clearing)\n"); 76 flags &= ~MACEPCI_ERROR_INTERRUPT_TEST; 77 } 78 79 mace->pci.error = flags; 80 81 return IRQ_HANDLED; 82 } 83 84 85 extern struct pci_ops mace_pci_ops; 86 #ifdef CONFIG_64BIT 87 static struct resource mace_pci_mem_resource = { 88 .name = "SGI O2 PCI MEM", 89 .start = MACEPCI_HI_MEMORY, 90 .end = 0x2FFFFFFFFUL, 91 .flags = IORESOURCE_MEM, 92 }; 93 static struct resource mace_pci_io_resource = { 94 .name = "SGI O2 PCI IO", 95 .start = 0x00000000UL, 96 .end = 0xffffffffUL, 97 .flags = IORESOURCE_IO, 98 }; 99 #define MACE_PCI_MEM_OFFSET 0x200000000 100 #else 101 static struct resource mace_pci_mem_resource = { 102 .name = "SGI O2 PCI MEM", 103 .start = MACEPCI_LOW_MEMORY, 104 .end = MACEPCI_LOW_MEMORY + 0x2000000 - 1, 105 .flags = IORESOURCE_MEM, 106 }; 107 static struct resource mace_pci_io_resource = { 108 .name = "SGI O2 PCI IO", 109 .start = 0x00000000, 110 .end = 0xFFFFFFFF, 111 .flags = IORESOURCE_IO, 112 }; 113 #define MACE_PCI_MEM_OFFSET (MACEPCI_LOW_MEMORY - 0x80000000) 114 #endif 115 static struct pci_controller mace_pci_controller = { 116 .pci_ops = &mace_pci_ops, 117 .mem_resource = &mace_pci_mem_resource, 118 .io_resource = &mace_pci_io_resource, 119 .mem_offset = MACE_PCI_MEM_OFFSET, 120 .io_offset = 0, 121 .io_map_base = CKSEG1ADDR(MACEPCI_LOW_IO), 122 }; 123 124 static int __init mace_init(void) 125 { 126 PCIBIOS_MIN_IO = 0x1000; 127 128 /* Clear any outstanding errors and enable interrupts */ 129 mace->pci.error_addr = 0; 130 mace->pci.error = 0; 131 mace->pci.control = 0xff008500; 132 133 printk("MACE PCI rev %d\n", mace->pci.rev); 134 135 BUG_ON(request_irq(MACE_PCI_BRIDGE_IRQ, macepci_error, 0, 136 "MACE PCI error", NULL)); 137 138 /* extend memory resources */ 139 iomem_resource.end = mace_pci_mem_resource.end; 140 ioport_resource = mace_pci_io_resource; 141 142 register_pci_controller(&mace_pci_controller); 143 144 return 0; 145 } 146 147 arch_initcall(mace_init); 148