aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sparc/Kconfig6
-rw-r--r--arch/sparc/include/asm/floppy_32.h40
-rw-r--r--arch/sparc/include/asm/irq_32.h6
-rw-r--r--arch/sparc/include/asm/system_32.h5
-rw-r--r--arch/sparc/kernel/Makefile4
-rw-r--r--arch/sparc/kernel/irq.h45
-rw-r--r--arch/sparc/kernel/irq_32.c494
-rw-r--r--arch/sparc/kernel/kernel.h1
-rw-r--r--arch/sparc/kernel/leon_kernel.c70
-rw-r--r--arch/sparc/kernel/pcic.c83
-rw-r--r--arch/sparc/kernel/sun4c_irq.c150
-rw-r--r--arch/sparc/kernel/sun4d_irq.c472
-rw-r--r--arch/sparc/kernel/sun4m_irq.c179
-rw-r--r--arch/sparc/kernel/sun4m_smp.c16
14 files changed, 636 insertions, 935 deletions
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index e560d102215a..a56630d4f14b 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -25,6 +25,10 @@ config SPARC
25 select HAVE_DMA_ATTRS 25 select HAVE_DMA_ATTRS
26 select HAVE_DMA_API_DEBUG 26 select HAVE_DMA_API_DEBUG
27 select HAVE_ARCH_JUMP_LABEL 27 select HAVE_ARCH_JUMP_LABEL
28 select HAVE_GENERIC_HARDIRQS
29 select GENERIC_HARDIRQS_NO_DEPRECATED
30 select GENERIC_IRQ_SHOW
31
28 32
29config SPARC32 33config SPARC32
30 def_bool !64BIT 34 def_bool !64BIT
@@ -50,8 +54,6 @@ config SPARC64
50 select RTC_DRV_STARFIRE 54 select RTC_DRV_STARFIRE
51 select HAVE_PERF_EVENTS 55 select HAVE_PERF_EVENTS
52 select PERF_USE_VMALLOC 56 select PERF_USE_VMALLOC
53 select HAVE_GENERIC_HARDIRQS
54 select GENERIC_IRQ_SHOW
55 select IRQ_PREFLOW_FASTEOI 57 select IRQ_PREFLOW_FASTEOI
56 58
57config ARCH_DEFCONFIG 59config ARCH_DEFCONFIG
diff --git a/arch/sparc/include/asm/floppy_32.h b/arch/sparc/include/asm/floppy_32.h
index 86666f70322e..482c79e2a416 100644
--- a/arch/sparc/include/asm/floppy_32.h
+++ b/arch/sparc/include/asm/floppy_32.h
@@ -281,28 +281,27 @@ static inline void sun_fd_enable_dma(void)
281 pdma_areasize = pdma_size; 281 pdma_areasize = pdma_size;
282} 282}
283 283
284/* Our low-level entry point in arch/sparc/kernel/entry.S */ 284extern int sparc_floppy_request_irq(unsigned int irq,
285extern int sparc_floppy_request_irq(int irq, unsigned long flags, 285 irq_handler_t irq_handler);
286 irq_handler_t irq_handler);
287 286
288static int sun_fd_request_irq(void) 287static int sun_fd_request_irq(void)
289{ 288{
290 static int once = 0; 289 static int once = 0;
291 int error;
292 290
293 if(!once) { 291 if (!once) {
294 once = 1; 292 once = 1;
295 error = sparc_floppy_request_irq(FLOPPY_IRQ, 293 return sparc_floppy_request_irq(FLOPPY_IRQ, floppy_interrupt);
296 IRQF_DISABLED, 294 } else {
297 floppy_interrupt); 295 return 0;
298 return ((error == 0) ? 0 : -1); 296 }
299 } else return 0;
300} 297}
301 298
302static struct linux_prom_registers fd_regs[2]; 299static struct linux_prom_registers fd_regs[2];
303 300
304static int sun_floppy_init(void) 301static int sun_floppy_init(void)
305{ 302{
303 struct platform_device *op;
304 struct device_node *dp;
306 char state[128]; 305 char state[128];
307 phandle tnode, fd_node; 306 phandle tnode, fd_node;
308 int num_regs; 307 int num_regs;
@@ -310,7 +309,6 @@ static int sun_floppy_init(void)
310 309
311 use_virtual_dma = 1; 310 use_virtual_dma = 1;
312 311
313 FLOPPY_IRQ = 11;
314 /* Forget it if we aren't on a machine that could possibly 312 /* Forget it if we aren't on a machine that could possibly
315 * ever have a floppy drive. 313 * ever have a floppy drive.
316 */ 314 */
@@ -349,6 +347,26 @@ static int sun_floppy_init(void)
349 sun_fdc = (struct sun_flpy_controller *) 347 sun_fdc = (struct sun_flpy_controller *)
350 of_ioremap(&r, 0, fd_regs[0].reg_size, "floppy"); 348 of_ioremap(&r, 0, fd_regs[0].reg_size, "floppy");
351 349
350 /* Look up irq in platform_device.
351 * We try "SUNW,fdtwo" and "fd"
352 */
353 for_each_node_by_name(dp, "SUNW,fdtwo") {
354 op = of_find_device_by_node(dp);
355 if (op)
356 break;
357 }
358 if (!op) {
359 for_each_node_by_name(dp, "fd") {
360 op = of_find_device_by_node(dp);
361 if (op)
362 break;
363 }
364 }
365 if (!op)
366 goto no_sun_fdc;
367
368 FLOPPY_IRQ = op->archdata.irqs[0];
369
352 /* Last minute sanity check... */ 370 /* Last minute sanity check... */
353 if(sun_fdc->status_82072 == 0xff) { 371 if(sun_fdc->status_82072 == 0xff) {
354 sun_fdc = NULL; 372 sun_fdc = NULL;
diff --git a/arch/sparc/include/asm/irq_32.h b/arch/sparc/include/asm/irq_32.h
index eced3e3ebd30..2ae3acaeb1b3 100644
--- a/arch/sparc/include/asm/irq_32.h
+++ b/arch/sparc/include/asm/irq_32.h
@@ -6,7 +6,11 @@
6#ifndef _SPARC_IRQ_H 6#ifndef _SPARC_IRQ_H
7#define _SPARC_IRQ_H 7#define _SPARC_IRQ_H
8 8
9#define NR_IRQS 16 9/* Allocated number of logical irq numbers.
10 * sun4d boxes (ss2000e) should be OK with ~32.
11 * Be on the safe side and make room for 64
12 */
13#define NR_IRQS 64
10 14
11#include <linux/interrupt.h> 15#include <linux/interrupt.h>
12 16
diff --git a/arch/sparc/include/asm/system_32.h b/arch/sparc/include/asm/system_32.h
index 890036b3689a..47a7e862474e 100644
--- a/arch/sparc/include/asm/system_32.h
+++ b/arch/sparc/include/asm/system_32.h
@@ -15,11 +15,6 @@
15 15
16#include <linux/irqflags.h> 16#include <linux/irqflags.h>
17 17
18static inline unsigned int probe_irq_mask(unsigned long val)
19{
20 return 0;
21}
22
23/* 18/*
24 * Sparc (general) CPU types 19 * Sparc (general) CPU types
25 */ 20 */
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index 99aa4db6e9c2..9cff2709a96d 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -71,10 +71,6 @@ obj-$(CONFIG_SPARC64) += pcr.o
71obj-$(CONFIG_SPARC64) += nmi.o 71obj-$(CONFIG_SPARC64) += nmi.o
72obj-$(CONFIG_SPARC64_SMP) += cpumap.o 72obj-$(CONFIG_SPARC64_SMP) += cpumap.o
73 73
74# sparc32 do not use GENERIC_HARDIRQS but uses the generic devres implementation
75obj-$(CONFIG_SPARC32) += devres.o
76devres-y := ../../../kernel/irq/devres.o
77
78obj-y += dma.o 74obj-y += dma.o
79 75
80obj-$(CONFIG_SPARC32_PCI) += pcic.o 76obj-$(CONFIG_SPARC32_PCI) += pcic.o
diff --git a/arch/sparc/kernel/irq.h b/arch/sparc/kernel/irq.h
index 008453b798ec..a189c273f638 100644
--- a/arch/sparc/kernel/irq.h
+++ b/arch/sparc/kernel/irq.h
@@ -2,6 +2,23 @@
2 2
3#include <asm/btfixup.h> 3#include <asm/btfixup.h>
4 4
5struct irq_bucket {
6 struct irq_bucket *next;
7 unsigned int real_irq;
8 unsigned int irq;
9 unsigned int pil;
10};
11
12#define SUN4D_MAX_BOARD 10
13#define SUN4D_MAX_IRQ ((SUN4D_MAX_BOARD + 2) << 5)
14
15/* Map between the irq identifier used in hw to the
16 * irq_bucket. The map is sufficient large to hold
17 * the sun4d hw identifiers.
18 */
19extern struct irq_bucket *irq_map[SUN4D_MAX_IRQ];
20
21
5/* sun4m specific type definitions */ 22/* sun4m specific type definitions */
6 23
7/* This maps direct to CPU specific interrupt registers */ 24/* This maps direct to CPU specific interrupt registers */
@@ -35,6 +52,10 @@ struct sparc_irq_config {
35}; 52};
36extern struct sparc_irq_config sparc_irq_config; 53extern struct sparc_irq_config sparc_irq_config;
37 54
55unsigned int irq_alloc(unsigned int real_irq, unsigned int pil);
56void irq_link(unsigned int irq);
57void irq_unlink(unsigned int irq);
58void handler_irq(unsigned int pil, struct pt_regs *regs);
38 59
39/* Dave Redman (djhr@tadpole.co.uk) 60/* Dave Redman (djhr@tadpole.co.uk)
40 * changed these to function pointers.. it saves cycles and will allow 61 * changed these to function pointers.. it saves cycles and will allow
@@ -44,33 +65,9 @@ extern struct sparc_irq_config sparc_irq_config;
44 * Changed these to btfixup entities... It saves cycles :) 65 * Changed these to btfixup entities... It saves cycles :)
45 */ 66 */
46 67
47BTFIXUPDEF_CALL(void, disable_irq, unsigned int)
48BTFIXUPDEF_CALL(void, enable_irq, unsigned int)
49BTFIXUPDEF_CALL(void, disable_pil_irq, unsigned int)
50BTFIXUPDEF_CALL(void, enable_pil_irq, unsigned int)
51BTFIXUPDEF_CALL(void, clear_clock_irq, void) 68BTFIXUPDEF_CALL(void, clear_clock_irq, void)
52BTFIXUPDEF_CALL(void, load_profile_irq, int, unsigned int) 69BTFIXUPDEF_CALL(void, load_profile_irq, int, unsigned int)
53 70
54static inline void __disable_irq(unsigned int irq)
55{
56 BTFIXUP_CALL(disable_irq)(irq);
57}
58
59static inline void __enable_irq(unsigned int irq)
60{
61 BTFIXUP_CALL(enable_irq)(irq);
62}
63
64static inline void disable_pil_irq(unsigned int irq)
65{
66 BTFIXUP_CALL(disable_pil_irq)(irq);
67}
68
69static inline void enable_pil_irq(unsigned int irq)
70{
71 BTFIXUP_CALL(enable_pil_irq)(irq);
72}
73
74static inline void clear_clock_irq(void) 71static inline void clear_clock_irq(void)
75{ 72{
76 BTFIXUP_CALL(clear_clock_irq)(); 73 BTFIXUP_CALL(clear_clock_irq)();
diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c
index b2dbb4ba8608..197e1ba85484 100644
--- a/arch/sparc/kernel/irq_32.c
+++ b/arch/sparc/kernel/irq_32.c
@@ -15,6 +15,7 @@
15#include <linux/seq_file.h> 15#include <linux/seq_file.h>
16 16
17#include <asm/cacheflush.h> 17#include <asm/cacheflush.h>
18#include <asm/cpudata.h>
18#include <asm/pcic.h> 19#include <asm/pcic.h>
19#include <asm/leon.h> 20#include <asm/leon.h>
20 21
@@ -101,284 +102,163 @@ EXPORT_SYMBOL(arch_local_irq_restore);
101 * directed CPU interrupts using the existing enable/disable irq code 102 * directed CPU interrupts using the existing enable/disable irq code
102 * with tweaks. 103 * with tweaks.
103 * 104 *
105 * Sun4d complicates things even further. IRQ numbers are arbitrary
106 * 32-bit values in that case. Since this is similar to sparc64,
107 * we adopt a virtual IRQ numbering scheme as is done there.
108 * Virutal interrupt numbers are allocated by build_irq(). So NR_IRQS
109 * just becomes a limit of how many interrupt sources we can handle in
110 * a single system. Even fully loaded SS2000 machines top off at
111 * about 32 interrupt sources or so, therefore a NR_IRQS value of 64
112 * is more than enough.
113 *
114 * We keep a map of per-PIL enable interrupts. These get wired
115 * up via the irq_chip->startup() method which gets invoked by
116 * the generic IRQ layer during request_irq().
104 */ 117 */
105 118
106 119
120/* Table of allocated irqs. Unused entries has irq == 0 */
121static struct irq_bucket irq_table[NR_IRQS];
122/* Protect access to irq_table */
123static DEFINE_SPINLOCK(irq_table_lock);
107 124
108/* 125/* Map between the irq identifier used in hw to the irq_bucket. */
109 * Dave Redman (djhr@tadpole.co.uk) 126struct irq_bucket *irq_map[SUN4D_MAX_IRQ];
110 * 127/* Protect access to irq_map */
111 * There used to be extern calls and hard coded values here.. very sucky! 128static DEFINE_SPINLOCK(irq_map_lock);
112 * instead, because some of the devices attach very early, I do something
113 * equally sucky but at least we'll never try to free statically allocated
114 * space or call kmalloc before kmalloc_init :(.
115 *
116 * In fact it's the timer10 that attaches first.. then timer14
117 * then kmalloc_init is called.. then the tty interrupts attach.
118 * hmmm....
119 *
120 */
121#define MAX_STATIC_ALLOC 4
122struct irqaction static_irqaction[MAX_STATIC_ALLOC];
123int static_irq_count;
124
125static struct {
126 struct irqaction *action;
127 int flags;
128} sparc_irq[NR_IRQS];
129#define SPARC_IRQ_INPROGRESS 1
130
131/* Used to protect the IRQ action lists */
132DEFINE_SPINLOCK(irq_action_lock);
133 129
134int show_interrupts(struct seq_file *p, void *v) 130/* Allocate a new irq from the irq_table */
131unsigned int irq_alloc(unsigned int real_irq, unsigned int pil)
135{ 132{
136 int i = *(loff_t *)v;
137 struct irqaction *action;
138 unsigned long flags; 133 unsigned long flags;
139#ifdef CONFIG_SMP 134 unsigned int i;
140 int j; 135
141#endif 136 spin_lock_irqsave(&irq_table_lock, flags);
137 for (i = 1; i < NR_IRQS; i++) {
138 if (irq_table[i].real_irq == real_irq && irq_table[i].pil == pil)
139 goto found;
140 }
142 141
143 if (sparc_cpu_model == sun4d) 142 for (i = 1; i < NR_IRQS; i++) {
144 return show_sun4d_interrupts(p, v); 143 if (!irq_table[i].irq)
144 break;
145 }
145 146
146 spin_lock_irqsave(&irq_action_lock, flags);
147 if (i < NR_IRQS) { 147 if (i < NR_IRQS) {
148 action = sparc_irq[i].action; 148 irq_table[i].real_irq = real_irq;
149 if (!action) 149 irq_table[i].irq = i;
150 goto out_unlock; 150 irq_table[i].pil = pil;
151 seq_printf(p, "%3d: ", i); 151 } else {
152#ifndef CONFIG_SMP 152 printk(KERN_ERR "IRQ: Out of virtual IRQs.\n");
153 seq_printf(p, "%10u ", kstat_irqs(i)); 153 i = 0;
154#else
155 for_each_online_cpu(j) {
156 seq_printf(p, "%10u ",
157 kstat_cpu(j).irqs[i]);
158 }
159#endif
160 seq_printf(p, " %c %s",
161 (action->flags & IRQF_DISABLED) ? '+' : ' ',
162 action->name);
163 for (action = action->next; action; action = action->next) {
164 seq_printf(p, ",%s %s",
165 (action->flags & IRQF_DISABLED) ? " +" : "",
166 action->name);
167 }
168 seq_putc(p, '\n');
169 } 154 }
170out_unlock: 155found:
171 spin_unlock_irqrestore(&irq_action_lock, flags); 156 spin_unlock_irqrestore(&irq_table_lock, flags);
172 return 0; 157
158 return i;
173} 159}
174 160
175void free_irq(unsigned int irq, void *dev_id) 161/* Based on a single pil handler_irq may need to call several
162 * interrupt handlers. Use irq_map as entry to irq_table,
163 * and let each entry in irq_table point to the next entry.
164 */
165void irq_link(unsigned int irq)
176{ 166{
177 struct irqaction *action; 167 struct irq_bucket *p;
178 struct irqaction **actionp;
179 unsigned long flags; 168 unsigned long flags;
180 unsigned int cpu_irq; 169 unsigned int pil;
181 170
182 if (sparc_cpu_model == sun4d) { 171 BUG_ON(irq >= NR_IRQS);
183 sun4d_free_irq(irq, dev_id);
184 return;
185 }
186 cpu_irq = irq & (NR_IRQS - 1);
187 if (cpu_irq > 14) { /* 14 irq levels on the sparc */
188 printk(KERN_ERR "Trying to free bogus IRQ %d\n", irq);
189 return;
190 }
191 172
192 spin_lock_irqsave(&irq_action_lock, flags); 173 spin_lock_irqsave(&irq_map_lock, flags);
193 174
194 actionp = &sparc_irq[cpu_irq].action; 175 p = &irq_table[irq];
195 action = *actionp; 176 pil = p->pil;
177 BUG_ON(pil > SUN4D_MAX_IRQ);
178 p->next = irq_map[pil];
179 irq_map[pil] = p;
196 180
197 if (!action->handler) { 181 spin_unlock_irqrestore(&irq_map_lock, flags);
198 printk(KERN_ERR "Trying to free free IRQ%d\n", irq); 182}
199 goto out_unlock;
200 }
201 if (dev_id) {
202 for (; action; action = action->next) {
203 if (action->dev_id == dev_id)
204 break;
205 actionp = &action->next;
206 }
207 if (!action) {
208 printk(KERN_ERR "Trying to free free shared IRQ%d\n",
209 irq);
210 goto out_unlock;
211 }
212 } else if (action->flags & IRQF_SHARED) {
213 printk(KERN_ERR "Trying to free shared IRQ%d with NULL device ID\n",
214 irq);
215 goto out_unlock;
216 }
217 if (action->flags & SA_STATIC_ALLOC) {
218 /*
219 * This interrupt is marked as specially allocated
220 * so it is a bad idea to free it.
221 */
222 printk(KERN_ERR "Attempt to free statically allocated IRQ%d (%s)\n",
223 irq, action->name);
224 goto out_unlock;
225 }
226
227 *actionp = action->next;
228
229 spin_unlock_irqrestore(&irq_action_lock, flags);
230 183
231 synchronize_irq(irq); 184void irq_unlink(unsigned int irq)
185{
186 struct irq_bucket *p, **pnext;
187 unsigned long flags;
232 188
233 spin_lock_irqsave(&irq_action_lock, flags); 189 BUG_ON(irq >= NR_IRQS);
234 190
235 kfree(action); 191 spin_lock_irqsave(&irq_map_lock, flags);
236 192
237 if (!sparc_irq[cpu_irq].action) 193 p = &irq_table[irq];
238 __disable_irq(irq); 194 BUG_ON(p->pil > SUN4D_MAX_IRQ);
195 pnext = &irq_map[p->pil];
196 while (*pnext != p)
197 pnext = &(*pnext)->next;
198 *pnext = p->next;
239 199
240out_unlock: 200 spin_unlock_irqrestore(&irq_map_lock, flags);
241 spin_unlock_irqrestore(&irq_action_lock, flags);
242} 201}
243EXPORT_SYMBOL(free_irq);
244 202
245/*
246 * This is called when we want to synchronize with
247 * interrupts. We may for example tell a device to
248 * stop sending interrupts: but to make sure there
249 * are no interrupts that are executing on another
250 * CPU we need to call this function.
251 */
252#ifdef CONFIG_SMP
253void synchronize_irq(unsigned int irq)
254{
255 unsigned int cpu_irq;
256 203
257 cpu_irq = irq & (NR_IRQS - 1); 204/* /proc/interrupts printing */
258 while (sparc_irq[cpu_irq].flags & SPARC_IRQ_INPROGRESS) 205int arch_show_interrupts(struct seq_file *p, int prec)
259 cpu_relax();
260}
261EXPORT_SYMBOL(synchronize_irq);
262#endif /* SMP */
263
264void unexpected_irq(int irq, void *dev_id, struct pt_regs *regs)
265{ 206{
266 int i; 207 int j;
267 struct irqaction *action;
268 unsigned int cpu_irq;
269 208
270 cpu_irq = irq & (NR_IRQS - 1); 209 seq_printf(p, "NMI: ");
271 action = sparc_irq[cpu_irq].action; 210 for_each_online_cpu(j)
272 211 seq_printf(p, "%10u ", cpu_data(j).counter);
273 printk(KERN_ERR "IO device interrupt, irq = %d\n", irq); 212 seq_printf(p, " Non-maskable interrupts\n");
274 printk(KERN_ERR "PC = %08lx NPC = %08lx FP=%08lx\n", regs->pc, 213 return 0;
275 regs->npc, regs->u_regs[14]);
276 if (action) {
277 printk(KERN_ERR "Expecting: ");
278 for (i = 0; i < 16; i++)
279 if (action->handler)
280 printk(KERN_CONT "[%s:%d:0x%x] ", action->name,
281 i, (unsigned int)action->handler);
282 }
283 printk(KERN_ERR "AIEEE\n");
284 panic("bogus interrupt received");
285} 214}
286 215
287void handler_irq(int pil, struct pt_regs *regs) 216void handler_irq(unsigned int pil, struct pt_regs *regs)
288{ 217{
289 struct pt_regs *old_regs; 218 struct pt_regs *old_regs;
290 struct irqaction *action; 219 struct irq_bucket *p;
291 int cpu = smp_processor_id();
292 220
221 BUG_ON(pil > 15);
293 old_regs = set_irq_regs(regs); 222 old_regs = set_irq_regs(regs);
294 irq_enter(); 223 irq_enter();
295 disable_pil_irq(pil); 224
296#ifdef CONFIG_SMP 225 p = irq_map[pil];
297 /* Only rotate on lower priority IRQs (scsi, ethernet, etc.). */ 226 while (p) {
298 if ((sparc_cpu_model==sun4m) && (pil < 10)) 227 struct irq_bucket *next = p->next;
299 smp4m_irq_rotate(cpu); 228
300#endif 229 generic_handle_irq(p->irq);
301 action = sparc_irq[pil].action; 230 p = next;
302 sparc_irq[pil].flags |= SPARC_IRQ_INPROGRESS; 231 }
303 kstat_cpu(cpu).irqs[pil]++;
304 do {
305 if (!action || !action->handler)
306 unexpected_irq(pil, NULL, regs);
307 action->handler(pil, action->dev_id);
308 action = action->next;
309 } while (action);
310 sparc_irq[pil].flags &= ~SPARC_IRQ_INPROGRESS;
311 enable_pil_irq(pil);
312 irq_exit(); 232 irq_exit();
313 set_irq_regs(old_regs); 233 set_irq_regs(old_regs);
314} 234}
315 235
316#if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE) 236#if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE)
237static unsigned int floppy_irq;
317 238
318/* 239int sparc_floppy_request_irq(unsigned int irq, irq_handler_t irq_handler)
319 * Fast IRQs on the Sparc can only have one routine attached to them,
320 * thus no sharing possible.
321 */
322static int request_fast_irq(unsigned int irq,
323 void (*handler)(void),
324 unsigned long irqflags, const char *devname)
325{ 240{
326 struct irqaction *action;
327 unsigned long flags;
328 unsigned int cpu_irq; 241 unsigned int cpu_irq;
329 int ret; 242 int err;
243
330#if defined CONFIG_SMP && !defined CONFIG_SPARC_LEON 244#if defined CONFIG_SMP && !defined CONFIG_SPARC_LEON
331 struct tt_entry *trap_table; 245 struct tt_entry *trap_table;
332#endif 246#endif
333 cpu_irq = irq & (NR_IRQS - 1);
334 if (cpu_irq > 14) {
335 ret = -EINVAL;
336 goto out;
337 }
338 if (!handler) {
339 ret = -EINVAL;
340 goto out;
341 }
342 247
343 spin_lock_irqsave(&irq_action_lock, flags); 248 err = request_irq(irq, irq_handler, 0, "floppy", NULL);
249 if (err)
250 return -1;
344 251
345 action = sparc_irq[cpu_irq].action; 252 /* Save for later use in floppy interrupt handler */
346 if (action) { 253 floppy_irq = irq;
347 if (action->flags & IRQF_SHARED)
348 panic("Trying to register fast irq when already shared.\n");
349 if (irqflags & IRQF_SHARED)
350 panic("Trying to register fast irq as shared.\n");
351 254
352 /* Anyway, someone already owns it so cannot be made fast. */ 255 cpu_irq = (irq & (NR_IRQS - 1));
353 printk(KERN_ERR "request_fast_irq: Trying to register yet already owned.\n");
354 ret = -EBUSY;
355 goto out_unlock;
356 }
357
358 /*
359 * If this is flagged as statically allocated then we use our
360 * private struct which is never freed.
361 */
362 if (irqflags & SA_STATIC_ALLOC) {
363 if (static_irq_count < MAX_STATIC_ALLOC)
364 action = &static_irqaction[static_irq_count++];
365 else
366 printk(KERN_ERR "Fast IRQ%d (%s) SA_STATIC_ALLOC failed using kmalloc\n",
367 irq, devname);
368 }
369
370 if (action == NULL)
371 action = kmalloc(sizeof(struct irqaction), GFP_ATOMIC);
372 if (!action) {
373 ret = -ENOMEM;
374 goto out_unlock;
375 }
376 256
377 /* Dork with trap table if we get this far. */ 257 /* Dork with trap table if we get this far. */
378#define INSTANTIATE(table) \ 258#define INSTANTIATE(table) \
379 table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_one = SPARC_RD_PSR_L0; \ 259 table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_one = SPARC_RD_PSR_L0; \
380 table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_two = \ 260 table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_two = \
381 SPARC_BRANCH((unsigned long) handler, \ 261 SPARC_BRANCH((unsigned long) floppy_hardint, \
382 (unsigned long) &table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_two);\ 262 (unsigned long) &table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_two);\
383 table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_three = SPARC_RD_WIM_L3; \ 263 table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_three = SPARC_RD_WIM_L3; \
384 table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_four = SPARC_NOP; 264 table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_four = SPARC_NOP;
@@ -399,22 +279,9 @@ static int request_fast_irq(unsigned int irq,
399 * writing we have no CPU-neutral interface to fine-grained flushes. 279 * writing we have no CPU-neutral interface to fine-grained flushes.
400 */ 280 */
401 flush_cache_all(); 281 flush_cache_all();
402 282 return 0;
403 action->flags = irqflags;
404 action->name = devname;
405 action->dev_id = NULL;
406 action->next = NULL;
407
408 sparc_irq[cpu_irq].action = action;
409
410 __enable_irq(irq);
411
412 ret = 0;
413out_unlock:
414 spin_unlock_irqrestore(&irq_action_lock, flags);
415out:
416 return ret;
417} 283}
284EXPORT_SYMBOL(sparc_floppy_request_irq);
418 285
419/* 286/*
420 * These variables are used to access state from the assembler 287 * These variables are used to access state from the assembler
@@ -440,154 +307,23 @@ EXPORT_SYMBOL(pdma_base);
440unsigned long pdma_areasize; 307unsigned long pdma_areasize;
441EXPORT_SYMBOL(pdma_areasize); 308EXPORT_SYMBOL(pdma_areasize);
442 309
443static irq_handler_t floppy_irq_handler; 310/* Use the generic irq support to call floppy_interrupt
444 311 * which was setup using request_irq() in sparc_floppy_request_irq().
312 * We only have one floppy interrupt so we do not need to check
313 * for additional handlers being wired up by irq_link()
314 */
445void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs) 315void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs)
446{ 316{
447 struct pt_regs *old_regs; 317 struct pt_regs *old_regs;
448 int cpu = smp_processor_id();
449 318
450 old_regs = set_irq_regs(regs); 319 old_regs = set_irq_regs(regs);
451 disable_pil_irq(irq);
452 irq_enter(); 320 irq_enter();
453 kstat_cpu(cpu).irqs[irq]++; 321 generic_handle_irq(floppy_irq);
454 floppy_irq_handler(irq, dev_id);
455 irq_exit(); 322 irq_exit();
456 enable_pil_irq(irq);
457 set_irq_regs(old_regs); 323 set_irq_regs(old_regs);
458 /*
459 * XXX Eek, it's totally changed with preempt_count() and such
460 * if (softirq_pending(cpu))
461 * do_softirq();
462 */
463} 324}
464
465int sparc_floppy_request_irq(int irq, unsigned long flags,
466 irq_handler_t irq_handler)
467{
468 floppy_irq_handler = irq_handler;
469 return request_fast_irq(irq, floppy_hardint, flags, "floppy");
470}
471EXPORT_SYMBOL(sparc_floppy_request_irq);
472
473#endif 325#endif
474 326
475int request_irq(unsigned int irq,
476 irq_handler_t handler,
477 unsigned long irqflags, const char *devname, void *dev_id)
478{
479 struct irqaction *action, **actionp;
480 unsigned long flags;
481 unsigned int cpu_irq;
482 int ret;
483
484 if (sparc_cpu_model == sun4d)
485 return sun4d_request_irq(irq, handler, irqflags, devname, dev_id);
486
487 cpu_irq = irq & (NR_IRQS - 1);
488 if (cpu_irq > 14) {
489 ret = -EINVAL;
490 goto out;
491 }
492 if (!handler) {
493 ret = -EINVAL;
494 goto out;
495 }
496
497 spin_lock_irqsave(&irq_action_lock, flags);
498
499 actionp = &sparc_irq[cpu_irq].action;
500 action = *actionp;
501 if (action) {
502 if (!(action->flags & IRQF_SHARED) || !(irqflags & IRQF_SHARED)) {
503 ret = -EBUSY;
504 goto out_unlock;
505 }
506 if ((action->flags & IRQF_DISABLED) != (irqflags & IRQF_DISABLED)) {
507 printk(KERN_ERR "Attempt to mix fast and slow interrupts on IRQ%d denied\n",
508 irq);
509 ret = -EBUSY;
510 goto out_unlock;
511 }
512 for ( ; action; action = *actionp)
513 actionp = &action->next;
514 }
515
516 /* If this is flagged as statically allocated then we use our
517 * private struct which is never freed.
518 */
519 if (irqflags & SA_STATIC_ALLOC) {
520 if (static_irq_count < MAX_STATIC_ALLOC)
521 action = &static_irqaction[static_irq_count++];
522 else
523 printk(KERN_ERR "Request for IRQ%d (%s) SA_STATIC_ALLOC failed using kmalloc\n",
524 irq, devname);
525 }
526 if (action == NULL)
527 action = kmalloc(sizeof(struct irqaction), GFP_ATOMIC);
528 if (!action) {
529 ret = -ENOMEM;
530 goto out_unlock;
531 }
532
533 action->handler = handler;
534 action->flags = irqflags;
535 action->name = devname;
536 action->next = NULL;
537 action->dev_id = dev_id;
538
539 *actionp = action;
540
541 __enable_irq(irq);
542
543 ret = 0;
544out_unlock:
545 spin_unlock_irqrestore(&irq_action_lock, flags);
546out:
547 return ret;
548}
549EXPORT_SYMBOL(request_irq);
550
551void disable_irq_nosync(unsigned int irq)
552{
553 __disable_irq(irq);
554}
555EXPORT_SYMBOL(disable_irq_nosync);
556
557void disable_irq(unsigned int irq)
558{
559 __disable_irq(irq);
560}
561EXPORT_SYMBOL(disable_irq);
562
563void enable_irq(unsigned int irq)
564{
565 __enable_irq(irq);
566}
567EXPORT_SYMBOL(enable_irq);
568
569/*
570 * We really don't need these at all on the Sparc. We only have
571 * stubs here because they are exported to modules.
572 */
573unsigned long probe_irq_on(void)
574{
575 return 0;
576}
577EXPORT_SYMBOL(probe_irq_on);
578
579int probe_irq_off(unsigned long mask)
580{
581 return 0;
582}
583EXPORT_SYMBOL(probe_irq_off);
584
585static unsigned int build_device_irq(struct platform_device *op,
586 unsigned int real_irq)
587{
588 return real_irq;
589}
590
591/* djhr 327/* djhr
592 * This could probably be made indirect too and assigned in the CPU 328 * This could probably be made indirect too and assigned in the CPU
593 * bits of the code. That would be much nicer I think and would also 329 * bits of the code. That would be much nicer I think and would also
@@ -598,8 +334,6 @@ static unsigned int build_device_irq(struct platform_device *op,
598 334
599void __init init_IRQ(void) 335void __init init_IRQ(void)
600{ 336{
601 sparc_irq_config.build_device_irq = build_device_irq;
602
603 switch (sparc_cpu_model) { 337 switch (sparc_cpu_model) {
604 case sun4c: 338 case sun4c:
605 case sun4: 339 case sun4:
@@ -629,9 +363,3 @@ void __init init_IRQ(void)
629 btfixup(); 363 btfixup();
630} 364}
631 365
632#ifdef CONFIG_PROC_FS
633void init_irq_proc(void)
634{
635 /* For now, nothing... */
636}
637#endif /* CONFIG_PROC_FS */
diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h
index 24ad449886be..487d67a4e7f6 100644
--- a/arch/sparc/kernel/kernel.h
+++ b/arch/sparc/kernel/kernel.h
@@ -37,6 +37,7 @@ extern void sun4c_init_IRQ(void);
37extern unsigned int lvl14_resolution; 37extern unsigned int lvl14_resolution;
38 38
39extern void sun4m_init_IRQ(void); 39extern void sun4m_init_IRQ(void);
40extern void sun4m_unmask_profile_irq(void);
40extern void sun4m_clear_profile_irq(int cpu); 41extern void sun4m_clear_profile_irq(int cpu);
41 42
42/* sun4d_irq.c */ 43/* sun4d_irq.c */
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index 2969f777fa11..8591cf124ecf 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -83,20 +83,22 @@ static inline unsigned long get_irqmask(unsigned int irq)
83 return mask; 83 return mask;
84} 84}
85 85
86static void leon_enable_irq(unsigned int irq_nr) 86static void leon_unmask_irq(struct irq_data *data)
87{ 87{
88 unsigned long mask, flags; 88 unsigned long mask, flags;
89 mask = get_irqmask(irq_nr); 89
90 mask = (unsigned long)data->chip_data;
90 local_irq_save(flags); 91 local_irq_save(flags);
91 LEON3_BYPASS_STORE_PA(LEON_IMASK, 92 LEON3_BYPASS_STORE_PA(LEON_IMASK,
92 (LEON3_BYPASS_LOAD_PA(LEON_IMASK) | (mask))); 93 (LEON3_BYPASS_LOAD_PA(LEON_IMASK) | (mask)));
93 local_irq_restore(flags); 94 local_irq_restore(flags);
94} 95}
95 96
96static void leon_disable_irq(unsigned int irq_nr) 97static void leon_mask_irq(struct irq_data *data)
97{ 98{
98 unsigned long mask, flags; 99 unsigned long mask, flags;
99 mask = get_irqmask(irq_nr); 100
101 mask = (unsigned long)data->chip_data;
100 local_irq_save(flags); 102 local_irq_save(flags);
101 LEON3_BYPASS_STORE_PA(LEON_IMASK, 103 LEON3_BYPASS_STORE_PA(LEON_IMASK,
102 (LEON3_BYPASS_LOAD_PA(LEON_IMASK) & ~(mask))); 104 (LEON3_BYPASS_LOAD_PA(LEON_IMASK) & ~(mask)));
@@ -104,6 +106,50 @@ static void leon_disable_irq(unsigned int irq_nr)
104 106
105} 107}
106 108
109static unsigned int leon_startup_irq(struct irq_data *data)
110{
111 irq_link(data->irq);
112 leon_unmask_irq(data);
113 return 0;
114}
115
116static void leon_shutdown_irq(struct irq_data *data)
117{
118 leon_mask_irq(data);
119 irq_unlink(data->irq);
120}
121
122static struct irq_chip leon_irq = {
123 .name = "leon",
124 .irq_startup = leon_startup_irq,
125 .irq_shutdown = leon_shutdown_irq,
126 .irq_mask = leon_mask_irq,
127 .irq_unmask = leon_unmask_irq,
128};
129
130static unsigned int leon_build_device_irq(struct platform_device *op,
131 unsigned int real_irq)
132{
133 unsigned int irq;
134 unsigned long mask;
135
136 irq = 0;
137 mask = get_irqmask(real_irq);
138 if (mask == 0)
139 goto out;
140
141 irq = irq_alloc(real_irq, real_irq);
142 if (irq == 0)
143 goto out;
144
145 irq_set_chip_and_handler_name(irq, &leon_irq,
146 handle_simple_irq, "edge");
147 irq_set_chip_data(irq, (void *)mask);
148
149out:
150 return irq;
151}
152
107void __init leon_init_timers(irq_handler_t counter_fn) 153void __init leon_init_timers(irq_handler_t counter_fn)
108{ 154{
109 int irq; 155 int irq;
@@ -112,6 +158,7 @@ void __init leon_init_timers(irq_handler_t counter_fn)
112 int len; 158 int len;
113 int cpu, icsel; 159 int cpu, icsel;
114 int ampopts; 160 int ampopts;
161 int err;
115 162
116 leondebug_irq_disable = 0; 163 leondebug_irq_disable = 0;
117 leon_debug_irqout = 0; 164 leon_debug_irqout = 0;
@@ -219,11 +266,10 @@ void __init leon_init_timers(irq_handler_t counter_fn)
219 goto bad; 266 goto bad;
220 } 267 }
221 268
222 irq = request_irq(leon3_gptimer_irq+leon3_gptimer_idx, 269 irq = leon_build_device_irq(NULL, leon3_gptimer_irq + leon3_gptimer_idx);
223 counter_fn, 270 err = request_irq(irq, counter_fn, IRQF_TIMER, "timer", NULL);
224 (IRQF_DISABLED | SA_STATIC_ALLOC), "timer", NULL);
225 271
226 if (irq) { 272 if (err) {
227 printk(KERN_ERR "leon_time_init: unable to attach IRQ%d\n", 273 printk(KERN_ERR "leon_time_init: unable to attach IRQ%d\n",
228 LEON_INTERRUPT_TIMER1); 274 LEON_INTERRUPT_TIMER1);
229 prom_halt(); 275 prom_halt();
@@ -347,12 +393,8 @@ void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu)
347 393
348void __init leon_init_IRQ(void) 394void __init leon_init_IRQ(void)
349{ 395{
350 sparc_irq_config.init_timers = leon_init_timers; 396 sparc_irq_config.init_timers = leon_init_timers;
351 397 sparc_irq_config.build_device_irq = leon_build_device_irq;
352 BTFIXUPSET_CALL(enable_irq, leon_enable_irq, BTFIXUPCALL_NORM);
353 BTFIXUPSET_CALL(disable_irq, leon_disable_irq, BTFIXUPCALL_NORM);
354 BTFIXUPSET_CALL(enable_pil_irq, leon_enable_irq, BTFIXUPCALL_NORM);
355 BTFIXUPSET_CALL(disable_pil_irq, leon_disable_irq, BTFIXUPCALL_NORM);
356 398
357 BTFIXUPSET_CALL(clear_clock_irq, leon_clear_clock_irq, 399 BTFIXUPSET_CALL(clear_clock_irq, leon_clear_clock_irq,
358 BTFIXUPCALL_NORM); 400 BTFIXUPCALL_NORM);
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index 2cdc131b50ac..948601a066ff 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -164,6 +164,9 @@ void __iomem *pcic_regs;
164volatile int pcic_speculative; 164volatile int pcic_speculative;
165volatile int pcic_trapped; 165volatile int pcic_trapped;
166 166
167/* forward */
168unsigned int pcic_build_device_irq(struct platform_device *op,
169 unsigned int real_irq);
167 170
168#define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (((unsigned int)bus) << 16) | (((unsigned int)device_fn) << 8) | (where & ~3)) 171#define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (((unsigned int)bus) << 16) | (((unsigned int)device_fn) << 8) | (where & ~3))
169 172
@@ -523,6 +526,7 @@ static void
523pcic_fill_irq(struct linux_pcic *pcic, struct pci_dev *dev, int node) 526pcic_fill_irq(struct linux_pcic *pcic, struct pci_dev *dev, int node)
524{ 527{
525 struct pcic_ca2irq *p; 528 struct pcic_ca2irq *p;
529 unsigned int real_irq;
526 int i, ivec; 530 int i, ivec;
527 char namebuf[64]; 531 char namebuf[64];
528 532
@@ -551,26 +555,25 @@ pcic_fill_irq(struct linux_pcic *pcic, struct pci_dev *dev, int node)
551 i = p->pin; 555 i = p->pin;
552 if (i >= 0 && i < 4) { 556 if (i >= 0 && i < 4) {
553 ivec = readw(pcic->pcic_regs+PCI_INT_SELECT_LO); 557 ivec = readw(pcic->pcic_regs+PCI_INT_SELECT_LO);
554 dev->irq = ivec >> (i << 2) & 0xF; 558 real_irq = ivec >> (i << 2) & 0xF;
555 } else if (i >= 4 && i < 8) { 559 } else if (i >= 4 && i < 8) {
556 ivec = readw(pcic->pcic_regs+PCI_INT_SELECT_HI); 560 ivec = readw(pcic->pcic_regs+PCI_INT_SELECT_HI);
557 dev->irq = ivec >> ((i-4) << 2) & 0xF; 561 real_irq = ivec >> ((i-4) << 2) & 0xF;
558 } else { /* Corrupted map */ 562 } else { /* Corrupted map */
559 printk("PCIC: BAD PIN %d\n", i); for (;;) {} 563 printk("PCIC: BAD PIN %d\n", i); for (;;) {}
560 } 564 }
561/* P3 */ /* printk("PCIC: device %s pin %d ivec 0x%x irq %x\n", namebuf, i, ivec, dev->irq); */ 565/* P3 */ /* printk("PCIC: device %s pin %d ivec 0x%x irq %x\n", namebuf, i, ivec, dev->irq); */
562 566
563 /* 567 /* real_irq means PROM did not bother to program the upper
564 * dev->irq=0 means PROM did not bother to program the upper
565 * half of PCIC. This happens on JS-E with PROM 3.11, for instance. 568 * half of PCIC. This happens on JS-E with PROM 3.11, for instance.
566 */ 569 */
567 if (dev->irq == 0 || p->force) { 570 if (real_irq == 0 || p->force) {
568 if (p->irq == 0 || p->irq >= 15) { /* Corrupted map */ 571 if (p->irq == 0 || p->irq >= 15) { /* Corrupted map */
569 printk("PCIC: BAD IRQ %d\n", p->irq); for (;;) {} 572 printk("PCIC: BAD IRQ %d\n", p->irq); for (;;) {}
570 } 573 }
571 printk("PCIC: setting irq %d at pin %d for device %02x:%02x\n", 574 printk("PCIC: setting irq %d at pin %d for device %02x:%02x\n",
572 p->irq, p->pin, dev->bus->number, dev->devfn); 575 p->irq, p->pin, dev->bus->number, dev->devfn);
573 dev->irq = p->irq; 576 real_irq = p->irq;
574 577
575 i = p->pin; 578 i = p->pin;
576 if (i >= 4) { 579 if (i >= 4) {
@@ -584,7 +587,8 @@ pcic_fill_irq(struct linux_pcic *pcic, struct pci_dev *dev, int node)
584 ivec |= p->irq << (i << 2); 587 ivec |= p->irq << (i << 2);
585 writew(ivec, pcic->pcic_regs+PCI_INT_SELECT_LO); 588 writew(ivec, pcic->pcic_regs+PCI_INT_SELECT_LO);
586 } 589 }
587 } 590 }
591 dev->irq = pcic_build_device_irq(NULL, real_irq);
588} 592}
589 593
590/* 594/*
@@ -729,6 +733,7 @@ void __init pci_time_init(void)
729 struct linux_pcic *pcic = &pcic0; 733 struct linux_pcic *pcic = &pcic0;
730 unsigned long v; 734 unsigned long v;
731 int timer_irq, irq; 735 int timer_irq, irq;
736 int err;
732 737
733 do_arch_gettimeoffset = pci_gettimeoffset; 738 do_arch_gettimeoffset = pci_gettimeoffset;
734 739
@@ -740,9 +745,10 @@ void __init pci_time_init(void)
740 timer_irq = PCI_COUNTER_IRQ_SYS(v); 745 timer_irq = PCI_COUNTER_IRQ_SYS(v);
741 writel (PCI_COUNTER_IRQ_SET(timer_irq, 0), 746 writel (PCI_COUNTER_IRQ_SET(timer_irq, 0),
742 pcic->pcic_regs+PCI_COUNTER_IRQ); 747 pcic->pcic_regs+PCI_COUNTER_IRQ);
743 irq = request_irq(timer_irq, pcic_timer_handler, 748 irq = pcic_build_device_irq(NULL, timer_irq);
744 (IRQF_DISABLED | SA_STATIC_ALLOC), "timer", NULL); 749 err = request_irq(irq, pcic_timer_handler,
745 if (irq) { 750 IRQF_TIMER, "timer", NULL);
751 if (err) {
746 prom_printf("time_init: unable to attach IRQ%d\n", timer_irq); 752 prom_printf("time_init: unable to attach IRQ%d\n", timer_irq);
747 prom_halt(); 753 prom_halt();
748 } 754 }
@@ -803,50 +809,73 @@ static inline unsigned long get_irqmask(int irq_nr)
803 return 1 << irq_nr; 809 return 1 << irq_nr;
804} 810}
805 811
806static void pcic_disable_irq(unsigned int irq_nr) 812static void pcic_mask_irq(struct irq_data *data)
807{ 813{
808 unsigned long mask, flags; 814 unsigned long mask, flags;
809 815
810 mask = get_irqmask(irq_nr); 816 mask = (unsigned long)data->chip_data;
811 local_irq_save(flags); 817 local_irq_save(flags);
812 writel(mask, pcic0.pcic_regs+PCI_SYS_INT_TARGET_MASK_SET); 818 writel(mask, pcic0.pcic_regs+PCI_SYS_INT_TARGET_MASK_SET);
813 local_irq_restore(flags); 819 local_irq_restore(flags);
814} 820}
815 821
816static void pcic_enable_irq(unsigned int irq_nr) 822static void pcic_unmask_irq(struct irq_data *data)
817{ 823{
818 unsigned long mask, flags; 824 unsigned long mask, flags;
819 825
820 mask = get_irqmask(irq_nr); 826 mask = (unsigned long)data->chip_data;
821 local_irq_save(flags); 827 local_irq_save(flags);
822 writel(mask, pcic0.pcic_regs+PCI_SYS_INT_TARGET_MASK_CLEAR); 828 writel(mask, pcic0.pcic_regs+PCI_SYS_INT_TARGET_MASK_CLEAR);
823 local_irq_restore(flags); 829 local_irq_restore(flags);
824} 830}
825 831
826static void pcic_load_profile_irq(int cpu, unsigned int limit) 832static unsigned int pcic_startup_irq(struct irq_data *data)
827{ 833{
828 printk("PCIC: unimplemented code: FILE=%s LINE=%d", __FILE__, __LINE__); 834 irq_link(data->irq);
835 pcic_unmask_irq(data);
836 return 0;
829} 837}
830 838
831/* We assume the caller has disabled local interrupts when these are called, 839static struct irq_chip pcic_irq = {
832 * or else very bizarre behavior will result. 840 .name = "pcic",
833 */ 841 .irq_startup = pcic_startup_irq,
834static void pcic_disable_pil_irq(unsigned int pil) 842 .irq_mask = pcic_mask_irq,
843 .irq_unmask = pcic_unmask_irq,
844};
845
846unsigned int pcic_build_device_irq(struct platform_device *op,
847 unsigned int real_irq)
835{ 848{
836 writel(get_irqmask(pil), pcic0.pcic_regs+PCI_SYS_INT_TARGET_MASK_SET); 849 unsigned int irq;
850 unsigned long mask;
851
852 irq = 0;
853 mask = get_irqmask(real_irq);
854 if (mask == 0)
855 goto out;
856
857 irq = irq_alloc(real_irq, real_irq);
858 if (irq == 0)
859 goto out;
860
861 irq_set_chip_and_handler_name(irq, &pcic_irq,
862 handle_level_irq, "PCIC");
863 irq_set_chip_data(irq, (void *)mask);
864
865out:
866 return irq;
837} 867}
838 868
839static void pcic_enable_pil_irq(unsigned int pil) 869
870static void pcic_load_profile_irq(int cpu, unsigned int limit)
840{ 871{
841 writel(get_irqmask(pil), pcic0.pcic_regs+PCI_SYS_INT_TARGET_MASK_CLEAR); 872 printk("PCIC: unimplemented code: FILE=%s LINE=%d", __FILE__, __LINE__);
842} 873}
843 874
844void __init sun4m_pci_init_IRQ(void) 875void __init sun4m_pci_init_IRQ(void)
845{ 876{
846 BTFIXUPSET_CALL(enable_irq, pcic_enable_irq, BTFIXUPCALL_NORM); 877 sparc_irq_config.build_device_irq = pcic_build_device_irq;
847 BTFIXUPSET_CALL(disable_irq, pcic_disable_irq, BTFIXUPCALL_NORM); 878
848 BTFIXUPSET_CALL(enable_pil_irq, pcic_enable_pil_irq, BTFIXUPCALL_NORM);
849 BTFIXUPSET_CALL(disable_pil_irq, pcic_disable_pil_irq, BTFIXUPCALL_NORM);
850 BTFIXUPSET_CALL(clear_clock_irq, pcic_clear_clock_irq, BTFIXUPCALL_NORM); 879 BTFIXUPSET_CALL(clear_clock_irq, pcic_clear_clock_irq, BTFIXUPCALL_NORM);
851 BTFIXUPSET_CALL(load_profile_irq, pcic_load_profile_irq, BTFIXUPCALL_NORM); 880 BTFIXUPSET_CALL(load_profile_irq, pcic_load_profile_irq, BTFIXUPCALL_NORM);
852} 881}
diff --git a/arch/sparc/kernel/sun4c_irq.c b/arch/sparc/kernel/sun4c_irq.c
index 90eea38ad66f..f6bf25a2ff80 100644
--- a/arch/sparc/kernel/sun4c_irq.c
+++ b/arch/sparc/kernel/sun4c_irq.c
@@ -65,62 +65,94 @@
65 */ 65 */
66unsigned char __iomem *interrupt_enable; 66unsigned char __iomem *interrupt_enable;
67 67
68static void sun4c_disable_irq(unsigned int irq_nr) 68static void sun4c_mask_irq(struct irq_data *data)
69{ 69{
70 unsigned long flags; 70 unsigned long mask = (unsigned long)data->chip_data;
71 unsigned char current_mask, new_mask; 71
72 72 if (mask) {
73 local_irq_save(flags); 73 unsigned long flags;
74 irq_nr &= (NR_IRQS - 1); 74
75 current_mask = sbus_readb(interrupt_enable); 75 local_irq_save(flags);
76 switch (irq_nr) { 76 mask = sbus_readb(interrupt_enable) & ~mask;
77 case 1: 77 sbus_writeb(mask, interrupt_enable);
78 new_mask = ((current_mask) & (~(SUN4C_INT_E1)));
79 break;
80 case 8:
81 new_mask = ((current_mask) & (~(SUN4C_INT_E8)));
82 break;
83 case 10:
84 new_mask = ((current_mask) & (~(SUN4C_INT_E10)));
85 break;
86 case 14:
87 new_mask = ((current_mask) & (~(SUN4C_INT_E14)));
88 break;
89 default:
90 local_irq_restore(flags); 78 local_irq_restore(flags);
91 return;
92 } 79 }
93 sbus_writeb(new_mask, interrupt_enable);
94 local_irq_restore(flags);
95} 80}
96 81
97static void sun4c_enable_irq(unsigned int irq_nr) 82static void sun4c_unmask_irq(struct irq_data *data)
98{ 83{
99 unsigned long flags; 84 unsigned long mask = (unsigned long)data->chip_data;
100 unsigned char current_mask, new_mask; 85
101 86 if (mask) {
102 local_irq_save(flags); 87 unsigned long flags;
103 irq_nr &= (NR_IRQS - 1); 88
104 current_mask = sbus_readb(interrupt_enable); 89 local_irq_save(flags);
105 switch (irq_nr) { 90 mask = sbus_readb(interrupt_enable) | mask;
106 case 1: 91 sbus_writeb(mask, interrupt_enable);
107 new_mask = ((current_mask) | SUN4C_INT_E1);
108 break;
109 case 8:
110 new_mask = ((current_mask) | SUN4C_INT_E8);
111 break;
112 case 10:
113 new_mask = ((current_mask) | SUN4C_INT_E10);
114 break;
115 case 14:
116 new_mask = ((current_mask) | SUN4C_INT_E14);
117 break;
118 default:
119 local_irq_restore(flags); 92 local_irq_restore(flags);
120 return;
121 } 93 }
122 sbus_writeb(new_mask, interrupt_enable); 94}
123 local_irq_restore(flags); 95
96static unsigned int sun4c_startup_irq(struct irq_data *data)
97{
98 irq_link(data->irq);
99 sun4c_unmask_irq(data);
100
101 return 0;
102}
103
104static void sun4c_shutdown_irq(struct irq_data *data)
105{
106 sun4c_mask_irq(data);
107 irq_unlink(data->irq);
108}
109
110static struct irq_chip sun4c_irq = {
111 .name = "sun4c",
112 .irq_startup = sun4c_startup_irq,
113 .irq_shutdown = sun4c_shutdown_irq,
114 .irq_mask = sun4c_mask_irq,
115 .irq_unmask = sun4c_unmask_irq,
116};
117
118static unsigned int sun4c_build_device_irq(struct platform_device *op,
119 unsigned int real_irq)
120{
121 unsigned int irq;
122
123 if (real_irq >= 16) {
124 prom_printf("Bogus sun4c IRQ %u\n", real_irq);
125 prom_halt();
126 }
127
128 irq = irq_alloc(real_irq, real_irq);
129 if (irq) {
130 unsigned long mask = 0UL;
131
132 switch (real_irq) {
133 case 1:
134 mask = SUN4C_INT_E1;
135 break;
136 case 8:
137 mask = SUN4C_INT_E8;
138 break;
139 case 10:
140 mask = SUN4C_INT_E10;
141 break;
142 case 14:
143 mask = SUN4C_INT_E14;
144 break;
145 default:
146 /* All the rest are either always enabled,
147 * or are for signalling software interrupts.
148 */
149 break;
150 }
151 irq_set_chip_and_handler_name(irq, &sun4c_irq,
152 handle_level_irq, "level");
153 irq_set_chip_data(irq, (void *)mask);
154 }
155 return irq;
124} 156}
125 157
126struct sun4c_timer_info { 158struct sun4c_timer_info {
@@ -144,8 +176,9 @@ static void sun4c_load_profile_irq(int cpu, unsigned int limit)
144 176
145static void __init sun4c_init_timers(irq_handler_t counter_fn) 177static void __init sun4c_init_timers(irq_handler_t counter_fn)
146{ 178{
147 const struct linux_prom_irqs *irq; 179 const struct linux_prom_irqs *prom_irqs;
148 struct device_node *dp; 180 struct device_node *dp;
181 unsigned int irq;
149 const u32 *addr; 182 const u32 *addr;
150 int err; 183 int err;
151 184
@@ -163,9 +196,9 @@ static void __init sun4c_init_timers(irq_handler_t counter_fn)
163 196
164 sun4c_timers = (void __iomem *) (unsigned long) addr[0]; 197 sun4c_timers = (void __iomem *) (unsigned long) addr[0];
165 198
166 irq = of_get_property(dp, "intr", NULL); 199 prom_irqs = of_get_property(dp, "intr", NULL);
167 of_node_put(dp); 200 of_node_put(dp);
168 if (!irq) { 201 if (!prom_irqs) {
169 prom_printf("sun4c_init_timers: No intr property\n"); 202 prom_printf("sun4c_init_timers: No intr property\n");
170 prom_halt(); 203 prom_halt();
171 } 204 }
@@ -178,15 +211,15 @@ static void __init sun4c_init_timers(irq_handler_t counter_fn)
178 211
179 master_l10_counter = &sun4c_timers->l10_count; 212 master_l10_counter = &sun4c_timers->l10_count;
180 213
181 err = request_irq(irq[0].pri, counter_fn, 214 irq = sun4c_build_device_irq(NULL, prom_irqs[0].pri);
182 (IRQF_DISABLED | SA_STATIC_ALLOC), 215 err = request_irq(irq, counter_fn, IRQF_TIMER, "timer", NULL);
183 "timer", NULL);
184 if (err) { 216 if (err) {
185 prom_printf("sun4c_init_timers: request_irq() fails with %d\n", err); 217 prom_printf("sun4c_init_timers: request_irq() fails with %d\n", err);
186 prom_halt(); 218 prom_halt();
187 } 219 }
188 220
189 sun4c_disable_irq(irq[1].pri); 221 /* disable timer interrupt */
222 sun4c_mask_irq(irq_get_irq_data(irq));
190} 223}
191 224
192#ifdef CONFIG_SMP 225#ifdef CONFIG_SMP
@@ -215,14 +248,11 @@ void __init sun4c_init_IRQ(void)
215 248
216 interrupt_enable = (void __iomem *) (unsigned long) addr[0]; 249 interrupt_enable = (void __iomem *) (unsigned long) addr[0];
217 250
218 BTFIXUPSET_CALL(enable_irq, sun4c_enable_irq, BTFIXUPCALL_NORM);
219 BTFIXUPSET_CALL(disable_irq, sun4c_disable_irq, BTFIXUPCALL_NORM);
220 BTFIXUPSET_CALL(enable_pil_irq, sun4c_enable_irq, BTFIXUPCALL_NORM);
221 BTFIXUPSET_CALL(disable_pil_irq, sun4c_disable_irq, BTFIXUPCALL_NORM);
222 BTFIXUPSET_CALL(clear_clock_irq, sun4c_clear_clock_irq, BTFIXUPCALL_NORM); 251 BTFIXUPSET_CALL(clear_clock_irq, sun4c_clear_clock_irq, BTFIXUPCALL_NORM);
223 BTFIXUPSET_CALL(load_profile_irq, sun4c_load_profile_irq, BTFIXUPCALL_NOP); 252 BTFIXUPSET_CALL(load_profile_irq, sun4c_load_profile_irq, BTFIXUPCALL_NOP);
224 253
225 sparc_irq_config.init_timers = sun4c_init_timers; 254 sparc_irq_config.init_timers = sun4c_init_timers;
255 sparc_irq_config.build_device_irq = sun4c_build_device_irq;
226 256
227#ifdef CONFIG_SMP 257#ifdef CONFIG_SMP
228 BTFIXUPSET_CALL(set_cpu_int, sun4c_nop, BTFIXUPCALL_NOP); 258 BTFIXUPSET_CALL(set_cpu_int, sun4c_nop, BTFIXUPCALL_NOP);
diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c
index ee35c45ffb89..14a043531dcb 100644
--- a/arch/sparc/kernel/sun4d_irq.c
+++ b/arch/sparc/kernel/sun4d_irq.c
@@ -22,22 +22,20 @@
22 * cpu local. CPU local interrupts cover the timer interrupts 22 * cpu local. CPU local interrupts cover the timer interrupts
23 * and whatnot, and we encode those as normal PILs between 23 * and whatnot, and we encode those as normal PILs between
24 * 0 and 15. 24 * 0 and 15.
25 * 25 * SBUS interrupts are encodes as a combination of board, level and slot.
26 * SBUS interrupts are encoded integers including the board number
27 * (plus one), the SBUS level, and the SBUS slot number. Sun4D
28 * IRQ dispatch is done by:
29 *
30 * 1) Reading the BW local interrupt table in order to get the bus
31 * interrupt mask.
32 *
33 * This table is indexed by SBUS interrupt level which can be
34 * derived from the PIL we got interrupted on.
35 *
36 * 2) For each bus showing interrupt pending from #1, read the
37 * SBI interrupt state register. This will indicate which slots
38 * have interrupts pending for that SBUS interrupt level.
39 */ 26 */
40 27
28struct sun4d_handler_data {
29 unsigned int cpuid; /* target cpu */
30 unsigned int real_irq; /* interrupt level */
31};
32
33
34static unsigned int sun4d_encode_irq(int board, int lvl, int slot)
35{
36 return (board + 1) << 5 | (lvl << 2) | slot;
37}
38
41struct sun4d_timer_regs { 39struct sun4d_timer_regs {
42 u32 l10_timer_limit; 40 u32 l10_timer_limit;
43 u32 l10_cur_countx; 41 u32 l10_cur_countx;
@@ -48,22 +46,13 @@ struct sun4d_timer_regs {
48 46
49static struct sun4d_timer_regs __iomem *sun4d_timers; 47static struct sun4d_timer_regs __iomem *sun4d_timers;
50 48
51#define TIMER_IRQ 10 49#define SUN4D_TIMER_IRQ 10
52
53#define MAX_STATIC_ALLOC 4
54 50
55/* Specify which cpu handle interrupts from which board. 51/* Specify which cpu handle interrupts from which board.
56 * Index is board - value is cpu. 52 * Index is board - value is cpu.
57 */ 53 */
58static unsigned char board_to_cpu[32]; 54static unsigned char board_to_cpu[32];
59 55
60static struct irqaction *irq_action[NR_IRQS];
61
62static struct sbus_action {
63 struct irqaction *action;
64 /* For SMP this needs to be extended */
65} *sbus_actions;
66
67static int pil_to_sbus[] = { 56static int pil_to_sbus[] = {
68 0, 57 0,
69 0, 58 0,
@@ -83,152 +72,81 @@ static int pil_to_sbus[] = {
83 0, 72 0,
84}; 73};
85 74
86static int sbus_to_pil[] = {
87 0,
88 2,
89 3,
90 5,
91 7,
92 9,
93 11,
94 13,
95};
96
97static int nsbi;
98
99/* Exported for sun4d_smp.c */ 75/* Exported for sun4d_smp.c */
100DEFINE_SPINLOCK(sun4d_imsk_lock); 76DEFINE_SPINLOCK(sun4d_imsk_lock);
101 77
102int show_sun4d_interrupts(struct seq_file *p, void *v) 78/* SBUS interrupts are encoded integers including the board number
79 * (plus one), the SBUS level, and the SBUS slot number. Sun4D
80 * IRQ dispatch is done by:
81 *
82 * 1) Reading the BW local interrupt table in order to get the bus
83 * interrupt mask.
84 *
85 * This table is indexed by SBUS interrupt level which can be
86 * derived from the PIL we got interrupted on.
87 *
88 * 2) For each bus showing interrupt pending from #1, read the
89 * SBI interrupt state register. This will indicate which slots
90 * have interrupts pending for that SBUS interrupt level.
91 *
92 * 3) Call the genreric IRQ support.
93 */
94static void sun4d_sbus_handler_irq(int sbusl)
103{ 95{
104 int i = *(loff_t *) v, j = 0, k = 0, sbusl; 96 unsigned int bus_mask;
105 struct irqaction *action; 97 unsigned int sbino, slot;
106 unsigned long flags; 98 unsigned int sbil;
107#ifdef CONFIG_SMP 99
108 int x; 100 bus_mask = bw_get_intr_mask(sbusl) & 0x3ffff;
109#endif 101 bw_clear_intr_mask(sbusl, bus_mask);
110 102
111 spin_lock_irqsave(&irq_action_lock, flags); 103 sbil = (sbusl << 2);
112 if (i < NR_IRQS) { 104 /* Loop for each pending SBI */
113 sbusl = pil_to_sbus[i]; 105 for (sbino = 0; bus_mask; sbino++) {
114 if (!sbusl) { 106 unsigned int idx, mask;
115 action = *(i + irq_action); 107
116 if (!action) 108 bus_mask >>= 1;
117 goto out_unlock; 109 if (!(bus_mask & 1))
118 } else { 110 continue;
119 for (j = 0; j < nsbi; j++) { 111 /* XXX This seems to ACK the irq twice. acquire_sbi()
120 for (k = 0; k < 4; k++) 112 * XXX uses swap, therefore this writes 0xf << sbil,
121 action = sbus_actions[(j << 5) + (sbusl << 2) + k].action; 113 * XXX then later release_sbi() will write the individual
122 if (action) 114 * XXX bits which were set again.
123 goto found_it; 115 */
124 } 116 mask = acquire_sbi(SBI2DEVID(sbino), 0xf << sbil);
125 goto out_unlock; 117 mask &= (0xf << sbil);
126 } 118
127found_it: seq_printf(p, "%3d: ", i); 119 /* Loop for each pending SBI slot */
128#ifndef CONFIG_SMP 120 idx = 0;
129 seq_printf(p, "%10u ", kstat_irqs(i)); 121 slot = (1 << sbil);
130#else 122 while (mask != 0) {
131 for_each_online_cpu(x) 123 unsigned int pil;
132 seq_printf(p, "%10u ", 124 struct irq_bucket *p;
133 kstat_cpu(cpu_logical_map(x)).irqs[i]); 125
134#endif 126 idx++;
135 seq_printf(p, "%c %s", 127 slot <<= 1;
136 (action->flags & IRQF_DISABLED) ? '+' : ' ', 128 if (!(mask & slot))
137 action->name); 129 continue;
138 action = action->next; 130
139 for (;;) { 131 mask &= ~slot;
140 for (; action; action = action->next) { 132 pil = sun4d_encode_irq(sbino, sbil, idx);
141 seq_printf(p, ",%s %s", 133
142 (action->flags & IRQF_DISABLED) ? " +" : "", 134 p = irq_map[pil];
143 action->name); 135 while (p) {
144 } 136 struct irq_bucket *next;
145 if (!sbusl) 137
146 break; 138 next = p->next;
147 k++; 139 generic_handle_irq(p->irq);
148 if (k < 4) { 140 p = next;
149 action = sbus_actions[(j << 5) + (sbusl << 2) + k].action;
150 } else {
151 j++;
152 if (j == nsbi)
153 break;
154 k = 0;
155 action = sbus_actions[(j << 5) + (sbusl << 2)].action;
156 } 141 }
142 release_sbi(SBI2DEVID(sbino), slot);
157 } 143 }
158 seq_putc(p, '\n');
159 }
160out_unlock:
161 spin_unlock_irqrestore(&irq_action_lock, flags);
162 return 0;
163}
164
165void sun4d_free_irq(unsigned int irq, void *dev_id)
166{
167 struct irqaction *action, **actionp;
168 struct irqaction *tmp = NULL;
169 unsigned long flags;
170
171 spin_lock_irqsave(&irq_action_lock, flags);
172 if (irq < 15)
173 actionp = irq + irq_action;
174 else
175 actionp = &(sbus_actions[irq - (1 << 5)].action);
176 action = *actionp;
177 if (!action) {
178 printk(KERN_ERR "Trying to free free IRQ%d\n", irq);
179 goto out_unlock;
180 }
181 if (dev_id) {
182 for (; action; action = action->next) {
183 if (action->dev_id == dev_id)
184 break;
185 tmp = action;
186 }
187 if (!action) {
188 printk(KERN_ERR "Trying to free free shared IRQ%d\n",
189 irq);
190 goto out_unlock;
191 }
192 } else if (action->flags & IRQF_SHARED) {
193 printk(KERN_ERR "Trying to free shared IRQ%d with NULL device ID\n",
194 irq);
195 goto out_unlock;
196 }
197 if (action->flags & SA_STATIC_ALLOC) {
198 /*
199 * This interrupt is marked as specially allocated
200 * so it is a bad idea to free it.
201 */
202 printk(KERN_ERR "Attempt to free statically allocated IRQ%d (%s)\n",
203 irq, action->name);
204 goto out_unlock;
205 } 144 }
206
207 if (tmp)
208 tmp->next = action->next;
209 else
210 *actionp = action->next;
211
212 spin_unlock_irqrestore(&irq_action_lock, flags);
213
214 synchronize_irq(irq);
215
216 spin_lock_irqsave(&irq_action_lock, flags);
217
218 kfree(action);
219
220 if (!(*actionp))
221 __disable_irq(irq);
222
223out_unlock:
224 spin_unlock_irqrestore(&irq_action_lock, flags);
225} 145}
226 146
227void sun4d_handler_irq(int pil, struct pt_regs *regs) 147void sun4d_handler_irq(int pil, struct pt_regs *regs)
228{ 148{
229 struct pt_regs *old_regs; 149 struct pt_regs *old_regs;
230 struct irqaction *action;
231 int cpu = smp_processor_id();
232 /* SBUS IRQ level (1 - 7) */ 150 /* SBUS IRQ level (1 - 7) */
233 int sbusl = pil_to_sbus[pil]; 151 int sbusl = pil_to_sbus[pil];
234 152
@@ -239,158 +157,85 @@ void sun4d_handler_irq(int pil, struct pt_regs *regs)
239 157
240 old_regs = set_irq_regs(regs); 158 old_regs = set_irq_regs(regs);
241 irq_enter(); 159 irq_enter();
242 kstat_cpu(cpu).irqs[pil]++; 160 if (sbusl == 0) {
243 if (!sbusl) { 161 /* cpu interrupt */
244 action = *(pil + irq_action); 162 struct irq_bucket *p;
245 if (!action) 163
246 unexpected_irq(pil, NULL, regs); 164 p = irq_map[pil];
247 do { 165 while (p) {
248 action->handler(pil, action->dev_id); 166 struct irq_bucket *next;
249 action = action->next; 167
250 } while (action); 168 next = p->next;
169 generic_handle_irq(p->irq);
170 p = next;
171 }
251 } else { 172 } else {
252 int bus_mask = bw_get_intr_mask(sbusl) & 0x3ffff; 173 /* SBUS interrupt */
253 int sbino; 174 sun4d_sbus_handler_irq(sbusl);
254 struct sbus_action *actionp;
255 unsigned mask, slot;
256 int sbil = (sbusl << 2);
257
258 bw_clear_intr_mask(sbusl, bus_mask);
259
260 /* Loop for each pending SBI */
261 for (sbino = 0; bus_mask; sbino++, bus_mask >>= 1)
262 if (bus_mask & 1) {
263 mask = acquire_sbi(SBI2DEVID(sbino), 0xf << sbil);
264 mask &= (0xf << sbil);
265 actionp = sbus_actions + (sbino << 5) + (sbil);
266 /* Loop for each pending SBI slot */
267 for (slot = (1 << sbil); mask; slot <<= 1, actionp++)
268 if (mask & slot) {
269 mask &= ~slot;
270 action = actionp->action;
271
272 if (!action)
273 unexpected_irq(pil, NULL, regs);
274 do {
275 action->handler(pil, action->dev_id);
276 action = action->next;
277 } while (action);
278 release_sbi(SBI2DEVID(sbino), slot);
279 }
280 }
281 } 175 }
282 irq_exit(); 176 irq_exit();
283 set_irq_regs(old_regs); 177 set_irq_regs(old_regs);
284} 178}
285 179
286int sun4d_request_irq(unsigned int irq, 180
287 irq_handler_t handler, 181static void sun4d_mask_irq(struct irq_data *data)
288 unsigned long irqflags, const char *devname, void *dev_id)
289{ 182{
290 struct irqaction *action, *tmp = NULL, **actionp; 183 struct sun4d_handler_data *handler_data = data->handler_data;
184 unsigned int real_irq;
185#ifdef CONFIG_SMP
186 int cpuid = handler_data->cpuid;
291 unsigned long flags; 187 unsigned long flags;
292 int ret; 188#endif
293 189 real_irq = handler_data->real_irq;
294 if (irq > 14 && irq < (1 << 5)) { 190#ifdef CONFIG_SMP
295 ret = -EINVAL; 191 spin_lock_irqsave(&sun4d_imsk_lock, flags);
296 goto out; 192 cc_set_imsk_other(cpuid, cc_get_imsk_other(cpuid) | (1 << real_irq));
297 } 193 spin_unlock_irqrestore(&sun4d_imsk_lock, flags);
298 194#else
299 if (!handler) { 195 cc_set_imsk(cc_get_imsk() | (1 << real_irq));
300 ret = -EINVAL; 196#endif
301 goto out;
302 }
303
304 spin_lock_irqsave(&irq_action_lock, flags);
305
306 if (irq >= (1 << 5))
307 actionp = &(sbus_actions[irq - (1 << 5)].action);
308 else
309 actionp = irq + irq_action;
310 action = *actionp;
311
312 if (action) {
313 if ((action->flags & IRQF_SHARED) && (irqflags & IRQF_SHARED)) {
314 for (tmp = action; tmp->next; tmp = tmp->next)
315 /* find last entry - tmp used below */;
316 } else {
317 ret = -EBUSY;
318 goto out_unlock;
319 }
320 if ((action->flags & IRQF_DISABLED) ^ (irqflags & IRQF_DISABLED)) {
321 printk(KERN_ERR "Attempt to mix fast and slow interrupts on IRQ%d denied\n",
322 irq);
323 ret = -EBUSY;
324 goto out_unlock;
325 }
326 action = NULL; /* Or else! */
327 }
328
329 /* If this is flagged as statically allocated then we use our
330 * private struct which is never freed.
331 */
332 if (irqflags & SA_STATIC_ALLOC) {
333 if (static_irq_count < MAX_STATIC_ALLOC)
334 action = &static_irqaction[static_irq_count++];
335 else
336 printk(KERN_ERR "Request for IRQ%d (%s) SA_STATIC_ALLOC failed using kmalloc\n",
337 irq, devname);
338 }
339
340 if (action == NULL)
341 action = kmalloc(sizeof(struct irqaction), GFP_ATOMIC);
342
343 if (!action) {
344 ret = -ENOMEM;
345 goto out_unlock;
346 }
347
348 action->handler = handler;
349 action->flags = irqflags;
350 action->name = devname;
351 action->next = NULL;
352 action->dev_id = dev_id;
353
354 if (tmp)
355 tmp->next = action;
356 else
357 *actionp = action;
358
359 __enable_irq(irq);
360
361 ret = 0;
362out_unlock:
363 spin_unlock_irqrestore(&irq_action_lock, flags);
364out:
365 return ret;
366} 197}
367 198
368static void sun4d_disable_irq(unsigned int irq) 199static void sun4d_unmask_irq(struct irq_data *data)
369{ 200{
370 int tid = board_to_cpu[(irq >> 5) - 1]; 201 struct sun4d_handler_data *handler_data = data->handler_data;
202 unsigned int real_irq;
203#ifdef CONFIG_SMP
204 int cpuid = handler_data->cpuid;
371 unsigned long flags; 205 unsigned long flags;
206#endif
207 real_irq = handler_data->real_irq;
372 208
373 if (irq < NR_IRQS) 209#ifdef CONFIG_SMP
374 return;
375
376 spin_lock_irqsave(&sun4d_imsk_lock, flags); 210 spin_lock_irqsave(&sun4d_imsk_lock, flags);
377 cc_set_imsk_other(tid, cc_get_imsk_other(tid) | (1 << sbus_to_pil[(irq >> 2) & 7])); 211 cc_set_imsk_other(cpuid, cc_get_imsk_other(cpuid) | ~(1 << real_irq));
378 spin_unlock_irqrestore(&sun4d_imsk_lock, flags); 212 spin_unlock_irqrestore(&sun4d_imsk_lock, flags);
213#else
214 cc_set_imsk(cc_get_imsk() | ~(1 << real_irq));
215#endif
379} 216}
380 217
381static void sun4d_enable_irq(unsigned int irq) 218static unsigned int sun4d_startup_irq(struct irq_data *data)
382{ 219{
383 int tid = board_to_cpu[(irq >> 5) - 1]; 220 irq_link(data->irq);
384 unsigned long flags; 221 sun4d_unmask_irq(data);
385 222 return 0;
386 if (irq < NR_IRQS) 223}
387 return;
388 224
389 spin_lock_irqsave(&sun4d_imsk_lock, flags); 225static void sun4d_shutdown_irq(struct irq_data *data)
390 cc_set_imsk_other(tid, cc_get_imsk_other(tid) & ~(1 << sbus_to_pil[(irq >> 2) & 7])); 226{
391 spin_unlock_irqrestore(&sun4d_imsk_lock, flags); 227 sun4d_mask_irq(data);
228 irq_unlink(data->irq);
392} 229}
393 230
231struct irq_chip sun4d_irq = {
232 .name = "sun4d",
233 .irq_startup = sun4d_startup_irq,
234 .irq_shutdown = sun4d_shutdown_irq,
235 .irq_unmask = sun4d_unmask_irq,
236 .irq_mask = sun4d_mask_irq,
237};
238
394#ifdef CONFIG_SMP 239#ifdef CONFIG_SMP
395static void sun4d_set_cpu_int(int cpu, int level) 240static void sun4d_set_cpu_int(int cpu, int level)
396{ 241{
@@ -447,15 +292,16 @@ static void __init sun4d_load_profile_irqs(void)
447unsigned int sun4d_build_device_irq(struct platform_device *op, 292unsigned int sun4d_build_device_irq(struct platform_device *op,
448 unsigned int real_irq) 293 unsigned int real_irq)
449{ 294{
450 static int pil_to_sbus[] = {
451 0, 0, 1, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 0,
452 };
453 struct device_node *dp = op->dev.of_node; 295 struct device_node *dp = op->dev.of_node;
454 struct device_node *io_unit, *sbi = dp->parent; 296 struct device_node *io_unit, *sbi = dp->parent;
455 const struct linux_prom_registers *regs; 297 const struct linux_prom_registers *regs;
298 struct sun4d_handler_data *handler_data;
299 unsigned int pil;
300 unsigned int irq;
456 int board, slot; 301 int board, slot;
457 int sbusl; 302 int sbusl;
458 303
304 irq = 0;
459 while (sbi) { 305 while (sbi) {
460 if (!strcmp(sbi->name, "sbi")) 306 if (!strcmp(sbi->name, "sbi"))
461 break; 307 break;
@@ -488,7 +334,28 @@ unsigned int sun4d_build_device_irq(struct platform_device *op,
488 334
489 sbusl = pil_to_sbus[real_irq]; 335 sbusl = pil_to_sbus[real_irq];
490 if (sbusl) 336 if (sbusl)
491 return (((board + 1) << 5) + (sbusl << 2) + slot); 337 pil = sun4d_encode_irq(board, sbusl, slot);
338 else
339 pil = real_irq;
340
341 irq = irq_alloc(real_irq, pil);
342 if (irq == 0)
343 goto err_out;
344
345 handler_data = irq_get_handler_data(irq);
346 if (unlikely(handler_data))
347 goto err_out;
348
349 handler_data = kzalloc(sizeof(struct sun4d_handler_data), GFP_ATOMIC);
350 if (unlikely(!handler_data)) {
351 prom_printf("IRQ: kzalloc(sun4d_handler_data) failed.\n");
352 prom_halt();
353 }
354 handler_data->cpuid = board_to_cpu[board];
355 handler_data->real_irq = real_irq;
356 irq_set_chip_and_handler_name(irq, &sun4d_irq,
357 handle_level_irq, "level");
358 irq_set_handler_data(irq, handler_data);
492 359
493err_out: 360err_out:
494 return real_irq; 361 return real_irq;
@@ -522,6 +389,7 @@ static void __init sun4d_init_timers(irq_handler_t counter_fn)
522{ 389{
523 struct device_node *dp; 390 struct device_node *dp;
524 struct resource res; 391 struct resource res;
392 unsigned int irq;
525 const u32 *reg; 393 const u32 *reg;
526 int err; 394 int err;
527 395
@@ -556,9 +424,8 @@ static void __init sun4d_init_timers(irq_handler_t counter_fn)
556 424
557 master_l10_counter = &sun4d_timers->l10_cur_count; 425 master_l10_counter = &sun4d_timers->l10_cur_count;
558 426
559 err = request_irq(TIMER_IRQ, counter_fn, 427 irq = sun4d_build_device_irq(NULL, SUN4D_TIMER_IRQ);
560 (IRQF_DISABLED | SA_STATIC_ALLOC), 428 err = request_irq(irq, counter_fn, IRQF_TIMER, "timer", NULL);
561 "timer", NULL);
562 if (err) { 429 if (err) {
563 prom_printf("sun4d_init_timers: request_irq() failed with %d\n", 430 prom_printf("sun4d_init_timers: request_irq() failed with %d\n",
564 err); 431 err);
@@ -576,15 +443,6 @@ void __init sun4d_init_sbi_irq(void)
576#ifdef CONFIG_SMP 443#ifdef CONFIG_SMP
577 target_cpu = boot_cpu_id; 444 target_cpu = boot_cpu_id;
578#endif 445#endif
579
580 nsbi = 0;
581 for_each_node_by_name(dp, "sbi")
582 nsbi++;
583 sbus_actions = kzalloc(nsbi * 8 * 4 * sizeof(struct sbus_action), GFP_ATOMIC);
584 if (!sbus_actions) {
585 prom_printf("SUN4D: Cannot allocate sbus_actions, halting.\n");
586 prom_halt();
587 }
588 for_each_node_by_name(dp, "sbi") { 446 for_each_node_by_name(dp, "sbi") {
589 int devid = of_getintprop_default(dp, "device-id", 0); 447 int devid = of_getintprop_default(dp, "device-id", 0);
590 int board = of_getintprop_default(dp, "board#", 0); 448 int board = of_getintprop_default(dp, "board#", 0);
@@ -607,12 +465,10 @@ void __init sun4d_init_IRQ(void)
607{ 465{
608 local_irq_disable(); 466 local_irq_disable();
609 467
610 BTFIXUPSET_CALL(enable_irq, sun4d_enable_irq, BTFIXUPCALL_NORM);
611 BTFIXUPSET_CALL(disable_irq, sun4d_disable_irq, BTFIXUPCALL_NORM);
612 BTFIXUPSET_CALL(clear_clock_irq, sun4d_clear_clock_irq, BTFIXUPCALL_NORM); 468 BTFIXUPSET_CALL(clear_clock_irq, sun4d_clear_clock_irq, BTFIXUPCALL_NORM);
613 BTFIXUPSET_CALL(load_profile_irq, sun4d_load_profile_irq, BTFIXUPCALL_NORM); 469 BTFIXUPSET_CALL(load_profile_irq, sun4d_load_profile_irq, BTFIXUPCALL_NORM);
614 470
615 sparc_irq_config.init_timers = sun4d_init_timers; 471 sparc_irq_config.init_timers = sun4d_init_timers;
616 sparc_irq_config.build_device_irq = sun4d_build_device_irq; 472 sparc_irq_config.build_device_irq = sun4d_build_device_irq;
617 473
618#ifdef CONFIG_SMP 474#ifdef CONFIG_SMP
diff --git a/arch/sparc/kernel/sun4m_irq.c b/arch/sparc/kernel/sun4m_irq.c
index 69df6257a32e..422c16dad1f6 100644
--- a/arch/sparc/kernel/sun4m_irq.c
+++ b/arch/sparc/kernel/sun4m_irq.c
@@ -100,6 +100,11 @@
100struct sun4m_irq_percpu __iomem *sun4m_irq_percpu[SUN4M_NCPUS]; 100struct sun4m_irq_percpu __iomem *sun4m_irq_percpu[SUN4M_NCPUS];
101struct sun4m_irq_global __iomem *sun4m_irq_global; 101struct sun4m_irq_global __iomem *sun4m_irq_global;
102 102
103struct sun4m_handler_data {
104 bool percpu;
105 long mask;
106};
107
103/* Dave Redman (djhr@tadpole.co.uk) 108/* Dave Redman (djhr@tadpole.co.uk)
104 * The sun4m interrupt registers. 109 * The sun4m interrupt registers.
105 */ 110 */
@@ -142,9 +147,9 @@ struct sun4m_irq_global __iomem *sun4m_irq_global;
142#define OBP_INT_LEVEL_VME 0x40 147#define OBP_INT_LEVEL_VME 0x40
143 148
144#define SUN4M_TIMER_IRQ (OBP_INT_LEVEL_ONBOARD | 10) 149#define SUN4M_TIMER_IRQ (OBP_INT_LEVEL_ONBOARD | 10)
145#define SUM4M_PROFILE_IRQ (OBP_INT_LEVEL_ONBOARD | 14) 150#define SUN4M_PROFILE_IRQ (OBP_INT_LEVEL_ONBOARD | 14)
146 151
147static unsigned long irq_mask[0x50] = { 152static unsigned long sun4m_imask[0x50] = {
148 /* 0x00 - SMP */ 153 /* 0x00 - SMP */
149 0, SUN4M_SOFT_INT(1), 154 0, SUN4M_SOFT_INT(1),
150 SUN4M_SOFT_INT(2), SUN4M_SOFT_INT(3), 155 SUN4M_SOFT_INT(2), SUN4M_SOFT_INT(3),
@@ -169,7 +174,7 @@ static unsigned long irq_mask[0x50] = {
169 SUN4M_INT_VIDEO, SUN4M_INT_MODULE, 174 SUN4M_INT_VIDEO, SUN4M_INT_MODULE,
170 SUN4M_INT_REALTIME, SUN4M_INT_FLOPPY, 175 SUN4M_INT_REALTIME, SUN4M_INT_FLOPPY,
171 (SUN4M_INT_SERIAL | SUN4M_INT_KBDMS), 176 (SUN4M_INT_SERIAL | SUN4M_INT_KBDMS),
172 SUN4M_INT_AUDIO, 0, SUN4M_INT_MODULE_ERR, 177 SUN4M_INT_AUDIO, SUN4M_INT_E14, SUN4M_INT_MODULE_ERR,
173 /* 0x30 - sbus */ 178 /* 0x30 - sbus */
174 0, 0, SUN4M_INT_SBUS(0), SUN4M_INT_SBUS(1), 179 0, 0, SUN4M_INT_SBUS(0), SUN4M_INT_SBUS(1),
175 0, SUN4M_INT_SBUS(2), 0, SUN4M_INT_SBUS(3), 180 0, SUN4M_INT_SBUS(2), 0, SUN4M_INT_SBUS(3),
@@ -182,105 +187,110 @@ static unsigned long irq_mask[0x50] = {
182 0, SUN4M_INT_VME(6), 0, 0 187 0, SUN4M_INT_VME(6), 0, 0
183}; 188};
184 189
185static unsigned long sun4m_get_irqmask(unsigned int irq) 190static void sun4m_mask_irq(struct irq_data *data)
186{ 191{
187 unsigned long mask; 192 struct sun4m_handler_data *handler_data = data->handler_data;
188 193 int cpu = smp_processor_id();
189 if (irq < 0x50)
190 mask = irq_mask[irq];
191 else
192 mask = 0;
193 194
194 if (!mask) 195 if (handler_data->mask) {
195 printk(KERN_ERR "sun4m_get_irqmask: IRQ%d has no valid mask!\n", 196 unsigned long flags;
196 irq);
197 197
198 return mask; 198 local_irq_save(flags);
199 if (handler_data->percpu) {
200 sbus_writel(handler_data->mask, &sun4m_irq_percpu[cpu]->set);
201 } else {
202 sbus_writel(handler_data->mask, &sun4m_irq_global->mask_set);
203 }
204 local_irq_restore(flags);
205 }
199} 206}
200 207
201static void sun4m_disable_irq(unsigned int irq_nr) 208static void sun4m_unmask_irq(struct irq_data *data)
202{ 209{
203 unsigned long mask, flags; 210 struct sun4m_handler_data *handler_data = data->handler_data;
204 int cpu = smp_processor_id(); 211 int cpu = smp_processor_id();
205 212
206 mask = sun4m_get_irqmask(irq_nr); 213 if (handler_data->mask) {
207 local_irq_save(flags); 214 unsigned long flags;
208 if (irq_nr > 15)
209 sbus_writel(mask, &sun4m_irq_global->mask_set);
210 else
211 sbus_writel(mask, &sun4m_irq_percpu[cpu]->set);
212 local_irq_restore(flags);
213}
214
215static void sun4m_enable_irq(unsigned int irq_nr)
216{
217 unsigned long mask, flags;
218 int cpu = smp_processor_id();
219 215
220 /* Dreadful floppy hack. When we use 0x2b instead of
221 * 0x0b the system blows (it starts to whistle!).
222 * So we continue to use 0x0b. Fixme ASAP. --P3
223 */
224 if (irq_nr != 0x0b) {
225 mask = sun4m_get_irqmask(irq_nr);
226 local_irq_save(flags);
227 if (irq_nr > 15)
228 sbus_writel(mask, &sun4m_irq_global->mask_clear);
229 else
230 sbus_writel(mask, &sun4m_irq_percpu[cpu]->clear);
231 local_irq_restore(flags);
232 } else {
233 local_irq_save(flags); 216 local_irq_save(flags);
234 sbus_writel(SUN4M_INT_FLOPPY, &sun4m_irq_global->mask_clear); 217 if (handler_data->percpu) {
218 sbus_writel(handler_data->mask, &sun4m_irq_percpu[cpu]->clear);
219 } else {
220 sbus_writel(handler_data->mask, &sun4m_irq_global->mask_clear);
221 }
235 local_irq_restore(flags); 222 local_irq_restore(flags);
236 } 223 }
237} 224}
238 225
239static unsigned long cpu_pil_to_imask[16] = { 226static unsigned int sun4m_startup_irq(struct irq_data *data)
240/*0*/ 0x00000000, 227{
241/*1*/ 0x00000000, 228 irq_link(data->irq);
242/*2*/ SUN4M_INT_SBUS(0) | SUN4M_INT_VME(0), 229 sun4m_unmask_irq(data);
243/*3*/ SUN4M_INT_SBUS(1) | SUN4M_INT_VME(1), 230 return 0;
244/*4*/ SUN4M_INT_SCSI, 231}
245/*5*/ SUN4M_INT_SBUS(2) | SUN4M_INT_VME(2),
246/*6*/ SUN4M_INT_ETHERNET,
247/*7*/ SUN4M_INT_SBUS(3) | SUN4M_INT_VME(3),
248/*8*/ SUN4M_INT_VIDEO,
249/*9*/ SUN4M_INT_SBUS(4) | SUN4M_INT_VME(4) | SUN4M_INT_MODULE_ERR,
250/*10*/ SUN4M_INT_REALTIME,
251/*11*/ SUN4M_INT_SBUS(5) | SUN4M_INT_VME(5) | SUN4M_INT_FLOPPY,
252/*12*/ SUN4M_INT_SERIAL | SUN4M_INT_KBDMS,
253/*13*/ SUN4M_INT_SBUS(6) | SUN4M_INT_VME(6) | SUN4M_INT_AUDIO,
254/*14*/ SUN4M_INT_E14,
255/*15*/ SUN4M_INT_ERROR,
256};
257 232
258/* We assume the caller has disabled local interrupts when these are called, 233static void sun4m_shutdown_irq(struct irq_data *data)
259 * or else very bizarre behavior will result.
260 */
261static void sun4m_disable_pil_irq(unsigned int pil)
262{ 234{
263 sbus_writel(cpu_pil_to_imask[pil], &sun4m_irq_global->mask_set); 235 sun4m_mask_irq(data);
236 irq_unlink(data->irq);
264} 237}
265 238
266static void sun4m_enable_pil_irq(unsigned int pil) 239static struct irq_chip sun4m_irq = {
240 .name = "sun4m",
241 .irq_startup = sun4m_startup_irq,
242 .irq_shutdown = sun4m_shutdown_irq,
243 .irq_mask = sun4m_mask_irq,
244 .irq_unmask = sun4m_unmask_irq,
245};
246
247
248static unsigned int sun4m_build_device_irq(struct platform_device *op,
249 unsigned int real_irq)
267{ 250{
268 sbus_writel(cpu_pil_to_imask[pil], &sun4m_irq_global->mask_clear); 251 struct sun4m_handler_data *handler_data;
252 unsigned int irq;
253 unsigned int pil;
254
255 if (real_irq >= OBP_INT_LEVEL_VME) {
256 prom_printf("Bogus sun4m IRQ %u\n", real_irq);
257 prom_halt();
258 }
259 pil = (real_irq & 0xf);
260 irq = irq_alloc(real_irq, pil);
261
262 if (irq == 0)
263 goto out;
264
265 handler_data = irq_get_handler_data(irq);
266 if (unlikely(handler_data))
267 goto out;
268
269 handler_data = kzalloc(sizeof(struct sun4m_handler_data), GFP_ATOMIC);
270 if (unlikely(!handler_data)) {
271 prom_printf("IRQ: kzalloc(sun4m_handler_data) failed.\n");
272 prom_halt();
273 }
274
275 handler_data->mask = sun4m_imask[real_irq];
276 handler_data->percpu = real_irq < OBP_INT_LEVEL_ONBOARD;
277 irq_set_chip_and_handler_name(irq, &sun4m_irq,
278 handle_level_irq, "level");
279 irq_set_handler_data(irq, handler_data);
280
281out:
282 return irq;
269} 283}
270 284
271#ifdef CONFIG_SMP 285#ifdef CONFIG_SMP
272static void sun4m_send_ipi(int cpu, int level) 286static void sun4m_send_ipi(int cpu, int level)
273{ 287{
274 unsigned long mask = sun4m_get_irqmask(level); 288 sbus_writel(SUN4M_SOFT_INT(level), &sun4m_irq_percpu[cpu]->set);
275
276 sbus_writel(mask, &sun4m_irq_percpu[cpu]->set);
277} 289}
278 290
279static void sun4m_clear_ipi(int cpu, int level) 291static void sun4m_clear_ipi(int cpu, int level)
280{ 292{
281 unsigned long mask = sun4m_get_irqmask(level); 293 sbus_writel(SUN4M_SOFT_INT(level), &sun4m_irq_percpu[cpu]->clear);
282
283 sbus_writel(mask, &sun4m_irq_percpu[cpu]->clear);
284} 294}
285 295
286static void sun4m_set_udt(int cpu) 296static void sun4m_set_udt(int cpu)
@@ -343,7 +353,15 @@ void sun4m_nmi(struct pt_regs *regs)
343 prom_halt(); 353 prom_halt();
344} 354}
345 355
346/* Exported for sun4m_smp.c */ 356void sun4m_unmask_profile_irq(void)
357{
358 unsigned long flags;
359
360 local_irq_save(flags);
361 sbus_writel(sun4m_imask[SUN4M_PROFILE_IRQ], &sun4m_irq_global->mask_clear);
362 local_irq_restore(flags);
363}
364
347void sun4m_clear_profile_irq(int cpu) 365void sun4m_clear_profile_irq(int cpu)
348{ 366{
349 sbus_readl(&timers_percpu[cpu]->l14_limit); 367 sbus_readl(&timers_percpu[cpu]->l14_limit);
@@ -358,6 +376,7 @@ static void __init sun4m_init_timers(irq_handler_t counter_fn)
358{ 376{
359 struct device_node *dp = of_find_node_by_name(NULL, "counter"); 377 struct device_node *dp = of_find_node_by_name(NULL, "counter");
360 int i, err, len, num_cpu_timers; 378 int i, err, len, num_cpu_timers;
379 unsigned int irq;
361 const u32 *addr; 380 const u32 *addr;
362 381
363 if (!dp) { 382 if (!dp) {
@@ -384,8 +403,9 @@ static void __init sun4m_init_timers(irq_handler_t counter_fn)
384 403
385 master_l10_counter = &timers_global->l10_count; 404 master_l10_counter = &timers_global->l10_count;
386 405
387 err = request_irq(SUN4M_TIMER_IRQ, counter_fn, 406 irq = sun4m_build_device_irq(NULL, SUN4M_TIMER_IRQ);
388 (IRQF_DISABLED | SA_STATIC_ALLOC), "timer", NULL); 407
408 err = request_irq(irq, counter_fn, IRQF_TIMER, "timer", NULL);
389 if (err) { 409 if (err) {
390 printk(KERN_ERR "sun4m_init_timers: Register IRQ error %d.\n", 410 printk(KERN_ERR "sun4m_init_timers: Register IRQ error %d.\n",
391 err); 411 err);
@@ -452,14 +472,11 @@ void __init sun4m_init_IRQ(void)
452 if (num_cpu_iregs == 4) 472 if (num_cpu_iregs == 4)
453 sbus_writel(0, &sun4m_irq_global->interrupt_target); 473 sbus_writel(0, &sun4m_irq_global->interrupt_target);
454 474
455 BTFIXUPSET_CALL(enable_irq, sun4m_enable_irq, BTFIXUPCALL_NORM);
456 BTFIXUPSET_CALL(disable_irq, sun4m_disable_irq, BTFIXUPCALL_NORM);
457 BTFIXUPSET_CALL(enable_pil_irq, sun4m_enable_pil_irq, BTFIXUPCALL_NORM);
458 BTFIXUPSET_CALL(disable_pil_irq, sun4m_disable_pil_irq, BTFIXUPCALL_NORM);
459 BTFIXUPSET_CALL(clear_clock_irq, sun4m_clear_clock_irq, BTFIXUPCALL_NORM); 475 BTFIXUPSET_CALL(clear_clock_irq, sun4m_clear_clock_irq, BTFIXUPCALL_NORM);
460 BTFIXUPSET_CALL(load_profile_irq, sun4m_load_profile_irq, BTFIXUPCALL_NORM); 476 BTFIXUPSET_CALL(load_profile_irq, sun4m_load_profile_irq, BTFIXUPCALL_NORM);
461 477
462 sparc_irq_config.init_timers = sun4m_init_timers; 478 sparc_irq_config.init_timers = sun4m_init_timers;
479 sparc_irq_config.build_device_irq = sun4m_build_device_irq;
463 480
464#ifdef CONFIG_SMP 481#ifdef CONFIG_SMP
465 BTFIXUPSET_CALL(set_cpu_int, sun4m_send_ipi, BTFIXUPCALL_NORM); 482 BTFIXUPSET_CALL(set_cpu_int, sun4m_send_ipi, BTFIXUPCALL_NORM);
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c
index 5cc7dc51de3d..58b8d849674c 100644
--- a/arch/sparc/kernel/sun4m_smp.c
+++ b/arch/sparc/kernel/sun4m_smp.c
@@ -150,20 +150,6 @@ void __init smp4m_smp_done(void)
150 /* Ok, they are spinning and ready to go. */ 150 /* Ok, they are spinning and ready to go. */
151} 151}
152 152
153/* At each hardware IRQ, we get this called to forward IRQ reception
154 * to the next processor. The caller must disable the IRQ level being
155 * serviced globally so that there are no double interrupts received.
156 *
157 * XXX See sparc64 irq.c.
158 */
159void smp4m_irq_rotate(int cpu)
160{
161 int next = cpu_data(cpu).next;
162
163 if (next != cpu)
164 set_irq_udt(next);
165}
166
167static struct smp_funcall { 153static struct smp_funcall {
168 smpfunc_t func; 154 smpfunc_t func;
169 unsigned long arg1; 155 unsigned long arg1;
@@ -277,7 +263,7 @@ static void __cpuinit smp_setup_percpu_timer(void)
277 load_profile_irq(cpu, lvl14_resolution); 263 load_profile_irq(cpu, lvl14_resolution);
278 264
279 if (cpu == boot_cpu_id) 265 if (cpu == boot_cpu_id)
280 enable_pil_irq(14); 266 sun4m_unmask_profile_irq();
281} 267}
282 268
283static void __init smp4m_blackbox_id(unsigned *addr) 269static void __init smp4m_blackbox_id(unsigned *addr)