2005-04-17 02:20:36 +04:00
/*
* Handle interrupts from the SRM , assuming no additional weirdness .
*/
# include <linux/init.h>
# include <linux/sched.h>
# include <linux/irq.h>
# include "proto.h"
# include "irq_impl.h"
/*
* Is the palcode SMP safe ? In other words : can we call cserve_ena / dis
* at the same time in multiple CPUs ? To be safe I added a spinlock
* but it can be removed trivially if the palcode is robust against smp .
*/
DEFINE_SPINLOCK ( srm_irq_lock ) ;
static inline void
2011-02-06 17:32:26 +03:00
srm_enable_irq ( struct irq_data * d )
2005-04-17 02:20:36 +04:00
{
spin_lock ( & srm_irq_lock ) ;
2011-02-06 17:32:26 +03:00
cserve_ena ( d - > irq - 16 ) ;
2005-04-17 02:20:36 +04:00
spin_unlock ( & srm_irq_lock ) ;
}
static void
2011-02-06 17:32:26 +03:00
srm_disable_irq ( struct irq_data * d )
2005-04-17 02:20:36 +04:00
{
spin_lock ( & srm_irq_lock ) ;
2011-02-06 17:32:26 +03:00
cserve_dis ( d - > irq - 16 ) ;
2005-04-17 02:20:36 +04:00
spin_unlock ( & srm_irq_lock ) ;
}
/* Handle interrupts from the SRM, assuming no additional weirdness. */
2009-06-17 02:33:25 +04:00
static struct irq_chip srm_irq_type = {
2009-12-01 06:51:31 +03:00
. name = " SRM " ,
2011-02-06 17:32:26 +03:00
. irq_unmask = srm_enable_irq ,
. irq_mask = srm_disable_irq ,
. irq_mask_ack = srm_disable_irq ,
2005-04-17 02:20:36 +04:00
} ;
void __init
init_srm_irqs ( long max , unsigned long ignore_mask )
{
long i ;
2009-01-16 00:51:17 +03:00
if ( NR_IRQS < = 16 )
return ;
2005-04-17 02:20:36 +04:00
for ( i = 16 ; i < max ; + + i ) {
if ( i < 64 & & ( ( ignore_mask > > i ) & 1 ) )
continue ;
2011-03-26 00:17:31 +03:00
irq_set_chip_and_handler ( i , & srm_irq_type , handle_level_irq ) ;
2011-02-06 17:32:26 +03:00
irq_set_status_flags ( i , IRQ_LEVEL ) ;
2005-04-17 02:20:36 +04:00
}
}
void
2006-10-08 17:36:08 +04:00
srm_device_interrupt ( unsigned long vector )
2005-04-17 02:20:36 +04:00
{
int irq = ( vector - 0x800 ) > > 4 ;
2006-10-08 17:37:32 +04:00
handle_irq ( irq ) ;
2005-04-17 02:20:36 +04:00
}