2005-04-17 02:20:36 +04:00
/*
* linux / arch / m68k / sun3 / sun3ints . c - - Sun - 3 ( x ) Linux interrupt handling code
*
* 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/types.h>
# include <linux/kernel.h>
# include <linux/sched.h>
# include <linux/kernel_stat.h>
# include <linux/interrupt.h>
# include <asm/segment.h>
# include <asm/intersil.h>
# include <asm/oplib.h>
# include <asm/sun3ints.h>
2006-10-07 17:16:45 +04:00
# include <asm/irq_regs.h>
2005-04-17 02:20:36 +04:00
# include <linux/seq_file.h>
extern void sun3_leds ( unsigned char ) ;
void sun3_disable_interrupts ( void )
{
sun3_disable_irq ( 0 ) ;
}
void sun3_enable_interrupts ( void )
{
sun3_enable_irq ( 0 ) ;
}
int led_pattern [ 8 ] = {
~ ( 0x80 ) , ~ ( 0x01 ) ,
~ ( 0x40 ) , ~ ( 0x02 ) ,
~ ( 0x20 ) , ~ ( 0x04 ) ,
~ ( 0x10 ) , ~ ( 0x08 )
} ;
volatile unsigned char * sun3_intreg ;
void sun3_enable_irq ( unsigned int irq )
{
2006-06-25 16:47:05 +04:00
* sun3_intreg | = ( 1 < < irq ) ;
2005-04-17 02:20:36 +04:00
}
void sun3_disable_irq ( unsigned int irq )
{
2006-06-25 16:47:05 +04:00
* sun3_intreg & = ~ ( 1 < < irq ) ;
2005-04-17 02:20:36 +04:00
}
2006-10-07 17:16:45 +04:00
static irqreturn_t sun3_int7 ( int irq , void * dev_id )
2005-04-17 02:20:36 +04:00
{
2006-06-25 16:47:05 +04:00
* sun3_intreg | = ( 1 < < irq ) ;
if ( ! ( kstat_cpu ( 0 ) . irqs [ irq ] % 2000 ) )
sun3_leds ( led_pattern [ ( kstat_cpu ( 0 ) . irqs [ irq ] % 16000 ) / 2000 ] ) ;
2005-04-17 02:20:36 +04:00
return IRQ_HANDLED ;
}
2006-10-07 17:16:45 +04:00
static irqreturn_t sun3_int5 ( int irq , void * dev_id )
2005-04-17 02:20:36 +04:00
{
# ifdef CONFIG_SUN3
intersil_clear ( ) ;
# endif
2006-06-25 16:47:05 +04:00
* sun3_intreg | = ( 1 < < irq ) ;
2005-04-17 02:20:36 +04:00
# ifdef CONFIG_SUN3
intersil_clear ( ) ;
# endif
2006-09-29 13:00:32 +04:00
do_timer ( 1 ) ;
2005-04-17 02:20:36 +04:00
# ifndef CONFIG_SMP
2006-10-07 17:16:45 +04:00
update_process_times ( user_mode ( get_irq_regs ( ) ) ) ;
2005-04-17 02:20:36 +04:00
# endif
2006-06-25 16:47:05 +04:00
if ( ! ( kstat_cpu ( 0 ) . irqs [ irq ] % 20 ) )
sun3_leds ( led_pattern [ ( kstat_cpu ( 0 ) . irqs [ irq ] % 160 ) / 20 ] ) ;
2005-04-17 02:20:36 +04:00
return IRQ_HANDLED ;
}
2006-10-07 17:16:45 +04:00
static irqreturn_t sun3_vec255 ( int irq , void * dev_id )
2005-04-17 02:20:36 +04:00
{
// intersil_clear();
return IRQ_HANDLED ;
}
2006-06-25 16:47:05 +04:00
static void sun3_inthandle ( unsigned int irq , struct pt_regs * fp )
2005-04-17 02:20:36 +04:00
{
2006-06-25 16:47:05 +04:00
* sun3_intreg & = ~ ( 1 < < irq ) ;
2005-04-17 02:20:36 +04:00
2006-10-07 17:16:45 +04:00
__m68k_handle_int ( irq , fp ) ;
2005-04-17 02:20:36 +04:00
}
2006-06-25 16:47:05 +04:00
static struct irq_controller sun3_irq_controller = {
. name = " sun3 " ,
2007-05-07 01:50:54 +04:00
. lock = __SPIN_LOCK_UNLOCKED ( sun3_irq_controller . lock ) ,
2006-06-25 16:47:05 +04:00
. startup = m68k_irq_startup ,
. shutdown = m68k_irq_shutdown ,
. enable = sun3_enable_irq ,
. disable = sun3_disable_irq ,
} ;
2005-04-17 02:20:36 +04:00
2007-07-20 07:33:28 +04:00
void __init sun3_init_IRQ ( void )
2005-04-17 02:20:36 +04:00
{
2006-06-25 16:47:05 +04:00
* sun3_intreg = 1 ;
2005-04-17 02:20:36 +04:00
2006-06-25 16:47:05 +04:00
m68k_setup_auto_interrupt ( sun3_inthandle ) ;
m68k_setup_irq_controller ( & sun3_irq_controller , IRQ_AUTO_1 , 7 ) ;
2007-05-02 00:32:47 +04:00
m68k_setup_user_interrupt ( VEC_USER , 128 , NULL ) ;
2005-04-17 02:20:36 +04:00
2006-06-25 16:47:05 +04:00
request_irq ( IRQ_AUTO_5 , sun3_int5 , 0 , " int5 " , NULL ) ;
request_irq ( IRQ_AUTO_7 , sun3_int7 , 0 , " int7 " , NULL ) ;
request_irq ( IRQ_USER + 127 , sun3_vec255 , 0 , " vec255 " , NULL ) ;
2005-04-17 02:20:36 +04:00
}