2005-04-17 02:20:36 +04:00
/*
2006-09-19 02:26:25 +04:00
* arch / arm / mach - iop33x / irq . c
2005-04-17 02:20:36 +04: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-19 02:26:25 +04:00
2005-04-17 02:20:36 +04:00
# include <linux/init.h>
# include <linux/interrupt.h>
# include <linux/list.h>
# include <asm/mach/irq.h>
# include <asm/irq.h>
2008-08-05 19:14:15 +04:00
# include <mach/hardware.h>
2005-04-17 02:20:36 +04:00
# include <asm/mach-types.h>
2006-09-19 02:26:25 +04:00
static u32 iop33x_mask0 ;
static u32 iop33x_mask1 ;
2005-04-17 02:20:36 +04:00
2007-05-15 04:03:36 +04:00
static void intctl0_write ( u32 val )
2005-04-17 02:20:36 +04:00
{
2006-09-19 02:26:25 +04:00
asm volatile ( " mcr p6, 0, %0, c0, c0, 0 " : : " r " ( val ) ) ;
2005-04-17 02:20:36 +04:00
}
2007-05-15 04:03:36 +04:00
static void intctl1_write ( u32 val )
2005-04-17 02:20:36 +04:00
{
2006-09-19 02:26:25 +04:00
asm volatile ( " mcr p6, 0, %0, c1, c0, 0 " : : " r " ( val ) ) ;
2005-04-17 02:20:36 +04:00
}
2007-05-15 04:03:36 +04:00
static void intstr0_write ( u32 val )
2005-04-17 02:20:36 +04:00
{
2006-09-19 02:26:25 +04:00
asm volatile ( " mcr p6, 0, %0, c2, c0, 0 " : : " r " ( val ) ) ;
2005-04-17 02:20:36 +04:00
}
2007-05-15 04:03:36 +04:00
static void intstr1_write ( u32 val )
2005-04-17 02:20:36 +04:00
{
2006-09-19 02:26:25 +04:00
asm volatile ( " mcr p6, 0, %0, c3, c0, 0 " : : " r " ( val ) ) ;
2005-04-17 02:20:36 +04:00
}
2007-05-15 04:03:36 +04:00
static void intbase_write ( u32 val )
2006-09-19 02:24:10 +04:00
{
asm volatile ( " mcr p6, 0, %0, c12, c0, 0 " : : " r " ( val ) ) ;
}
2007-05-15 04:03:36 +04:00
static void intsize_write ( u32 val )
2006-09-19 02:24:10 +04:00
{
asm volatile ( " mcr p6, 0, %0, c13, c0, 0 " : : " r " ( val ) ) ;
}
2005-04-17 02:20:36 +04:00
static void
2010-11-29 12:32:37 +03:00
iop33x_irq_mask1 ( struct irq_data * d )
2005-04-17 02:20:36 +04:00
{
2010-11-29 12:32:37 +03:00
iop33x_mask0 & = ~ ( 1 < < d - > irq ) ;
2006-09-19 02:26:25 +04:00
intctl0_write ( iop33x_mask0 ) ;
2005-04-17 02:20:36 +04:00
}
static void
2010-11-29 12:32:37 +03:00
iop33x_irq_mask2 ( struct irq_data * d )
2005-04-17 02:20:36 +04:00
{
2010-11-29 12:32:37 +03:00
iop33x_mask1 & = ~ ( 1 < < ( d - > irq - 32 ) ) ;
2006-09-19 02:26:25 +04:00
intctl1_write ( iop33x_mask1 ) ;
2005-04-17 02:20:36 +04:00
}
static void
2010-11-29 12:32:37 +03:00
iop33x_irq_unmask1 ( struct irq_data * d )
2005-04-17 02:20:36 +04:00
{
2010-11-29 12:32:37 +03:00
iop33x_mask0 | = 1 < < d - > irq ;
2006-09-19 02:26:25 +04:00
intctl0_write ( iop33x_mask0 ) ;
2005-04-17 02:20:36 +04:00
}
static void
2010-11-29 12:32:37 +03:00
iop33x_irq_unmask2 ( struct irq_data * d )
2005-04-17 02:20:36 +04:00
{
2010-11-29 12:32:37 +03:00
iop33x_mask1 | = ( 1 < < ( d - > irq - 32 ) ) ;
2006-09-19 02:26:25 +04:00
intctl1_write ( iop33x_mask1 ) ;
2005-04-17 02:20:36 +04:00
}
2006-09-19 02:26:25 +04:00
struct irq_chip iop33x_irqchip1 = {
2010-11-29 12:32:37 +03:00
. name = " IOP33x-1 " ,
. irq_ack = iop33x_irq_mask1 ,
. irq_mask = iop33x_irq_mask1 ,
. irq_unmask = iop33x_irq_unmask1 ,
2005-04-17 02:20:36 +04:00
} ;
2006-09-19 02:26:25 +04:00
struct irq_chip iop33x_irqchip2 = {
2010-11-29 12:32:37 +03:00
. name = " IOP33x-2 " ,
. irq_ack = iop33x_irq_mask2 ,
. irq_mask = iop33x_irq_mask2 ,
. irq_unmask = iop33x_irq_unmask2 ,
2005-04-17 02:20:36 +04:00
} ;
2006-09-19 02:26:25 +04:00
void __init iop33x_init_irq ( void )
2005-04-17 02:20:36 +04:00
{
2006-09-19 02:26:25 +04:00
int i ;
2005-04-17 02:20:36 +04:00
2007-02-13 19:12:04 +03:00
iop_init_cp6_handler ( ) ;
2006-09-19 02:26:25 +04:00
intctl0_write ( 0 ) ;
intctl1_write ( 0 ) ;
intstr0_write ( 0 ) ;
intstr1_write ( 0 ) ;
2006-09-19 02:24:10 +04:00
intbase_write ( 0 ) ;
intsize_write ( 1 ) ;
2006-09-19 02:26:25 +04:00
if ( machine_is_iq80331 ( ) )
2006-09-19 02:17:36 +04:00
* IOP3XX_PCIIRSR = 0x0f ;
2005-04-17 02:20:36 +04:00
2006-09-19 02:26:25 +04:00
for ( i = 0 ; i < NR_IRQS ; i + + ) {
2011-03-24 15:35:09 +03:00
irq_set_chip_and_handler ( i ,
( i < 32 ) ? & iop33x_irqchip1 : & iop33x_irqchip2 ,
handle_level_irq ) ;
2005-04-17 02:20:36 +04:00
set_irq_flags ( i , IRQF_VALID | IRQF_PROBE ) ;
}
}