Commit 7998b3bd156478c35de685f90d4d0dda57916c60
1 parent
14ff626a64
Exists in
master
and in
7 other branches
parisc: convert gsc and dino pci interrupts to flow handlers
Signed-off-by: Kyle McMartin <kyle@redhat.com>
Showing 2 changed files with 13 additions and 31 deletions Inline Diff
drivers/parisc/dino.c
1 | /* | 1 | /* |
2 | ** DINO manager | 2 | ** DINO manager |
3 | ** | 3 | ** |
4 | ** (c) Copyright 1999 Red Hat Software | 4 | ** (c) Copyright 1999 Red Hat Software |
5 | ** (c) Copyright 1999 SuSE GmbH | 5 | ** (c) Copyright 1999 SuSE GmbH |
6 | ** (c) Copyright 1999,2000 Hewlett-Packard Company | 6 | ** (c) Copyright 1999,2000 Hewlett-Packard Company |
7 | ** (c) Copyright 2000 Grant Grundler | 7 | ** (c) Copyright 2000 Grant Grundler |
8 | ** (c) Copyright 2006 Helge Deller | 8 | ** (c) Copyright 2006 Helge Deller |
9 | ** | 9 | ** |
10 | ** This program is free software; you can redistribute it and/or modify | 10 | ** This program is free software; you can redistribute it and/or modify |
11 | ** it under the terms of the GNU General Public License as published by | 11 | ** it under the terms of the GNU General Public License as published by |
12 | ** the Free Software Foundation; either version 2 of the License, or | 12 | ** the Free Software Foundation; either version 2 of the License, or |
13 | ** (at your option) any later version. | 13 | ** (at your option) any later version. |
14 | ** | 14 | ** |
15 | ** This module provides access to Dino PCI bus (config/IOport spaces) | 15 | ** This module provides access to Dino PCI bus (config/IOport spaces) |
16 | ** and helps manage Dino IRQ lines. | 16 | ** and helps manage Dino IRQ lines. |
17 | ** | 17 | ** |
18 | ** Dino interrupt handling is a bit complicated. | 18 | ** Dino interrupt handling is a bit complicated. |
19 | ** Dino always writes to the broadcast EIR via irr0 for now. | 19 | ** Dino always writes to the broadcast EIR via irr0 for now. |
20 | ** (BIG WARNING: using broadcast EIR is a really bad thing for SMP!) | 20 | ** (BIG WARNING: using broadcast EIR is a really bad thing for SMP!) |
21 | ** Only one processor interrupt is used for the 11 IRQ line | 21 | ** Only one processor interrupt is used for the 11 IRQ line |
22 | ** inputs to dino. | 22 | ** inputs to dino. |
23 | ** | 23 | ** |
24 | ** The different between Built-in Dino and Card-Mode | 24 | ** The different between Built-in Dino and Card-Mode |
25 | ** dino is in chip initialization and pci device initialization. | 25 | ** dino is in chip initialization and pci device initialization. |
26 | ** | 26 | ** |
27 | ** Linux drivers can only use Card-Mode Dino if pci devices I/O port | 27 | ** Linux drivers can only use Card-Mode Dino if pci devices I/O port |
28 | ** BARs are configured and used by the driver. Programming MMIO address | 28 | ** BARs are configured and used by the driver. Programming MMIO address |
29 | ** requires substantial knowledge of available Host I/O address ranges | 29 | ** requires substantial knowledge of available Host I/O address ranges |
30 | ** is currently not supported. Port/Config accessor functions are the | 30 | ** is currently not supported. Port/Config accessor functions are the |
31 | ** same. "BIOS" differences are handled within the existing routines. | 31 | ** same. "BIOS" differences are handled within the existing routines. |
32 | */ | 32 | */ |
33 | 33 | ||
34 | /* Changes : | 34 | /* Changes : |
35 | ** 2001-06-14 : Clement Moyroud (moyroudc@esiee.fr) | 35 | ** 2001-06-14 : Clement Moyroud (moyroudc@esiee.fr) |
36 | ** - added support for the integrated RS232. | 36 | ** - added support for the integrated RS232. |
37 | */ | 37 | */ |
38 | 38 | ||
39 | /* | 39 | /* |
40 | ** TODO: create a virtual address for each Dino HPA. | 40 | ** TODO: create a virtual address for each Dino HPA. |
41 | ** GSC code might be able to do this since IODC data tells us | 41 | ** GSC code might be able to do this since IODC data tells us |
42 | ** how many pages are used. PCI subsystem could (must?) do this | 42 | ** how many pages are used. PCI subsystem could (must?) do this |
43 | ** for PCI drivers devices which implement/use MMIO registers. | 43 | ** for PCI drivers devices which implement/use MMIO registers. |
44 | */ | 44 | */ |
45 | 45 | ||
46 | #include <linux/delay.h> | 46 | #include <linux/delay.h> |
47 | #include <linux/types.h> | 47 | #include <linux/types.h> |
48 | #include <linux/kernel.h> | 48 | #include <linux/kernel.h> |
49 | #include <linux/pci.h> | 49 | #include <linux/pci.h> |
50 | #include <linux/init.h> | 50 | #include <linux/init.h> |
51 | #include <linux/ioport.h> | 51 | #include <linux/ioport.h> |
52 | #include <linux/slab.h> | 52 | #include <linux/slab.h> |
53 | #include <linux/interrupt.h> /* for struct irqaction */ | 53 | #include <linux/interrupt.h> /* for struct irqaction */ |
54 | #include <linux/spinlock.h> /* for spinlock_t and prototypes */ | 54 | #include <linux/spinlock.h> /* for spinlock_t and prototypes */ |
55 | 55 | ||
56 | #include <asm/pdc.h> | 56 | #include <asm/pdc.h> |
57 | #include <asm/page.h> | 57 | #include <asm/page.h> |
58 | #include <asm/system.h> | 58 | #include <asm/system.h> |
59 | #include <asm/io.h> | 59 | #include <asm/io.h> |
60 | #include <asm/hardware.h> | 60 | #include <asm/hardware.h> |
61 | 61 | ||
62 | #include "gsc.h" | 62 | #include "gsc.h" |
63 | 63 | ||
64 | #undef DINO_DEBUG | 64 | #undef DINO_DEBUG |
65 | 65 | ||
66 | #ifdef DINO_DEBUG | 66 | #ifdef DINO_DEBUG |
67 | #define DBG(x...) printk(x) | 67 | #define DBG(x...) printk(x) |
68 | #else | 68 | #else |
69 | #define DBG(x...) | 69 | #define DBG(x...) |
70 | #endif | 70 | #endif |
71 | 71 | ||
72 | /* | 72 | /* |
73 | ** Config accessor functions only pass in the 8-bit bus number | 73 | ** Config accessor functions only pass in the 8-bit bus number |
74 | ** and not the 8-bit "PCI Segment" number. Each Dino will be | 74 | ** and not the 8-bit "PCI Segment" number. Each Dino will be |
75 | ** assigned a PCI bus number based on "when" it's discovered. | 75 | ** assigned a PCI bus number based on "when" it's discovered. |
76 | ** | 76 | ** |
77 | ** The "secondary" bus number is set to this before calling | 77 | ** The "secondary" bus number is set to this before calling |
78 | ** pci_scan_bus(). If any PPB's are present, the scan will | 78 | ** pci_scan_bus(). If any PPB's are present, the scan will |
79 | ** discover them and update the "secondary" and "subordinate" | 79 | ** discover them and update the "secondary" and "subordinate" |
80 | ** fields in Dino's pci_bus structure. | 80 | ** fields in Dino's pci_bus structure. |
81 | ** | 81 | ** |
82 | ** Changes in the configuration *will* result in a different | 82 | ** Changes in the configuration *will* result in a different |
83 | ** bus number for each dino. | 83 | ** bus number for each dino. |
84 | */ | 84 | */ |
85 | 85 | ||
86 | #define is_card_dino(id) ((id)->hw_type == HPHW_A_DMA) | 86 | #define is_card_dino(id) ((id)->hw_type == HPHW_A_DMA) |
87 | #define is_cujo(id) ((id)->hversion == 0x682) | 87 | #define is_cujo(id) ((id)->hversion == 0x682) |
88 | 88 | ||
89 | #define DINO_IAR0 0x004 | 89 | #define DINO_IAR0 0x004 |
90 | #define DINO_IODC_ADDR 0x008 | 90 | #define DINO_IODC_ADDR 0x008 |
91 | #define DINO_IODC_DATA_0 0x008 | 91 | #define DINO_IODC_DATA_0 0x008 |
92 | #define DINO_IODC_DATA_1 0x008 | 92 | #define DINO_IODC_DATA_1 0x008 |
93 | #define DINO_IRR0 0x00C | 93 | #define DINO_IRR0 0x00C |
94 | #define DINO_IAR1 0x010 | 94 | #define DINO_IAR1 0x010 |
95 | #define DINO_IRR1 0x014 | 95 | #define DINO_IRR1 0x014 |
96 | #define DINO_IMR 0x018 | 96 | #define DINO_IMR 0x018 |
97 | #define DINO_IPR 0x01C | 97 | #define DINO_IPR 0x01C |
98 | #define DINO_TOC_ADDR 0x020 | 98 | #define DINO_TOC_ADDR 0x020 |
99 | #define DINO_ICR 0x024 | 99 | #define DINO_ICR 0x024 |
100 | #define DINO_ILR 0x028 | 100 | #define DINO_ILR 0x028 |
101 | #define DINO_IO_COMMAND 0x030 | 101 | #define DINO_IO_COMMAND 0x030 |
102 | #define DINO_IO_STATUS 0x034 | 102 | #define DINO_IO_STATUS 0x034 |
103 | #define DINO_IO_CONTROL 0x038 | 103 | #define DINO_IO_CONTROL 0x038 |
104 | #define DINO_IO_GSC_ERR_RESP 0x040 | 104 | #define DINO_IO_GSC_ERR_RESP 0x040 |
105 | #define DINO_IO_ERR_INFO 0x044 | 105 | #define DINO_IO_ERR_INFO 0x044 |
106 | #define DINO_IO_PCI_ERR_RESP 0x048 | 106 | #define DINO_IO_PCI_ERR_RESP 0x048 |
107 | #define DINO_IO_FBB_EN 0x05c | 107 | #define DINO_IO_FBB_EN 0x05c |
108 | #define DINO_IO_ADDR_EN 0x060 | 108 | #define DINO_IO_ADDR_EN 0x060 |
109 | #define DINO_PCI_ADDR 0x064 | 109 | #define DINO_PCI_ADDR 0x064 |
110 | #define DINO_CONFIG_DATA 0x068 | 110 | #define DINO_CONFIG_DATA 0x068 |
111 | #define DINO_IO_DATA 0x06c | 111 | #define DINO_IO_DATA 0x06c |
112 | #define DINO_MEM_DATA 0x070 /* Dino 3.x only */ | 112 | #define DINO_MEM_DATA 0x070 /* Dino 3.x only */ |
113 | #define DINO_GSC2X_CONFIG 0x7b4 | 113 | #define DINO_GSC2X_CONFIG 0x7b4 |
114 | #define DINO_GMASK 0x800 | 114 | #define DINO_GMASK 0x800 |
115 | #define DINO_PAMR 0x804 | 115 | #define DINO_PAMR 0x804 |
116 | #define DINO_PAPR 0x808 | 116 | #define DINO_PAPR 0x808 |
117 | #define DINO_DAMODE 0x80c | 117 | #define DINO_DAMODE 0x80c |
118 | #define DINO_PCICMD 0x810 | 118 | #define DINO_PCICMD 0x810 |
119 | #define DINO_PCISTS 0x814 | 119 | #define DINO_PCISTS 0x814 |
120 | #define DINO_MLTIM 0x81c | 120 | #define DINO_MLTIM 0x81c |
121 | #define DINO_BRDG_FEAT 0x820 | 121 | #define DINO_BRDG_FEAT 0x820 |
122 | #define DINO_PCIROR 0x824 | 122 | #define DINO_PCIROR 0x824 |
123 | #define DINO_PCIWOR 0x828 | 123 | #define DINO_PCIWOR 0x828 |
124 | #define DINO_TLTIM 0x830 | 124 | #define DINO_TLTIM 0x830 |
125 | 125 | ||
126 | #define DINO_IRQS 11 /* bits 0-10 are architected */ | 126 | #define DINO_IRQS 11 /* bits 0-10 are architected */ |
127 | #define DINO_IRR_MASK 0x5ff /* only 10 bits are implemented */ | 127 | #define DINO_IRR_MASK 0x5ff /* only 10 bits are implemented */ |
128 | #define DINO_LOCAL_IRQS (DINO_IRQS+1) | 128 | #define DINO_LOCAL_IRQS (DINO_IRQS+1) |
129 | 129 | ||
130 | #define DINO_MASK_IRQ(x) (1<<(x)) | 130 | #define DINO_MASK_IRQ(x) (1<<(x)) |
131 | 131 | ||
132 | #define PCIINTA 0x001 | 132 | #define PCIINTA 0x001 |
133 | #define PCIINTB 0x002 | 133 | #define PCIINTB 0x002 |
134 | #define PCIINTC 0x004 | 134 | #define PCIINTC 0x004 |
135 | #define PCIINTD 0x008 | 135 | #define PCIINTD 0x008 |
136 | #define PCIINTE 0x010 | 136 | #define PCIINTE 0x010 |
137 | #define PCIINTF 0x020 | 137 | #define PCIINTF 0x020 |
138 | #define GSCEXTINT 0x040 | 138 | #define GSCEXTINT 0x040 |
139 | /* #define xxx 0x080 - bit 7 is "default" */ | 139 | /* #define xxx 0x080 - bit 7 is "default" */ |
140 | /* #define xxx 0x100 - bit 8 not used */ | 140 | /* #define xxx 0x100 - bit 8 not used */ |
141 | /* #define xxx 0x200 - bit 9 not used */ | 141 | /* #define xxx 0x200 - bit 9 not used */ |
142 | #define RS232INT 0x400 | 142 | #define RS232INT 0x400 |
143 | 143 | ||
144 | struct dino_device | 144 | struct dino_device |
145 | { | 145 | { |
146 | struct pci_hba_data hba; /* 'C' inheritance - must be first */ | 146 | struct pci_hba_data hba; /* 'C' inheritance - must be first */ |
147 | spinlock_t dinosaur_pen; | 147 | spinlock_t dinosaur_pen; |
148 | unsigned long txn_addr; /* EIR addr to generate interrupt */ | 148 | unsigned long txn_addr; /* EIR addr to generate interrupt */ |
149 | u32 txn_data; /* EIR data assign to each dino */ | 149 | u32 txn_data; /* EIR data assign to each dino */ |
150 | u32 imr; /* IRQ's which are enabled */ | 150 | u32 imr; /* IRQ's which are enabled */ |
151 | int global_irq[DINO_LOCAL_IRQS]; /* map IMR bit to global irq */ | 151 | int global_irq[DINO_LOCAL_IRQS]; /* map IMR bit to global irq */ |
152 | #ifdef DINO_DEBUG | 152 | #ifdef DINO_DEBUG |
153 | unsigned int dino_irr0; /* save most recent IRQ line stat */ | 153 | unsigned int dino_irr0; /* save most recent IRQ line stat */ |
154 | #endif | 154 | #endif |
155 | }; | 155 | }; |
156 | 156 | ||
157 | /* Looks nice and keeps the compiler happy */ | 157 | /* Looks nice and keeps the compiler happy */ |
158 | #define DINO_DEV(d) ((struct dino_device *) d) | 158 | #define DINO_DEV(d) ((struct dino_device *) d) |
159 | 159 | ||
160 | 160 | ||
161 | /* | 161 | /* |
162 | * Dino Configuration Space Accessor Functions | 162 | * Dino Configuration Space Accessor Functions |
163 | */ | 163 | */ |
164 | 164 | ||
165 | #define DINO_CFG_TOK(bus,dfn,pos) ((u32) ((bus)<<16 | (dfn)<<8 | (pos))) | 165 | #define DINO_CFG_TOK(bus,dfn,pos) ((u32) ((bus)<<16 | (dfn)<<8 | (pos))) |
166 | 166 | ||
167 | /* | 167 | /* |
168 | * keep the current highest bus count to assist in allocating busses. This | 168 | * keep the current highest bus count to assist in allocating busses. This |
169 | * tries to keep a global bus count total so that when we discover an | 169 | * tries to keep a global bus count total so that when we discover an |
170 | * entirely new bus, it can be given a unique bus number. | 170 | * entirely new bus, it can be given a unique bus number. |
171 | */ | 171 | */ |
172 | static int dino_current_bus = 0; | 172 | static int dino_current_bus = 0; |
173 | 173 | ||
174 | static int dino_cfg_read(struct pci_bus *bus, unsigned int devfn, int where, | 174 | static int dino_cfg_read(struct pci_bus *bus, unsigned int devfn, int where, |
175 | int size, u32 *val) | 175 | int size, u32 *val) |
176 | { | 176 | { |
177 | struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->bridge)); | 177 | struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->bridge)); |
178 | u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary; | 178 | u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary; |
179 | u32 v = DINO_CFG_TOK(local_bus, devfn, where & ~3); | 179 | u32 v = DINO_CFG_TOK(local_bus, devfn, where & ~3); |
180 | void __iomem *base_addr = d->hba.base_addr; | 180 | void __iomem *base_addr = d->hba.base_addr; |
181 | unsigned long flags; | 181 | unsigned long flags; |
182 | 182 | ||
183 | DBG("%s: %p, %d, %d, %d\n", __func__, base_addr, devfn, where, | 183 | DBG("%s: %p, %d, %d, %d\n", __func__, base_addr, devfn, where, |
184 | size); | 184 | size); |
185 | spin_lock_irqsave(&d->dinosaur_pen, flags); | 185 | spin_lock_irqsave(&d->dinosaur_pen, flags); |
186 | 186 | ||
187 | /* tell HW which CFG address */ | 187 | /* tell HW which CFG address */ |
188 | __raw_writel(v, base_addr + DINO_PCI_ADDR); | 188 | __raw_writel(v, base_addr + DINO_PCI_ADDR); |
189 | 189 | ||
190 | /* generate cfg read cycle */ | 190 | /* generate cfg read cycle */ |
191 | if (size == 1) { | 191 | if (size == 1) { |
192 | *val = readb(base_addr + DINO_CONFIG_DATA + (where & 3)); | 192 | *val = readb(base_addr + DINO_CONFIG_DATA + (where & 3)); |
193 | } else if (size == 2) { | 193 | } else if (size == 2) { |
194 | *val = readw(base_addr + DINO_CONFIG_DATA + (where & 2)); | 194 | *val = readw(base_addr + DINO_CONFIG_DATA + (where & 2)); |
195 | } else if (size == 4) { | 195 | } else if (size == 4) { |
196 | *val = readl(base_addr + DINO_CONFIG_DATA); | 196 | *val = readl(base_addr + DINO_CONFIG_DATA); |
197 | } | 197 | } |
198 | 198 | ||
199 | spin_unlock_irqrestore(&d->dinosaur_pen, flags); | 199 | spin_unlock_irqrestore(&d->dinosaur_pen, flags); |
200 | return 0; | 200 | return 0; |
201 | } | 201 | } |
202 | 202 | ||
203 | /* | 203 | /* |
204 | * Dino address stepping "feature": | 204 | * Dino address stepping "feature": |
205 | * When address stepping, Dino attempts to drive the bus one cycle too soon | 205 | * When address stepping, Dino attempts to drive the bus one cycle too soon |
206 | * even though the type of cycle (config vs. MMIO) might be different. | 206 | * even though the type of cycle (config vs. MMIO) might be different. |
207 | * The read of Ven/Prod ID is harmless and avoids Dino's address stepping. | 207 | * The read of Ven/Prod ID is harmless and avoids Dino's address stepping. |
208 | */ | 208 | */ |
209 | static int dino_cfg_write(struct pci_bus *bus, unsigned int devfn, int where, | 209 | static int dino_cfg_write(struct pci_bus *bus, unsigned int devfn, int where, |
210 | int size, u32 val) | 210 | int size, u32 val) |
211 | { | 211 | { |
212 | struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->bridge)); | 212 | struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->bridge)); |
213 | u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary; | 213 | u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary; |
214 | u32 v = DINO_CFG_TOK(local_bus, devfn, where & ~3); | 214 | u32 v = DINO_CFG_TOK(local_bus, devfn, where & ~3); |
215 | void __iomem *base_addr = d->hba.base_addr; | 215 | void __iomem *base_addr = d->hba.base_addr; |
216 | unsigned long flags; | 216 | unsigned long flags; |
217 | 217 | ||
218 | DBG("%s: %p, %d, %d, %d\n", __func__, base_addr, devfn, where, | 218 | DBG("%s: %p, %d, %d, %d\n", __func__, base_addr, devfn, where, |
219 | size); | 219 | size); |
220 | spin_lock_irqsave(&d->dinosaur_pen, flags); | 220 | spin_lock_irqsave(&d->dinosaur_pen, flags); |
221 | 221 | ||
222 | /* avoid address stepping feature */ | 222 | /* avoid address stepping feature */ |
223 | __raw_writel(v & 0xffffff00, base_addr + DINO_PCI_ADDR); | 223 | __raw_writel(v & 0xffffff00, base_addr + DINO_PCI_ADDR); |
224 | __raw_readl(base_addr + DINO_CONFIG_DATA); | 224 | __raw_readl(base_addr + DINO_CONFIG_DATA); |
225 | 225 | ||
226 | /* tell HW which CFG address */ | 226 | /* tell HW which CFG address */ |
227 | __raw_writel(v, base_addr + DINO_PCI_ADDR); | 227 | __raw_writel(v, base_addr + DINO_PCI_ADDR); |
228 | /* generate cfg read cycle */ | 228 | /* generate cfg read cycle */ |
229 | if (size == 1) { | 229 | if (size == 1) { |
230 | writeb(val, base_addr + DINO_CONFIG_DATA + (where & 3)); | 230 | writeb(val, base_addr + DINO_CONFIG_DATA + (where & 3)); |
231 | } else if (size == 2) { | 231 | } else if (size == 2) { |
232 | writew(val, base_addr + DINO_CONFIG_DATA + (where & 2)); | 232 | writew(val, base_addr + DINO_CONFIG_DATA + (where & 2)); |
233 | } else if (size == 4) { | 233 | } else if (size == 4) { |
234 | writel(val, base_addr + DINO_CONFIG_DATA); | 234 | writel(val, base_addr + DINO_CONFIG_DATA); |
235 | } | 235 | } |
236 | 236 | ||
237 | spin_unlock_irqrestore(&d->dinosaur_pen, flags); | 237 | spin_unlock_irqrestore(&d->dinosaur_pen, flags); |
238 | return 0; | 238 | return 0; |
239 | } | 239 | } |
240 | 240 | ||
241 | static struct pci_ops dino_cfg_ops = { | 241 | static struct pci_ops dino_cfg_ops = { |
242 | .read = dino_cfg_read, | 242 | .read = dino_cfg_read, |
243 | .write = dino_cfg_write, | 243 | .write = dino_cfg_write, |
244 | }; | 244 | }; |
245 | 245 | ||
246 | 246 | ||
247 | /* | 247 | /* |
248 | * Dino "I/O Port" Space Accessor Functions | 248 | * Dino "I/O Port" Space Accessor Functions |
249 | * | 249 | * |
250 | * Many PCI devices don't require use of I/O port space (eg Tulip, | 250 | * Many PCI devices don't require use of I/O port space (eg Tulip, |
251 | * NCR720) since they export the same registers to both MMIO and | 251 | * NCR720) since they export the same registers to both MMIO and |
252 | * I/O port space. Performance is going to stink if drivers use | 252 | * I/O port space. Performance is going to stink if drivers use |
253 | * I/O port instead of MMIO. | 253 | * I/O port instead of MMIO. |
254 | */ | 254 | */ |
255 | 255 | ||
256 | #define DINO_PORT_IN(type, size, mask) \ | 256 | #define DINO_PORT_IN(type, size, mask) \ |
257 | static u##size dino_in##size (struct pci_hba_data *d, u16 addr) \ | 257 | static u##size dino_in##size (struct pci_hba_data *d, u16 addr) \ |
258 | { \ | 258 | { \ |
259 | u##size v; \ | 259 | u##size v; \ |
260 | unsigned long flags; \ | 260 | unsigned long flags; \ |
261 | spin_lock_irqsave(&(DINO_DEV(d)->dinosaur_pen), flags); \ | 261 | spin_lock_irqsave(&(DINO_DEV(d)->dinosaur_pen), flags); \ |
262 | /* tell HW which IO Port address */ \ | 262 | /* tell HW which IO Port address */ \ |
263 | __raw_writel((u32) addr, d->base_addr + DINO_PCI_ADDR); \ | 263 | __raw_writel((u32) addr, d->base_addr + DINO_PCI_ADDR); \ |
264 | /* generate I/O PORT read cycle */ \ | 264 | /* generate I/O PORT read cycle */ \ |
265 | v = read##type(d->base_addr+DINO_IO_DATA+(addr&mask)); \ | 265 | v = read##type(d->base_addr+DINO_IO_DATA+(addr&mask)); \ |
266 | spin_unlock_irqrestore(&(DINO_DEV(d)->dinosaur_pen), flags); \ | 266 | spin_unlock_irqrestore(&(DINO_DEV(d)->dinosaur_pen), flags); \ |
267 | return v; \ | 267 | return v; \ |
268 | } | 268 | } |
269 | 269 | ||
270 | DINO_PORT_IN(b, 8, 3) | 270 | DINO_PORT_IN(b, 8, 3) |
271 | DINO_PORT_IN(w, 16, 2) | 271 | DINO_PORT_IN(w, 16, 2) |
272 | DINO_PORT_IN(l, 32, 0) | 272 | DINO_PORT_IN(l, 32, 0) |
273 | 273 | ||
274 | #define DINO_PORT_OUT(type, size, mask) \ | 274 | #define DINO_PORT_OUT(type, size, mask) \ |
275 | static void dino_out##size (struct pci_hba_data *d, u16 addr, u##size val) \ | 275 | static void dino_out##size (struct pci_hba_data *d, u16 addr, u##size val) \ |
276 | { \ | 276 | { \ |
277 | unsigned long flags; \ | 277 | unsigned long flags; \ |
278 | spin_lock_irqsave(&(DINO_DEV(d)->dinosaur_pen), flags); \ | 278 | spin_lock_irqsave(&(DINO_DEV(d)->dinosaur_pen), flags); \ |
279 | /* tell HW which IO port address */ \ | 279 | /* tell HW which IO port address */ \ |
280 | __raw_writel((u32) addr, d->base_addr + DINO_PCI_ADDR); \ | 280 | __raw_writel((u32) addr, d->base_addr + DINO_PCI_ADDR); \ |
281 | /* generate cfg write cycle */ \ | 281 | /* generate cfg write cycle */ \ |
282 | write##type(val, d->base_addr+DINO_IO_DATA+(addr&mask)); \ | 282 | write##type(val, d->base_addr+DINO_IO_DATA+(addr&mask)); \ |
283 | spin_unlock_irqrestore(&(DINO_DEV(d)->dinosaur_pen), flags); \ | 283 | spin_unlock_irqrestore(&(DINO_DEV(d)->dinosaur_pen), flags); \ |
284 | } | 284 | } |
285 | 285 | ||
286 | DINO_PORT_OUT(b, 8, 3) | 286 | DINO_PORT_OUT(b, 8, 3) |
287 | DINO_PORT_OUT(w, 16, 2) | 287 | DINO_PORT_OUT(w, 16, 2) |
288 | DINO_PORT_OUT(l, 32, 0) | 288 | DINO_PORT_OUT(l, 32, 0) |
289 | 289 | ||
290 | static struct pci_port_ops dino_port_ops = { | 290 | static struct pci_port_ops dino_port_ops = { |
291 | .inb = dino_in8, | 291 | .inb = dino_in8, |
292 | .inw = dino_in16, | 292 | .inw = dino_in16, |
293 | .inl = dino_in32, | 293 | .inl = dino_in32, |
294 | .outb = dino_out8, | 294 | .outb = dino_out8, |
295 | .outw = dino_out16, | 295 | .outw = dino_out16, |
296 | .outl = dino_out32 | 296 | .outl = dino_out32 |
297 | }; | 297 | }; |
298 | 298 | ||
299 | static void dino_disable_irq(unsigned int irq) | 299 | static void dino_mask_irq(unsigned int irq) |
300 | { | 300 | { |
301 | struct dino_device *dino_dev = get_irq_chip_data(irq); | 301 | struct dino_device *dino_dev = get_irq_chip_data(irq); |
302 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); | 302 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); |
303 | 303 | ||
304 | DBG(KERN_WARNING "%s(0x%p, %d)\n", __func__, dino_dev, irq); | 304 | DBG(KERN_WARNING "%s(0x%p, %d)\n", __func__, dino_dev, irq); |
305 | 305 | ||
306 | /* Clear the matching bit in the IMR register */ | 306 | /* Clear the matching bit in the IMR register */ |
307 | dino_dev->imr &= ~(DINO_MASK_IRQ(local_irq)); | 307 | dino_dev->imr &= ~(DINO_MASK_IRQ(local_irq)); |
308 | __raw_writel(dino_dev->imr, dino_dev->hba.base_addr+DINO_IMR); | 308 | __raw_writel(dino_dev->imr, dino_dev->hba.base_addr+DINO_IMR); |
309 | } | 309 | } |
310 | 310 | ||
311 | static void dino_enable_irq(unsigned int irq) | 311 | static void dino_unmask_irq(unsigned int irq) |
312 | { | 312 | { |
313 | struct dino_device *dino_dev = get_irq_chip_data(irq); | 313 | struct dino_device *dino_dev = get_irq_chip_data(irq); |
314 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); | 314 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); |
315 | u32 tmp; | 315 | u32 tmp; |
316 | 316 | ||
317 | DBG(KERN_WARNING "%s(0x%p, %d)\n", __func__, dino_dev, irq); | 317 | DBG(KERN_WARNING "%s(0x%p, %d)\n", __func__, dino_dev, irq); |
318 | 318 | ||
319 | /* | 319 | /* |
320 | ** clear pending IRQ bits | 320 | ** clear pending IRQ bits |
321 | ** | 321 | ** |
322 | ** This does NOT change ILR state! | 322 | ** This does NOT change ILR state! |
323 | ** See comment below for ILR usage. | 323 | ** See comment below for ILR usage. |
324 | */ | 324 | */ |
325 | __raw_readl(dino_dev->hba.base_addr+DINO_IPR); | 325 | __raw_readl(dino_dev->hba.base_addr+DINO_IPR); |
326 | 326 | ||
327 | /* set the matching bit in the IMR register */ | 327 | /* set the matching bit in the IMR register */ |
328 | dino_dev->imr |= DINO_MASK_IRQ(local_irq); /* used in dino_isr() */ | 328 | dino_dev->imr |= DINO_MASK_IRQ(local_irq); /* used in dino_isr() */ |
329 | __raw_writel( dino_dev->imr, dino_dev->hba.base_addr+DINO_IMR); | 329 | __raw_writel( dino_dev->imr, dino_dev->hba.base_addr+DINO_IMR); |
330 | 330 | ||
331 | /* Emulate "Level Triggered" Interrupt | 331 | /* Emulate "Level Triggered" Interrupt |
332 | ** Basically, a driver is blowing it if the IRQ line is asserted | 332 | ** Basically, a driver is blowing it if the IRQ line is asserted |
333 | ** while the IRQ is disabled. But tulip.c seems to do that.... | 333 | ** while the IRQ is disabled. But tulip.c seems to do that.... |
334 | ** Give 'em a kluge award and a nice round of applause! | 334 | ** Give 'em a kluge award and a nice round of applause! |
335 | ** | 335 | ** |
336 | ** The gsc_write will generate an interrupt which invokes dino_isr(). | 336 | ** The gsc_write will generate an interrupt which invokes dino_isr(). |
337 | ** dino_isr() will read IPR and find nothing. But then catch this | 337 | ** dino_isr() will read IPR and find nothing. But then catch this |
338 | ** when it also checks ILR. | 338 | ** when it also checks ILR. |
339 | */ | 339 | */ |
340 | tmp = __raw_readl(dino_dev->hba.base_addr+DINO_ILR); | 340 | tmp = __raw_readl(dino_dev->hba.base_addr+DINO_ILR); |
341 | if (tmp & DINO_MASK_IRQ(local_irq)) { | 341 | if (tmp & DINO_MASK_IRQ(local_irq)) { |
342 | DBG(KERN_WARNING "%s(): IRQ asserted! (ILR 0x%x)\n", | 342 | DBG(KERN_WARNING "%s(): IRQ asserted! (ILR 0x%x)\n", |
343 | __func__, tmp); | 343 | __func__, tmp); |
344 | gsc_writel(dino_dev->txn_data, dino_dev->txn_addr); | 344 | gsc_writel(dino_dev->txn_data, dino_dev->txn_addr); |
345 | } | 345 | } |
346 | } | 346 | } |
347 | 347 | ||
348 | static unsigned int dino_startup_irq(unsigned int irq) | ||
349 | { | ||
350 | dino_enable_irq(irq); | ||
351 | return 0; | ||
352 | } | ||
353 | |||
354 | static struct irq_chip dino_interrupt_type = { | 348 | static struct irq_chip dino_interrupt_type = { |
355 | .name = "GSC-PCI", | 349 | .name = "GSC-PCI", |
356 | .startup = dino_startup_irq, | 350 | .unmask = dino_unmask_irq, |
357 | .shutdown = dino_disable_irq, | 351 | .mask = dino_mask_irq, |
358 | .enable = dino_enable_irq, | 352 | .ack = no_ack_irq, |
359 | .disable = dino_disable_irq, | ||
360 | .ack = no_ack_irq, | ||
361 | .end = no_end_irq, | ||
362 | }; | 353 | }; |
363 | 354 | ||
364 | 355 | ||
365 | /* | 356 | /* |
366 | * Handle a Processor interrupt generated by Dino. | 357 | * Handle a Processor interrupt generated by Dino. |
367 | * | 358 | * |
368 | * ilr_loop counter is a kluge to prevent a "stuck" IRQ line from | 359 | * ilr_loop counter is a kluge to prevent a "stuck" IRQ line from |
369 | * wedging the CPU. Could be removed or made optional at some point. | 360 | * wedging the CPU. Could be removed or made optional at some point. |
370 | */ | 361 | */ |
371 | static irqreturn_t dino_isr(int irq, void *intr_dev) | 362 | static irqreturn_t dino_isr(int irq, void *intr_dev) |
372 | { | 363 | { |
373 | struct dino_device *dino_dev = intr_dev; | 364 | struct dino_device *dino_dev = intr_dev; |
374 | u32 mask; | 365 | u32 mask; |
375 | int ilr_loop = 100; | 366 | int ilr_loop = 100; |
376 | 367 | ||
377 | /* read and acknowledge pending interrupts */ | 368 | /* read and acknowledge pending interrupts */ |
378 | #ifdef DINO_DEBUG | 369 | #ifdef DINO_DEBUG |
379 | dino_dev->dino_irr0 = | 370 | dino_dev->dino_irr0 = |
380 | #endif | 371 | #endif |
381 | mask = __raw_readl(dino_dev->hba.base_addr+DINO_IRR0) & DINO_IRR_MASK; | 372 | mask = __raw_readl(dino_dev->hba.base_addr+DINO_IRR0) & DINO_IRR_MASK; |
382 | 373 | ||
383 | if (mask == 0) | 374 | if (mask == 0) |
384 | return IRQ_NONE; | 375 | return IRQ_NONE; |
385 | 376 | ||
386 | ilr_again: | 377 | ilr_again: |
387 | do { | 378 | do { |
388 | int local_irq = __ffs(mask); | 379 | int local_irq = __ffs(mask); |
389 | int irq = dino_dev->global_irq[local_irq]; | 380 | int irq = dino_dev->global_irq[local_irq]; |
390 | DBG(KERN_DEBUG "%s(%d, %p) mask 0x%x\n", | 381 | DBG(KERN_DEBUG "%s(%d, %p) mask 0x%x\n", |
391 | __func__, irq, intr_dev, mask); | 382 | __func__, irq, intr_dev, mask); |
392 | generic_handle_irq(irq); | 383 | generic_handle_irq(irq); |
393 | mask &= ~(1 << local_irq); | 384 | mask &= ~(1 << local_irq); |
394 | } while (mask); | 385 | } while (mask); |
395 | 386 | ||
396 | /* Support for level triggered IRQ lines. | 387 | /* Support for level triggered IRQ lines. |
397 | ** | 388 | ** |
398 | ** Dropping this support would make this routine *much* faster. | 389 | ** Dropping this support would make this routine *much* faster. |
399 | ** But since PCI requires level triggered IRQ line to share lines... | 390 | ** But since PCI requires level triggered IRQ line to share lines... |
400 | ** device drivers may assume lines are level triggered (and not | 391 | ** device drivers may assume lines are level triggered (and not |
401 | ** edge triggered like EISA/ISA can be). | 392 | ** edge triggered like EISA/ISA can be). |
402 | */ | 393 | */ |
403 | mask = __raw_readl(dino_dev->hba.base_addr+DINO_ILR) & dino_dev->imr; | 394 | mask = __raw_readl(dino_dev->hba.base_addr+DINO_ILR) & dino_dev->imr; |
404 | if (mask) { | 395 | if (mask) { |
405 | if (--ilr_loop > 0) | 396 | if (--ilr_loop > 0) |
406 | goto ilr_again; | 397 | goto ilr_again; |
407 | printk(KERN_ERR "Dino 0x%p: stuck interrupt %d\n", | 398 | printk(KERN_ERR "Dino 0x%p: stuck interrupt %d\n", |
408 | dino_dev->hba.base_addr, mask); | 399 | dino_dev->hba.base_addr, mask); |
409 | return IRQ_NONE; | 400 | return IRQ_NONE; |
410 | } | 401 | } |
411 | return IRQ_HANDLED; | 402 | return IRQ_HANDLED; |
412 | } | 403 | } |
413 | 404 | ||
414 | static void dino_assign_irq(struct dino_device *dino, int local_irq, int *irqp) | 405 | static void dino_assign_irq(struct dino_device *dino, int local_irq, int *irqp) |
415 | { | 406 | { |
416 | int irq = gsc_assign_irq(&dino_interrupt_type, dino); | 407 | int irq = gsc_assign_irq(&dino_interrupt_type, dino); |
417 | if (irq == NO_IRQ) | 408 | if (irq == NO_IRQ) |
418 | return; | 409 | return; |
419 | 410 | ||
420 | *irqp = irq; | 411 | *irqp = irq; |
421 | dino->global_irq[local_irq] = irq; | 412 | dino->global_irq[local_irq] = irq; |
422 | } | 413 | } |
423 | 414 | ||
424 | static void dino_choose_irq(struct parisc_device *dev, void *ctrl) | 415 | static void dino_choose_irq(struct parisc_device *dev, void *ctrl) |
425 | { | 416 | { |
426 | int irq; | 417 | int irq; |
427 | struct dino_device *dino = ctrl; | 418 | struct dino_device *dino = ctrl; |
428 | 419 | ||
429 | switch (dev->id.sversion) { | 420 | switch (dev->id.sversion) { |
430 | case 0x00084: irq = 8; break; /* PS/2 */ | 421 | case 0x00084: irq = 8; break; /* PS/2 */ |
431 | case 0x0008c: irq = 10; break; /* RS232 */ | 422 | case 0x0008c: irq = 10; break; /* RS232 */ |
432 | case 0x00096: irq = 8; break; /* PS/2 */ | 423 | case 0x00096: irq = 8; break; /* PS/2 */ |
433 | default: return; /* Unknown */ | 424 | default: return; /* Unknown */ |
434 | } | 425 | } |
435 | 426 | ||
436 | dino_assign_irq(dino, irq, &dev->irq); | 427 | dino_assign_irq(dino, irq, &dev->irq); |
437 | } | 428 | } |
438 | 429 | ||
439 | 430 | ||
440 | /* | 431 | /* |
441 | * Cirrus 6832 Cardbus reports wrong irq on RDI Tadpole PARISC Laptop (deller@gmx.de) | 432 | * Cirrus 6832 Cardbus reports wrong irq on RDI Tadpole PARISC Laptop (deller@gmx.de) |
442 | * (the irqs are off-by-one, not sure yet if this is a cirrus, dino-hardware or dino-driver problem...) | 433 | * (the irqs are off-by-one, not sure yet if this is a cirrus, dino-hardware or dino-driver problem...) |
443 | */ | 434 | */ |
444 | static void __devinit quirk_cirrus_cardbus(struct pci_dev *dev) | 435 | static void __devinit quirk_cirrus_cardbus(struct pci_dev *dev) |
445 | { | 436 | { |
446 | u8 new_irq = dev->irq - 1; | 437 | u8 new_irq = dev->irq - 1; |
447 | printk(KERN_INFO "PCI: Cirrus Cardbus IRQ fixup for %s, from %d to %d\n", | 438 | printk(KERN_INFO "PCI: Cirrus Cardbus IRQ fixup for %s, from %d to %d\n", |
448 | pci_name(dev), dev->irq, new_irq); | 439 | pci_name(dev), dev->irq, new_irq); |
449 | dev->irq = new_irq; | 440 | dev->irq = new_irq; |
450 | } | 441 | } |
451 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_6832, quirk_cirrus_cardbus ); | 442 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_6832, quirk_cirrus_cardbus ); |
452 | 443 | ||
453 | 444 | ||
454 | static void __init | 445 | static void __init |
455 | dino_bios_init(void) | 446 | dino_bios_init(void) |
456 | { | 447 | { |
457 | DBG("dino_bios_init\n"); | 448 | DBG("dino_bios_init\n"); |
458 | } | 449 | } |
459 | 450 | ||
460 | /* | 451 | /* |
461 | * dino_card_setup - Set up the memory space for a Dino in card mode. | 452 | * dino_card_setup - Set up the memory space for a Dino in card mode. |
462 | * @bus: the bus under this dino | 453 | * @bus: the bus under this dino |
463 | * | 454 | * |
464 | * Claim an 8MB chunk of unused IO space and call the generic PCI routines | 455 | * Claim an 8MB chunk of unused IO space and call the generic PCI routines |
465 | * to set up the addresses of the devices on this bus. | 456 | * to set up the addresses of the devices on this bus. |
466 | */ | 457 | */ |
467 | #define _8MB 0x00800000UL | 458 | #define _8MB 0x00800000UL |
468 | static void __init | 459 | static void __init |
469 | dino_card_setup(struct pci_bus *bus, void __iomem *base_addr) | 460 | dino_card_setup(struct pci_bus *bus, void __iomem *base_addr) |
470 | { | 461 | { |
471 | int i; | 462 | int i; |
472 | struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge)); | 463 | struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge)); |
473 | struct resource *res; | 464 | struct resource *res; |
474 | char name[128]; | 465 | char name[128]; |
475 | int size; | 466 | int size; |
476 | 467 | ||
477 | res = &dino_dev->hba.lmmio_space; | 468 | res = &dino_dev->hba.lmmio_space; |
478 | res->flags = IORESOURCE_MEM; | 469 | res->flags = IORESOURCE_MEM; |
479 | size = scnprintf(name, sizeof(name), "Dino LMMIO (%s)", | 470 | size = scnprintf(name, sizeof(name), "Dino LMMIO (%s)", |
480 | dev_name(bus->bridge)); | 471 | dev_name(bus->bridge)); |
481 | res->name = kmalloc(size+1, GFP_KERNEL); | 472 | res->name = kmalloc(size+1, GFP_KERNEL); |
482 | if(res->name) | 473 | if(res->name) |
483 | strcpy((char *)res->name, name); | 474 | strcpy((char *)res->name, name); |
484 | else | 475 | else |
485 | res->name = dino_dev->hba.lmmio_space.name; | 476 | res->name = dino_dev->hba.lmmio_space.name; |
486 | 477 | ||
487 | 478 | ||
488 | if (ccio_allocate_resource(dino_dev->hba.dev, res, _8MB, | 479 | if (ccio_allocate_resource(dino_dev->hba.dev, res, _8MB, |
489 | F_EXTEND(0xf0000000UL) | _8MB, | 480 | F_EXTEND(0xf0000000UL) | _8MB, |
490 | F_EXTEND(0xffffffffUL) &~ _8MB, _8MB) < 0) { | 481 | F_EXTEND(0xffffffffUL) &~ _8MB, _8MB) < 0) { |
491 | struct list_head *ln, *tmp_ln; | 482 | struct list_head *ln, *tmp_ln; |
492 | 483 | ||
493 | printk(KERN_ERR "Dino: cannot attach bus %s\n", | 484 | printk(KERN_ERR "Dino: cannot attach bus %s\n", |
494 | dev_name(bus->bridge)); | 485 | dev_name(bus->bridge)); |
495 | /* kill the bus, we can't do anything with it */ | 486 | /* kill the bus, we can't do anything with it */ |
496 | list_for_each_safe(ln, tmp_ln, &bus->devices) { | 487 | list_for_each_safe(ln, tmp_ln, &bus->devices) { |
497 | struct pci_dev *dev = pci_dev_b(ln); | 488 | struct pci_dev *dev = pci_dev_b(ln); |
498 | 489 | ||
499 | list_del(&dev->bus_list); | 490 | list_del(&dev->bus_list); |
500 | } | 491 | } |
501 | 492 | ||
502 | return; | 493 | return; |
503 | } | 494 | } |
504 | bus->resource[1] = res; | 495 | bus->resource[1] = res; |
505 | bus->resource[0] = &(dino_dev->hba.io_space); | 496 | bus->resource[0] = &(dino_dev->hba.io_space); |
506 | 497 | ||
507 | /* Now tell dino what range it has */ | 498 | /* Now tell dino what range it has */ |
508 | for (i = 1; i < 31; i++) { | 499 | for (i = 1; i < 31; i++) { |
509 | if (res->start == F_EXTEND(0xf0000000UL | (i * _8MB))) | 500 | if (res->start == F_EXTEND(0xf0000000UL | (i * _8MB))) |
510 | break; | 501 | break; |
511 | } | 502 | } |
512 | DBG("DINO GSC WRITE i=%d, start=%lx, dino addr = %p\n", | 503 | DBG("DINO GSC WRITE i=%d, start=%lx, dino addr = %p\n", |
513 | i, res->start, base_addr + DINO_IO_ADDR_EN); | 504 | i, res->start, base_addr + DINO_IO_ADDR_EN); |
514 | __raw_writel(1 << i, base_addr + DINO_IO_ADDR_EN); | 505 | __raw_writel(1 << i, base_addr + DINO_IO_ADDR_EN); |
515 | } | 506 | } |
516 | 507 | ||
517 | static void __init | 508 | static void __init |
518 | dino_card_fixup(struct pci_dev *dev) | 509 | dino_card_fixup(struct pci_dev *dev) |
519 | { | 510 | { |
520 | u32 irq_pin; | 511 | u32 irq_pin; |
521 | 512 | ||
522 | /* | 513 | /* |
523 | ** REVISIT: card-mode PCI-PCI expansion chassis do exist. | 514 | ** REVISIT: card-mode PCI-PCI expansion chassis do exist. |
524 | ** Not sure they were ever productized. | 515 | ** Not sure they were ever productized. |
525 | ** Die here since we'll die later in dino_inb() anyway. | 516 | ** Die here since we'll die later in dino_inb() anyway. |
526 | */ | 517 | */ |
527 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { | 518 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { |
528 | panic("Card-Mode Dino: PCI-PCI Bridge not supported\n"); | 519 | panic("Card-Mode Dino: PCI-PCI Bridge not supported\n"); |
529 | } | 520 | } |
530 | 521 | ||
531 | /* | 522 | /* |
532 | ** Set Latency Timer to 0xff (not a shared bus) | 523 | ** Set Latency Timer to 0xff (not a shared bus) |
533 | ** Set CACHELINE_SIZE. | 524 | ** Set CACHELINE_SIZE. |
534 | */ | 525 | */ |
535 | dino_cfg_write(dev->bus, dev->devfn, | 526 | dino_cfg_write(dev->bus, dev->devfn, |
536 | PCI_CACHE_LINE_SIZE, 2, 0xff00 | L1_CACHE_BYTES/4); | 527 | PCI_CACHE_LINE_SIZE, 2, 0xff00 | L1_CACHE_BYTES/4); |
537 | 528 | ||
538 | /* | 529 | /* |
539 | ** Program INT_LINE for card-mode devices. | 530 | ** Program INT_LINE for card-mode devices. |
540 | ** The cards are hardwired according to this algorithm. | 531 | ** The cards are hardwired according to this algorithm. |
541 | ** And it doesn't matter if PPB's are present or not since | 532 | ** And it doesn't matter if PPB's are present or not since |
542 | ** the IRQ lines bypass the PPB. | 533 | ** the IRQ lines bypass the PPB. |
543 | ** | 534 | ** |
544 | ** "-1" converts INTA-D (1-4) to PCIINTA-D (0-3) range. | 535 | ** "-1" converts INTA-D (1-4) to PCIINTA-D (0-3) range. |
545 | ** The additional "-1" adjusts for skewing the IRQ<->slot. | 536 | ** The additional "-1" adjusts for skewing the IRQ<->slot. |
546 | */ | 537 | */ |
547 | dino_cfg_read(dev->bus, dev->devfn, PCI_INTERRUPT_PIN, 1, &irq_pin); | 538 | dino_cfg_read(dev->bus, dev->devfn, PCI_INTERRUPT_PIN, 1, &irq_pin); |
548 | dev->irq = pci_swizzle_interrupt_pin(dev, irq_pin) - 1; | 539 | dev->irq = pci_swizzle_interrupt_pin(dev, irq_pin) - 1; |
549 | 540 | ||
550 | /* Shouldn't really need to do this but it's in case someone tries | 541 | /* Shouldn't really need to do this but it's in case someone tries |
551 | ** to bypass PCI services and look at the card themselves. | 542 | ** to bypass PCI services and look at the card themselves. |
552 | */ | 543 | */ |
553 | dino_cfg_write(dev->bus, dev->devfn, PCI_INTERRUPT_LINE, 1, dev->irq); | 544 | dino_cfg_write(dev->bus, dev->devfn, PCI_INTERRUPT_LINE, 1, dev->irq); |
554 | } | 545 | } |
555 | 546 | ||
556 | /* The alignment contraints for PCI bridges under dino */ | 547 | /* The alignment contraints for PCI bridges under dino */ |
557 | #define DINO_BRIDGE_ALIGN 0x100000 | 548 | #define DINO_BRIDGE_ALIGN 0x100000 |
558 | 549 | ||
559 | 550 | ||
560 | static void __init | 551 | static void __init |
561 | dino_fixup_bus(struct pci_bus *bus) | 552 | dino_fixup_bus(struct pci_bus *bus) |
562 | { | 553 | { |
563 | struct list_head *ln; | 554 | struct list_head *ln; |
564 | struct pci_dev *dev; | 555 | struct pci_dev *dev; |
565 | struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge)); | 556 | struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge)); |
566 | int port_base = HBA_PORT_BASE(dino_dev->hba.hba_num); | 557 | int port_base = HBA_PORT_BASE(dino_dev->hba.hba_num); |
567 | 558 | ||
568 | DBG(KERN_WARNING "%s(0x%p) bus %d platform_data 0x%p\n", | 559 | DBG(KERN_WARNING "%s(0x%p) bus %d platform_data 0x%p\n", |
569 | __func__, bus, bus->secondary, | 560 | __func__, bus, bus->secondary, |
570 | bus->bridge->platform_data); | 561 | bus->bridge->platform_data); |
571 | 562 | ||
572 | /* Firmware doesn't set up card-mode dino, so we have to */ | 563 | /* Firmware doesn't set up card-mode dino, so we have to */ |
573 | if (is_card_dino(&dino_dev->hba.dev->id)) { | 564 | if (is_card_dino(&dino_dev->hba.dev->id)) { |
574 | dino_card_setup(bus, dino_dev->hba.base_addr); | 565 | dino_card_setup(bus, dino_dev->hba.base_addr); |
575 | } else if(bus->parent == NULL) { | 566 | } else if(bus->parent == NULL) { |
576 | /* must have a dino above it, reparent the resources | 567 | /* must have a dino above it, reparent the resources |
577 | * into the dino window */ | 568 | * into the dino window */ |
578 | int i; | 569 | int i; |
579 | struct resource *res = &dino_dev->hba.lmmio_space; | 570 | struct resource *res = &dino_dev->hba.lmmio_space; |
580 | 571 | ||
581 | bus->resource[0] = &(dino_dev->hba.io_space); | 572 | bus->resource[0] = &(dino_dev->hba.io_space); |
582 | for(i = 0; i < DINO_MAX_LMMIO_RESOURCES; i++) { | 573 | for(i = 0; i < DINO_MAX_LMMIO_RESOURCES; i++) { |
583 | if(res[i].flags == 0) | 574 | if(res[i].flags == 0) |
584 | break; | 575 | break; |
585 | bus->resource[i+1] = &res[i]; | 576 | bus->resource[i+1] = &res[i]; |
586 | } | 577 | } |
587 | 578 | ||
588 | } else if (bus->parent) { | 579 | } else if (bus->parent) { |
589 | int i; | 580 | int i; |
590 | 581 | ||
591 | pci_read_bridge_bases(bus); | 582 | pci_read_bridge_bases(bus); |
592 | 583 | ||
593 | 584 | ||
594 | for(i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) { | 585 | for(i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) { |
595 | if((bus->self->resource[i].flags & | 586 | if((bus->self->resource[i].flags & |
596 | (IORESOURCE_IO | IORESOURCE_MEM)) == 0) | 587 | (IORESOURCE_IO | IORESOURCE_MEM)) == 0) |
597 | continue; | 588 | continue; |
598 | 589 | ||
599 | if(bus->self->resource[i].flags & IORESOURCE_MEM) { | 590 | if(bus->self->resource[i].flags & IORESOURCE_MEM) { |
600 | /* There's a quirk to alignment of | 591 | /* There's a quirk to alignment of |
601 | * bridge memory resources: the start | 592 | * bridge memory resources: the start |
602 | * is the alignment and start-end is | 593 | * is the alignment and start-end is |
603 | * the size. However, firmware will | 594 | * the size. However, firmware will |
604 | * have assigned start and end, so we | 595 | * have assigned start and end, so we |
605 | * need to take this into account */ | 596 | * need to take this into account */ |
606 | bus->self->resource[i].end = bus->self->resource[i].end - bus->self->resource[i].start + DINO_BRIDGE_ALIGN; | 597 | bus->self->resource[i].end = bus->self->resource[i].end - bus->self->resource[i].start + DINO_BRIDGE_ALIGN; |
607 | bus->self->resource[i].start = DINO_BRIDGE_ALIGN; | 598 | bus->self->resource[i].start = DINO_BRIDGE_ALIGN; |
608 | 599 | ||
609 | } | 600 | } |
610 | 601 | ||
611 | DBG("DEBUG %s assigning %d [0x%lx,0x%lx]\n", | 602 | DBG("DEBUG %s assigning %d [0x%lx,0x%lx]\n", |
612 | dev_name(&bus->self->dev), i, | 603 | dev_name(&bus->self->dev), i, |
613 | bus->self->resource[i].start, | 604 | bus->self->resource[i].start, |
614 | bus->self->resource[i].end); | 605 | bus->self->resource[i].end); |
615 | WARN_ON(pci_assign_resource(bus->self, i)); | 606 | WARN_ON(pci_assign_resource(bus->self, i)); |
616 | DBG("DEBUG %s after assign %d [0x%lx,0x%lx]\n", | 607 | DBG("DEBUG %s after assign %d [0x%lx,0x%lx]\n", |
617 | dev_name(&bus->self->dev), i, | 608 | dev_name(&bus->self->dev), i, |
618 | bus->self->resource[i].start, | 609 | bus->self->resource[i].start, |
619 | bus->self->resource[i].end); | 610 | bus->self->resource[i].end); |
620 | } | 611 | } |
621 | } | 612 | } |
622 | 613 | ||
623 | 614 | ||
624 | list_for_each(ln, &bus->devices) { | 615 | list_for_each(ln, &bus->devices) { |
625 | int i; | 616 | int i; |
626 | 617 | ||
627 | dev = pci_dev_b(ln); | 618 | dev = pci_dev_b(ln); |
628 | if (is_card_dino(&dino_dev->hba.dev->id)) | 619 | if (is_card_dino(&dino_dev->hba.dev->id)) |
629 | dino_card_fixup(dev); | 620 | dino_card_fixup(dev); |
630 | 621 | ||
631 | /* | 622 | /* |
632 | ** P2PB's only have 2 BARs, no IRQs. | 623 | ** P2PB's only have 2 BARs, no IRQs. |
633 | ** I'd like to just ignore them for now. | 624 | ** I'd like to just ignore them for now. |
634 | */ | 625 | */ |
635 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) | 626 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) |
636 | continue; | 627 | continue; |
637 | 628 | ||
638 | /* Adjust the I/O Port space addresses */ | 629 | /* Adjust the I/O Port space addresses */ |
639 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | 630 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { |
640 | struct resource *res = &dev->resource[i]; | 631 | struct resource *res = &dev->resource[i]; |
641 | if (res->flags & IORESOURCE_IO) { | 632 | if (res->flags & IORESOURCE_IO) { |
642 | res->start |= port_base; | 633 | res->start |= port_base; |
643 | res->end |= port_base; | 634 | res->end |= port_base; |
644 | } | 635 | } |
645 | #ifdef __LP64__ | 636 | #ifdef __LP64__ |
646 | /* Sign Extend MMIO addresses */ | 637 | /* Sign Extend MMIO addresses */ |
647 | else if (res->flags & IORESOURCE_MEM) { | 638 | else if (res->flags & IORESOURCE_MEM) { |
648 | res->start |= F_EXTEND(0UL); | 639 | res->start |= F_EXTEND(0UL); |
649 | res->end |= F_EXTEND(0UL); | 640 | res->end |= F_EXTEND(0UL); |
650 | } | 641 | } |
651 | #endif | 642 | #endif |
652 | } | 643 | } |
653 | /* null out the ROM resource if there is one (we don't | 644 | /* null out the ROM resource if there is one (we don't |
654 | * care about an expansion rom on parisc, since it | 645 | * care about an expansion rom on parisc, since it |
655 | * usually contains (x86) bios code) */ | 646 | * usually contains (x86) bios code) */ |
656 | dev->resource[PCI_ROM_RESOURCE].flags = 0; | 647 | dev->resource[PCI_ROM_RESOURCE].flags = 0; |
657 | 648 | ||
658 | if(dev->irq == 255) { | 649 | if(dev->irq == 255) { |
659 | 650 | ||
660 | #define DINO_FIX_UNASSIGNED_INTERRUPTS | 651 | #define DINO_FIX_UNASSIGNED_INTERRUPTS |
661 | #ifdef DINO_FIX_UNASSIGNED_INTERRUPTS | 652 | #ifdef DINO_FIX_UNASSIGNED_INTERRUPTS |
662 | 653 | ||
663 | /* This code tries to assign an unassigned | 654 | /* This code tries to assign an unassigned |
664 | * interrupt. Leave it disabled unless you | 655 | * interrupt. Leave it disabled unless you |
665 | * *really* know what you're doing since the | 656 | * *really* know what you're doing since the |
666 | * pin<->interrupt line mapping varies by bus | 657 | * pin<->interrupt line mapping varies by bus |
667 | * and machine */ | 658 | * and machine */ |
668 | 659 | ||
669 | u32 irq_pin; | 660 | u32 irq_pin; |
670 | 661 | ||
671 | dino_cfg_read(dev->bus, dev->devfn, | 662 | dino_cfg_read(dev->bus, dev->devfn, |
672 | PCI_INTERRUPT_PIN, 1, &irq_pin); | 663 | PCI_INTERRUPT_PIN, 1, &irq_pin); |
673 | irq_pin = pci_swizzle_interrupt_pin(dev, irq_pin) - 1; | 664 | irq_pin = pci_swizzle_interrupt_pin(dev, irq_pin) - 1; |
674 | printk(KERN_WARNING "Device %s has undefined IRQ, " | 665 | printk(KERN_WARNING "Device %s has undefined IRQ, " |
675 | "setting to %d\n", pci_name(dev), irq_pin); | 666 | "setting to %d\n", pci_name(dev), irq_pin); |
676 | dino_cfg_write(dev->bus, dev->devfn, | 667 | dino_cfg_write(dev->bus, dev->devfn, |
677 | PCI_INTERRUPT_LINE, 1, irq_pin); | 668 | PCI_INTERRUPT_LINE, 1, irq_pin); |
678 | dino_assign_irq(dino_dev, irq_pin, &dev->irq); | 669 | dino_assign_irq(dino_dev, irq_pin, &dev->irq); |
679 | #else | 670 | #else |
680 | dev->irq = 65535; | 671 | dev->irq = 65535; |
681 | printk(KERN_WARNING "Device %s has unassigned IRQ\n", pci_name(dev)); | 672 | printk(KERN_WARNING "Device %s has unassigned IRQ\n", pci_name(dev)); |
682 | #endif | 673 | #endif |
683 | } else { | 674 | } else { |
684 | /* Adjust INT_LINE for that busses region */ | 675 | /* Adjust INT_LINE for that busses region */ |
685 | dino_assign_irq(dino_dev, dev->irq, &dev->irq); | 676 | dino_assign_irq(dino_dev, dev->irq, &dev->irq); |
686 | } | 677 | } |
687 | } | 678 | } |
688 | } | 679 | } |
689 | 680 | ||
690 | 681 | ||
691 | static struct pci_bios_ops dino_bios_ops = { | 682 | static struct pci_bios_ops dino_bios_ops = { |
692 | .init = dino_bios_init, | 683 | .init = dino_bios_init, |
693 | .fixup_bus = dino_fixup_bus | 684 | .fixup_bus = dino_fixup_bus |
694 | }; | 685 | }; |
695 | 686 | ||
696 | 687 | ||
697 | /* | 688 | /* |
698 | * Initialise a DINO controller chip | 689 | * Initialise a DINO controller chip |
699 | */ | 690 | */ |
700 | static void __init | 691 | static void __init |
701 | dino_card_init(struct dino_device *dino_dev) | 692 | dino_card_init(struct dino_device *dino_dev) |
702 | { | 693 | { |
703 | u32 brdg_feat = 0x00784e05; | 694 | u32 brdg_feat = 0x00784e05; |
704 | unsigned long status; | 695 | unsigned long status; |
705 | 696 | ||
706 | status = __raw_readl(dino_dev->hba.base_addr+DINO_IO_STATUS); | 697 | status = __raw_readl(dino_dev->hba.base_addr+DINO_IO_STATUS); |
707 | if (status & 0x0000ff80) { | 698 | if (status & 0x0000ff80) { |
708 | __raw_writel(0x00000005, | 699 | __raw_writel(0x00000005, |
709 | dino_dev->hba.base_addr+DINO_IO_COMMAND); | 700 | dino_dev->hba.base_addr+DINO_IO_COMMAND); |
710 | udelay(1); | 701 | udelay(1); |
711 | } | 702 | } |
712 | 703 | ||
713 | __raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_GMASK); | 704 | __raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_GMASK); |
714 | __raw_writel(0x00000001, dino_dev->hba.base_addr+DINO_IO_FBB_EN); | 705 | __raw_writel(0x00000001, dino_dev->hba.base_addr+DINO_IO_FBB_EN); |
715 | __raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_ICR); | 706 | __raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_ICR); |
716 | 707 | ||
717 | #if 1 | 708 | #if 1 |
718 | /* REVISIT - should be a runtime check (eg if (CPU_IS_PCX_L) ...) */ | 709 | /* REVISIT - should be a runtime check (eg if (CPU_IS_PCX_L) ...) */ |
719 | /* | 710 | /* |
720 | ** PCX-L processors don't support XQL like Dino wants it. | 711 | ** PCX-L processors don't support XQL like Dino wants it. |
721 | ** PCX-L2 ignore XQL signal and it doesn't matter. | 712 | ** PCX-L2 ignore XQL signal and it doesn't matter. |
722 | */ | 713 | */ |
723 | brdg_feat &= ~0x4; /* UXQL */ | 714 | brdg_feat &= ~0x4; /* UXQL */ |
724 | #endif | 715 | #endif |
725 | __raw_writel( brdg_feat, dino_dev->hba.base_addr+DINO_BRDG_FEAT); | 716 | __raw_writel( brdg_feat, dino_dev->hba.base_addr+DINO_BRDG_FEAT); |
726 | 717 | ||
727 | /* | 718 | /* |
728 | ** Don't enable address decoding until we know which I/O range | 719 | ** Don't enable address decoding until we know which I/O range |
729 | ** currently is available from the host. Only affects MMIO | 720 | ** currently is available from the host. Only affects MMIO |
730 | ** and not I/O port space. | 721 | ** and not I/O port space. |
731 | */ | 722 | */ |
732 | __raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_IO_ADDR_EN); | 723 | __raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_IO_ADDR_EN); |
733 | 724 | ||
734 | __raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_DAMODE); | 725 | __raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_DAMODE); |
735 | __raw_writel(0x00222222, dino_dev->hba.base_addr+DINO_PCIROR); | 726 | __raw_writel(0x00222222, dino_dev->hba.base_addr+DINO_PCIROR); |
736 | __raw_writel(0x00222222, dino_dev->hba.base_addr+DINO_PCIWOR); | 727 | __raw_writel(0x00222222, dino_dev->hba.base_addr+DINO_PCIWOR); |
737 | 728 | ||
738 | __raw_writel(0x00000040, dino_dev->hba.base_addr+DINO_MLTIM); | 729 | __raw_writel(0x00000040, dino_dev->hba.base_addr+DINO_MLTIM); |
739 | __raw_writel(0x00000080, dino_dev->hba.base_addr+DINO_IO_CONTROL); | 730 | __raw_writel(0x00000080, dino_dev->hba.base_addr+DINO_IO_CONTROL); |
740 | __raw_writel(0x0000008c, dino_dev->hba.base_addr+DINO_TLTIM); | 731 | __raw_writel(0x0000008c, dino_dev->hba.base_addr+DINO_TLTIM); |
741 | 732 | ||
742 | /* Disable PAMR before writing PAPR */ | 733 | /* Disable PAMR before writing PAPR */ |
743 | __raw_writel(0x0000007e, dino_dev->hba.base_addr+DINO_PAMR); | 734 | __raw_writel(0x0000007e, dino_dev->hba.base_addr+DINO_PAMR); |
744 | __raw_writel(0x0000007f, dino_dev->hba.base_addr+DINO_PAPR); | 735 | __raw_writel(0x0000007f, dino_dev->hba.base_addr+DINO_PAPR); |
745 | __raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_PAMR); | 736 | __raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_PAMR); |
746 | 737 | ||
747 | /* | 738 | /* |
748 | ** Dino ERS encourages enabling FBB (0x6f). | 739 | ** Dino ERS encourages enabling FBB (0x6f). |
749 | ** We can't until we know *all* devices below us can support it. | 740 | ** We can't until we know *all* devices below us can support it. |
750 | ** (Something in device configuration header tells us). | 741 | ** (Something in device configuration header tells us). |
751 | */ | 742 | */ |
752 | __raw_writel(0x0000004f, dino_dev->hba.base_addr+DINO_PCICMD); | 743 | __raw_writel(0x0000004f, dino_dev->hba.base_addr+DINO_PCICMD); |
753 | 744 | ||
754 | /* Somewhere, the PCI spec says give devices 1 second | 745 | /* Somewhere, the PCI spec says give devices 1 second |
755 | ** to recover from the #RESET being de-asserted. | 746 | ** to recover from the #RESET being de-asserted. |
756 | ** Experience shows most devices only need 10ms. | 747 | ** Experience shows most devices only need 10ms. |
757 | ** This short-cut speeds up booting significantly. | 748 | ** This short-cut speeds up booting significantly. |
758 | */ | 749 | */ |
759 | mdelay(pci_post_reset_delay); | 750 | mdelay(pci_post_reset_delay); |
760 | } | 751 | } |
761 | 752 | ||
762 | static int __init | 753 | static int __init |
763 | dino_bridge_init(struct dino_device *dino_dev, const char *name) | 754 | dino_bridge_init(struct dino_device *dino_dev, const char *name) |
764 | { | 755 | { |
765 | unsigned long io_addr; | 756 | unsigned long io_addr; |
766 | int result, i, count=0; | 757 | int result, i, count=0; |
767 | struct resource *res, *prevres = NULL; | 758 | struct resource *res, *prevres = NULL; |
768 | /* | 759 | /* |
769 | * Decoding IO_ADDR_EN only works for Built-in Dino | 760 | * Decoding IO_ADDR_EN only works for Built-in Dino |
770 | * since PDC has already initialized this. | 761 | * since PDC has already initialized this. |
771 | */ | 762 | */ |
772 | 763 | ||
773 | io_addr = __raw_readl(dino_dev->hba.base_addr + DINO_IO_ADDR_EN); | 764 | io_addr = __raw_readl(dino_dev->hba.base_addr + DINO_IO_ADDR_EN); |
774 | if (io_addr == 0) { | 765 | if (io_addr == 0) { |
775 | printk(KERN_WARNING "%s: No PCI devices enabled.\n", name); | 766 | printk(KERN_WARNING "%s: No PCI devices enabled.\n", name); |
776 | return -ENODEV; | 767 | return -ENODEV; |
777 | } | 768 | } |
778 | 769 | ||
779 | res = &dino_dev->hba.lmmio_space; | 770 | res = &dino_dev->hba.lmmio_space; |
780 | for (i = 0; i < 32; i++) { | 771 | for (i = 0; i < 32; i++) { |
781 | unsigned long start, end; | 772 | unsigned long start, end; |
782 | 773 | ||
783 | if((io_addr & (1 << i)) == 0) | 774 | if((io_addr & (1 << i)) == 0) |
784 | continue; | 775 | continue; |
785 | 776 | ||
786 | start = F_EXTEND(0xf0000000UL) | (i << 23); | 777 | start = F_EXTEND(0xf0000000UL) | (i << 23); |
787 | end = start + 8 * 1024 * 1024 - 1; | 778 | end = start + 8 * 1024 * 1024 - 1; |
788 | 779 | ||
789 | DBG("DINO RANGE %d is at 0x%lx-0x%lx\n", count, | 780 | DBG("DINO RANGE %d is at 0x%lx-0x%lx\n", count, |
790 | start, end); | 781 | start, end); |
791 | 782 | ||
792 | if(prevres && prevres->end + 1 == start) { | 783 | if(prevres && prevres->end + 1 == start) { |
793 | prevres->end = end; | 784 | prevres->end = end; |
794 | } else { | 785 | } else { |
795 | if(count >= DINO_MAX_LMMIO_RESOURCES) { | 786 | if(count >= DINO_MAX_LMMIO_RESOURCES) { |
796 | printk(KERN_ERR "%s is out of resource windows for range %d (0x%lx-0x%lx)\n", name, count, start, end); | 787 | printk(KERN_ERR "%s is out of resource windows for range %d (0x%lx-0x%lx)\n", name, count, start, end); |
797 | break; | 788 | break; |
798 | } | 789 | } |
799 | prevres = res; | 790 | prevres = res; |
800 | res->start = start; | 791 | res->start = start; |
801 | res->end = end; | 792 | res->end = end; |
802 | res->flags = IORESOURCE_MEM; | 793 | res->flags = IORESOURCE_MEM; |
803 | res->name = kmalloc(64, GFP_KERNEL); | 794 | res->name = kmalloc(64, GFP_KERNEL); |
804 | if(res->name) | 795 | if(res->name) |
805 | snprintf((char *)res->name, 64, "%s LMMIO %d", | 796 | snprintf((char *)res->name, 64, "%s LMMIO %d", |
806 | name, count); | 797 | name, count); |
807 | res++; | 798 | res++; |
808 | count++; | 799 | count++; |
809 | } | 800 | } |
810 | } | 801 | } |
811 | 802 | ||
812 | res = &dino_dev->hba.lmmio_space; | 803 | res = &dino_dev->hba.lmmio_space; |
813 | 804 | ||
814 | for(i = 0; i < DINO_MAX_LMMIO_RESOURCES; i++) { | 805 | for(i = 0; i < DINO_MAX_LMMIO_RESOURCES; i++) { |
815 | if(res[i].flags == 0) | 806 | if(res[i].flags == 0) |
816 | break; | 807 | break; |
817 | 808 | ||
818 | result = ccio_request_resource(dino_dev->hba.dev, &res[i]); | 809 | result = ccio_request_resource(dino_dev->hba.dev, &res[i]); |
819 | if (result < 0) { | 810 | if (result < 0) { |
820 | printk(KERN_ERR "%s: failed to claim PCI Bus address " | 811 | printk(KERN_ERR "%s: failed to claim PCI Bus address " |
821 | "space %d (0x%lx-0x%lx)!\n", name, i, | 812 | "space %d (0x%lx-0x%lx)!\n", name, i, |
822 | (unsigned long)res[i].start, (unsigned long)res[i].end); | 813 | (unsigned long)res[i].start, (unsigned long)res[i].end); |
823 | return result; | 814 | return result; |
824 | } | 815 | } |
825 | } | 816 | } |
826 | return 0; | 817 | return 0; |
827 | } | 818 | } |
828 | 819 | ||
829 | static int __init dino_common_init(struct parisc_device *dev, | 820 | static int __init dino_common_init(struct parisc_device *dev, |
830 | struct dino_device *dino_dev, const char *name) | 821 | struct dino_device *dino_dev, const char *name) |
831 | { | 822 | { |
832 | int status; | 823 | int status; |
833 | u32 eim; | 824 | u32 eim; |
834 | struct gsc_irq gsc_irq; | 825 | struct gsc_irq gsc_irq; |
835 | struct resource *res; | 826 | struct resource *res; |
836 | 827 | ||
837 | pcibios_register_hba(&dino_dev->hba); | 828 | pcibios_register_hba(&dino_dev->hba); |
838 | 829 | ||
839 | pci_bios = &dino_bios_ops; /* used by pci_scan_bus() */ | 830 | pci_bios = &dino_bios_ops; /* used by pci_scan_bus() */ |
840 | pci_port = &dino_port_ops; | 831 | pci_port = &dino_port_ops; |
841 | 832 | ||
842 | /* | 833 | /* |
843 | ** Note: SMP systems can make use of IRR1/IAR1 registers | 834 | ** Note: SMP systems can make use of IRR1/IAR1 registers |
844 | ** But it won't buy much performance except in very | 835 | ** But it won't buy much performance except in very |
845 | ** specific applications/configurations. Note Dino | 836 | ** specific applications/configurations. Note Dino |
846 | ** still only has 11 IRQ input lines - just map some of them | 837 | ** still only has 11 IRQ input lines - just map some of them |
847 | ** to a different processor. | 838 | ** to a different processor. |
848 | */ | 839 | */ |
849 | dev->irq = gsc_alloc_irq(&gsc_irq); | 840 | dev->irq = gsc_alloc_irq(&gsc_irq); |
850 | dino_dev->txn_addr = gsc_irq.txn_addr; | 841 | dino_dev->txn_addr = gsc_irq.txn_addr; |
851 | dino_dev->txn_data = gsc_irq.txn_data; | 842 | dino_dev->txn_data = gsc_irq.txn_data; |
852 | eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data; | 843 | eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data; |
853 | 844 | ||
854 | /* | 845 | /* |
855 | ** Dino needs a PA "IRQ" to get a processor's attention. | 846 | ** Dino needs a PA "IRQ" to get a processor's attention. |
856 | ** arch/parisc/kernel/irq.c returns an EIRR bit. | 847 | ** arch/parisc/kernel/irq.c returns an EIRR bit. |
857 | */ | 848 | */ |
858 | if (dev->irq < 0) { | 849 | if (dev->irq < 0) { |
859 | printk(KERN_WARNING "%s: gsc_alloc_irq() failed\n", name); | 850 | printk(KERN_WARNING "%s: gsc_alloc_irq() failed\n", name); |
860 | return 1; | 851 | return 1; |
861 | } | 852 | } |
862 | 853 | ||
863 | status = request_irq(dev->irq, dino_isr, 0, name, dino_dev); | 854 | status = request_irq(dev->irq, dino_isr, 0, name, dino_dev); |
864 | if (status) { | 855 | if (status) { |
865 | printk(KERN_WARNING "%s: request_irq() failed with %d\n", | 856 | printk(KERN_WARNING "%s: request_irq() failed with %d\n", |
866 | name, status); | 857 | name, status); |
867 | return 1; | 858 | return 1; |
868 | } | 859 | } |
869 | 860 | ||
870 | /* Support the serial port which is sometimes attached on built-in | 861 | /* Support the serial port which is sometimes attached on built-in |
871 | * Dino / Cujo chips. | 862 | * Dino / Cujo chips. |
872 | */ | 863 | */ |
873 | 864 | ||
874 | gsc_fixup_irqs(dev, dino_dev, dino_choose_irq); | 865 | gsc_fixup_irqs(dev, dino_dev, dino_choose_irq); |
875 | 866 | ||
876 | /* | 867 | /* |
877 | ** This enables DINO to generate interrupts when it sees | 868 | ** This enables DINO to generate interrupts when it sees |
878 | ** any of its inputs *change*. Just asserting an IRQ | 869 | ** any of its inputs *change*. Just asserting an IRQ |
879 | ** before it's enabled (ie unmasked) isn't good enough. | 870 | ** before it's enabled (ie unmasked) isn't good enough. |
880 | */ | 871 | */ |
881 | __raw_writel(eim, dino_dev->hba.base_addr+DINO_IAR0); | 872 | __raw_writel(eim, dino_dev->hba.base_addr+DINO_IAR0); |
882 | 873 | ||
883 | /* | 874 | /* |
884 | ** Some platforms don't clear Dino's IRR0 register at boot time. | 875 | ** Some platforms don't clear Dino's IRR0 register at boot time. |
885 | ** Reading will clear it now. | 876 | ** Reading will clear it now. |
886 | */ | 877 | */ |
887 | __raw_readl(dino_dev->hba.base_addr+DINO_IRR0); | 878 | __raw_readl(dino_dev->hba.base_addr+DINO_IRR0); |
888 | 879 | ||
889 | /* allocate I/O Port resource region */ | 880 | /* allocate I/O Port resource region */ |
890 | res = &dino_dev->hba.io_space; | 881 | res = &dino_dev->hba.io_space; |
891 | if (!is_cujo(&dev->id)) { | 882 | if (!is_cujo(&dev->id)) { |
892 | res->name = "Dino I/O Port"; | 883 | res->name = "Dino I/O Port"; |
893 | } else { | 884 | } else { |
894 | res->name = "Cujo I/O Port"; | 885 | res->name = "Cujo I/O Port"; |
895 | } | 886 | } |
896 | res->start = HBA_PORT_BASE(dino_dev->hba.hba_num); | 887 | res->start = HBA_PORT_BASE(dino_dev->hba.hba_num); |
897 | res->end = res->start + (HBA_PORT_SPACE_SIZE - 1); | 888 | res->end = res->start + (HBA_PORT_SPACE_SIZE - 1); |
898 | res->flags = IORESOURCE_IO; /* do not mark it busy ! */ | 889 | res->flags = IORESOURCE_IO; /* do not mark it busy ! */ |
899 | if (request_resource(&ioport_resource, res) < 0) { | 890 | if (request_resource(&ioport_resource, res) < 0) { |
900 | printk(KERN_ERR "%s: request I/O Port region failed " | 891 | printk(KERN_ERR "%s: request I/O Port region failed " |
901 | "0x%lx/%lx (hpa 0x%p)\n", | 892 | "0x%lx/%lx (hpa 0x%p)\n", |
902 | name, (unsigned long)res->start, (unsigned long)res->end, | 893 | name, (unsigned long)res->start, (unsigned long)res->end, |
903 | dino_dev->hba.base_addr); | 894 | dino_dev->hba.base_addr); |
904 | return 1; | 895 | return 1; |
905 | } | 896 | } |
906 | 897 | ||
907 | return 0; | 898 | return 0; |
908 | } | 899 | } |
909 | 900 | ||
910 | #define CUJO_RAVEN_ADDR F_EXTEND(0xf1000000UL) | 901 | #define CUJO_RAVEN_ADDR F_EXTEND(0xf1000000UL) |
911 | #define CUJO_FIREHAWK_ADDR F_EXTEND(0xf1604000UL) | 902 | #define CUJO_FIREHAWK_ADDR F_EXTEND(0xf1604000UL) |
912 | #define CUJO_RAVEN_BADPAGE 0x01003000UL | 903 | #define CUJO_RAVEN_BADPAGE 0x01003000UL |
913 | #define CUJO_FIREHAWK_BADPAGE 0x01607000UL | 904 | #define CUJO_FIREHAWK_BADPAGE 0x01607000UL |
914 | 905 | ||
915 | static const char *dino_vers[] = { | 906 | static const char *dino_vers[] = { |
916 | "2.0", | 907 | "2.0", |
917 | "2.1", | 908 | "2.1", |
918 | "3.0", | 909 | "3.0", |
919 | "3.1" | 910 | "3.1" |
920 | }; | 911 | }; |
921 | 912 | ||
922 | static const char *cujo_vers[] = { | 913 | static const char *cujo_vers[] = { |
923 | "1.0", | 914 | "1.0", |
924 | "2.0" | 915 | "2.0" |
925 | }; | 916 | }; |
926 | 917 | ||
927 | void ccio_cujo20_fixup(struct parisc_device *dev, u32 iovp); | 918 | void ccio_cujo20_fixup(struct parisc_device *dev, u32 iovp); |
928 | 919 | ||
929 | /* | 920 | /* |
930 | ** Determine if dino should claim this chip (return 0) or not (return 1). | 921 | ** Determine if dino should claim this chip (return 0) or not (return 1). |
931 | ** If so, initialize the chip appropriately (card-mode vs bridge mode). | 922 | ** If so, initialize the chip appropriately (card-mode vs bridge mode). |
932 | ** Much of the initialization is common though. | 923 | ** Much of the initialization is common though. |
933 | */ | 924 | */ |
934 | static int __init dino_probe(struct parisc_device *dev) | 925 | static int __init dino_probe(struct parisc_device *dev) |
935 | { | 926 | { |
936 | struct dino_device *dino_dev; // Dino specific control struct | 927 | struct dino_device *dino_dev; // Dino specific control struct |
937 | const char *version = "unknown"; | 928 | const char *version = "unknown"; |
938 | char *name; | 929 | char *name; |
939 | int is_cujo = 0; | 930 | int is_cujo = 0; |
940 | struct pci_bus *bus; | 931 | struct pci_bus *bus; |
941 | unsigned long hpa = dev->hpa.start; | 932 | unsigned long hpa = dev->hpa.start; |
942 | 933 | ||
943 | name = "Dino"; | 934 | name = "Dino"; |
944 | if (is_card_dino(&dev->id)) { | 935 | if (is_card_dino(&dev->id)) { |
945 | version = "3.x (card mode)"; | 936 | version = "3.x (card mode)"; |
946 | } else { | 937 | } else { |
947 | if (!is_cujo(&dev->id)) { | 938 | if (!is_cujo(&dev->id)) { |
948 | if (dev->id.hversion_rev < 4) { | 939 | if (dev->id.hversion_rev < 4) { |
949 | version = dino_vers[dev->id.hversion_rev]; | 940 | version = dino_vers[dev->id.hversion_rev]; |
950 | } | 941 | } |
951 | } else { | 942 | } else { |
952 | name = "Cujo"; | 943 | name = "Cujo"; |
953 | is_cujo = 1; | 944 | is_cujo = 1; |
954 | if (dev->id.hversion_rev < 2) { | 945 | if (dev->id.hversion_rev < 2) { |
955 | version = cujo_vers[dev->id.hversion_rev]; | 946 | version = cujo_vers[dev->id.hversion_rev]; |
956 | } | 947 | } |
957 | } | 948 | } |
958 | } | 949 | } |
959 | 950 | ||
960 | printk("%s version %s found at 0x%lx\n", name, version, hpa); | 951 | printk("%s version %s found at 0x%lx\n", name, version, hpa); |
961 | 952 | ||
962 | if (!request_mem_region(hpa, PAGE_SIZE, name)) { | 953 | if (!request_mem_region(hpa, PAGE_SIZE, name)) { |
963 | printk(KERN_ERR "DINO: Hey! Someone took my MMIO space (0x%ld)!\n", | 954 | printk(KERN_ERR "DINO: Hey! Someone took my MMIO space (0x%ld)!\n", |
964 | hpa); | 955 | hpa); |
965 | return 1; | 956 | return 1; |
966 | } | 957 | } |
967 | 958 | ||
968 | /* Check for bugs */ | 959 | /* Check for bugs */ |
969 | if (is_cujo && dev->id.hversion_rev == 1) { | 960 | if (is_cujo && dev->id.hversion_rev == 1) { |
970 | #ifdef CONFIG_IOMMU_CCIO | 961 | #ifdef CONFIG_IOMMU_CCIO |
971 | printk(KERN_WARNING "Enabling Cujo 2.0 bug workaround\n"); | 962 | printk(KERN_WARNING "Enabling Cujo 2.0 bug workaround\n"); |
972 | if (hpa == (unsigned long)CUJO_RAVEN_ADDR) { | 963 | if (hpa == (unsigned long)CUJO_RAVEN_ADDR) { |
973 | ccio_cujo20_fixup(dev, CUJO_RAVEN_BADPAGE); | 964 | ccio_cujo20_fixup(dev, CUJO_RAVEN_BADPAGE); |
974 | } else if (hpa == (unsigned long)CUJO_FIREHAWK_ADDR) { | 965 | } else if (hpa == (unsigned long)CUJO_FIREHAWK_ADDR) { |
975 | ccio_cujo20_fixup(dev, CUJO_FIREHAWK_BADPAGE); | 966 | ccio_cujo20_fixup(dev, CUJO_FIREHAWK_BADPAGE); |
976 | } else { | 967 | } else { |
977 | printk("Don't recognise Cujo at address 0x%lx, not enabling workaround\n", hpa); | 968 | printk("Don't recognise Cujo at address 0x%lx, not enabling workaround\n", hpa); |
978 | } | 969 | } |
979 | #endif | 970 | #endif |
980 | } else if (!is_cujo && !is_card_dino(&dev->id) && | 971 | } else if (!is_cujo && !is_card_dino(&dev->id) && |
981 | dev->id.hversion_rev < 3) { | 972 | dev->id.hversion_rev < 3) { |
982 | printk(KERN_WARNING | 973 | printk(KERN_WARNING |
983 | "The GSCtoPCI (Dino hrev %d) bus converter found may exhibit\n" | 974 | "The GSCtoPCI (Dino hrev %d) bus converter found may exhibit\n" |
984 | "data corruption. See Service Note Numbers: A4190A-01, A4191A-01.\n" | 975 | "data corruption. See Service Note Numbers: A4190A-01, A4191A-01.\n" |
985 | "Systems shipped after Aug 20, 1997 will not exhibit this problem.\n" | 976 | "Systems shipped after Aug 20, 1997 will not exhibit this problem.\n" |
986 | "Models affected: C180, C160, C160L, B160L, and B132L workstations.\n\n", | 977 | "Models affected: C180, C160, C160L, B160L, and B132L workstations.\n\n", |
987 | dev->id.hversion_rev); | 978 | dev->id.hversion_rev); |
988 | /* REVISIT: why are C200/C240 listed in the README table but not | 979 | /* REVISIT: why are C200/C240 listed in the README table but not |
989 | ** "Models affected"? Could be an omission in the original literature. | 980 | ** "Models affected"? Could be an omission in the original literature. |
990 | */ | 981 | */ |
991 | } | 982 | } |
992 | 983 | ||
993 | dino_dev = kzalloc(sizeof(struct dino_device), GFP_KERNEL); | 984 | dino_dev = kzalloc(sizeof(struct dino_device), GFP_KERNEL); |
994 | if (!dino_dev) { | 985 | if (!dino_dev) { |
995 | printk("dino_init_chip - couldn't alloc dino_device\n"); | 986 | printk("dino_init_chip - couldn't alloc dino_device\n"); |
996 | return 1; | 987 | return 1; |
997 | } | 988 | } |
998 | 989 | ||
999 | dino_dev->hba.dev = dev; | 990 | dino_dev->hba.dev = dev; |
1000 | dino_dev->hba.base_addr = ioremap_nocache(hpa, 4096); | 991 | dino_dev->hba.base_addr = ioremap_nocache(hpa, 4096); |
1001 | dino_dev->hba.lmmio_space_offset = 0; /* CPU addrs == bus addrs */ | 992 | dino_dev->hba.lmmio_space_offset = 0; /* CPU addrs == bus addrs */ |
1002 | spin_lock_init(&dino_dev->dinosaur_pen); | 993 | spin_lock_init(&dino_dev->dinosaur_pen); |
1003 | dino_dev->hba.iommu = ccio_get_iommu(dev); | 994 | dino_dev->hba.iommu = ccio_get_iommu(dev); |
1004 | 995 | ||
1005 | if (is_card_dino(&dev->id)) { | 996 | if (is_card_dino(&dev->id)) { |
1006 | dino_card_init(dino_dev); | 997 | dino_card_init(dino_dev); |
1007 | } else { | 998 | } else { |
1008 | dino_bridge_init(dino_dev, name); | 999 | dino_bridge_init(dino_dev, name); |
1009 | } | 1000 | } |
1010 | 1001 | ||
1011 | if (dino_common_init(dev, dino_dev, name)) | 1002 | if (dino_common_init(dev, dino_dev, name)) |
1012 | return 1; | 1003 | return 1; |
1013 | 1004 | ||
1014 | dev->dev.platform_data = dino_dev; | 1005 | dev->dev.platform_data = dino_dev; |
1015 | 1006 | ||
1016 | /* | 1007 | /* |
1017 | ** It's not used to avoid chicken/egg problems | 1008 | ** It's not used to avoid chicken/egg problems |
1018 | ** with configuration accessor functions. | 1009 | ** with configuration accessor functions. |
1019 | */ | 1010 | */ |
1020 | dino_dev->hba.hba_bus = bus = pci_scan_bus_parented(&dev->dev, | 1011 | dino_dev->hba.hba_bus = bus = pci_scan_bus_parented(&dev->dev, |
1021 | dino_current_bus, &dino_cfg_ops, NULL); | 1012 | dino_current_bus, &dino_cfg_ops, NULL); |
1022 | 1013 | ||
1023 | if(bus) { | 1014 | if(bus) { |
1024 | /* This code *depends* on scanning being single threaded | 1015 | /* This code *depends* on scanning being single threaded |
1025 | * if it isn't, this global bus number count will fail | 1016 | * if it isn't, this global bus number count will fail |
1026 | */ | 1017 | */ |
1027 | dino_current_bus = bus->subordinate + 1; | 1018 | dino_current_bus = bus->subordinate + 1; |
1028 | pci_bus_assign_resources(bus); | 1019 | pci_bus_assign_resources(bus); |
1029 | pci_bus_add_devices(bus); | 1020 | pci_bus_add_devices(bus); |
1030 | } else { | 1021 | } else { |
1031 | printk(KERN_ERR "ERROR: failed to scan PCI bus on %s (duplicate bus number %d?)\n", | 1022 | printk(KERN_ERR "ERROR: failed to scan PCI bus on %s (duplicate bus number %d?)\n", |
1032 | dev_name(&dev->dev), dino_current_bus); | 1023 | dev_name(&dev->dev), dino_current_bus); |
1033 | /* increment the bus number in case of duplicates */ | 1024 | /* increment the bus number in case of duplicates */ |
1034 | dino_current_bus++; | 1025 | dino_current_bus++; |
1035 | } | 1026 | } |
1036 | return 0; | 1027 | return 0; |
1037 | } | 1028 | } |
1038 | 1029 | ||
1039 | /* | 1030 | /* |
1040 | * Normally, we would just test sversion. But the Elroy PCI adapter has | 1031 | * Normally, we would just test sversion. But the Elroy PCI adapter has |
1041 | * the same sversion as Dino, so we have to check hversion as well. | 1032 | * the same sversion as Dino, so we have to check hversion as well. |
1042 | * Unfortunately, the J2240 PDC reports the wrong hversion for the first | 1033 | * Unfortunately, the J2240 PDC reports the wrong hversion for the first |
1043 | * Dino, so we have to test for Dino, Cujo and Dino-in-a-J2240. | 1034 | * Dino, so we have to test for Dino, Cujo and Dino-in-a-J2240. |
1044 | * For card-mode Dino, most machines report an sversion of 9D. But 715 | 1035 | * For card-mode Dino, most machines report an sversion of 9D. But 715 |
1045 | * and 725 firmware misreport it as 0x08080 for no adequately explained | 1036 | * and 725 firmware misreport it as 0x08080 for no adequately explained |
1046 | * reason. | 1037 | * reason. |
1047 | */ | 1038 | */ |
1048 | static struct parisc_device_id dino_tbl[] = { | 1039 | static struct parisc_device_id dino_tbl[] = { |
1049 | { HPHW_A_DMA, HVERSION_REV_ANY_ID, 0x004, 0x0009D },/* Card-mode Dino */ | 1040 | { HPHW_A_DMA, HVERSION_REV_ANY_ID, 0x004, 0x0009D },/* Card-mode Dino */ |
1050 | { HPHW_A_DMA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x08080 }, /* XXX */ | 1041 | { HPHW_A_DMA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x08080 }, /* XXX */ |
1051 | { HPHW_BRIDGE, HVERSION_REV_ANY_ID, 0x680, 0xa }, /* Bridge-mode Dino */ | 1042 | { HPHW_BRIDGE, HVERSION_REV_ANY_ID, 0x680, 0xa }, /* Bridge-mode Dino */ |
1052 | { HPHW_BRIDGE, HVERSION_REV_ANY_ID, 0x682, 0xa }, /* Bridge-mode Cujo */ | 1043 | { HPHW_BRIDGE, HVERSION_REV_ANY_ID, 0x682, 0xa }, /* Bridge-mode Cujo */ |
1053 | { HPHW_BRIDGE, HVERSION_REV_ANY_ID, 0x05d, 0xa }, /* Dino in a J2240 */ | 1044 | { HPHW_BRIDGE, HVERSION_REV_ANY_ID, 0x05d, 0xa }, /* Dino in a J2240 */ |
1054 | { 0, } | 1045 | { 0, } |
1055 | }; | 1046 | }; |
1056 | 1047 | ||
1057 | static struct parisc_driver dino_driver = { | 1048 | static struct parisc_driver dino_driver = { |
1058 | .name = "dino", | 1049 | .name = "dino", |
1059 | .id_table = dino_tbl, | 1050 | .id_table = dino_tbl, |
1060 | .probe = dino_probe, | 1051 | .probe = dino_probe, |
1061 | }; | 1052 | }; |
1062 | 1053 | ||
1063 | /* | 1054 | /* |
1064 | * One time initialization to let the world know Dino is here. | 1055 | * One time initialization to let the world know Dino is here. |
1065 | * This is the only routine which is NOT static. | 1056 | * This is the only routine which is NOT static. |
1066 | * Must be called exactly once before pci_init(). | 1057 | * Must be called exactly once before pci_init(). |
1067 | */ | 1058 | */ |
1068 | int __init dino_init(void) | 1059 | int __init dino_init(void) |
1069 | { | 1060 | { |
1070 | register_parisc_driver(&dino_driver); | 1061 | register_parisc_driver(&dino_driver); |
1071 | return 0; | 1062 | return 0; |
1072 | } | 1063 | } |
1073 | 1064 | ||
1074 | 1065 |
drivers/parisc/gsc.c
1 | /* | 1 | /* |
2 | * Interrupt management for most GSC and related devices. | 2 | * Interrupt management for most GSC and related devices. |
3 | * | 3 | * |
4 | * (c) Copyright 1999 Alex deVries for The Puffin Group | 4 | * (c) Copyright 1999 Alex deVries for The Puffin Group |
5 | * (c) Copyright 1999 Grant Grundler for Hewlett-Packard | 5 | * (c) Copyright 1999 Grant Grundler for Hewlett-Packard |
6 | * (c) Copyright 1999 Matthew Wilcox | 6 | * (c) Copyright 1999 Matthew Wilcox |
7 | * (c) Copyright 2000 Helge Deller | 7 | * (c) Copyright 2000 Helge Deller |
8 | * (c) Copyright 2001 Matthew Wilcox for Hewlett-Packard | 8 | * (c) Copyright 2001 Matthew Wilcox for Hewlett-Packard |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
12 | * the Free Software Foundation; either version 2 of the License, or | 12 | * the Free Software Foundation; either version 2 of the License, or |
13 | * (at your option) any later version. | 13 | * (at your option) any later version. |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/bitops.h> | 16 | #include <linux/bitops.h> |
17 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/ioport.h> | 20 | #include <linux/ioport.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/types.h> | 22 | #include <linux/types.h> |
23 | 23 | ||
24 | #include <asm/hardware.h> | 24 | #include <asm/hardware.h> |
25 | #include <asm/io.h> | 25 | #include <asm/io.h> |
26 | 26 | ||
27 | #include "gsc.h" | 27 | #include "gsc.h" |
28 | 28 | ||
29 | #undef DEBUG | 29 | #undef DEBUG |
30 | 30 | ||
31 | #ifdef DEBUG | 31 | #ifdef DEBUG |
32 | #define DEBPRINTK printk | 32 | #define DEBPRINTK printk |
33 | #else | 33 | #else |
34 | #define DEBPRINTK(x,...) | 34 | #define DEBPRINTK(x,...) |
35 | #endif | 35 | #endif |
36 | 36 | ||
37 | int gsc_alloc_irq(struct gsc_irq *i) | 37 | int gsc_alloc_irq(struct gsc_irq *i) |
38 | { | 38 | { |
39 | int irq = txn_alloc_irq(GSC_EIM_WIDTH); | 39 | int irq = txn_alloc_irq(GSC_EIM_WIDTH); |
40 | if (irq < 0) { | 40 | if (irq < 0) { |
41 | printk("cannot get irq\n"); | 41 | printk("cannot get irq\n"); |
42 | return irq; | 42 | return irq; |
43 | } | 43 | } |
44 | 44 | ||
45 | i->txn_addr = txn_alloc_addr(irq); | 45 | i->txn_addr = txn_alloc_addr(irq); |
46 | i->txn_data = txn_alloc_data(irq); | 46 | i->txn_data = txn_alloc_data(irq); |
47 | i->irq = irq; | 47 | i->irq = irq; |
48 | 48 | ||
49 | return irq; | 49 | return irq; |
50 | } | 50 | } |
51 | 51 | ||
52 | int gsc_claim_irq(struct gsc_irq *i, int irq) | 52 | int gsc_claim_irq(struct gsc_irq *i, int irq) |
53 | { | 53 | { |
54 | int c = irq; | 54 | int c = irq; |
55 | 55 | ||
56 | irq += CPU_IRQ_BASE; /* virtualize the IRQ first */ | 56 | irq += CPU_IRQ_BASE; /* virtualize the IRQ first */ |
57 | 57 | ||
58 | irq = txn_claim_irq(irq); | 58 | irq = txn_claim_irq(irq); |
59 | if (irq < 0) { | 59 | if (irq < 0) { |
60 | printk("cannot claim irq %d\n", c); | 60 | printk("cannot claim irq %d\n", c); |
61 | return irq; | 61 | return irq; |
62 | } | 62 | } |
63 | 63 | ||
64 | i->txn_addr = txn_alloc_addr(irq); | 64 | i->txn_addr = txn_alloc_addr(irq); |
65 | i->txn_data = txn_alloc_data(irq); | 65 | i->txn_data = txn_alloc_data(irq); |
66 | i->irq = irq; | 66 | i->irq = irq; |
67 | 67 | ||
68 | return irq; | 68 | return irq; |
69 | } | 69 | } |
70 | 70 | ||
71 | EXPORT_SYMBOL(gsc_alloc_irq); | 71 | EXPORT_SYMBOL(gsc_alloc_irq); |
72 | EXPORT_SYMBOL(gsc_claim_irq); | 72 | EXPORT_SYMBOL(gsc_claim_irq); |
73 | 73 | ||
74 | /* Common interrupt demultiplexer used by Asp, Lasi & Wax. */ | 74 | /* Common interrupt demultiplexer used by Asp, Lasi & Wax. */ |
75 | irqreturn_t gsc_asic_intr(int gsc_asic_irq, void *dev) | 75 | irqreturn_t gsc_asic_intr(int gsc_asic_irq, void *dev) |
76 | { | 76 | { |
77 | unsigned long irr; | 77 | unsigned long irr; |
78 | struct gsc_asic *gsc_asic = dev; | 78 | struct gsc_asic *gsc_asic = dev; |
79 | 79 | ||
80 | irr = gsc_readl(gsc_asic->hpa + OFFSET_IRR); | 80 | irr = gsc_readl(gsc_asic->hpa + OFFSET_IRR); |
81 | if (irr == 0) | 81 | if (irr == 0) |
82 | return IRQ_NONE; | 82 | return IRQ_NONE; |
83 | 83 | ||
84 | DEBPRINTK("%s intr, mask=0x%x\n", gsc_asic->name, irr); | 84 | DEBPRINTK("%s intr, mask=0x%x\n", gsc_asic->name, irr); |
85 | 85 | ||
86 | do { | 86 | do { |
87 | int local_irq = __ffs(irr); | 87 | int local_irq = __ffs(irr); |
88 | unsigned int irq = gsc_asic->global_irq[local_irq]; | 88 | unsigned int irq = gsc_asic->global_irq[local_irq]; |
89 | generic_handle_irq(irq); | 89 | generic_handle_irq(irq); |
90 | irr &= ~(1 << local_irq); | 90 | irr &= ~(1 << local_irq); |
91 | } while (irr); | 91 | } while (irr); |
92 | 92 | ||
93 | return IRQ_HANDLED; | 93 | return IRQ_HANDLED; |
94 | } | 94 | } |
95 | 95 | ||
96 | int gsc_find_local_irq(unsigned int irq, int *global_irqs, int limit) | 96 | int gsc_find_local_irq(unsigned int irq, int *global_irqs, int limit) |
97 | { | 97 | { |
98 | int local_irq; | 98 | int local_irq; |
99 | 99 | ||
100 | for (local_irq = 0; local_irq < limit; local_irq++) { | 100 | for (local_irq = 0; local_irq < limit; local_irq++) { |
101 | if (global_irqs[local_irq] == irq) | 101 | if (global_irqs[local_irq] == irq) |
102 | return local_irq; | 102 | return local_irq; |
103 | } | 103 | } |
104 | 104 | ||
105 | return NO_IRQ; | 105 | return NO_IRQ; |
106 | } | 106 | } |
107 | 107 | ||
108 | static void gsc_asic_disable_irq(unsigned int irq) | 108 | static void gsc_asic_mask_irq(unsigned int irq) |
109 | { | 109 | { |
110 | struct gsc_asic *irq_dev = get_irq_chip_data(irq); | 110 | struct gsc_asic *irq_dev = get_irq_chip_data(irq); |
111 | int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); | 111 | int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); |
112 | u32 imr; | 112 | u32 imr; |
113 | 113 | ||
114 | DEBPRINTK(KERN_DEBUG "%s(%d) %s: IMR 0x%x\n", __func__, irq, | 114 | DEBPRINTK(KERN_DEBUG "%s(%d) %s: IMR 0x%x\n", __func__, irq, |
115 | irq_dev->name, imr); | 115 | irq_dev->name, imr); |
116 | 116 | ||
117 | /* Disable the IRQ line by clearing the bit in the IMR */ | 117 | /* Disable the IRQ line by clearing the bit in the IMR */ |
118 | imr = gsc_readl(irq_dev->hpa + OFFSET_IMR); | 118 | imr = gsc_readl(irq_dev->hpa + OFFSET_IMR); |
119 | imr &= ~(1 << local_irq); | 119 | imr &= ~(1 << local_irq); |
120 | gsc_writel(imr, irq_dev->hpa + OFFSET_IMR); | 120 | gsc_writel(imr, irq_dev->hpa + OFFSET_IMR); |
121 | } | 121 | } |
122 | 122 | ||
123 | static void gsc_asic_enable_irq(unsigned int irq) | 123 | static void gsc_asic_unmask_irq(unsigned int irq) |
124 | { | 124 | { |
125 | struct gsc_asic *irq_dev = get_irq_chip_data(irq); | 125 | struct gsc_asic *irq_dev = get_irq_chip_data(irq); |
126 | int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); | 126 | int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); |
127 | u32 imr; | 127 | u32 imr; |
128 | 128 | ||
129 | DEBPRINTK(KERN_DEBUG "%s(%d) %s: IMR 0x%x\n", __func__, irq, | 129 | DEBPRINTK(KERN_DEBUG "%s(%d) %s: IMR 0x%x\n", __func__, irq, |
130 | irq_dev->name, imr); | 130 | irq_dev->name, imr); |
131 | 131 | ||
132 | /* Enable the IRQ line by setting the bit in the IMR */ | 132 | /* Enable the IRQ line by setting the bit in the IMR */ |
133 | imr = gsc_readl(irq_dev->hpa + OFFSET_IMR); | 133 | imr = gsc_readl(irq_dev->hpa + OFFSET_IMR); |
134 | imr |= 1 << local_irq; | 134 | imr |= 1 << local_irq; |
135 | gsc_writel(imr, irq_dev->hpa + OFFSET_IMR); | 135 | gsc_writel(imr, irq_dev->hpa + OFFSET_IMR); |
136 | /* | 136 | /* |
137 | * FIXME: read IPR to make sure the IRQ isn't already pending. | 137 | * FIXME: read IPR to make sure the IRQ isn't already pending. |
138 | * If so, we need to read IRR and manually call do_irq(). | 138 | * If so, we need to read IRR and manually call do_irq(). |
139 | */ | 139 | */ |
140 | } | 140 | } |
141 | 141 | ||
142 | static unsigned int gsc_asic_startup_irq(unsigned int irq) | ||
143 | { | ||
144 | gsc_asic_enable_irq(irq); | ||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | static struct irq_chip gsc_asic_interrupt_type = { | 142 | static struct irq_chip gsc_asic_interrupt_type = { |
149 | .name = "GSC-ASIC", | 143 | .name = "GSC-ASIC", |
150 | .startup = gsc_asic_startup_irq, | 144 | .unmask = gsc_asic_unmask_irq, |
151 | .shutdown = gsc_asic_disable_irq, | 145 | .mask = gsc_asic_mask_irq, |
152 | .enable = gsc_asic_enable_irq, | 146 | .ack = no_ack_irq, |
153 | .disable = gsc_asic_disable_irq, | ||
154 | .ack = no_ack_irq, | ||
155 | .end = no_end_irq, | ||
156 | }; | 147 | }; |
157 | 148 | ||
158 | int gsc_assign_irq(struct irq_chip *type, void *data) | 149 | int gsc_assign_irq(struct irq_chip *type, void *data) |
159 | { | 150 | { |
160 | static int irq = GSC_IRQ_BASE; | 151 | static int irq = GSC_IRQ_BASE; |
161 | 152 | ||
162 | if (irq > GSC_IRQ_MAX) | 153 | if (irq > GSC_IRQ_MAX) |
163 | return NO_IRQ; | 154 | return NO_IRQ; |
164 | 155 | ||
165 | set_irq_chip_and_handler(irq, type, parisc_do_IRQ); | 156 | set_irq_chip_and_handler(irq, type, handle_level_irq); |
166 | set_irq_chip_data(irq, data); | 157 | set_irq_chip_data(irq, data); |
167 | 158 | ||
168 | return irq++; | 159 | return irq++; |
169 | } | 160 | } |
170 | 161 | ||
171 | void gsc_asic_assign_irq(struct gsc_asic *asic, int local_irq, int *irqp) | 162 | void gsc_asic_assign_irq(struct gsc_asic *asic, int local_irq, int *irqp) |
172 | { | 163 | { |
173 | int irq = asic->global_irq[local_irq]; | 164 | int irq = asic->global_irq[local_irq]; |
174 | 165 | ||
175 | if (irq <= 0) { | 166 | if (irq <= 0) { |
176 | irq = gsc_assign_irq(&gsc_asic_interrupt_type, asic); | 167 | irq = gsc_assign_irq(&gsc_asic_interrupt_type, asic); |
177 | if (irq == NO_IRQ) | 168 | if (irq == NO_IRQ) |
178 | return; | 169 | return; |
179 | 170 | ||
180 | asic->global_irq[local_irq] = irq; | 171 | asic->global_irq[local_irq] = irq; |
181 | } | 172 | } |
182 | *irqp = irq; | 173 | *irqp = irq; |
183 | } | 174 | } |
184 | 175 | ||
185 | struct gsc_fixup_struct { | 176 | struct gsc_fixup_struct { |
186 | void (*choose_irq)(struct parisc_device *, void *); | 177 | void (*choose_irq)(struct parisc_device *, void *); |
187 | void *ctrl; | 178 | void *ctrl; |
188 | }; | 179 | }; |
189 | 180 | ||
190 | static int gsc_fixup_irqs_callback(struct device *dev, void *data) | 181 | static int gsc_fixup_irqs_callback(struct device *dev, void *data) |
191 | { | 182 | { |
192 | struct parisc_device *padev = to_parisc_device(dev); | 183 | struct parisc_device *padev = to_parisc_device(dev); |
193 | struct gsc_fixup_struct *gf = data; | 184 | struct gsc_fixup_struct *gf = data; |
194 | 185 | ||
195 | /* work-around for 715/64 and others which have parent | 186 | /* work-around for 715/64 and others which have parent |
196 | at path [5] and children at path [5/0/x] */ | 187 | at path [5] and children at path [5/0/x] */ |
197 | if (padev->id.hw_type == HPHW_FAULTY) | 188 | if (padev->id.hw_type == HPHW_FAULTY) |
198 | gsc_fixup_irqs(padev, gf->ctrl, gf->choose_irq); | 189 | gsc_fixup_irqs(padev, gf->ctrl, gf->choose_irq); |
199 | gf->choose_irq(padev, gf->ctrl); | 190 | gf->choose_irq(padev, gf->ctrl); |
200 | 191 | ||
201 | return 0; | 192 | return 0; |
202 | } | 193 | } |
203 | 194 | ||
204 | void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl, | 195 | void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl, |
205 | void (*choose_irq)(struct parisc_device *, void *)) | 196 | void (*choose_irq)(struct parisc_device *, void *)) |
206 | { | 197 | { |
207 | struct gsc_fixup_struct data = { | 198 | struct gsc_fixup_struct data = { |
208 | .choose_irq = choose_irq, | 199 | .choose_irq = choose_irq, |
209 | .ctrl = ctrl, | 200 | .ctrl = ctrl, |
210 | }; | 201 | }; |
211 | 202 | ||
212 | device_for_each_child(&parent->dev, &data, gsc_fixup_irqs_callback); | 203 | device_for_each_child(&parent->dev, &data, gsc_fixup_irqs_callback); |
213 | } | 204 | } |
214 | 205 | ||
215 | int gsc_common_setup(struct parisc_device *parent, struct gsc_asic *gsc_asic) | 206 | int gsc_common_setup(struct parisc_device *parent, struct gsc_asic *gsc_asic) |
216 | { | 207 | { |
217 | struct resource *res; | 208 | struct resource *res; |
218 | int i; | 209 | int i; |
219 | 210 | ||
220 | gsc_asic->gsc = parent; | 211 | gsc_asic->gsc = parent; |
221 | 212 | ||
222 | /* Initialise local irq -> global irq mapping */ | 213 | /* Initialise local irq -> global irq mapping */ |
223 | for (i = 0; i < 32; i++) { | 214 | for (i = 0; i < 32; i++) { |
224 | gsc_asic->global_irq[i] = NO_IRQ; | 215 | gsc_asic->global_irq[i] = NO_IRQ; |
225 | } | 216 | } |
226 | 217 | ||
227 | /* allocate resource region */ | 218 | /* allocate resource region */ |
228 | res = request_mem_region(gsc_asic->hpa, 0x100000, gsc_asic->name); | 219 | res = request_mem_region(gsc_asic->hpa, 0x100000, gsc_asic->name); |
229 | if (res) { | 220 | if (res) { |
230 | res->flags = IORESOURCE_MEM; /* do not mark it busy ! */ | 221 | res->flags = IORESOURCE_MEM; /* do not mark it busy ! */ |
231 | } | 222 | } |
232 | 223 | ||
233 | #if 0 | 224 | #if 0 |
234 | printk(KERN_WARNING "%s IRQ %d EIM 0x%x", gsc_asic->name, | 225 | printk(KERN_WARNING "%s IRQ %d EIM 0x%x", gsc_asic->name, |
235 | parent->irq, gsc_asic->eim); | 226 | parent->irq, gsc_asic->eim); |
236 | if (gsc_readl(gsc_asic->hpa + OFFSET_IMR)) | 227 | if (gsc_readl(gsc_asic->hpa + OFFSET_IMR)) |
237 | printk(" IMR is non-zero! (0x%x)", | 228 | printk(" IMR is non-zero! (0x%x)", |
238 | gsc_readl(gsc_asic->hpa + OFFSET_IMR)); | 229 | gsc_readl(gsc_asic->hpa + OFFSET_IMR)); |
239 | printk("\n"); | 230 | printk("\n"); |
240 | #endif | 231 | #endif |
241 | 232 | ||
242 | return 0; | 233 | return 0; |
243 | } | 234 | } |
244 | 235 | ||
245 | extern struct parisc_driver lasi_driver; | 236 | extern struct parisc_driver lasi_driver; |
246 | extern struct parisc_driver asp_driver; | 237 | extern struct parisc_driver asp_driver; |
247 | extern struct parisc_driver wax_driver; | 238 | extern struct parisc_driver wax_driver; |
248 | 239 | ||
249 | void __init gsc_init(void) | 240 | void __init gsc_init(void) |
250 | { | 241 | { |
251 | #ifdef CONFIG_GSC_LASI | 242 | #ifdef CONFIG_GSC_LASI |
252 | register_parisc_driver(&lasi_driver); | 243 | register_parisc_driver(&lasi_driver); |
253 | register_parisc_driver(&asp_driver); | 244 | register_parisc_driver(&asp_driver); |
254 | #endif | 245 | #endif |
255 | #ifdef CONFIG_GSC_WAX | 246 | #ifdef CONFIG_GSC_WAX |
256 | register_parisc_driver(&wax_driver); | 247 | register_parisc_driver(&wax_driver); |
257 | #endif | 248 | #endif |
258 | } | 249 | } |
259 | 250 |