IRQ: Modularize the setup_irq code (1)
RFC PATCH 1/2 IRQ: Modularize the setup_irq code (1)
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(-)
kernel/irq/manage.c +55 -37
@@ -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 ; }/**
Signature · 3 lines
Ahmed S. Darwish HomePage: http://darwish.07.googlepages.com Blog: http://darwish-07.blogspot.com
RFC PATCH 2/2 IRQ: Modularize the setup_irq code (2)
Introduce irq_desc_match_fist_irqaction() to support setup_irq() code modularity.
Signed-off-by Ahmed S. Darwish <[email protected]>
---
Any ideas for a better method name ?
manage.c | 89 ++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 51 insertions(+), 38 deletions(-)
kernel/irq/manage.c +51 -38
@@ -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 ;
Signature · 3 lines
Ahmed S. Darwish HomePage: http://darwish.07.googlepages.com Blog: http://darwish-07.blogspot.com