aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-03-12 20:33:21 -0400
committerIngo Molnar <mingo@elte.hu>2009-03-12 20:33:21 -0400
commit480c93df5b99699390f93a7024c9f60d09da0e96 (patch)
treeb93b6c8c71c5f2e716dd05b126e01ef4e20ff0af /arch/sparc
parentaecfcde920da8d32949f6cbbc1fc051b4ef9e7be (diff)
parentd820ac4c2fa881079e6b689d2098adce337558ae (diff)
Merge branch 'core/locking' into tracing/ftrace
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/kernel/irq_64.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index 3d2c6baae96b..233bd87a9637 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -324,17 +324,25 @@ static void sun4u_set_affinity(unsigned int virt_irq,
324 sun4u_irq_enable(virt_irq); 324 sun4u_irq_enable(virt_irq);
325} 325}
326 326
327/* Don't do anything. The desc->status check for IRQ_DISABLED in
328 * handler_irq() will skip the handler call and that will leave the
329 * interrupt in the sent state. The next ->enable() call will hit the
330 * ICLR register to reset the state machine.
331 *
332 * This scheme is necessary, instead of clearing the Valid bit in the
333 * IMAP register, to handle the case of IMAP registers being shared by
334 * multiple INOs (and thus ICLR registers). Since we use a different
335 * virtual IRQ for each shared IMAP instance, the generic code thinks
336 * there is only one user so it prematurely calls ->disable() on
337 * free_irq().
338 *
339 * We have to provide an explicit ->disable() method instead of using
340 * NULL to get the default. The reason is that if the generic code
341 * sees that, it also hooks up a default ->shutdown method which
342 * invokes ->mask() which we do not want. See irq_chip_set_defaults().
343 */
327static void sun4u_irq_disable(unsigned int virt_irq) 344static void sun4u_irq_disable(unsigned int virt_irq)
328{ 345{
329 struct irq_handler_data *data = get_irq_chip_data(virt_irq);
330
331 if (likely(data)) {
332 unsigned long imap = data->imap;
333 unsigned long tmp = upa_readq(imap);
334
335 tmp &= ~IMAP_VALID;
336 upa_writeq(tmp, imap);
337 }
338} 346}
339 347
340static void sun4u_irq_eoi(unsigned int virt_irq) 348static void sun4u_irq_eoi(unsigned int virt_irq)
@@ -747,7 +755,8 @@ void handler_irq(int irq, struct pt_regs *regs)
747 755
748 desc = irq_desc + virt_irq; 756 desc = irq_desc + virt_irq;
749 757
750 desc->handle_irq(virt_irq, desc); 758 if (!(desc->status & IRQ_DISABLED))
759 desc->handle_irq(virt_irq, desc);
751 760
752 bucket_pa = next_pa; 761 bucket_pa = next_pa;
753 } 762 }