| /* |
| * This file is subject to the terms and conditions of the GNU General Public |
| * License. See the file "COPYING" in the main directory of this archive |
| * for more details. |
| */ |
| #include <linux/init.h> |
| #include <linux/irq.h> |
| #include <linux/types.h> |
| |
| #include <asm/barrier.h> |
| |
| static DECLARE_BITMAP(irq_map, NR_IRQS); |
| |
| int allocate_irqno(void) |
| { |
| int irq; |
| |
| again: |
| irq = find_first_zero_bit(irq_map, NR_IRQS); |
| |
| if (irq >= NR_IRQS) |
| return -ENOSPC; |
| |
| if (test_and_set_bit(irq, irq_map)) |
| goto again; |
| |
| return irq; |
| } |
| |
| /* |
| * Allocate the 16 legacy interrupts for i8259 devices. This happens early |
| * in the kernel initialization so treating allocation failure as BUG() is |
| * ok. |
| */ |
| void __init alloc_legacy_irqno(void) |
| { |
| int i; |
| |
| for (i = 0; i <= 16; i++) |
| BUG_ON(test_and_set_bit(i, irq_map)); |
| } |
| |
| void free_irqno(unsigned int irq) |
| { |
| smp_mb__before_atomic(); |
| clear_bit(irq, irq_map); |
| smp_mb__after_atomic(); |
| } |