[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Needs-Build: 4833



Geert,
Neither do I - but the IRQ being disabled is the device specific one, not the master chip interrupt dispatching the device specific one. The only way around that is to share this one with a dummy handler (and Paul did veto that).

I forgot to mention one alternative: add a handle_polled_irq() to kernel/chip.c that does explicitly fudge the handler return value. Or, in the alternative, set IRQS_POLL_INPROGRESS on the IRQ state for all interrupts multiplexed from the timer D IRQ chip, which will make note_interrupt shut up about spurious interrupts, but may have other unintended side effects. I'll try both, but rate the chance to get such a hack to pass review as minimal (you would not support that yourself, now would you?).

To illustrate - see attached two patches. This does actually work, without the need for noirqdebug.

And no, I'm not seriously suggesting you accept this.

Cheers,

 Michael

>From 261996aa2c73995c19abca1b3c08dc9000eef1a8 Mon Sep 17 00:00:00 2001
From: Michael Schmitz <schmitz@debian.org>
Date: Sat, 17 Nov 2012 17:32:16 +1300
Subject: [PATCH] [m68k] use handle_polled_irq for timer D softirqs

---
 arch/m68k/atari/ataints.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c
index 96f82f7..f98b744 100644
--- a/arch/m68k/atari/ataints.c
+++ b/arch/m68k/atari/ataints.c
@@ -254,7 +254,7 @@ void __init atari_init_IRQ(void)
 	sound_ym.rd_data_reg_sel = 7;
 	sound_ym.wd_data = 0xff;
 
-	m68k_setup_irq_controller(&atari_mfptimer_chip, handle_simple_irq,
+	m68k_setup_irq_controller(&atari_mfptimer_chip, handle_polled_irq,
 				  IRQ_MFP_TIMER1, 8);
 	/* possibly unneeded */ 
 	m68k_setup_irq_controller(&atari_irq_chip, handle_simple_irq, 
-- 
1.5.6

>From 468418539424d220720b148dfc144b2f2bc8967b Mon Sep 17 00:00:00 2001
From: Michael Schmitz <schmitz@debian.org>
Date: Sat, 17 Nov 2012 17:30:22 +1300
Subject: [PATCH] [m68k] add handle_polled_irq() for timer based soft interrupts

---
 include/linux/irq.h |    1 +
 kernel/irq/chip.c   |   37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index a5261e3..a5a7498 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -402,6 +402,7 @@ extern void handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc);
 extern void handle_edge_irq(unsigned int irq, struct irq_desc *desc);
 extern void handle_edge_eoi_irq(unsigned int irq, struct irq_desc *desc);
 extern void handle_simple_irq(unsigned int irq, struct irq_desc *desc);
+extern void handle_polled_irq(unsigned int irq, struct irq_desc *desc);
 extern void handle_percpu_irq(unsigned int irq, struct irq_desc *desc);
 extern void handle_percpu_devid_irq(unsigned int irq, struct irq_desc *desc);
 extern void handle_bad_irq(unsigned int irq, struct irq_desc *desc);
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index eebd6d5..c3e0c34 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -254,6 +254,7 @@ void unmask_irq(struct irq_desc *desc)
 	}
 }
 
+
 /*
  *	handle_nested_irq - Handle a nested irq from a irq thread
  *	@irq:	the interrupt number
@@ -338,6 +339,42 @@ out_unlock:
 }
 EXPORT_SYMBOL_GPL(handle_simple_irq);
 
+/**
+ *	handle_polled_irq - Simple and software-decoded IRQs.
+ *	@irq:	the interrupt number
+ *	@desc:	the interrupt description structure for this irq
+ *
+ *	Polled interrupts are sent from a demultiplexing software interrupt
+ *	handler, where no interrupt hardware control is necessary.
+ */
+void
+handle_polled_irq(unsigned int irq, struct irq_desc *desc)
+{
+	raw_spin_lock(&desc->lock);
+
+	if (unlikely(irqd_irq_inprogress(&desc->irq_data)))
+		if (!irq_check_poll(desc))
+			goto out_unlock;
+
+	desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
+	kstat_incr_irqs_this_cpu(irq, desc);
+
+	if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
+		desc->istate |= IRQS_PENDING;
+		goto out_unlock;
+	}
+
+	desc->istate |= IRQS_POLL_INPROGRESS;
+
+	handle_irq_event(desc);
+
+	desc->istate &= ~(IRQS_POLL_INPROGRESS);
+
+out_unlock:
+	raw_spin_unlock(&desc->lock);
+}
+EXPORT_SYMBOL_GPL(handle_polled_irq);
+
 /*
  * Called unconditionally from handle_level_irq() and only for oneshot
  * interrupts from handle_fasteoi_irq()
-- 
1.5.6


Reply to: