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