public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC 1/2] IRQ: Modularize the setup_irq code (1)
@ 2007-10-05  5:30 Ahmed S. Darwish
  2007-10-05  5:36 ` [PATCH RFC 2/2] IRQ: Modularize the setup_irq code (2) Ahmed S. Darwish
  0 siblings, 1 reply; 2+ messages in thread
From: Ahmed S. Darwish @ 2007-10-05  5:30 UTC (permalink / raw)
  To: tglx; +Cc: linux-kernel, akpm

Hi Thomas/lkml,

setup_irq() code contains a big chunk of 130 code lines that 
can be divided to several smaller methods. These 2 patches introduce 
those small functions to aid toward setup_irq() code modularity. 
No major code logic changes exist.

Patches can be applied cleanly over v2.6.23-rc9.

Thanks,

==> (Description for Logs)

Introduce can_add_irqaction_on_allocated_irq and warn_about_irqaction_mismatch
methods to support setup_irq() code modularity.

Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
---

 manage.c |   92 +++++++++++++++++++++++++++++++++++++--------------------------
 1 file changed, 55 insertions(+), 37 deletions(-)

diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 7230d91..6a0d778 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -248,6 +248,50 @@ void compat_irq_chip_set_default_handler(struct irq_desc *desc)
 		desc->handle_irq = NULL;
 }
 
+static inline void warn_about_irqaction_mismatch(unsigned int irq,
+						 struct irqaction *new)
+{
+#ifdef CONFIG_DEBUG_SHIRQ
+	const char *name = irq_desc[irq].action->name;
+	/* If device doesn't expect the mismatch */
+	if (!(new->flags & IRQF_PROBE_SHARED)) {
+		printk(KERN_ERR "IRQ handler type mismatch for IRQ %d\n", irq);
+		if (name)
+			printk(KERN_ERR "current handler: %s\n", name);
+		dump_stack();
+	}
+#endif
+}
+
+/*
+ * Test if an irqaction can be added to the passed allocated IRQ line
+ * Must be called with the irq_desc[irq]->lock held.
+ */
+int can_add_irqaction_on_allocated_irq(unsigned int irq, struct irqaction *new)
+{
+	struct irqaction *old = irq_desc[irq].action;
+
+	BUG_ON(!old);
+	/*
+	 * Can't share interrupts unless both agree to and are
+	 * the same type (level, edge, polarity). So both flag
+	 * fields must have IRQF_SHARED set and the bits which
+	 * set the trigger type must match.
+	 */
+	if (!((old->flags & new->flags) & IRQF_SHARED) ||
+	    ((old->flags ^ new->flags) & IRQF_TRIGGER_MASK))
+		return 0;
+
+#if defined(CONFIG_IRQ_PER_CPU)
+	/* All handlers must agree on per-cpuness */
+	if ((old->flags & IRQF_PERCPU) !=
+	    (new->flags & IRQF_PERCPU))
+		return 0;
+#endif
+
+	return 1;
+}
+
 /*
  * Internal function to register an irqaction - typically used to
  * allocate special interrupts that are part of the architecture.
@@ -256,7 +300,6 @@ int setup_irq(unsigned int irq, struct irqaction *new)
 {
 	struct irq_desc *desc = irq_desc + irq;
 	struct irqaction *old, **p;
-	const char *old_name = NULL;
 	unsigned long flags;
 	int shared = 0;
 
@@ -289,31 +332,18 @@ int setup_irq(unsigned int irq, struct irqaction *new)
 	p = &desc->action;
 	old = *p;
 	if (old) {
-		/*
-		 * Can't share interrupts unless both agree to and are
-		 * the same type (level, edge, polarity). So both flag
-		 * fields must have IRQF_SHARED set and the bits which
-		 * set the trigger type must match.
-		 */
-		if (!((old->flags & new->flags) & IRQF_SHARED) ||
-		    ((old->flags ^ new->flags) & IRQF_TRIGGER_MASK)) {
-			old_name = old->name;
-			goto mismatch;
-		}
-
-#if defined(CONFIG_IRQ_PER_CPU)
-		/* All handlers must agree on per-cpuness */
-		if ((old->flags & IRQF_PERCPU) !=
-		    (new->flags & IRQF_PERCPU))
-			goto mismatch;
-#endif
-
-		/* add new interrupt at end of irq queue */
-		do {
-			p = &old->next;
-			old = *p;
-		} while (old);
 		shared = 1;
+		if (can_add_irqaction_on_allocated_irq(irq, new)) {
+			/* add new interrupt at end of irq queue */
+			do {
+				p = &old->next;
+				old = *p;
+			} while (old);
+		} else {
+			warn_about_irqaction_mismatch(irq, new);
+			spin_unlock_irqrestore(&desc->lock, flags);
+			return -EBUSY;
+		}
 	}
 
 	*p = new;
@@ -372,18 +402,6 @@ int setup_irq(unsigned int irq, struct irqaction *new)
 	register_handler_proc(irq, new);
 
 	return 0;
-
-mismatch:
-#ifdef CONFIG_DEBUG_SHIRQ
-	if (!(new->flags & IRQF_PROBE_SHARED)) {
-		printk(KERN_ERR "IRQ handler type mismatch for IRQ %d\n", irq);
-		if (old_name)
-			printk(KERN_ERR "current handler: %s\n", old_name);
-		dump_stack();
-	}
-#endif
-	spin_unlock_irqrestore(&desc->lock, flags);
-	return -EBUSY;
 }
 
 /**


-- 
Ahmed S. Darwish
HomePage: http://darwish.07.googlepages.com
Blog: http://darwish-07.blogspot.com

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

* [PATCH RFC 2/2] IRQ: Modularize the setup_irq code (2)
  2007-10-05  5:30 [PATCH RFC 1/2] IRQ: Modularize the setup_irq code (1) Ahmed S. Darwish
@ 2007-10-05  5:36 ` Ahmed S. Darwish
  0 siblings, 0 replies; 2+ messages in thread
From: Ahmed S. Darwish @ 2007-10-05  5:36 UTC (permalink / raw)
  To: tglx; +Cc: linux-kernel, akpm

Introduce irq_desc_match_fist_irqaction() to support setup_irq() 
code modularity.

Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
---

Any ideas for a better method name ?

 manage.c |   89 ++++++++++++++++++++++++++++++++++++---------------------------
 1 file changed, 51 insertions(+), 38 deletions(-)

diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 6a0d778..4e96d56 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -293,6 +293,55 @@ int can_add_irqaction_on_allocated_irq(unsigned int irq, struct irqaction *new)
 }
 
 /*
+ * Configure the passed irq descriptor to satisfy our first newly
+ * added irqaction needs
+ * must be called with the irq_desc[irq]->lock held
+ */
+void irq_desc_match_fist_irqaction(unsigned int irq, struct irqaction *new)
+{
+	struct irq_desc *desc = irq_desc + irq;
+
+	/* We must be the first and the only irqaction */
+	BUG_ON(desc->action != new || new->next);
+
+	irq_chip_set_defaults(desc->chip);
+
+#if defined(CONFIG_IRQ_PER_CPU)
+	if (new->flags & IRQF_PERCPU)
+		desc->status |= IRQ_PER_CPU;
+#endif
+
+	/* Setup the type (level, edge polarity) if configured: */
+	if (new->flags & IRQF_TRIGGER_MASK) {
+		if (desc->chip && desc->chip->set_type)
+			desc->chip->set_type(irq,
+					     new->flags & IRQF_TRIGGER_MASK);
+		else
+			/*
+			 * IRQF_TRIGGER_* but the PIC does not support
+			 * multiple flow-types?
+			 */
+			printk(KERN_WARNING "No IRQF_TRIGGER set_type "
+			       "function for IRQ %d (%s)\n", irq,
+			       desc->chip ? desc->chip->name : "unknown");
+	} else
+		compat_irq_chip_set_default_handler(desc);
+
+	desc->status &= ~(IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS);
+
+	if (!(desc->status & IRQ_NOAUTOEN)) {
+		desc->depth = 0;
+		desc->status &= ~IRQ_DISABLED;
+		if (desc->chip->startup)
+			desc->chip->startup(irq);
+		else
+			desc->chip->enable(irq);
+	} else
+		/* Undo nested disables: */
+		desc->depth = 1;
+}
+
+/*
  * Internal function to register an irqaction - typically used to
  * allocate special interrupts that are part of the architecture.
  */
@@ -352,45 +401,9 @@ int setup_irq(unsigned int irq, struct irqaction *new)
 	if (new->flags & IRQF_NOBALANCING)
 		desc->status |= IRQ_NO_BALANCING;
 
-	if (!shared) {
-		irq_chip_set_defaults(desc->chip);
+	if (!shared)
+		irq_desc_match_fist_irqaction(irq, new);
 
-#if defined(CONFIG_IRQ_PER_CPU)
-		if (new->flags & IRQF_PERCPU)
-			desc->status |= IRQ_PER_CPU;
-#endif
-
-		/* Setup the type (level, edge polarity) if configured: */
-		if (new->flags & IRQF_TRIGGER_MASK) {
-			if (desc->chip && desc->chip->set_type)
-				desc->chip->set_type(irq,
-						new->flags & IRQF_TRIGGER_MASK);
-			else
-				/*
-				 * IRQF_TRIGGER_* but the PIC does not support
-				 * multiple flow-types?
-				 */
-				printk(KERN_WARNING "No IRQF_TRIGGER set_type "
-				       "function for IRQ %d (%s)\n", irq,
-				       desc->chip ? desc->chip->name :
-				       "unknown");
-		} else
-			compat_irq_chip_set_default_handler(desc);
-
-		desc->status &= ~(IRQ_AUTODETECT | IRQ_WAITING |
-				  IRQ_INPROGRESS);
-
-		if (!(desc->status & IRQ_NOAUTOEN)) {
-			desc->depth = 0;
-			desc->status &= ~IRQ_DISABLED;
-			if (desc->chip->startup)
-				desc->chip->startup(irq);
-			else
-				desc->chip->enable(irq);
-		} else
-			/* Undo nested disables: */
-			desc->depth = 1;
-	}
 	/* Reset broken irq detection when installing new handler */
 	desc->irq_count = 0;
 	desc->irqs_unhandled = 0;

-- 
Ahmed S. Darwish
HomePage: http://darwish.07.googlepages.com
Blog: http://darwish-07.blogspot.com

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

end of thread, other threads:[~2007-10-05  5:37 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-10-05  5:30 [PATCH RFC 1/2] IRQ: Modularize the setup_irq code (1) Ahmed S. Darwish
2007-10-05  5:36 ` [PATCH RFC 2/2] IRQ: Modularize the setup_irq code (2) Ahmed S. Darwish

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox