Merge /spare/repo/linux-2.6/
[linux-2.6] / arch / mips / pci / pci-ip32.c
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         ioport_resource.end = mace_pci_io_resource.end;
140         register_pci_controller(&mace_pci_controller);
141
142         return 0;
143 }
144
145 arch_initcall(mace_init);