2005-04-16 15:20:36 -07: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 14:32:26 +00:00
srm_enable_irq ( struct irq_data * d )
2005-04-16 15:20:36 -07:00
{
spin_lock ( & srm_irq_lock ) ;
2011-02-06 14:32:26 +00:00
cserve_ena ( d - > irq - 16 ) ;
2005-04-16 15:20:36 -07:00
spin_unlock ( & srm_irq_lock ) ;
}
static void
2011-02-06 14:32:26 +00:00
srm_disable_irq ( struct irq_data * d )
2005-04-16 15:20:36 -07:00
{
spin_lock ( & srm_irq_lock ) ;
2011-02-06 14:32:26 +00:00
cserve_dis ( d - > irq - 16 ) ;
2005-04-16 15:20:36 -07:00
spin_unlock ( & srm_irq_lock ) ;
}
/* Handle interrupts from the SRM, assuming no additional weirdness. */
2009-06-16 15:33:25 -07:00
static struct irq_chip srm_irq_type = {
2009-11-30 22:51:31 -05:00
. name = " SRM " ,
2011-02-06 14:32:26 +00:00
. irq_unmask = srm_enable_irq ,
. irq_mask = srm_disable_irq ,
. irq_mask_ack = srm_disable_irq ,
2005-04-16 15:20:36 -07:00
} ;
void __init
init_srm_irqs ( long max , unsigned long ignore_mask )
{
long i ;
2009-01-15 13:51:17 -08:00
if ( NR_IRQS < = 16 )
return ;
2005-04-16 15:20:36 -07:00
for ( i = 16 ; i < max ; + + i ) {
if ( i < 64 & & ( ( ignore_mask > > i ) & 1 ) )
continue ;
2011-03-25 22:17:31 +01:00
irq_set_chip_and_handler ( i , & srm_irq_type , handle_level_irq ) ;
2011-02-06 14:32:26 +00:00
irq_set_status_flags ( i , IRQ_LEVEL ) ;
2005-04-16 15:20:36 -07:00
}
}
void
2006-10-08 14:36:08 +01:00
srm_device_interrupt ( unsigned long vector )
2005-04-16 15:20:36 -07:00
{
int irq = ( vector - 0x800 ) > > 4 ;
2006-10-08 14:37:32 +01:00
handle_irq ( irq ) ;
2005-04-16 15:20:36 -07:00
}