2010-10-05 22:10:30 +09:00
/*
* Dynamic IRQ management
*
* Copyright ( C ) 2010 Paul Mundt
*
* Modelled after arch / x86 / kernel / apic / io_apic . c
*
* 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 .
*/
# define pr_fmt(fmt) "intc: " fmt
# include <linux/irq.h>
# include <linux/bitmap.h>
# include <linux/spinlock.h>
# include "internals.h" /* only for activate_irq() damage.. */
/*
2010-10-26 16:05:08 +09:00
* The IRQ bitmap provides a global map of bound IRQ vectors for a
2010-10-05 22:10:30 +09:00
* given platform . Allocation of IRQs are either static through the CPU
* vector map , or dynamic in the case of board mux vectors or MSI .
*
* As this is a central point for all IRQ controllers on the system ,
* each of the available sources are mapped out here . This combined with
* sparseirq makes it quite trivial to keep the vector map tightly packed
* when dynamically creating IRQs , as well as tying in to otherwise
* unused irq_desc positions in the sparse array .
*/
/*
* Dynamic IRQ allocation and deallocation
*/
unsigned int create_irq_nr ( unsigned int irq_want , int node )
{
2010-10-26 16:05:08 +09:00
int irq = irq_alloc_desc_at ( irq_want , node ) ;
if ( irq < 0 )
2010-10-12 02:03:09 +09:00
return 0 ;
2010-10-05 22:10:30 +09:00
2010-10-12 02:03:09 +09:00
activate_irq ( irq ) ;
2010-10-26 16:05:08 +09:00
return irq ;
2010-10-05 22:10:30 +09:00
}
int create_irq ( void )
{
2010-10-26 16:05:08 +09:00
int irq = irq_alloc_desc ( numa_node_id ( ) ) ;
if ( irq > = 0 )
activate_irq ( irq ) ;
2010-10-05 22:10:30 +09:00
return irq ;
}
void destroy_irq ( unsigned int irq )
{
2010-10-12 02:03:09 +09:00
irq_free_desc ( irq ) ;
2010-10-05 22:10:30 +09:00
}
void reserve_intc_vectors ( struct intc_vect * vectors , unsigned int nr_vecs )
{
int i ;
for ( i = 0 ; i < nr_vecs ; i + + )
2010-11-01 16:10:48 -04:00
irq_reserve_irq ( evt2irq ( vectors [ i ] . vect ) ) ;
2010-10-05 22:10:30 +09:00
}