* [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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.