diff options
Diffstat (limited to 'arch/sparc/kernel')
-rw-r--r-- | arch/sparc/kernel/irq_64.c | 31 | ||||
-rw-r--r-- | arch/sparc/kernel/time_64.c | 2 |
2 files changed, 21 insertions, 12 deletions
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index e289376198eb..8ba064f08a6f 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c | |||
@@ -185,7 +185,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
185 | seq_printf(p, "%10u ", kstat_irqs(i)); | 185 | seq_printf(p, "%10u ", kstat_irqs(i)); |
186 | #else | 186 | #else |
187 | for_each_online_cpu(j) | 187 | for_each_online_cpu(j) |
188 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); | 188 | seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); |
189 | #endif | 189 | #endif |
190 | seq_printf(p, " %9s", irq_desc[i].chip->typename); | 190 | seq_printf(p, " %9s", irq_desc[i].chip->typename); |
191 | seq_printf(p, " %s", action->name); | 191 | seq_printf(p, " %s", action->name); |
@@ -323,17 +323,25 @@ static void sun4u_set_affinity(unsigned int virt_irq, | |||
323 | sun4u_irq_enable(virt_irq); | 323 | sun4u_irq_enable(virt_irq); |
324 | } | 324 | } |
325 | 325 | ||
326 | /* Don't do anything. The desc->status check for IRQ_DISABLED in | ||
327 | * handler_irq() will skip the handler call and that will leave the | ||
328 | * interrupt in the sent state. The next ->enable() call will hit the | ||
329 | * ICLR register to reset the state machine. | ||
330 | * | ||
331 | * This scheme is necessary, instead of clearing the Valid bit in the | ||
332 | * IMAP register, to handle the case of IMAP registers being shared by | ||
333 | * multiple INOs (and thus ICLR registers). Since we use a different | ||
334 | * virtual IRQ for each shared IMAP instance, the generic code thinks | ||
335 | * there is only one user so it prematurely calls ->disable() on | ||
336 | * free_irq(). | ||
337 | * | ||
338 | * We have to provide an explicit ->disable() method instead of using | ||
339 | * NULL to get the default. The reason is that if the generic code | ||
340 | * sees that, it also hooks up a default ->shutdown method which | ||
341 | * invokes ->mask() which we do not want. See irq_chip_set_defaults(). | ||
342 | */ | ||
326 | static void sun4u_irq_disable(unsigned int virt_irq) | 343 | static void sun4u_irq_disable(unsigned int virt_irq) |
327 | { | 344 | { |
328 | struct irq_handler_data *data = get_irq_chip_data(virt_irq); | ||
329 | |||
330 | if (likely(data)) { | ||
331 | unsigned long imap = data->imap; | ||
332 | unsigned long tmp = upa_readq(imap); | ||
333 | |||
334 | tmp &= ~IMAP_VALID; | ||
335 | upa_writeq(tmp, imap); | ||
336 | } | ||
337 | } | 345 | } |
338 | 346 | ||
339 | static void sun4u_irq_eoi(unsigned int virt_irq) | 347 | static void sun4u_irq_eoi(unsigned int virt_irq) |
@@ -746,7 +754,8 @@ void handler_irq(int irq, struct pt_regs *regs) | |||
746 | 754 | ||
747 | desc = irq_desc + virt_irq; | 755 | desc = irq_desc + virt_irq; |
748 | 756 | ||
749 | desc->handle_irq(virt_irq, desc); | 757 | if (!(desc->status & IRQ_DISABLED)) |
758 | desc->handle_irq(virt_irq, desc); | ||
750 | 759 | ||
751 | bucket_pa = next_pa; | 760 | bucket_pa = next_pa; |
752 | } | 761 | } |
diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index 2db3c2229b95..642562d83ec4 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c | |||
@@ -36,10 +36,10 @@ | |||
36 | #include <linux/clocksource.h> | 36 | #include <linux/clocksource.h> |
37 | #include <linux/of_device.h> | 37 | #include <linux/of_device.h> |
38 | #include <linux/platform_device.h> | 38 | #include <linux/platform_device.h> |
39 | #include <linux/irq.h> | ||
39 | 40 | ||
40 | #include <asm/oplib.h> | 41 | #include <asm/oplib.h> |
41 | #include <asm/timer.h> | 42 | #include <asm/timer.h> |
42 | #include <asm/irq.h> | ||
43 | #include <asm/io.h> | 43 | #include <asm/io.h> |
44 | #include <asm/prom.h> | 44 | #include <asm/prom.h> |
45 | #include <asm/starfire.h> | 45 | #include <asm/starfire.h> |