2005-04-17 02:20:36 +04:00
/*
* linux / arch / arm / mach - shark / irq . c
*
* by Alexander Schulz
*
* derived from linux / arch / ppc / kernel / i8259 . c and :
2008-08-05 19:14:15 +04:00
* arch / arm / mach - ebsa110 / include / mach / irq . h
2005-04-17 02:20:36 +04:00
* Copyright ( C ) 1996 - 1998 Russell King
*/
# include <linux/init.h>
# include <linux/fs.h>
# include <linux/interrupt.h>
2008-09-06 15:10:45 +04:00
# include <linux/io.h>
2005-04-17 02:20:36 +04:00
# include <asm/irq.h>
# include <asm/mach/irq.h>
/*
* 8259 A PIC functions to handle ISA devices :
*/
/*
* This contains the irq mask for both 8259 A irq controllers ,
* Let through the cascade - interrupt no . 2 ( ff - ( 1 < < 2 ) = = fb )
*/
static unsigned char cached_irq_mask [ 2 ] = { 0xfb , 0xff } ;
/*
* These have to be protected by the irq controller spinlock
* before being called .
*/
2010-11-29 13:12:34 +03:00
static void shark_disable_8259A_irq ( struct irq_data * d )
2005-04-17 02:20:36 +04:00
{
unsigned int mask ;
2010-11-29 13:12:34 +03:00
if ( d - > irq < 8 ) {
mask = 1 < < d - > irq ;
2005-04-17 02:20:36 +04:00
cached_irq_mask [ 0 ] | = mask ;
outb ( cached_irq_mask [ 1 ] , 0xA1 ) ;
} else {
2010-11-29 13:12:34 +03:00
mask = 1 < < ( d - > irq - 8 ) ;
2005-04-17 02:20:36 +04:00
cached_irq_mask [ 1 ] | = mask ;
outb ( cached_irq_mask [ 0 ] , 0x21 ) ;
}
}
2010-11-29 13:12:34 +03:00
static void shark_enable_8259A_irq ( struct irq_data * d )
2005-04-17 02:20:36 +04:00
{
unsigned int mask ;
2010-11-29 13:12:34 +03:00
if ( d - > irq < 8 ) {
mask = ~ ( 1 < < d - > irq ) ;
2005-04-17 02:20:36 +04:00
cached_irq_mask [ 0 ] & = mask ;
outb ( cached_irq_mask [ 0 ] , 0x21 ) ;
} else {
2010-11-29 13:12:34 +03:00
mask = ~ ( 1 < < ( d - > irq - 8 ) ) ;
2005-04-17 02:20:36 +04:00
cached_irq_mask [ 1 ] & = mask ;
outb ( cached_irq_mask [ 1 ] , 0xA1 ) ;
}
}
2010-11-29 13:12:34 +03:00
static void shark_ack_8259A_irq ( struct irq_data * d ) { }
2005-04-17 02:20:36 +04:00
2006-10-06 21:53:39 +04:00
static irqreturn_t bogus_int ( int irq , void * dev_id )
2005-04-17 02:20:36 +04:00
{
printk ( " Got interrupt %i! \n " , irq ) ;
return IRQ_NONE ;
}
static struct irqaction cascade ;
2006-08-02 01:26:25 +04:00
static struct irq_chip fb_chip = {
2010-11-29 13:12:34 +03:00
. name = " XT-PIC " ,
. irq_ack = shark_ack_8259A_irq ,
. irq_mask = shark_disable_8259A_irq ,
. irq_unmask = shark_enable_8259A_irq ,
2005-04-17 02:20:36 +04:00
} ;
void __init shark_init_irq ( void )
{
int irq ;
for ( irq = 0 ; irq < NR_IRQS ; irq + + ) {
2011-03-24 15:35:09 +03:00
irq_set_chip_and_handler ( irq , & fb_chip , handle_edge_irq ) ;
2005-04-17 02:20:36 +04:00
set_irq_flags ( irq , IRQF_VALID | IRQF_PROBE ) ;
}
/* init master interrupt controller */
outb ( 0x11 , 0x20 ) ; /* Start init sequence, edge triggered (level: 0x19)*/
outb ( 0x00 , 0x21 ) ; /* Vector base */
outb ( 0x04 , 0x21 ) ; /* Cascade (slave) on IRQ2 */
outb ( 0x03 , 0x21 ) ; /* Select 8086 mode , auto eoi*/
outb ( 0x0A , 0x20 ) ;
/* init slave interrupt controller */
outb ( 0x11 , 0xA0 ) ; /* Start init sequence, edge triggered */
outb ( 0x08 , 0xA1 ) ; /* Vector base */
outb ( 0x02 , 0xA1 ) ; /* Cascade (slave) on IRQ2 */
outb ( 0x03 , 0xA1 ) ; /* Select 8086 mode, auto eoi */
outb ( 0x0A , 0xA0 ) ;
outb ( cached_irq_mask [ 1 ] , 0xA1 ) ;
outb ( cached_irq_mask [ 0 ] , 0x21 ) ;
//request_region(0x20,0x2,"pic1");
//request_region(0xA0,0x2,"pic2");
cascade . handler = bogus_int ;
cascade . name = " cascade " ;
setup_irq ( 2 , & cascade ) ;
}