diff options
author | Sebastian Andrzej Siewior <sebastian@breakpoint.cc> | 2011-07-11 12:17:31 +0200 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2011-07-28 11:23:21 +0200 |
commit | b6873807a7143b7d6d8b06809295e559d07d7deb (patch) | |
tree | 1187413ab85f1a7b7d5da91bf61ae21601da3855 /include | |
parent | irq: Always set IRQF_ONESHOT if no primary handler is specified (diff) | |
download | linux-b6873807a7143b7d6d8b06809295e559d07d7deb.tar.xz linux-b6873807a7143b7d6d8b06809295e559d07d7deb.zip |
irq: Track the owner of irq descriptor
Interrupt descriptors can be allocated from modules. The interrupts
are used by other modules, but we have no refcount on the module which
provides the interrupts and there is no way to establish one on the
device level as the interrupt using module is agnostic to the fact
that the interrupt is provided by a module rather than by some builtin
interrupt controller.
To prevent removal of the interrupt providing module, we can track the
owner of the interrupt descriptor, which also provides the relevant
irq chip functions in the irq descriptor.
request/setup_irq() can now acquire a refcount on the owner module to
prevent unloading. free_irq() drops the refcount.
Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
Link: http://lkml.kernel.org/r/20110711101731.GA13804@Chamillionaire.breakpoint.cc
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/irq.h | 11 | ||||
-rw-r--r-- | include/linux/irqdesc.h | 1 |
2 files changed, 11 insertions, 1 deletions
diff --git a/include/linux/irq.h b/include/linux/irq.h index baa397eb9c33..16d6f54ef1dd 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -23,6 +23,7 @@ #include <linux/errno.h> #include <linux/topology.h> #include <linux/wait.h> +#include <linux/module.h> #include <asm/irq.h> #include <asm/ptrace.h> @@ -546,7 +547,15 @@ static inline struct msi_desc *irq_data_get_msi(struct irq_data *d) return d->msi_desc; } -int irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node); +int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node, + struct module *owner); + +static inline int irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, + int node) +{ + return __irq_alloc_descs(irq, from, cnt, node, THIS_MODULE); +} + void irq_free_descs(unsigned int irq, unsigned int cnt); int irq_reserve_irqs(unsigned int from, unsigned int cnt); diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h index 2d921b35212c..150134ac709a 100644 --- a/include/linux/irqdesc.h +++ b/include/linux/irqdesc.h @@ -66,6 +66,7 @@ struct irq_desc { #ifdef CONFIG_PROC_FS struct proc_dir_entry *dir; #endif + struct module *owner; const char *name; } ____cacheline_internodealigned_in_smp; |