aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <sebastian@breakpoint.cc>2011-07-11 06:17:31 -0400
committerThomas Gleixner <tglx@linutronix.de>2011-07-28 05:23:21 -0400
commitb6873807a7143b7d6d8b06809295e559d07d7deb (patch)
tree1187413ab85f1a7b7d5da91bf61ae21601da3855 /include/linux
parentf3637a5f2e2eb391ff5757bc83fb5de8f9726464 (diff)
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/linux')
-rw-r--r--include/linux/irq.h11
-rw-r--r--include/linux/irqdesc.h1
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 @@
23#include <linux/errno.h> 23#include <linux/errno.h>
24#include <linux/topology.h> 24#include <linux/topology.h>
25#include <linux/wait.h> 25#include <linux/wait.h>
26#include <linux/module.h>
26 27
27#include <asm/irq.h> 28#include <asm/irq.h>
28#include <asm/ptrace.h> 29#include <asm/ptrace.h>
@@ -546,7 +547,15 @@ static inline struct msi_desc *irq_data_get_msi(struct irq_data *d)
546 return d->msi_desc; 547 return d->msi_desc;
547} 548}
548 549
549int irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node); 550int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
551 struct module *owner);
552
553static inline int irq_alloc_descs(int irq, unsigned int from, unsigned int cnt,
554 int node)
555{
556 return __irq_alloc_descs(irq, from, cnt, node, THIS_MODULE);
557}
558
550void irq_free_descs(unsigned int irq, unsigned int cnt); 559void irq_free_descs(unsigned int irq, unsigned int cnt);
551int irq_reserve_irqs(unsigned int from, unsigned int cnt); 560int irq_reserve_irqs(unsigned int from, unsigned int cnt);
552 561
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 {
66#ifdef CONFIG_PROC_FS 66#ifdef CONFIG_PROC_FS
67 struct proc_dir_entry *dir; 67 struct proc_dir_entry *dir;
68#endif 68#endif
69 struct module *owner;
69 const char *name; 70 const char *name;
70} ____cacheline_internodealigned_in_smp; 71} ____cacheline_internodealigned_in_smp;
71 72