aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/irq/irqdesc.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/irq/irqdesc.c')
-rw-r--r--kernel/irq/irqdesc.c102
1 files changed, 70 insertions, 32 deletions
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index a7174617616b..7339e42a85ab 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -278,7 +278,12 @@ EXPORT_SYMBOL(irq_to_desc);
278 278
279static void free_desc(unsigned int irq) 279static void free_desc(unsigned int irq)
280{ 280{
281 dynamic_irq_cleanup(irq); 281 struct irq_desc *desc = irq_to_desc(irq);
282 unsigned long flags;
283
284 raw_spin_lock_irqsave(&desc->lock, flags);
285 desc_set_defaults(irq, desc, desc_node(desc), NULL);
286 raw_spin_unlock_irqrestore(&desc->lock, flags);
282} 287}
283 288
284static inline int alloc_descs(unsigned int start, unsigned int cnt, int node, 289static inline int alloc_descs(unsigned int start, unsigned int cnt, int node,
@@ -299,6 +304,20 @@ static int irq_expand_nr_irqs(unsigned int nr)
299 return -ENOMEM; 304 return -ENOMEM;
300} 305}
301 306
307void irq_mark_irq(unsigned int irq)
308{
309 mutex_lock(&sparse_irq_lock);
310 bitmap_set(allocated_irqs, irq, 1);
311 mutex_unlock(&sparse_irq_lock);
312}
313
314#ifdef CONFIG_GENERIC_IRQ_LEGACY
315void irq_init_desc(unsigned int irq)
316{
317 free_desc(irq);
318}
319#endif
320
302#endif /* !CONFIG_SPARSE_IRQ */ 321#endif /* !CONFIG_SPARSE_IRQ */
303 322
304/** 323/**
@@ -363,6 +382,13 @@ __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
363 if (from > irq) 382 if (from > irq)
364 return -EINVAL; 383 return -EINVAL;
365 from = irq; 384 from = irq;
385 } else {
386 /*
387 * For interrupts which are freely allocated the
388 * architecture can force a lower bound to the @from
389 * argument. x86 uses this to exclude the GSI space.
390 */
391 from = arch_dynirq_lower_bound(from);
366 } 392 }
367 393
368 mutex_lock(&sparse_irq_lock); 394 mutex_lock(&sparse_irq_lock);
@@ -389,30 +415,56 @@ err:
389} 415}
390EXPORT_SYMBOL_GPL(__irq_alloc_descs); 416EXPORT_SYMBOL_GPL(__irq_alloc_descs);
391 417
418#ifdef CONFIG_GENERIC_IRQ_LEGACY_ALLOC_HWIRQ
392/** 419/**
393 * irq_reserve_irqs - mark irqs allocated 420 * irq_alloc_hwirqs - Allocate an irq descriptor and initialize the hardware
394 * @from: mark from irq number 421 * @cnt: number of interrupts to allocate
395 * @cnt: number of irqs to mark 422 * @node: node on which to allocate
396 * 423 *
397 * Returns 0 on success or an appropriate error code 424 * Returns an interrupt number > 0 or 0, if the allocation fails.
398 */ 425 */
399int irq_reserve_irqs(unsigned int from, unsigned int cnt) 426unsigned int irq_alloc_hwirqs(int cnt, int node)
400{ 427{
401 unsigned int start; 428 int i, irq = __irq_alloc_descs(-1, 0, cnt, node, NULL);
402 int ret = 0;
403 429
404 if (!cnt || (from + cnt) > nr_irqs) 430 if (irq < 0)
405 return -EINVAL; 431 return 0;
406 432
407 mutex_lock(&sparse_irq_lock); 433 for (i = irq; cnt > 0; i++, cnt--) {
408 start = bitmap_find_next_zero_area(allocated_irqs, nr_irqs, from, cnt, 0); 434 if (arch_setup_hwirq(i, node))
409 if (start == from) 435 goto err;
410 bitmap_set(allocated_irqs, start, cnt); 436 irq_clear_status_flags(i, _IRQ_NOREQUEST);
411 else 437 }
412 ret = -EEXIST; 438 return irq;
413 mutex_unlock(&sparse_irq_lock); 439
414 return ret; 440err:
441 for (i--; i >= irq; i--) {
442 irq_set_status_flags(i, _IRQ_NOREQUEST | _IRQ_NOPROBE);
443 arch_teardown_hwirq(i);
444 }
445 irq_free_descs(irq, cnt);
446 return 0;
447}
448EXPORT_SYMBOL_GPL(irq_alloc_hwirqs);
449
450/**
451 * irq_free_hwirqs - Free irq descriptor and cleanup the hardware
452 * @from: Free from irq number
453 * @cnt: number of interrupts to free
454 *
455 */
456void irq_free_hwirqs(unsigned int from, int cnt)
457{
458 int i;
459
460 for (i = from; cnt > 0; i++, cnt--) {
461 irq_set_status_flags(i, _IRQ_NOREQUEST | _IRQ_NOPROBE);
462 arch_teardown_hwirq(i);
463 }
464 irq_free_descs(from, cnt);
415} 465}
466EXPORT_SYMBOL_GPL(irq_free_hwirqs);
467#endif
416 468
417/** 469/**
418 * irq_get_next_irq - get next allocated irq number 470 * irq_get_next_irq - get next allocated irq number
@@ -475,20 +527,6 @@ int irq_set_percpu_devid(unsigned int irq)
475 return 0; 527 return 0;
476} 528}
477 529
478/**
479 * dynamic_irq_cleanup - cleanup a dynamically allocated irq
480 * @irq: irq number to initialize
481 */
482void dynamic_irq_cleanup(unsigned int irq)
483{
484 struct irq_desc *desc = irq_to_desc(irq);
485 unsigned long flags;
486
487 raw_spin_lock_irqsave(&desc->lock, flags);
488 desc_set_defaults(irq, desc, desc_node(desc), NULL);
489 raw_spin_unlock_irqrestore(&desc->lock, flags);
490}
491
492void kstat_incr_irq_this_cpu(unsigned int irq) 530void kstat_incr_irq_this_cpu(unsigned int irq)
493{ 531{
494 kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq)); 532 kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));