LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [patch 0/8] genirq: Further cleanups for .39
@ 2011-02-02 21:41 Thomas Gleixner
  2011-02-02 21:41 ` [patch 1/8] genirq: Remove bogus conditional Thomas Gleixner
                   ` (7 more replies)
  0 siblings, 8 replies; 17+ messages in thread
From: Thomas Gleixner @ 2011-02-02 21:41 UTC (permalink / raw)
  To: LKML; +Cc: Ingo Molnar, Peter Zijlstra

The following series consolidates the IRQ_MASKED handling which is a
prerequisite for forced threaded handlers and cleans up a few flow
handlers in the architecture code so handle_IRQ_event becomes local to
the core code.

Thanks,

	tglx


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [patch 1/8] genirq: Remove bogus conditional
  2011-02-02 21:41 [patch 0/8] genirq: Further cleanups for .39 Thomas Gleixner
@ 2011-02-02 21:41 ` Thomas Gleixner
  2011-02-19 12:22   ` [tip:irq/core] " tip-bot for Thomas Gleixner
  2011-02-02 21:41 ` [patch 2/8] genirq: Consolidate startup/shutdown of interrupts Thomas Gleixner
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 17+ messages in thread
From: Thomas Gleixner @ 2011-02-02 21:41 UTC (permalink / raw)
  To: LKML; +Cc: Ingo Molnar, Peter Zijlstra

[-- Attachment #1: genirq-remove-bogus-conditional.patch --]
[-- Type: text/plain, Size: 948 bytes --]

The if (chip->irq_shutdown) check will always evaluate to true, as we
fill in chip->irq_shutdown with default_shutdown in
irq_chip_set_defaults() if the chip does not provide its own function.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/irq/manage.c |    5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

Index: linux-2.6-tip/kernel/irq/manage.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/manage.c
+++ linux-2.6-tip/kernel/irq/manage.c
@@ -1003,10 +1003,7 @@ static struct irqaction *__free_irq(unsi
 	/* If this was the last handler, shut down the IRQ line: */
 	if (!desc->action) {
 		desc->status |= IRQ_DISABLED;
-		if (desc->irq_data.chip->irq_shutdown)
-			desc->irq_data.chip->irq_shutdown(&desc->irq_data);
-		else
-			desc->irq_data.chip->irq_disable(&desc->irq_data);
+		desc->irq_data.chip->irq_shutdown(&desc->irq_data);
 	}
 
 #ifdef CONFIG_SMP



^ permalink raw reply	[flat|nested] 17+ messages in thread

* [patch 2/8] genirq: Consolidate startup/shutdown of interrupts
  2011-02-02 21:41 [patch 0/8] genirq: Further cleanups for .39 Thomas Gleixner
  2011-02-02 21:41 ` [patch 1/8] genirq: Remove bogus conditional Thomas Gleixner
@ 2011-02-02 21:41 ` Thomas Gleixner
  2011-02-19 12:22   ` [tip:irq/core] " tip-bot for Thomas Gleixner
  2011-02-02 21:41 ` [patch 3/8] genirq: Do not fiddle with IRQ_MASKED in handle_edge_irq() Thomas Gleixner
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 17+ messages in thread
From: Thomas Gleixner @ 2011-02-02 21:41 UTC (permalink / raw)
  To: LKML; +Cc: Ingo Molnar, Peter Zijlstra

[-- Attachment #1: genirq-clear-IRQ_MASKED-flag-in-startup.patch --]
[-- Type: text/plain, Size: 4816 bytes --]

Aside of duplicated code some of the startup/shutdown sites do not
handle the MASKED/DISABLED flags and the depth field at all. Move that
to a helper function and take care of it there.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/irq/autoprobe.c |   10 +++++-----
 kernel/irq/chip.c      |   18 +++++++++++++++---
 kernel/irq/internals.h |    3 +++
 kernel/irq/manage.c    |   14 +++++---------
 4 files changed, 28 insertions(+), 17 deletions(-)

Index: linux-2.6-tip/kernel/irq/autoprobe.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/autoprobe.c
+++ linux-2.6-tip/kernel/irq/autoprobe.c
@@ -60,7 +60,7 @@ unsigned long probe_irq_on(void)
 			if (desc->irq_data.chip->irq_set_type)
 				desc->irq_data.chip->irq_set_type(&desc->irq_data,
 							 IRQ_TYPE_PROBE);
-			desc->irq_data.chip->irq_startup(&desc->irq_data);
+			startup_irq(desc);
 		}
 		raw_spin_unlock_irq(&desc->lock);
 	}
@@ -77,7 +77,7 @@ unsigned long probe_irq_on(void)
 		raw_spin_lock_irq(&desc->lock);
 		if (!desc->action && !(desc->status & IRQ_NOPROBE)) {
 			desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
-			if (desc->irq_data.chip->irq_startup(&desc->irq_data))
+			if (startup_irq(desc))
 				desc->status |= IRQ_PENDING;
 		}
 		raw_spin_unlock_irq(&desc->lock);
@@ -99,7 +99,7 @@ unsigned long probe_irq_on(void)
 			/* It triggered already - consider it spurious. */
 			if (!(status & IRQ_WAITING)) {
 				desc->status = status & ~IRQ_AUTODETECT;
-				desc->irq_data.chip->irq_shutdown(&desc->irq_data);
+				shutdown_irq(desc);
 			} else
 				if (i < 32)
 					mask |= 1 << i;
@@ -138,7 +138,7 @@ unsigned int probe_irq_mask(unsigned lon
 				mask |= 1 << i;
 
 			desc->status = status & ~IRQ_AUTODETECT;
-			desc->irq_data.chip->irq_shutdown(&desc->irq_data);
+			shutdown_irq(desc);
 		}
 		raw_spin_unlock_irq(&desc->lock);
 	}
@@ -182,7 +182,7 @@ int probe_irq_off(unsigned long val)
 				nr_of_irqs++;
 			}
 			desc->status = status & ~IRQ_AUTODETECT;
-			desc->irq_data.chip->irq_shutdown(&desc->irq_data);
+			shutdown_irq(desc);
 		}
 		raw_spin_unlock_irq(&desc->lock);
 	}
Index: linux-2.6-tip/kernel/irq/chip.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/chip.c
+++ linux-2.6-tip/kernel/irq/chip.c
@@ -190,6 +190,20 @@ void set_irq_nested_thread(unsigned int 
 }
 EXPORT_SYMBOL_GPL(set_irq_nested_thread);
 
+int startup_irq(struct irq_desc *desc)
+{
+	desc->status &= ~(IRQ_MASKED | IRQ_DISABLED);
+	desc->depth = 0;
+	return desc->irq_data.chip->irq_startup(&desc->irq_data);
+}
+
+void shutdown_irq(struct irq_desc *desc)
+{
+	desc->status |= IRQ_MASKED | IRQ_DISABLED;
+	desc->depth = 1;
+	desc->irq_data.chip->irq_shutdown(&desc->irq_data);
+}
+
 /*
  * default enable function
  */
@@ -731,10 +745,8 @@ __set_irq_handler(unsigned int irq, irq_
 	desc->name = name;
 
 	if (handle != handle_bad_irq && is_chained) {
-		desc->status &= ~IRQ_DISABLED;
 		desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE;
-		desc->depth = 0;
-		desc->irq_data.chip->irq_startup(&desc->irq_data);
+		startup_irq(desc);
 	}
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
 	chip_bus_sync_unlock(desc);
Index: linux-2.6-tip/kernel/irq/internals.h
===================================================================
--- linux-2.6-tip.orig/kernel/irq/internals.h
+++ linux-2.6-tip/kernel/irq/internals.h
@@ -18,6 +18,9 @@ extern int __irq_set_trigger(struct irq_
 extern void __disable_irq(struct irq_desc *desc, unsigned int irq, bool susp);
 extern void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume);
 
+extern int startup_irq(struct irq_desc *desc);
+extern void shutdown_irq(struct irq_desc *desc);
+
 extern void init_kstat_irqs(struct irq_desc *desc, int node, int nr);
 
 /* Resending of interrupts :*/
Index: linux-2.6-tip/kernel/irq/manage.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/manage.c
+++ linux-2.6-tip/kernel/irq/manage.c
@@ -860,11 +860,9 @@ __setup_irq(unsigned int irq, struct irq
 		if (new->flags & IRQF_ONESHOT)
 			desc->status |= IRQ_ONESHOT;
 
-		if (!(desc->status & IRQ_NOAUTOEN)) {
-			desc->depth = 0;
-			desc->status &= ~IRQ_DISABLED;
-			desc->irq_data.chip->irq_startup(&desc->irq_data);
-		} else
+		if (!(desc->status & IRQ_NOAUTOEN))
+			startup_irq(desc);
+		else
 			/* Undo nested disables: */
 			desc->depth = 1;
 
@@ -1001,10 +999,8 @@ static struct irqaction *__free_irq(unsi
 #endif
 
 	/* If this was the last handler, shut down the IRQ line: */
-	if (!desc->action) {
-		desc->status |= IRQ_DISABLED;
-		desc->irq_data.chip->irq_shutdown(&desc->irq_data);
-	}
+	if (!desc->action)
+		shutdown_irq(desc);
 
 #ifdef CONFIG_SMP
 	/* make sure affinity_hint is cleaned up */



^ permalink raw reply	[flat|nested] 17+ messages in thread

* [patch 3/8] genirq: Do not fiddle with IRQ_MASKED in handle_edge_irq()
  2011-02-02 21:41 [patch 0/8] genirq: Further cleanups for .39 Thomas Gleixner
  2011-02-02 21:41 ` [patch 1/8] genirq: Remove bogus conditional Thomas Gleixner
  2011-02-02 21:41 ` [patch 2/8] genirq: Consolidate startup/shutdown of interrupts Thomas Gleixner
@ 2011-02-02 21:41 ` Thomas Gleixner
  2011-02-19 12:24   ` [tip:irq/core] " tip-bot for Thomas Gleixner
  2011-02-02 21:41 ` [patch 4/8] genirq: Introduce IRQ_EDGE_EOI flag Thomas Gleixner
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 17+ messages in thread
From: Thomas Gleixner @ 2011-02-02 21:41 UTC (permalink / raw)
  To: LKML; +Cc: Ingo Molnar, Peter Zijlstra

[-- Attachment #1: genirq-remove-redundant-mask.patch --]
[-- Type: text/plain, Size: 728 bytes --]

IRQ_MASKED is set in mask_ack_irq() anyway. Remove it from
handle_edge_irq() to allow simpler ab^HHreuse of that function.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/irq/chip.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux-2.6-tip/kernel/irq/chip.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/chip.c
+++ linux-2.6-tip/kernel/irq/chip.c
@@ -632,7 +632,7 @@ handle_edge_irq(unsigned int irq, struct
 	 */
 	if (unlikely((desc->status & (IRQ_INPROGRESS | IRQ_DISABLED)) ||
 		    !desc->action)) {
-		desc->status |= (IRQ_PENDING | IRQ_MASKED);
+		desc->status |= IRQ_PENDING;
 		mask_ack_irq(desc);
 		goto out_unlock;
 	}



^ permalink raw reply	[flat|nested] 17+ messages in thread

* [patch 4/8] genirq: Introduce IRQ_EDGE_EOI flag
  2011-02-02 21:41 [patch 0/8] genirq: Further cleanups for .39 Thomas Gleixner
                   ` (2 preceding siblings ...)
  2011-02-02 21:41 ` [patch 3/8] genirq: Do not fiddle with IRQ_MASKED in handle_edge_irq() Thomas Gleixner
@ 2011-02-02 21:41 ` Thomas Gleixner
  2011-02-02 21:41 ` [patch 5/8] powerpc: cell: Use handle_edge_irq Thomas Gleixner
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 17+ messages in thread
From: Thomas Gleixner @ 2011-02-02 21:41 UTC (permalink / raw)
  To: LKML
  Cc: Ingo Molnar, Peter Zijlstra, Benjamin Herrenschmidt, Jeremy Kerr,
	Arnd Bergmann

[-- Attachment #1: genirq-introduce-edge-eoi-flag.patch --]
[-- Type: text/plain, Size: 2727 bytes --]

powerpc/cell has a slightly modified version of the edge handler. The
main difference is that it does not ack and mask, but uses
eoi. handle_edge_irq is an oddball handler anyway, which should be
avoided wherever it can. So it's not worth to have a slightly
different copy around.

Add a special flag to reuse handle_edge_irq for this odd case.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Jeremy Kerr <jk@ozlabs.org>
Cc: Arnd Bergmann <arnd@arndb.de>
---
 include/linux/irq.h |    3 ++-
 kernel/irq/chip.c   |   11 ++++++++---
 2 files changed, 10 insertions(+), 4 deletions(-)

Index: linux-2.6-tip/include/linux/irq.h
===================================================================
--- linux-2.6-tip.orig/include/linux/irq.h
+++ linux-2.6-tip/include/linux/irq.h
@@ -71,10 +71,11 @@ typedef	void (*irq_flow_handler_t)(unsig
 #define IRQ_SUSPENDED		0x04000000	/* IRQ has gone through suspend sequence */
 #define IRQ_ONESHOT		0x08000000	/* IRQ is not unmasked after hardirq */
 #define IRQ_NESTED_THREAD	0x10000000	/* IRQ is nested into another, no own handler thread */
+#define IRQ_EDGE_EOI		0x20000000	/* IRQ abuses edge handler with EOI */
 
 #define IRQF_MODIFY_MASK	\
 	(IRQ_TYPE_SENSE_MASK | IRQ_NOPROBE | IRQ_NOREQUEST | \
-	 IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL)
+	 IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL | IRQ_EDGE_EOI)
 
 #ifdef CONFIG_IRQ_PER_CPU
 # define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU)
Index: linux-2.6-tip/kernel/irq/chip.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/chip.c
+++ linux-2.6-tip/kernel/irq/chip.c
@@ -633,13 +633,15 @@ handle_edge_irq(unsigned int irq, struct
 	if (unlikely((desc->status & (IRQ_INPROGRESS | IRQ_DISABLED)) ||
 		    !desc->action)) {
 		desc->status |= IRQ_PENDING;
-		mask_ack_irq(desc);
+		if (!(desc->status & IRQ_EDGE_EOI))
+			mask_ack_irq(desc);
 		goto out_unlock;
 	}
 	kstat_incr_irqs_this_cpu(irq, desc);
 
 	/* Start handling the irq */
-	desc->irq_data.chip->irq_ack(&desc->irq_data);
+	if (!(desc->status & IRQ_EDGE_EOI))
+		desc->irq_data.chip->irq_ack(&desc->irq_data);
 
 	/* Mark the IRQ currently in progress.*/
 	desc->status |= IRQ_INPROGRESS;
@@ -649,7 +651,8 @@ handle_edge_irq(unsigned int irq, struct
 		irqreturn_t action_ret;
 
 		if (unlikely(!action)) {
-			mask_irq(desc);
+			if (!(desc->status & IRQ_EDGE_EOI))
+				mask_irq(desc);
 			goto out_unlock;
 		}
 
@@ -675,6 +678,8 @@ handle_edge_irq(unsigned int irq, struct
 
 	desc->status &= ~IRQ_INPROGRESS;
 out_unlock:
+	if (desc->status & IRQ_EDGE_EOI)
+		desc->irq_data.chip->irq_eoi(&desc->irq_data);
 	raw_spin_unlock(&desc->lock);
 }
 



^ permalink raw reply	[flat|nested] 17+ messages in thread

* [patch 5/8] powerpc: cell: Use handle_edge_irq
  2011-02-02 21:41 [patch 0/8] genirq: Further cleanups for .39 Thomas Gleixner
                   ` (3 preceding siblings ...)
  2011-02-02 21:41 ` [patch 4/8] genirq: Introduce IRQ_EDGE_EOI flag Thomas Gleixner
@ 2011-02-02 21:41 ` Thomas Gleixner
  2011-02-02 21:41 ` [patch 6/8] arm: ns9xxx: Remove private irq flow handler Thomas Gleixner
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 17+ messages in thread
From: Thomas Gleixner @ 2011-02-02 21:41 UTC (permalink / raw)
  To: LKML
  Cc: Ingo Molnar, Peter Zijlstra, Benjamin Herrenschmidt, Jeremy Kerr,
	Arnd Bergmann

[-- Attachment #1: powerpc-cell-use-handle-edge-irq.patch --]
[-- Type: text/plain, Size: 2521 bytes --]

handle_edge_irq is now special cased for the cell EOI
requirements. Use it and remove the duplicate code.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Jeremy Kerr <jk@ozlabs.org>
Cc: Arnd Bergmann <arnd@arndb.de>
---
 arch/powerpc/platforms/cell/interrupt.c |   52 ++------------------------------
 1 file changed, 4 insertions(+), 48 deletions(-)

Index: linux-2.6-tip/arch/powerpc/platforms/cell/interrupt.c
===================================================================
--- linux-2.6-tip.orig/arch/powerpc/platforms/cell/interrupt.c
+++ linux-2.6-tip/arch/powerpc/platforms/cell/interrupt.c
@@ -233,52 +233,6 @@ static int iic_host_match(struct irq_hos
 				    "IBM,CBEA-Internal-Interrupt-Controller");
 }
 
-extern int noirqdebug;
-
-static void handle_iic_irq(unsigned int irq, struct irq_desc *desc)
-{
-	raw_spin_lock(&desc->lock);
-
-	desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
-
-	/*
-	 * If we're currently running this IRQ, or its disabled,
-	 * we shouldn't process the IRQ. Mark it pending, handle
-	 * the necessary masking and go out
-	 */
-	if (unlikely((desc->status & (IRQ_INPROGRESS | IRQ_DISABLED)) ||
-		    !desc->action)) {
-		desc->status |= IRQ_PENDING;
-		goto out_eoi;
-	}
-
-	kstat_incr_irqs_this_cpu(irq, desc);
-
-	/* Mark the IRQ currently in progress.*/
-	desc->status |= IRQ_INPROGRESS;
-
-	do {
-		struct irqaction *action = desc->action;
-		irqreturn_t action_ret;
-
-		if (unlikely(!action))
-			goto out_eoi;
-
-		desc->status &= ~IRQ_PENDING;
-		raw_spin_unlock(&desc->lock);
-		action_ret = handle_IRQ_event(irq, action);
-		if (!noirqdebug)
-			note_interrupt(irq, desc, action_ret);
-		raw_spin_lock(&desc->lock);
-
-	} while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING);
-
-	desc->status &= ~IRQ_INPROGRESS;
-out_eoi:
-	desc->chip->eoi(irq);
-	raw_spin_unlock(&desc->lock);
-}
-
 static int iic_host_map(struct irq_host *h, unsigned int virq,
 			irq_hw_number_t hw)
 {
@@ -287,11 +241,13 @@ static int iic_host_map(struct irq_host 
 		set_irq_chip_and_handler(virq, &iic_chip, handle_percpu_irq);
 		break;
 	case IIC_IRQ_TYPE_IOEXC:
+		irq_set_status_flags(i, IRQ_EDGE_EOI);
 		set_irq_chip_and_handler(virq, &iic_ioexc_chip,
-					 handle_iic_irq);
+					 handle_edge_irq);
 		break;
 	default:
-		set_irq_chip_and_handler(virq, &iic_chip, handle_iic_irq);
+		irq_set_status_flags(i, IRQ_EDGE_EOI);
+		set_irq_chip_and_handler(virq, &iic_chip, handle_edge_irq);
 	}
 	return 0;
 }



^ permalink raw reply	[flat|nested] 17+ messages in thread

* [patch 6/8] arm: ns9xxx: Remove private irq flow handler
  2011-02-02 21:41 [patch 0/8] genirq: Further cleanups for .39 Thomas Gleixner
                   ` (4 preceding siblings ...)
  2011-02-02 21:41 ` [patch 5/8] powerpc: cell: Use handle_edge_irq Thomas Gleixner
@ 2011-02-02 21:41 ` Thomas Gleixner
  2011-02-03  7:56   ` Uwe Kleine-König
  2011-03-28 17:13   ` [tip:irq/urgent] arm: Ns9xxx: " tip-bot for Thomas Gleixner
  2011-02-02 21:41 ` [patch 7/8] m68knommu: 5772: Replace " Thomas Gleixner
  2011-02-02 21:41 ` [patch 8/8] genirq: Make handle_IRQ_event private to the core code Thomas Gleixner
  7 siblings, 2 replies; 17+ messages in thread
From: Thomas Gleixner @ 2011-02-02 21:41 UTC (permalink / raw)
  To: LKML; +Cc: Ingo Molnar, Peter Zijlstra, Uwe Kleine-Koenig, linux-arm-kernel

[-- Attachment #1: arm-ns9xxx-remove-private-irq-handler.patch --]
[-- Type: text/plain, Size: 4036 bytes --]

handle_prio_irq is almost identical with handle_fasteoi_irq. The
subtle differences are

1) The handler checks for IRQ_DISABLED after the device handler has
   been called. In case it's set it masks the interrupt.

2) When the handler sees IRQ_DISABLED on entry it masks the interupt
   in the same way as handle_fastoei_irq, but does not set the
   IRQ_PENDING flag.

3) Instead of gracefully handling a recursive interrupt it crashes the
   kernel.

#1 is just relevant when a device handler calls disable_irq_nosync()
   and it does not matter whether we mask the interrupt right away or
   not. We handle lazy masking for disable_irq anyway, so there is no
   real reason to have this extra mask in place.

#2 will prevent the resend of a pending interrupt, which can result in
   lost interrupts for edge type interrupts. For level type interrupts
   the resend is a noop in the generic code. According to the
   datasheet all interrupts are level type, so marking them as such
   will result in the exact same behaviour as the private
   handle_prio_irq implementation.

#3 is just stupid. Crashing the kernel instead of handling a problem
   gracefully is just wrong. With the current semantics- all handlers
   run with interrupts disabled - this is even more wrong.

Rename ack to eoi, remove the unused mask_ack, switch to
handle_fasteoi_irq and remove the private function.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
Cc: linux-arm-kernel@lists.infradead.org
---
 arch/arm/mach-ns9xxx/irq.c |   58 +++------------------------------------------
 1 file changed, 4 insertions(+), 54 deletions(-)

Index: linux-2.6-tip/arch/arm/mach-ns9xxx/irq.c
===================================================================
--- linux-2.6-tip.orig/arch/arm/mach-ns9xxx/irq.c
+++ linux-2.6-tip/arch/arm/mach-ns9xxx/irq.c
@@ -31,17 +31,11 @@ static void ns9xxx_mask_irq(struct irq_d
 	__raw_writel(ic, SYS_IC(prio / 4));
 }
 
-static void ns9xxx_ack_irq(struct irq_data *d)
+static void ns9xxx_eoi_irq(struct irq_data *d)
 {
 	__raw_writel(0, SYS_ISRADDR);
 }
 
-static void ns9xxx_maskack_irq(struct irq_data *d)
-{
-	ns9xxx_mask_irq(d);
-	ns9xxx_ack_irq(d);
-}
-
 static void ns9xxx_unmask_irq(struct irq_data *d)
 {
 	/* XXX: better use cpp symbols */
@@ -52,56 +46,11 @@ static void ns9xxx_unmask_irq(struct irq
 }
 
 static struct irq_chip ns9xxx_chip = {
-	.irq_ack	= ns9xxx_ack_irq,
+	.irq_eoi	= ns9xxx_eoi_irq,
 	.irq_mask	= ns9xxx_mask_irq,
-	.irq_mask_ack	= ns9xxx_maskack_irq,
 	.irq_unmask	= ns9xxx_unmask_irq,
 };
 
-#if 0
-#define handle_irq handle_level_irq
-#else
-static void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
-{
-	struct irqaction *action;
-	irqreturn_t action_ret;
-
-	raw_spin_lock(&desc->lock);
-
-	BUG_ON(desc->status & IRQ_INPROGRESS);
-
-	desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
-	kstat_incr_irqs_this_cpu(irq, desc);
-
-	action = desc->action;
-	if (unlikely(!action || (desc->status & IRQ_DISABLED)))
-		goto out_mask;
-
-	desc->status |= IRQ_INPROGRESS;
-	raw_spin_unlock(&desc->lock);
-
-	action_ret = handle_IRQ_event(irq, action);
-
-	/* XXX: There is no direct way to access noirqdebug, so check
-	 * unconditionally for spurious irqs...
-	 * Maybe this function should go to kernel/irq/chip.c? */
-	note_interrupt(irq, desc, action_ret);
-
-	raw_spin_lock(&desc->lock);
-	desc->status &= ~IRQ_INPROGRESS;
-
-	if (desc->status & IRQ_DISABLED)
-out_mask:
-		desc->irq_data.chip->irq_mask(&desc->irq_data);
-
-	/* ack unconditionally to unmask lower prio irqs */
-	desc->irq_data.chip->irq_ack(&desc->irq_data);
-
-	raw_spin_unlock(&desc->lock);
-}
-#define handle_irq handle_prio_irq
-#endif
-
 void __init ns9xxx_init_irq(void)
 {
 	int i;
@@ -119,7 +68,8 @@ void __init ns9xxx_init_irq(void)
 
 	for (i = 0; i <= 31; ++i) {
 		set_irq_chip(i, &ns9xxx_chip);
-		set_irq_handler(i, handle_irq);
+		set_irq_handler(i, handle_fasteoi_irq);
 		set_irq_flags(i, IRQF_VALID);
+		irq_set_status_flags(i, IRQ_LEVEL);
 	}
 }



^ permalink raw reply	[flat|nested] 17+ messages in thread

* [patch 7/8] m68knommu: 5772: Replace private irq flow handler
  2011-02-02 21:41 [patch 0/8] genirq: Further cleanups for .39 Thomas Gleixner
                   ` (5 preceding siblings ...)
  2011-02-02 21:41 ` [patch 6/8] arm: ns9xxx: Remove private irq flow handler Thomas Gleixner
@ 2011-02-02 21:41 ` Thomas Gleixner
  2011-02-02 22:27   ` Greg Ungerer
  2011-02-02 21:41 ` [patch 8/8] genirq: Make handle_IRQ_event private to the core code Thomas Gleixner
  7 siblings, 1 reply; 17+ messages in thread
From: Thomas Gleixner @ 2011-02-02 21:41 UTC (permalink / raw)
  To: LKML; +Cc: Ingo Molnar, Peter Zijlstra, Greg Ungerer

[-- Attachment #1: m68knommu-replace-private-handler.patch --]
[-- Type: text/plain, Size: 1000 bytes --]

That handler lacks the minimal checks for action being zero etc. Keep
the weird flow - ack before handling - intact and call into
handle_simple_irq which does the right thing.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Greg Ungerer <gerg@uclinux.org>
---
 arch/m68knommu/platform/5272/intc.c |    5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

Index: linux-2.6-tip/arch/m68knommu/platform/5272/intc.c
===================================================================
--- linux-2.6-tip.orig/arch/m68knommu/platform/5272/intc.c
+++ linux-2.6-tip/arch/m68knommu/platform/5272/intc.c
@@ -137,11 +137,8 @@ static int intc_irq_set_type(unsigned in
  */
 static void intc_external_irq(unsigned int irq, struct irq_desc *desc)
 {
-	kstat_incr_irqs_this_cpu(irq, desc);
-	desc->status |= IRQ_INPROGRESS;
 	desc->chip->ack(irq);
-	handle_IRQ_event(irq, desc->action);
-	desc->status &= ~IRQ_INPROGRESS;
+	handle_simple_irq(irq, desc);
 }
 
 static struct irq_chip intc_irq_chip = {



^ permalink raw reply	[flat|nested] 17+ messages in thread

* [patch 8/8] genirq: Make handle_IRQ_event private to the core code
  2011-02-02 21:41 [patch 0/8] genirq: Further cleanups for .39 Thomas Gleixner
                   ` (6 preceding siblings ...)
  2011-02-02 21:41 ` [patch 7/8] m68knommu: 5772: Replace " Thomas Gleixner
@ 2011-02-02 21:41 ` Thomas Gleixner
  7 siblings, 0 replies; 17+ messages in thread
From: Thomas Gleixner @ 2011-02-02 21:41 UTC (permalink / raw)
  To: LKML; +Cc: Ingo Molnar, Peter Zijlstra

[-- Attachment #1: genirq-make-handle_IRQ_event-private-to-genirq.patch --]
[-- Type: text/plain, Size: 5996 bytes --]

No more users outside of kernel/irq. We really want to have flow
handlers in the core code.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 Documentation/DocBook/genericirq.tmpl |   10 +++++-----
 include/linux/irq.h                   |    3 ---
 kernel/irq/chip.c                     |   10 +++++-----
 kernel/irq/handle.c                   |    4 ++--
 kernel/irq/internals.h                |    3 +++
 kernel/irq/spurious.c                 |    2 +-
 6 files changed, 16 insertions(+), 16 deletions(-)

Index: linux-2.6-tip/Documentation/DocBook/genericirq.tmpl
===================================================================
--- linux-2.6-tip.orig/Documentation/DocBook/genericirq.tmpl
+++ linux-2.6-tip/Documentation/DocBook/genericirq.tmpl
@@ -285,7 +285,7 @@ noop(struct irq_data *data))
 		The following control flow is implemented (simplified excerpt):
 		<programlisting>
 desc->chip->irq_mask();
-handle_IRQ_event(desc->action);
+handle_irq_event(desc->action);
 desc->chip->irq_unmask();
 		</programlisting>
 		</para>
@@ -300,7 +300,7 @@ desc->chip->irq_unmask();
 		<para>
 		The following control flow is implemented (simplified excerpt):
 		<programlisting>
-handle_IRQ_event(desc->action);
+handle_irq_event(desc->action);
 desc->chip->irq_eoi();
 		</programlisting>
 		</para>
@@ -325,7 +325,7 @@ do {
 	if (desc->status &amp; masked)
 		desc->chip->irq_unmask();
 	desc->status &amp;= ~pending;
-	handle_IRQ_event(desc->action);
+	handle_irq_event(desc->action);
 } while (status &amp; pending);
 desc->status &amp;= ~running;
 		</programlisting>
@@ -344,7 +344,7 @@ desc->status &amp;= ~running;
 		<para>
 		The following control flow is implemented (simplified excerpt):
 		<programlisting>
-handle_IRQ_event(desc->action);
+handle_irq_event(desc->action);
 		</programlisting>
 		</para>
    	    </sect3>
@@ -362,7 +362,7 @@ handle_IRQ_event(desc->action);
 		<para>
 		The following control flow is implemented (simplified excerpt):
 		<programlisting>
-handle_IRQ_event(desc->action);
+handle_irq_event(desc->action);
 if (desc->chip->irq_eoi)
         desc->chip->irq_eoi();
 		</programlisting>
Index: linux-2.6-tip/include/linux/irq.h
===================================================================
--- linux-2.6-tip.orig/include/linux/irq.h
+++ linux-2.6-tip/include/linux/irq.h
@@ -236,9 +236,6 @@ static inline void move_masked_irq(int i
 
 extern int no_irq_affinity;
 
-/* Handle irq action chains: */
-extern irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action);
-
 /*
  * Built-in IRQ handlers for various IRQ types,
  * callable via desc->handle_irq()
Index: linux-2.6-tip/kernel/irq/chip.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/chip.c
+++ linux-2.6-tip/kernel/irq/chip.c
@@ -492,7 +492,7 @@ handle_simple_irq(unsigned int irq, stru
 	desc->status |= IRQ_INPROGRESS;
 	raw_spin_unlock(&desc->lock);
 
-	action_ret = handle_IRQ_event(irq, action);
+	action_ret = handle_irq_event(irq, action);
 	if (!noirqdebug)
 		note_interrupt(irq, desc, action_ret);
 
@@ -537,7 +537,7 @@ handle_level_irq(unsigned int irq, struc
 	desc->status |= IRQ_INPROGRESS;
 	raw_spin_unlock(&desc->lock);
 
-	action_ret = handle_IRQ_event(irq, action);
+	action_ret = handle_irq_event(irq, action);
 	if (!noirqdebug)
 		note_interrupt(irq, desc, action_ret);
 
@@ -590,7 +590,7 @@ handle_fasteoi_irq(unsigned int irq, str
 	desc->status &= ~IRQ_PENDING;
 	raw_spin_unlock(&desc->lock);
 
-	action_ret = handle_IRQ_event(irq, action);
+	action_ret = handle_irq_event(irq, action);
 	if (!noirqdebug)
 		note_interrupt(irq, desc, action_ret);
 
@@ -669,7 +669,7 @@ handle_edge_irq(unsigned int irq, struct
 
 		desc->status &= ~IRQ_PENDING;
 		raw_spin_unlock(&desc->lock);
-		action_ret = handle_IRQ_event(irq, action);
+		action_ret = handle_irq_event(irq, action);
 		if (!noirqdebug)
 			note_interrupt(irq, desc, action_ret);
 		raw_spin_lock(&desc->lock);
@@ -700,7 +700,7 @@ handle_percpu_irq(unsigned int irq, stru
 	if (desc->irq_data.chip->irq_ack)
 		desc->irq_data.chip->irq_ack(&desc->irq_data);
 
-	action_ret = handle_IRQ_event(irq, desc->action);
+	action_ret = handle_irq_event(irq, desc->action);
 	if (!noirqdebug)
 		note_interrupt(irq, desc, action_ret);
 
Index: linux-2.6-tip/kernel/irq/handle.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/handle.c
+++ linux-2.6-tip/kernel/irq/handle.c
@@ -52,13 +52,13 @@ static void warn_no_thread(unsigned int 
 }
 
 /**
- * handle_IRQ_event - irq action chain handler
+ * handle_irq_event - irq action chain handler
  * @irq:	the interrupt number
  * @action:	the interrupt action chain for this irq
  *
  * Handles the action chain of an irq event
  */
-irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
+irqreturn_t handle_irq_event(unsigned int irq, struct irqaction *action)
 {
 	irqreturn_t ret, retval = IRQ_NONE;
 	unsigned int status = 0;
Index: linux-2.6-tip/kernel/irq/internals.h
===================================================================
--- linux-2.6-tip.orig/kernel/irq/internals.h
+++ linux-2.6-tip/kernel/irq/internals.h
@@ -40,6 +40,9 @@ static inline void unregister_handler_pr
 					   struct irqaction *action) { }
 #endif
 
+/* Handle irq action chains: */
+extern irqreturn_t handle_irq_event(unsigned int irq, struct irqaction *action);
+
 extern int irq_select_affinity_usr(unsigned int irq);
 
 extern void irq_set_thread_affinity(struct irq_desc *desc);
Index: linux-2.6-tip/kernel/irq/spurious.c
===================================================================
--- linux-2.6-tip.orig/kernel/irq/spurious.c
+++ linux-2.6-tip/kernel/irq/spurious.c
@@ -71,7 +71,7 @@ static int try_one_irq(int irq, struct i
 		 */
 		work = 1;
 		raw_spin_unlock(&desc->lock);
-		handle_IRQ_event(irq, action);
+		handle_irq_event(irq, action);
 		raw_spin_lock(&desc->lock);
 		desc->status &= ~IRQ_PENDING;
 	}



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [patch 7/8] m68knommu: 5772: Replace private irq flow handler
  2011-02-02 21:41 ` [patch 7/8] m68knommu: 5772: Replace " Thomas Gleixner
@ 2011-02-02 22:27   ` Greg Ungerer
  2011-02-02 22:37     ` Thomas Gleixner
  0 siblings, 1 reply; 17+ messages in thread
From: Greg Ungerer @ 2011-02-02 22:27 UTC (permalink / raw)
  To: Thomas Gleixner; +Cc: LKML, Ingo Molnar, Peter Zijlstra, Greg Ungerer


Hi Thomas,

On 03/02/11 07:41, Thomas Gleixner wrote:
> That handler lacks the minimal checks for action being zero etc. Keep
> the weird flow - ack before handling - intact and call into
> handle_simple_irq which does the right thing.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Cc: Greg Ungerer <gerg@uclinux.org>

Acked-by: Greg Ungerer <gerg@uclinux.org>

(I can't test this change for a week or two at least, I don't
have access to any 5272 based boards at the moment.)

Do you want me to push it through the m68knommu tree,
or are you going to do that yourself?

Regards
Greg


> ---
>  arch/m68knommu/platform/5272/intc.c |    5 +----
>  1 file changed, 1 insertion(+), 4 deletions(-)
>
> Index: linux-2.6-tip/arch/m68knommu/platform/5272/intc.c
> ===================================================================
> --- linux-2.6-tip.orig/arch/m68knommu/platform/5272/intc.c
> +++ linux-2.6-tip/arch/m68knommu/platform/5272/intc.c
> @@ -137,11 +137,8 @@ static int intc_irq_set_type(unsigned in
>   */
>  static void intc_external_irq(unsigned int irq, struct irq_desc *desc)
>  {
> -	kstat_incr_irqs_this_cpu(irq, desc);
> -	desc->status |= IRQ_INPROGRESS;
>  	desc->chip->ack(irq);
> -	handle_IRQ_event(irq, desc->action);
> -	desc->status &= ~IRQ_INPROGRESS;
> +	handle_simple_irq(irq, desc);
>  }
>
>  static struct irq_chip intc_irq_chip = {

-- 
------------------------------------------------------------------------
Greg Ungerer  --  Principal Engineer        EMAIL:     gerg@snapgear.com
SnapGear Group, McAfee                      PHONE:       +61 7 3435 2888
8 Gardner Close                             FAX:         +61 7 3217 5323
Milton, QLD, 4064, Australia                WEB: http://www.SnapGear.com

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [patch 7/8] m68knommu: 5772: Replace private irq flow handler
  2011-02-02 22:27   ` Greg Ungerer
@ 2011-02-02 22:37     ` Thomas Gleixner
  2011-02-02 22:41       ` Greg Ungerer
  0 siblings, 1 reply; 17+ messages in thread
From: Thomas Gleixner @ 2011-02-02 22:37 UTC (permalink / raw)
  To: Greg Ungerer; +Cc: LKML, Ingo Molnar, Peter Zijlstra, Greg Ungerer

On Thu, 3 Feb 2011, Greg Ungerer wrote:

> 
> Hi Thomas,
> 
> On 03/02/11 07:41, Thomas Gleixner wrote:
> > That handler lacks the minimal checks for action being zero etc. Keep
> > the weird flow - ack before handling - intact and call into
> > handle_simple_irq which does the right thing.
> > 
> > Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> > Cc: Greg Ungerer <gerg@uclinux.org>
> 
> Acked-by: Greg Ungerer <gerg@uclinux.org>
> 
> (I can't test this change for a week or two at least, I don't
> have access to any 5272 based boards at the moment.)
> 
> Do you want me to push it through the m68knommu tree,
> or are you going to do that yourself?

If it does not conflict with your stuff, I'd prefer to push it myself,
so I can apply the depending patches as well.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [patch 7/8] m68knommu: 5772: Replace private irq flow handler
  2011-02-02 22:37     ` Thomas Gleixner
@ 2011-02-02 22:41       ` Greg Ungerer
  0 siblings, 0 replies; 17+ messages in thread
From: Greg Ungerer @ 2011-02-02 22:41 UTC (permalink / raw)
  To: Thomas Gleixner; +Cc: LKML, Ingo Molnar, Peter Zijlstra, Greg Ungerer

On 03/02/11 08:37, Thomas Gleixner wrote:
> On Thu, 3 Feb 2011, Greg Ungerer wrote:
>
>>
>> Hi Thomas,
>>
>> On 03/02/11 07:41, Thomas Gleixner wrote:
>>> That handler lacks the minimal checks for action being zero etc. Keep
>>> the weird flow - ack before handling - intact and call into
>>> handle_simple_irq which does the right thing.
>>>
>>> Signed-off-by: Thomas Gleixner<tglx@linutronix.de>
>>> Cc: Greg Ungerer<gerg@uclinux.org>
>>
>> Acked-by: Greg Ungerer<gerg@uclinux.org>
>>
>> (I can't test this change for a week or two at least, I don't
>> have access to any 5272 based boards at the moment.)
>>
>> Do you want me to push it through the m68knommu tree,
>> or are you going to do that yourself?
>
> If it does not conflict with your stuff, I'd prefer to push it myself,
> so I can apply the depending patches as well.

No conflicts right now, and no planned changes in that area,
so feel free to push it yourself.

Regards
Greg


------------------------------------------------------------------------
Greg Ungerer  --  Principal Engineer        EMAIL:     gerg@snapgear.com
SnapGear Group, McAfee                      PHONE:       +61 7 3435 2888
8 Gardner Close                             FAX:         +61 7 3217 5323
Milton, QLD, 4064, Australia                WEB: http://www.SnapGear.com

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [patch 6/8] arm: ns9xxx: Remove private irq flow handler
  2011-02-02 21:41 ` [patch 6/8] arm: ns9xxx: Remove private irq flow handler Thomas Gleixner
@ 2011-02-03  7:56   ` Uwe Kleine-König
  2011-03-28 17:13   ` [tip:irq/urgent] arm: Ns9xxx: " tip-bot for Thomas Gleixner
  1 sibling, 0 replies; 17+ messages in thread
From: Uwe Kleine-König @ 2011-02-03  7:56 UTC (permalink / raw)
  To: Thomas Gleixner; +Cc: LKML, Peter Zijlstra, Ingo Molnar, linux-arm-kernel

Hi Thomas,

On Wed, Feb 02, 2011 at 09:41:27PM -0000, Thomas Gleixner wrote:
> handle_prio_irq is almost identical with handle_fasteoi_irq. The
> subtle differences are
> 
> 1) The handler checks for IRQ_DISABLED after the device handler has
>    been called. In case it's set it masks the interrupt.
> 
> 2) When the handler sees IRQ_DISABLED on entry it masks the interupt
>    in the same way as handle_fastoei_irq, but does not set the
>    IRQ_PENDING flag.
> 
> 3) Instead of gracefully handling a recursive interrupt it crashes the
>    kernel.
> 
> #1 is just relevant when a device handler calls disable_irq_nosync()
>    and it does not matter whether we mask the interrupt right away or
>    not. We handle lazy masking for disable_irq anyway, so there is no
>    real reason to have this extra mask in place.
> 
> #2 will prevent the resend of a pending interrupt, which can result in
>    lost interrupts for edge type interrupts. For level type interrupts
>    the resend is a noop in the generic code. According to the
>    datasheet all interrupts are level type, so marking them as such
>    will result in the exact same behaviour as the private
>    handle_prio_irq implementation.
> 
> #3 is just stupid. Crashing the kernel instead of handling a problem
>    gracefully is just wrong. With the current semantics- all handlers
>    run with interrupts disabled - this is even more wrong.
> 
> Rename ack to eoi, remove the unused mask_ack, switch to
> handle_fasteoi_irq and remove the private function.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Cc: Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
> Cc: linux-arm-kernel@lists.infradead.org
I have no access to a ns9xxx machine, but this looks sane.

Acked-by: Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>

Thanks
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [tip:irq/core] genirq: Remove bogus conditional
  2011-02-02 21:41 ` [patch 1/8] genirq: Remove bogus conditional Thomas Gleixner
@ 2011-02-19 12:22   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 17+ messages in thread
From: tip-bot for Thomas Gleixner @ 2011-02-19 12:22 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, peterz, tglx

Commit-ID:  3b56f0585fd4c02d047dc406668cb40159b2d340
Gitweb:     http://git.kernel.org/tip/3b56f0585fd4c02d047dc406668cb40159b2d340
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Wed, 2 Feb 2011 21:41:12 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sat, 19 Feb 2011 12:58:10 +0100

genirq: Remove bogus conditional

The if (chip->irq_shutdown) check will always evaluate to true, as we
fill in chip->irq_shutdown with default_shutdown in
irq_chip_set_defaults() if the chip does not provide its own function.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
LKML-Reference: <20110202212551.667607458@linutronix.de>
---
 kernel/irq/manage.c |    5 +----
 1 files changed, 1 insertions(+), 4 deletions(-)

diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 33a6ee0..30bc8de 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1057,10 +1057,7 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
 	/* If this was the last handler, shut down the IRQ line: */
 	if (!desc->action) {
 		desc->status |= IRQ_DISABLED;
-		if (desc->irq_data.chip->irq_shutdown)
-			desc->irq_data.chip->irq_shutdown(&desc->irq_data);
-		else
-			desc->irq_data.chip->irq_disable(&desc->irq_data);
+		desc->irq_data.chip->irq_shutdown(&desc->irq_data);
 	}
 
 #ifdef CONFIG_SMP

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [tip:irq/core] genirq: Consolidate startup/shutdown of interrupts
  2011-02-02 21:41 ` [patch 2/8] genirq: Consolidate startup/shutdown of interrupts Thomas Gleixner
@ 2011-02-19 12:22   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 17+ messages in thread
From: tip-bot for Thomas Gleixner @ 2011-02-19 12:22 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, peterz, tglx

Commit-ID:  4699923861513671d3f6ade8efb4e56a9a7ecadf
Gitweb:     http://git.kernel.org/tip/4699923861513671d3f6ade8efb4e56a9a7ecadf
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Wed, 2 Feb 2011 21:41:14 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sat, 19 Feb 2011 12:58:10 +0100

genirq: Consolidate startup/shutdown of interrupts

Aside of duplicated code some of the startup/shutdown sites do not
handle the MASKED/DISABLED flags and the depth field at all. Move that
to a helper function and take care of it there.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
LKML-Reference: <20110202212551.787481468@linutronix.de>
---
 kernel/irq/autoprobe.c |   10 +++++-----
 kernel/irq/chip.c      |   37 ++++++++++++++++++++-----------------
 kernel/irq/internals.h |    3 +++
 kernel/irq/manage.c    |   14 +++++---------
 4 files changed, 33 insertions(+), 31 deletions(-)

diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c
index 505798f..08947cb 100644
--- a/kernel/irq/autoprobe.c
+++ b/kernel/irq/autoprobe.c
@@ -60,7 +60,7 @@ unsigned long probe_irq_on(void)
 			if (desc->irq_data.chip->irq_set_type)
 				desc->irq_data.chip->irq_set_type(&desc->irq_data,
 							 IRQ_TYPE_PROBE);
-			desc->irq_data.chip->irq_startup(&desc->irq_data);
+			irq_startup(desc);
 		}
 		raw_spin_unlock_irq(&desc->lock);
 	}
@@ -77,7 +77,7 @@ unsigned long probe_irq_on(void)
 		raw_spin_lock_irq(&desc->lock);
 		if (!desc->action && !(desc->status & IRQ_NOPROBE)) {
 			desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
-			if (desc->irq_data.chip->irq_startup(&desc->irq_data))
+			if (irq_startup(desc))
 				desc->status |= IRQ_PENDING;
 		}
 		raw_spin_unlock_irq(&desc->lock);
@@ -99,7 +99,7 @@ unsigned long probe_irq_on(void)
 			/* It triggered already - consider it spurious. */
 			if (!(status & IRQ_WAITING)) {
 				desc->status = status & ~IRQ_AUTODETECT;
-				desc->irq_data.chip->irq_shutdown(&desc->irq_data);
+				irq_shutdown(desc);
 			} else
 				if (i < 32)
 					mask |= 1 << i;
@@ -138,7 +138,7 @@ unsigned int probe_irq_mask(unsigned long val)
 				mask |= 1 << i;
 
 			desc->status = status & ~IRQ_AUTODETECT;
-			desc->irq_data.chip->irq_shutdown(&desc->irq_data);
+			irq_shutdown(desc);
 		}
 		raw_spin_unlock_irq(&desc->lock);
 	}
@@ -182,7 +182,7 @@ int probe_irq_off(unsigned long val)
 				nr_of_irqs++;
 			}
 			desc->status = status & ~IRQ_AUTODETECT;
-			desc->irq_data.chip->irq_shutdown(&desc->irq_data);
+			irq_shutdown(desc);
 		}
 		raw_spin_unlock_irq(&desc->lock);
 	}
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 3125878..988fe7a 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -192,6 +192,25 @@ void set_irq_nested_thread(unsigned int irq, int nest)
 }
 EXPORT_SYMBOL_GPL(set_irq_nested_thread);
 
+int irq_startup(struct irq_desc *desc)
+{
+	desc->status &= ~(IRQ_MASKED | IRQ_DISABLED);
+	desc->depth = 0;
+
+	if (desc->irq_data.chip->irq_startup)
+		return desc->irq_data.chip->irq_startup(&desc->irq_data);
+
+	desc->irq_data.chip->irq_enable(&desc->irq_data);
+	return 0;
+}
+
+void irq_shutdown(struct irq_desc *desc)
+{
+	desc->status |= IRQ_MASKED | IRQ_DISABLED;
+	desc->depth = 1;
+	desc->irq_data.chip->irq_shutdown(&desc->irq_data);
+}
+
 /*
  * default enable function
  */
@@ -211,17 +230,6 @@ static void default_disable(struct irq_data *data)
 }
 
 /*
- * default startup function
- */
-static unsigned int default_startup(struct irq_data *data)
-{
-	struct irq_desc *desc = irq_data_to_desc(data);
-
-	desc->irq_data.chip->irq_enable(data);
-	return 0;
-}
-
-/*
  * default shutdown function
  */
 static void default_shutdown(struct irq_data *data)
@@ -229,7 +237,6 @@ static void default_shutdown(struct irq_data *data)
 	struct irq_desc *desc = irq_data_to_desc(data);
 
 	desc->irq_data.chip->irq_mask(&desc->irq_data);
-	desc->status |= IRQ_MASKED;
 }
 
 #ifndef CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED
@@ -337,8 +344,6 @@ void irq_chip_set_defaults(struct irq_chip *chip)
 		chip->irq_enable = default_enable;
 	if (!chip->irq_disable)
 		chip->irq_disable = default_disable;
-	if (!chip->irq_startup)
-		chip->irq_startup = default_startup;
 	/*
 	 * We use chip->irq_disable, when the user provided its own. When
 	 * we have default_disable set for chip->irq_disable, then we need
@@ -747,10 +752,8 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
 	desc->name = name;
 
 	if (handle != handle_bad_irq && is_chained) {
-		desc->status &= ~IRQ_DISABLED;
 		desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE;
-		desc->depth = 0;
-		desc->irq_data.chip->irq_startup(&desc->irq_data);
+		irq_startup(desc);
 	}
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
 	chip_bus_sync_unlock(desc);
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index b17c984..5cbfc93 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -38,6 +38,9 @@ extern int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
 extern void __disable_irq(struct irq_desc *desc, unsigned int irq, bool susp);
 extern void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume);
 
+extern int irq_startup(struct irq_desc *desc);
+extern void irq_shutdown(struct irq_desc *desc);
+
 extern void init_kstat_irqs(struct irq_desc *desc, int node, int nr);
 
 /* Resending of interrupts :*/
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 30bc8de..9c56247 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -906,11 +906,9 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
 		if (new->flags & IRQF_ONESHOT)
 			desc->status |= IRQ_ONESHOT;
 
-		if (!(desc->status & IRQ_NOAUTOEN)) {
-			desc->depth = 0;
-			desc->status &= ~IRQ_DISABLED;
-			desc->irq_data.chip->irq_startup(&desc->irq_data);
-		} else
+		if (!(desc->status & IRQ_NOAUTOEN))
+			irq_startup(desc);
+		else
 			/* Undo nested disables: */
 			desc->depth = 1;
 
@@ -1055,10 +1053,8 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
 #endif
 
 	/* If this was the last handler, shut down the IRQ line: */
-	if (!desc->action) {
-		desc->status |= IRQ_DISABLED;
-		desc->irq_data.chip->irq_shutdown(&desc->irq_data);
-	}
+	if (!desc->action)
+		irq_shutdown(desc);
 
 #ifdef CONFIG_SMP
 	/* make sure affinity_hint is cleaned up */

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [tip:irq/core] genirq: Do not fiddle with IRQ_MASKED in handle_edge_irq()
  2011-02-02 21:41 ` [patch 3/8] genirq: Do not fiddle with IRQ_MASKED in handle_edge_irq() Thomas Gleixner
@ 2011-02-19 12:24   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 17+ messages in thread
From: tip-bot for Thomas Gleixner @ 2011-02-19 12:24 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, peterz, tglx

Commit-ID:  d78f8dd36b90626106ce19cb2e6828b0dc39447e
Gitweb:     http://git.kernel.org/tip/d78f8dd36b90626106ce19cb2e6828b0dc39447e
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Wed, 2 Feb 2011 21:41:17 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sat, 19 Feb 2011 12:58:11 +0100

genirq: Do not fiddle with IRQ_MASKED in handle_edge_irq()

IRQ_MASKED is set in mask_ack_irq() anyway. Remove it from
handle_edge_irq() to allow simpler ab^HHreuse of that function.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
LKML-Reference: <20110202212551.918484270@linutronix.de>
---
 kernel/irq/chip.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 43c62ca..2c30b78 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -611,7 +611,7 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
 	if (unlikely((desc->status & (IRQ_INPROGRESS | IRQ_DISABLED)) ||
 		    !desc->action)) {
 		if (!irq_check_poll(desc)) {
-			desc->status |= (IRQ_PENDING | IRQ_MASKED);
+			desc->status |= IRQ_PENDING;
 			mask_ack_irq(desc);
 			goto out_unlock;
 		}

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [tip:irq/urgent] arm: Ns9xxx: Remove private irq flow handler
  2011-02-02 21:41 ` [patch 6/8] arm: ns9xxx: Remove private irq flow handler Thomas Gleixner
  2011-02-03  7:56   ` Uwe Kleine-König
@ 2011-03-28 17:13   ` tip-bot for Thomas Gleixner
  1 sibling, 0 replies; 17+ messages in thread
From: tip-bot for Thomas Gleixner @ 2011-03-28 17:13 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, peterz, u.kleine-koenig, tglx

Commit-ID:  6829310548a76d343205029bb41c14e75bf6a7fb
Gitweb:     http://git.kernel.org/tip/6829310548a76d343205029bb41c14e75bf6a7fb
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Wed, 2 Feb 2011 21:41:27 +0000
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Mon, 28 Mar 2011 16:55:11 +0200

arm: Ns9xxx: Remove private irq flow handler

handle_prio_irq is almost identical with handle_fasteoi_irq. The
subtle differences are

1) The handler checks for IRQ_DISABLED after the device handler has
   been called. In case it's set it masks the interrupt.

2) When the handler sees IRQ_DISABLED on entry it masks the interupt
   in the same way as handle_fastoei_irq, but does not set the
   IRQ_PENDING flag.

3) Instead of gracefully handling a recursive interrupt it crashes the
   kernel.

#1 is just relevant when a device handler calls disable_irq_nosync()
   and it does not matter whether we mask the interrupt right away or
   not. We handle lazy masking for disable_irq anyway, so there is no
   real reason to have this extra mask in place.

#2 will prevent the resend of a pending interrupt, which can result in
   lost interrupts for edge type interrupts. For level type interrupts
   the resend is a noop in the generic code. According to the
   datasheet all interrupts are level type, so marking them as such
   will result in the exact same behaviour as the private
   handle_prio_irq implementation.

#3 is just stupid. Crashing the kernel instead of handling a problem
   gracefully is just wrong. With the current semantics- all handlers
   run with interrupts disabled - this is even more wrong.

Rename ack to eoi, remove the unused mask_ack, switch to
handle_fasteoi_irq and remove the private function.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Acked-by: Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
Cc: linux-arm-kernel@lists.infradead.org
LKML-Reference: <20110202212552.299898447@linutronix.de>
---
 arch/arm/mach-ns9xxx/irq.c |   58 +++----------------------------------------
 1 files changed, 4 insertions(+), 54 deletions(-)

diff --git a/arch/arm/mach-ns9xxx/irq.c b/arch/arm/mach-ns9xxx/irq.c
index 389fa5c..bf0fd48 100644
--- a/arch/arm/mach-ns9xxx/irq.c
+++ b/arch/arm/mach-ns9xxx/irq.c
@@ -31,17 +31,11 @@ static void ns9xxx_mask_irq(struct irq_data *d)
 	__raw_writel(ic, SYS_IC(prio / 4));
 }
 
-static void ns9xxx_ack_irq(struct irq_data *d)
+static void ns9xxx_eoi_irq(struct irq_data *d)
 {
 	__raw_writel(0, SYS_ISRADDR);
 }
 
-static void ns9xxx_maskack_irq(struct irq_data *d)
-{
-	ns9xxx_mask_irq(d);
-	ns9xxx_ack_irq(d);
-}
-
 static void ns9xxx_unmask_irq(struct irq_data *d)
 {
 	/* XXX: better use cpp symbols */
@@ -52,56 +46,11 @@ static void ns9xxx_unmask_irq(struct irq_data *d)
 }
 
 static struct irq_chip ns9xxx_chip = {
-	.irq_ack	= ns9xxx_ack_irq,
+	.irq_eoi	= ns9xxx_eoi_irq,
 	.irq_mask	= ns9xxx_mask_irq,
-	.irq_mask_ack	= ns9xxx_maskack_irq,
 	.irq_unmask	= ns9xxx_unmask_irq,
 };
 
-#if 0
-#define handle_irq handle_level_irq
-#else
-static void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
-{
-	struct irqaction *action;
-	irqreturn_t action_ret;
-
-	raw_spin_lock(&desc->lock);
-
-	BUG_ON(desc->status & IRQ_INPROGRESS);
-
-	desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
-	kstat_incr_irqs_this_cpu(irq, desc);
-
-	action = desc->action;
-	if (unlikely(!action || (desc->status & IRQ_DISABLED)))
-		goto out_mask;
-
-	desc->status |= IRQ_INPROGRESS;
-	raw_spin_unlock(&desc->lock);
-
-	action_ret = handle_IRQ_event(irq, action);
-
-	/* XXX: There is no direct way to access noirqdebug, so check
-	 * unconditionally for spurious irqs...
-	 * Maybe this function should go to kernel/irq/chip.c? */
-	note_interrupt(irq, desc, action_ret);
-
-	raw_spin_lock(&desc->lock);
-	desc->status &= ~IRQ_INPROGRESS;
-
-	if (desc->status & IRQ_DISABLED)
-out_mask:
-		desc->irq_data.chip->irq_mask(&desc->irq_data);
-
-	/* ack unconditionally to unmask lower prio irqs */
-	desc->irq_data.chip->irq_ack(&desc->irq_data);
-
-	raw_spin_unlock(&desc->lock);
-}
-#define handle_irq handle_prio_irq
-#endif
-
 void __init ns9xxx_init_irq(void)
 {
 	int i;
@@ -119,7 +68,8 @@ void __init ns9xxx_init_irq(void)
 
 	for (i = 0; i <= 31; ++i) {
 		set_irq_chip(i, &ns9xxx_chip);
-		set_irq_handler(i, handle_irq);
+		set_irq_handler(i, handle_fasteoi_irq);
 		set_irq_flags(i, IRQF_VALID);
+		irq_set_status_flags(i, IRQ_LEVEL);
 	}
 }

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2011-03-28 17:14 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-02-02 21:41 [patch 0/8] genirq: Further cleanups for .39 Thomas Gleixner
2011-02-02 21:41 ` [patch 1/8] genirq: Remove bogus conditional Thomas Gleixner
2011-02-19 12:22   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2011-02-02 21:41 ` [patch 2/8] genirq: Consolidate startup/shutdown of interrupts Thomas Gleixner
2011-02-19 12:22   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2011-02-02 21:41 ` [patch 3/8] genirq: Do not fiddle with IRQ_MASKED in handle_edge_irq() Thomas Gleixner
2011-02-19 12:24   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2011-02-02 21:41 ` [patch 4/8] genirq: Introduce IRQ_EDGE_EOI flag Thomas Gleixner
2011-02-02 21:41 ` [patch 5/8] powerpc: cell: Use handle_edge_irq Thomas Gleixner
2011-02-02 21:41 ` [patch 6/8] arm: ns9xxx: Remove private irq flow handler Thomas Gleixner
2011-02-03  7:56   ` Uwe Kleine-König
2011-03-28 17:13   ` [tip:irq/urgent] arm: Ns9xxx: " tip-bot for Thomas Gleixner
2011-02-02 21:41 ` [patch 7/8] m68knommu: 5772: Replace " Thomas Gleixner
2011-02-02 22:27   ` Greg Ungerer
2011-02-02 22:37     ` Thomas Gleixner
2011-02-02 22:41       ` Greg Ungerer
2011-02-02 21:41 ` [patch 8/8] genirq: Make handle_IRQ_event private to the core code Thomas Gleixner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).