2009-03-27 16:25:49 +03:00
/*
* Copyright ( C ) 2007 - 2009 Michal Simek < monstr @ monstr . eu >
* Copyright ( C ) 2007 - 2009 PetaLogix
* Copyright ( C ) 2006 Atmark Techno , Inc .
*
* 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>
2010-04-13 01:01:36 +04:00
# include <linux/ftrace.h>
2009-03-27 16:25:49 +03:00
# include <linux/kernel.h>
# include <linux/hardirq.h>
# include <linux/interrupt.h>
# include <linux/irqflags.h>
# include <linux/seq_file.h>
# include <linux/kernel_stat.h>
# include <linux/irq.h>
2010-06-18 21:09:59 +04:00
# include <linux/of_irq.h>
2009-03-27 16:25:49 +03:00
# include <asm/prom.h>
static u32 concurrent_irq ;
2010-04-13 01:01:36 +04:00
void __irq_entry do_IRQ ( struct pt_regs * regs )
2009-03-27 16:25:49 +03:00
{
unsigned int irq ;
struct pt_regs * old_regs = set_irq_regs ( regs ) ;
2010-05-25 15:44:38 +04:00
trace_hardirqs_off ( ) ;
2009-03-27 16:25:49 +03:00
irq_enter ( ) ;
irq = get_irq ( regs ) ;
next_irq :
BUG_ON ( irq = = - 1U ) ;
generic_handle_irq ( irq ) ;
irq = get_irq ( regs ) ;
if ( irq ! = - 1U ) {
pr_debug ( " next irq: %d \n " , irq ) ;
+ + concurrent_irq ;
goto next_irq ;
}
irq_exit ( ) ;
set_irq_regs ( old_regs ) ;
2010-05-25 15:44:38 +04:00
trace_hardirqs_on ( ) ;
2009-03-27 16:25:49 +03:00
}
int show_interrupts ( struct seq_file * p , void * v )
{
int i = * ( loff_t * ) v , j ;
struct irqaction * action ;
unsigned long flags ;
if ( i = = 0 ) {
seq_printf ( p , " " ) ;
for_each_online_cpu ( j )
seq_printf ( p , " CPU%-8d " , j ) ;
seq_putc ( p , ' \n ' ) ;
}
if ( i < nr_irq ) {
2009-11-17 18:46:45 +03:00
raw_spin_lock_irqsave ( & irq_desc [ i ] . lock , flags ) ;
2009-03-27 16:25:49 +03:00
action = irq_desc [ i ] . action ;
if ( ! action )
goto skip ;
seq_printf ( p , " %3d: " , i ) ;
# ifndef CONFIG_SMP
seq_printf ( p , " %10u " , kstat_irqs ( i ) ) ;
# else
for_each_online_cpu ( j )
seq_printf ( p , " %10u " , kstat_cpu ( j ) . irqs [ i ] ) ;
# endif
seq_printf ( p , " %8s " , irq_desc [ i ] . status &
IRQ_LEVEL ? " level " : " edge " ) ;
seq_printf ( p , " %8s " , irq_desc [ i ] . chip - > name ) ;
seq_printf ( p , " %s " , action - > name ) ;
for ( action = action - > next ; action ; action = action - > next )
seq_printf ( p , " , %s " , action - > name ) ;
seq_putc ( p , ' \n ' ) ;
skip :
2009-11-17 18:46:45 +03:00
raw_spin_unlock_irqrestore ( & irq_desc [ i ] . lock , flags ) ;
2009-03-27 16:25:49 +03:00
}
return 0 ;
}
2010-01-14 17:16:31 +03:00
/* MS: There is no any advance mapping mechanism. We are using simple 32bit
intc without any cascades or any connection that ' s why mapping is 1 : 1 */
unsigned int irq_create_mapping ( struct irq_host * host , irq_hw_number_t hwirq )
{
return hwirq ;
}
EXPORT_SYMBOL_GPL ( irq_create_mapping ) ;
unsigned int irq_create_of_mapping ( struct device_node * controller ,
2010-06-18 21:09:59 +04:00
const u32 * intspec , unsigned int intsize )
2010-01-14 17:16:31 +03:00
{
return intspec [ 0 ] ;
}
EXPORT_SYMBOL_GPL ( irq_create_of_mapping ) ;