2005-04-16 15:20:36 -07:00
/*
2006-09-18 23:26:25 +01:00
* arch / arm / mach - iop33x / irq . c
2005-04-16 15:20:36 -07:00
*
* Generic IOP331 IRQ handling functionality
*
* Author : Dave Jiang < dave . jiang @ intel . com >
* Copyright ( C ) 2003 Intel Corp .
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
2006-09-18 23:26:25 +01:00
2005-04-16 15:20:36 -07:00
# include <linux/init.h>
# include <linux/interrupt.h>
# include <linux/list.h>
# include <asm/mach/irq.h>
# include <asm/irq.h>
# include <asm/hardware.h>
# include <asm/mach-types.h>
2006-09-18 23:26:25 +01:00
static u32 iop33x_mask0 ;
static u32 iop33x_mask1 ;
2005-04-16 15:20:36 -07:00
2006-09-18 23:26:25 +01:00
static inline void intctl0_write ( u32 val )
2005-04-16 15:20:36 -07:00
{
2006-09-18 23:21:38 +01:00
iop3xx_cp6_enable ( ) ;
2006-09-18 23:26:25 +01:00
asm volatile ( " mcr p6, 0, %0, c0, c0, 0 " : : " r " ( val ) ) ;
2006-09-18 23:21:38 +01:00
iop3xx_cp6_disable ( ) ;
2005-04-16 15:20:36 -07:00
}
2006-09-18 23:26:25 +01:00
static inline void intctl1_write ( u32 val )
2005-04-16 15:20:36 -07:00
{
2006-09-18 23:21:38 +01:00
iop3xx_cp6_enable ( ) ;
2006-09-18 23:26:25 +01:00
asm volatile ( " mcr p6, 0, %0, c1, c0, 0 " : : " r " ( val ) ) ;
2006-09-18 23:21:38 +01:00
iop3xx_cp6_disable ( ) ;
2005-04-16 15:20:36 -07:00
}
2006-09-18 23:26:25 +01:00
static inline void intstr0_write ( u32 val )
2005-04-16 15:20:36 -07:00
{
2006-09-18 23:21:38 +01:00
iop3xx_cp6_enable ( ) ;
2006-09-18 23:26:25 +01:00
asm volatile ( " mcr p6, 0, %0, c2, c0, 0 " : : " r " ( val ) ) ;
2006-09-18 23:21:38 +01:00
iop3xx_cp6_disable ( ) ;
2005-04-16 15:20:36 -07:00
}
2006-09-18 23:26:25 +01:00
static inline void intstr1_write ( u32 val )
2005-04-16 15:20:36 -07:00
{
2006-09-18 23:21:38 +01:00
iop3xx_cp6_enable ( ) ;
2006-09-18 23:26:25 +01:00
asm volatile ( " mcr p6, 0, %0, c3, c0, 0 " : : " r " ( val ) ) ;
2006-09-18 23:21:38 +01:00
iop3xx_cp6_disable ( ) ;
2005-04-16 15:20:36 -07:00
}
2006-09-18 23:24:10 +01:00
static inline void intbase_write ( u32 val )
{
iop3xx_cp6_enable ( ) ;
asm volatile ( " mcr p6, 0, %0, c12, c0, 0 " : : " r " ( val ) ) ;
iop3xx_cp6_disable ( ) ;
}
static inline void intsize_write ( u32 val )
{
iop3xx_cp6_enable ( ) ;
asm volatile ( " mcr p6, 0, %0, c13, c0, 0 " : : " r " ( val ) ) ;
iop3xx_cp6_disable ( ) ;
}
2005-04-16 15:20:36 -07:00
static void
2006-09-18 23:26:25 +01:00
iop33x_irq_mask1 ( unsigned int irq )
2005-04-16 15:20:36 -07:00
{
2006-09-18 23:26:25 +01:00
iop33x_mask0 & = ~ ( 1 < < irq ) ;
intctl0_write ( iop33x_mask0 ) ;
2005-04-16 15:20:36 -07:00
}
static void
2006-09-18 23:26:25 +01:00
iop33x_irq_mask2 ( unsigned int irq )
2005-04-16 15:20:36 -07:00
{
2006-09-18 23:26:25 +01:00
iop33x_mask1 & = ~ ( 1 < < ( irq - 32 ) ) ;
intctl1_write ( iop33x_mask1 ) ;
2005-04-16 15:20:36 -07:00
}
static void
2006-09-18 23:26:25 +01:00
iop33x_irq_unmask1 ( unsigned int irq )
2005-04-16 15:20:36 -07:00
{
2006-09-18 23:26:25 +01:00
iop33x_mask0 | = 1 < < irq ;
intctl0_write ( iop33x_mask0 ) ;
2005-04-16 15:20:36 -07:00
}
static void
2006-09-18 23:26:25 +01:00
iop33x_irq_unmask2 ( unsigned int irq )
2005-04-16 15:20:36 -07:00
{
2006-09-18 23:26:25 +01:00
iop33x_mask1 | = ( 1 < < ( irq - 32 ) ) ;
intctl1_write ( iop33x_mask1 ) ;
2005-04-16 15:20:36 -07:00
}
2006-09-18 23:26:25 +01:00
struct irq_chip iop33x_irqchip1 = {
. name = " IOP33x-1 " ,
. ack = iop33x_irq_mask1 ,
. mask = iop33x_irq_mask1 ,
. unmask = iop33x_irq_unmask1 ,
2005-04-16 15:20:36 -07:00
} ;
2006-09-18 23:26:25 +01:00
struct irq_chip iop33x_irqchip2 = {
. name = " IOP33x-2 " ,
. ack = iop33x_irq_mask2 ,
. mask = iop33x_irq_mask2 ,
. unmask = iop33x_irq_unmask2 ,
2005-04-16 15:20:36 -07:00
} ;
2006-09-18 23:26:25 +01:00
void __init iop33x_init_irq ( void )
2005-04-16 15:20:36 -07:00
{
2006-09-18 23:26:25 +01:00
int i ;
2005-04-16 15:20:36 -07:00
2006-09-18 23:26:25 +01:00
intctl0_write ( 0 ) ;
intctl1_write ( 0 ) ;
intstr0_write ( 0 ) ;
intstr1_write ( 0 ) ;
2006-09-18 23:24:10 +01:00
intbase_write ( 0 ) ;
intsize_write ( 1 ) ;
2006-09-18 23:26:25 +01:00
if ( machine_is_iq80331 ( ) )
2006-09-18 23:17:36 +01:00
* IOP3XX_PCIIRSR = 0x0f ;
2005-04-16 15:20:36 -07:00
2006-09-18 23:26:25 +01:00
for ( i = 0 ; i < NR_IRQS ; i + + ) {
set_irq_chip ( i , ( i < 32 ) ? & iop33x_irqchip1 : & iop33x_irqchip2 ) ;
2005-04-16 15:20:36 -07:00
set_irq_handler ( i , do_level_IRQ ) ;
set_irq_flags ( i , IRQF_VALID | IRQF_PROBE ) ;
}
}