aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/irq
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2011-02-16 11:12:57 -0500
committerThomas Gleixner <tglx@linutronix.de>2011-02-19 06:58:06 -0500
commite7bcecb7b1d29b9ad5af939149a945658620ca8f (patch)
tree8f5ea66fd6e178574a31f2b1cfc5eeb2da28bef6 /kernel/irq
parent218502bfe674f570205367b9094048207b04ba15 (diff)
genirq: Make nr_irqs runtime expandable
We face more and more the requirement to expand nr_irqs at runtime. The reason are irq expanders which can not be detected in the early boot stage. So we speculate nr_irqs to have enough room. Further Xen needs extra irq numbers and we really want to avoid adding more "detection" code into the early boot. There is no real good reason why we need to limit nr_irqs at early boot. Allow the allocation code to expand nr_irqs. We have already 8k extra number space in the allocation bitmap, so lets use it. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/irq')
-rw-r--r--kernel/irq/irqdesc.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index a250d3a0af1..6f6644f819d 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -206,6 +206,14 @@ struct irq_desc * __ref irq_to_desc_alloc_node(unsigned int irq, int node)
206 return NULL; 206 return NULL;
207} 207}
208 208
209static int irq_expand_nr_irqs(unsigned int cnt)
210{
211 if (nr_irqs + cnt > IRQ_BITMAP_BITS)
212 return -ENOMEM;
213 nr_irqs += cnt;
214 return 0;
215}
216
209int __init early_irq_init(void) 217int __init early_irq_init(void)
210{ 218{
211 int i, initcnt, node = first_online_node; 219 int i, initcnt, node = first_online_node;
@@ -287,6 +295,12 @@ static inline int alloc_descs(unsigned int start, unsigned int cnt, int node)
287{ 295{
288 return start; 296 return start;
289} 297}
298
299static int irq_expand_nr_irqs(unsigned int cnt)
300{
301 return -ENOMEM;
302}
303
290#endif /* !CONFIG_SPARSE_IRQ */ 304#endif /* !CONFIG_SPARSE_IRQ */
291 305
292/* Dynamic interrupt handling */ 306/* Dynamic interrupt handling */
@@ -335,9 +349,11 @@ irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node)
335 if (irq >=0 && start != irq) 349 if (irq >=0 && start != irq)
336 goto err; 350 goto err;
337 351
338 ret = -ENOMEM; 352 if (start >= nr_irqs) {
339 if (start >= nr_irqs) 353 ret = irq_expand_nr_irqs(cnt);
340 goto err; 354 if (ret)
355 goto err;
356 }
341 357
342 bitmap_set(allocated_irqs, start, cnt); 358 bitmap_set(allocated_irqs, start, cnt);
343 mutex_unlock(&sparse_irq_lock); 359 mutex_unlock(&sparse_irq_lock);