On Tue, 2006-06-20 at 16:28 -0600, Eric W. Biederman wrote: > With the msi support comes a new concept in irq handling, > irqs that are created dynamically at run time. > > Currently the msi code allocates irqs backwards. First it > allocates a platform dependent routing value for an > interrupt the ``vector'' and then it figures out from the > vector which irq you are on. You may want to look at the work I'm currently doing for powerpc where we need a fully dynamic linux irq number allocation, completely separate spaces for hw numbers (vectors) and linux irq numbers for arbitrary PICs (and more than one in a given system) etc... I'll post a patch that shows the stuff I'm adding later today so you can have a look. There is some overlap with your dynamic irq stuff. I haven't completely ported all of powerpc to my new core yet which is why I haven't posted patches yet, but I'll have something out today. Ben. > This msi backwards allocator suffers from two basic > problems. The allocator suffers because it is trying > to do something that is architecture specific in a generic > way making it brittle, inflexible, and tied to tightly > to the architecture implementation. The alloctor also > suffers from it's very backwards nature as it has tied > things together that should have no dependencies. > > To solve the basic dynamic irq allocation problem two > new architecture specific functions are added: > create_irq and destroy_irq. > > create_irq takes no input and returns an unused irq number, > that won't be reused until it is returned to the free > poll with destroy_irq. The irq then can be used for > any purpose although the only initial consumer is > the msi code. > > destroy_irq takes an irq number allocated with create_irq > and returns it to the free pool. > > Making this functionality per architecture increases > the simplicity of the irq allocation code and increases > it's flexibility. > > dynamic_irq_init() and dynamic_irq_cleanup() are added > to automate the irq_desc initializtion that should happen > for dynamic irqs. > > Signed-off-by: Eric W. Biederman <ebiederm@xxxxxxxxxxxx> > --- > include/linux/irq.h | 9 +++++++- > kernel/irq/chip.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 64 insertions(+), 1 deletions(-) > > diff --git a/include/linux/irq.h b/include/linux/irq.h > index b79d178..6d1ad88 100644 > --- a/include/linux/irq.h > +++ b/include/linux/irq.h > @@ -392,8 +392,15 @@ set_irq_chained_handler(unsigned int irq > __set_irq_handler(irq, handle, 1); > } > > -/* Set/get chip/data for an IRQ: */ > +/* Handle dynamic irq creation and destruction */ > +extern int create_irq(void); > +extern void destroy_irq(unsigned int irq); > + > +/* Dynamic irq helper functions */ > +extern void dynamic_irq_init(unsigned int irq); > +extern void dynamic_irq_cleanup(unsigned int irq); > > +/* Set/get chip/data for an IRQ: */ > extern int set_irq_chip(unsigned int irq, struct irq_chip *chip); > extern int set_irq_data(unsigned int irq, void *data); > extern int set_irq_chip_data(unsigned int irq, void *data); > diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c > index 431e9d5..9c01e48 100644 > --- a/kernel/irq/chip.c > +++ b/kernel/irq/chip.c > @@ -18,6 +18,62 @@ #include <linux/kernel_stat.h> > #include "internals.h" > > /** > + * dynamic_irq_init - initialize a dynamically allocated irq > + * @irq: irq number to initialize > + */ > +void dynamic_irq_init(unsigned int irq) > +{ > + struct irq_desc *desc; > + unsigned long flags; > + > + if (irq >= NR_IRQS) { > + printk(KERN_ERR "Trying to initialize invalid IRQ%d\n", irq); > + WARN_ON(1); > + return; > + } > + > + /* Ensure we don't have left over values from a previous use of this irq */ > + desc = irq_desc + irq; > + spin_lock_irqsave(&desc->lock, flags); > + desc->status = IRQ_DISABLED; > + desc->chip = &no_irq_chip; > + desc->handle_irq = handle_bad_irq; > + desc->depth = 1; > + desc->handler_data = NULL; > + desc->chip_data = NULL; > + desc->action = NULL; > + desc->irq_count = 0; > + desc->irqs_unhandled = 0; > +#ifdef CONFIG_SMP > + desc->affinity = CPU_MASK_ALL; > +#endif > + spin_unlock_irqrestore(&desc->lock, flags); > +} > + > +/** > + * dynamic_irq_cleanup - cleanup a dynamically allocated irq > + * @irq: irq number to initialize > + */ > +void dynamic_irq_cleanup(unsigned int irq) > +{ > + struct irq_desc *desc; > + unsigned long flags; > + > + if (irq >= NR_IRQS) { > + printk(KERN_ERR "Trying to cleanup invalid IRQ%d\n", irq); > + WARN_ON(1); > + return; > + } > + > + desc = irq_desc + irq; > + spin_lock_irqsave(&desc->lock, flags); > + desc->handle_irq = handle_bad_irq; > + desc->chip = &no_irq_chip; > + spin_unlock_irqrestore(&desc->lock, flags); > +} > + > + > +/** > * set_irq_chip - set the irq chip for an irq > * @irq: irq number > * @chip: pointer to irq chip description structure > -- > 1.4.0.gc07e > > - > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ - To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html