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.c24
1 files changed, 7 insertions, 17 deletions
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index 73be2b3909bd..82afb7ed369f 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -421,10 +421,8 @@ static void free_desc(unsigned int irq)
421 * The sysfs entry must be serialized against a concurrent 421 * The sysfs entry must be serialized against a concurrent
422 * irq_sysfs_init() as well. 422 * irq_sysfs_init() as well.
423 */ 423 */
424 mutex_lock(&sparse_irq_lock);
425 kobject_del(&desc->kobj); 424 kobject_del(&desc->kobj);
426 delete_irq_desc(irq); 425 delete_irq_desc(irq);
427 mutex_unlock(&sparse_irq_lock);
428 426
429 /* 427 /*
430 * We free the descriptor, masks and stat fields via RCU. That 428 * We free the descriptor, masks and stat fields via RCU. That
@@ -462,20 +460,15 @@ static int alloc_descs(unsigned int start, unsigned int cnt, int node,
462 desc = alloc_desc(start + i, node, flags, mask, owner); 460 desc = alloc_desc(start + i, node, flags, mask, owner);
463 if (!desc) 461 if (!desc)
464 goto err; 462 goto err;
465 mutex_lock(&sparse_irq_lock);
466 irq_insert_desc(start + i, desc); 463 irq_insert_desc(start + i, desc);
467 irq_sysfs_add(start + i, desc); 464 irq_sysfs_add(start + i, desc);
468 mutex_unlock(&sparse_irq_lock);
469 } 465 }
466 bitmap_set(allocated_irqs, start, cnt);
470 return start; 467 return start;
471 468
472err: 469err:
473 for (i--; i >= 0; i--) 470 for (i--; i >= 0; i--)
474 free_desc(start + i); 471 free_desc(start + i);
475
476 mutex_lock(&sparse_irq_lock);
477 bitmap_clear(allocated_irqs, start, cnt);
478 mutex_unlock(&sparse_irq_lock);
479 return -ENOMEM; 472 return -ENOMEM;
480} 473}
481 474
@@ -575,6 +568,7 @@ static inline int alloc_descs(unsigned int start, unsigned int cnt, int node,
575 568
576 desc->owner = owner; 569 desc->owner = owner;
577 } 570 }
571 bitmap_set(allocated_irqs, start, cnt);
578 return start; 572 return start;
579} 573}
580 574
@@ -670,10 +664,10 @@ void irq_free_descs(unsigned int from, unsigned int cnt)
670 if (from >= nr_irqs || (from + cnt) > nr_irqs) 664 if (from >= nr_irqs || (from + cnt) > nr_irqs)
671 return; 665 return;
672 666
667 mutex_lock(&sparse_irq_lock);
673 for (i = 0; i < cnt; i++) 668 for (i = 0; i < cnt; i++)
674 free_desc(from + i); 669 free_desc(from + i);
675 670
676 mutex_lock(&sparse_irq_lock);
677 bitmap_clear(allocated_irqs, from, cnt); 671 bitmap_clear(allocated_irqs, from, cnt);
678 mutex_unlock(&sparse_irq_lock); 672 mutex_unlock(&sparse_irq_lock);
679} 673}
@@ -720,19 +714,15 @@ __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
720 from, cnt, 0); 714 from, cnt, 0);
721 ret = -EEXIST; 715 ret = -EEXIST;
722 if (irq >=0 && start != irq) 716 if (irq >=0 && start != irq)
723 goto err; 717 goto unlock;
724 718
725 if (start + cnt > nr_irqs) { 719 if (start + cnt > nr_irqs) {
726 ret = irq_expand_nr_irqs(start + cnt); 720 ret = irq_expand_nr_irqs(start + cnt);
727 if (ret) 721 if (ret)
728 goto err; 722 goto unlock;
729 } 723 }
730 724 ret = alloc_descs(start, cnt, node, affinity, owner);
731 bitmap_set(allocated_irqs, start, cnt); 725unlock:
732 mutex_unlock(&sparse_irq_lock);
733 return alloc_descs(start, cnt, node, affinity, owner);
734
735err:
736 mutex_unlock(&sparse_irq_lock); 726 mutex_unlock(&sparse_irq_lock);
737 return ret; 727 return ret;
738} 728}