2005-04-17 02:20:36 +04:00
# include <linux/init.h>
# include <linux/list.h>
2008-09-06 15:10:45 +04:00
# include <linux/io.h>
2005-04-17 02:20:36 +04:00
# include <asm/mach/irq.h>
# include <asm/hardware/iomd.h>
# include <asm/irq.h>
2012-02-09 04:24:23 +04:00
# include <asm/fiq.h>
2005-04-17 02:20:36 +04:00
2010-11-29 13:07:20 +03:00
static void iomd_ack_irq_a ( struct irq_data * d )
2005-04-17 02:20:36 +04:00
{
unsigned int val , mask ;
2010-11-29 13:07:20 +03:00
mask = 1 < < d - > irq ;
2005-04-17 02:20:36 +04:00
val = iomd_readb ( IOMD_IRQMASKA ) ;
iomd_writeb ( val & ~ mask , IOMD_IRQMASKA ) ;
iomd_writeb ( mask , IOMD_IRQCLRA ) ;
}
2010-11-29 13:07:20 +03:00
static void iomd_mask_irq_a ( struct irq_data * d )
2005-04-17 02:20:36 +04:00
{
unsigned int val , mask ;
2010-11-29 13:07:20 +03:00
mask = 1 < < d - > irq ;
2005-04-17 02:20:36 +04:00
val = iomd_readb ( IOMD_IRQMASKA ) ;
iomd_writeb ( val & ~ mask , IOMD_IRQMASKA ) ;
}
2010-11-29 13:07:20 +03:00
static void iomd_unmask_irq_a ( struct irq_data * d )
2005-04-17 02:20:36 +04:00
{
unsigned int val , mask ;
2010-11-29 13:07:20 +03:00
mask = 1 < < d - > irq ;
2005-04-17 02:20:36 +04:00
val = iomd_readb ( IOMD_IRQMASKA ) ;
iomd_writeb ( val | mask , IOMD_IRQMASKA ) ;
}
2006-11-23 14:41:32 +03:00
static struct irq_chip iomd_a_chip = {
2010-11-29 13:07:20 +03:00
. irq_ack = iomd_ack_irq_a ,
. irq_mask = iomd_mask_irq_a ,
. irq_unmask = iomd_unmask_irq_a ,
2005-04-17 02:20:36 +04:00
} ;
2010-11-29 13:07:20 +03:00
static void iomd_mask_irq_b ( struct irq_data * d )
2005-04-17 02:20:36 +04:00
{
unsigned int val , mask ;
2010-11-29 13:07:20 +03:00
mask = 1 < < ( d - > irq & 7 ) ;
2005-04-17 02:20:36 +04:00
val = iomd_readb ( IOMD_IRQMASKB ) ;
iomd_writeb ( val & ~ mask , IOMD_IRQMASKB ) ;
}
2010-11-29 13:07:20 +03:00
static void iomd_unmask_irq_b ( struct irq_data * d )
2005-04-17 02:20:36 +04:00
{
unsigned int val , mask ;
2010-11-29 13:07:20 +03:00
mask = 1 < < ( d - > irq & 7 ) ;
2005-04-17 02:20:36 +04:00
val = iomd_readb ( IOMD_IRQMASKB ) ;
iomd_writeb ( val | mask , IOMD_IRQMASKB ) ;
}
2006-11-23 14:41:32 +03:00
static struct irq_chip iomd_b_chip = {
2010-11-29 13:07:20 +03:00
. irq_ack = iomd_mask_irq_b ,
. irq_mask = iomd_mask_irq_b ,
. irq_unmask = iomd_unmask_irq_b ,
2005-04-17 02:20:36 +04:00
} ;
2010-11-29 13:07:20 +03:00
static void iomd_mask_irq_dma ( struct irq_data * d )
2005-04-17 02:20:36 +04:00
{
unsigned int val , mask ;
2010-11-29 13:07:20 +03:00
mask = 1 < < ( d - > irq & 7 ) ;
2005-04-17 02:20:36 +04:00
val = iomd_readb ( IOMD_DMAMASK ) ;
iomd_writeb ( val & ~ mask , IOMD_DMAMASK ) ;
}
2010-11-29 13:07:20 +03:00
static void iomd_unmask_irq_dma ( struct irq_data * d )
2005-04-17 02:20:36 +04:00
{
unsigned int val , mask ;
2010-11-29 13:07:20 +03:00
mask = 1 < < ( d - > irq & 7 ) ;
2005-04-17 02:20:36 +04:00
val = iomd_readb ( IOMD_DMAMASK ) ;
iomd_writeb ( val | mask , IOMD_DMAMASK ) ;
}
2006-11-23 14:41:32 +03:00
static struct irq_chip iomd_dma_chip = {
2010-11-29 13:07:20 +03:00
. irq_ack = iomd_mask_irq_dma ,
. irq_mask = iomd_mask_irq_dma ,
. irq_unmask = iomd_unmask_irq_dma ,
2005-04-17 02:20:36 +04:00
} ;
2010-11-29 13:07:20 +03:00
static void iomd_mask_irq_fiq ( struct irq_data * d )
2005-04-17 02:20:36 +04:00
{
unsigned int val , mask ;
2010-11-29 13:07:20 +03:00
mask = 1 < < ( d - > irq & 7 ) ;
2005-04-17 02:20:36 +04:00
val = iomd_readb ( IOMD_FIQMASK ) ;
iomd_writeb ( val & ~ mask , IOMD_FIQMASK ) ;
}
2010-11-29 13:07:20 +03:00
static void iomd_unmask_irq_fiq ( struct irq_data * d )
2005-04-17 02:20:36 +04:00
{
unsigned int val , mask ;
2010-11-29 13:07:20 +03:00
mask = 1 < < ( d - > irq & 7 ) ;
2005-04-17 02:20:36 +04:00
val = iomd_readb ( IOMD_FIQMASK ) ;
iomd_writeb ( val | mask , IOMD_FIQMASK ) ;
}
2006-11-23 14:41:32 +03:00
static struct irq_chip iomd_fiq_chip = {
2010-11-29 13:07:20 +03:00
. irq_ack = iomd_mask_irq_fiq ,
. irq_mask = iomd_mask_irq_fiq ,
. irq_unmask = iomd_unmask_irq_fiq ,
2005-04-17 02:20:36 +04:00
} ;
2012-02-09 04:24:23 +04:00
extern unsigned char rpc_default_fiq_start , rpc_default_fiq_end ;
2005-04-17 02:20:36 +04:00
void __init rpc_init_irq ( void )
{
unsigned int irq , flags ;
iomd_writeb ( 0 , IOMD_IRQMASKA ) ;
iomd_writeb ( 0 , IOMD_IRQMASKB ) ;
iomd_writeb ( 0 , IOMD_FIQMASK ) ;
iomd_writeb ( 0 , IOMD_DMAMASK ) ;
2012-02-09 04:24:23 +04:00
set_fiq_handler ( & rpc_default_fiq_start ,
& rpc_default_fiq_end - & rpc_default_fiq_start ) ;
2005-04-17 02:20:36 +04:00
for ( irq = 0 ; irq < NR_IRQS ; irq + + ) {
flags = IRQF_VALID ;
if ( irq < = 6 | | ( irq > = 9 & & irq < = 15 ) )
flags | = IRQF_PROBE ;
if ( irq = = 21 | | ( irq > = 16 & & irq < = 19 ) | |
irq = = IRQ_KEYBOARDTX )
flags | = IRQF_NOAUTOEN ;
switch ( irq ) {
case 0 . . . 7 :
2011-03-24 15:35:09 +03:00
irq_set_chip_and_handler ( irq , & iomd_a_chip ,
handle_level_irq ) ;
2005-04-17 02:20:36 +04:00
set_irq_flags ( irq , flags ) ;
break ;
case 8 . . . 15 :
2011-03-24 15:35:09 +03:00
irq_set_chip_and_handler ( irq , & iomd_b_chip ,
handle_level_irq ) ;
2005-04-17 02:20:36 +04:00
set_irq_flags ( irq , flags ) ;
break ;
case 16 . . . 21 :
2011-03-24 15:35:09 +03:00
irq_set_chip_and_handler ( irq , & iomd_dma_chip ,
handle_level_irq ) ;
2005-04-17 02:20:36 +04:00
set_irq_flags ( irq , flags ) ;
break ;
case 64 . . . 71 :
2011-03-24 15:25:22 +03:00
irq_set_chip ( irq , & iomd_fiq_chip ) ;
2005-04-17 02:20:36 +04:00
set_irq_flags ( irq , IRQF_VALID ) ;
break ;
}
}
2012-06-28 10:42:08 +04:00
init_FIQ ( FIQ_START ) ;
2005-04-17 02:20:36 +04:00
}