[PATCH RFC 1/2] IRQ: Modularize the setup_irq code (1)

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

 



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 <[email protected]>
---

 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
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux