Re: [PATCH 9/25] irq: Add a dynamic irq creation API

From: Benjamin Herrenschmidt
Date: Tue Jun 20 2006 - 19:56:45 EST


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-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/