rewrite of the amazon irq code

SVN-Revision: 8333
This commit is contained in:
John Crispin 2007-08-04 01:37:23 +00:00
parent 1152f2f11f
commit 17cd570979
2 changed files with 106 additions and 219 deletions

View File

@ -1,6 +1,7 @@
/* /*
* Gary Jennejohn (C) 2003 <gj@denx.de> * Gary Jennejohn (C) 2003 <gj@denx.de>
* Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org> * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2007 John Crispin <blogic@openwrt.org>
* *
* This program is free software; you can distribute it and/or modify it * This program is free software; you can distribute it and/or modify it
* under the terms of the GNU General Public License (Version 2) as * under the terms of the GNU General Public License (Version 2) as
@ -35,77 +36,64 @@
static void amazon_disable_irq(unsigned int irq_nr) static void amazon_disable_irq(unsigned int irq_nr)
{ {
/* have to access the correct register here */ int i;
u32 amazon_ier = AMAZON_ICU_IM0_IER;
if (irq_nr <= INT_NUM_IM0_IRL11 && irq_nr >= INT_NUM_IM0_IRL0) if (irq_nr <= INT_NUM_IM0_IRL11 && irq_nr >= INT_NUM_IM0_IRL0)
/* access IM0 DMA channels */ amazon_writel(amazon_readl(amazon_ier) & (~(AMAZON_DMA_H_MASK)), amazon_ier);
*AMAZON_ICU_IM0_IER &= (~(AMAZON_DMA_H_MASK)); else {
else if (irq_nr <= INT_NUM_IM0_IRL31 && irq_nr >= INT_NUM_IM0_IRL12) irq_nr -= INT_NUM_IRQ0;
/* access IM0 except DMA*/ for (i = 0; i <= 4; i++)
*AMAZON_ICU_IM0_IER &= (~AMAZON_ICU_IM0_IER_IR(irq_nr)); {
else if (irq_nr <= INT_NUM_IM1_IRL31 && irq_nr >= INT_NUM_IM1_IRL0) if (irq_nr <= 31)
/* access IM1 */ amazon_writel(amazon_readl(amazon_ier) & ~(1 << irq_nr ), amazon_ier);
*AMAZON_ICU_IM1_IER &= (~AMAZON_ICU_IM1_IER_IR(irq_nr - INT_NUM_IM1_IRL0)); amazon_ier += 0x10;
else if (irq_nr <= INT_NUM_IM2_IRL31 && irq_nr >= INT_NUM_IM2_IRL0) irq_nr -= 32;
/* access IM2 */ }
*AMAZON_ICU_IM2_IER &= (~AMAZON_ICU_IM2_IER_IR(irq_nr - INT_NUM_IM2_IRL0)); }
else if (irq_nr <= INT_NUM_IM3_IRL31 && irq_nr >= INT_NUM_IM3_IRL0)
/* access IM3 */
*AMAZON_ICU_IM3_IER &= (~AMAZON_ICU_IM3_IER_IR((irq_nr - INT_NUM_IM3_IRL0)));
else if (irq_nr <= INT_NUM_IM4_IRL31 && irq_nr >= INT_NUM_IM4_IRL0)
/* access IM4 */
*AMAZON_ICU_IM4_IER &= (~AMAZON_ICU_IM4_IER_IR((irq_nr - INT_NUM_IM4_IRL0)));
} }
static void amazon_mask_and_ack_irq(unsigned int irq_nr) static void amazon_mask_and_ack_irq(unsigned int irq_nr)
{ {
/* have to access the correct register here */ int i;
if (irq_nr <= INT_NUM_IM0_IRL11 && irq_nr >= INT_NUM_IM0_IRL0) { u32 amazon_ier = AMAZON_ICU_IM0_IER;
/* access IM0 DMA channels */ u32 amazon_isr = AMAZON_ICU_IM0_ISR;
*AMAZON_ICU_IM0_IER &= (~(AMAZON_DMA_H_MASK)); /* mask */
*AMAZON_ICU_IM0_ISR = AMAZON_DMA_H_MASK; /* ack */ if (irq_nr <= INT_NUM_IM0_IRL11 && irq_nr >= INT_NUM_IM0_IRL0){
} else if (irq_nr <= INT_NUM_IM0_IRL31 && irq_nr >= INT_NUM_IM0_IRL12) { amazon_writel(amazon_readl(amazon_ier) & (~(AMAZON_DMA_H_MASK)), amazon_ier);
/* access IM0 except DMA */ amazon_writel(AMAZON_DMA_H_MASK, amazon_isr);
*AMAZON_ICU_IM0_IER &= ~AMAZON_ICU_IM0_IER_IR(irq_nr - INT_NUM_IM0_IRL0); /* mask */ } else {
*AMAZON_ICU_IM0_ISR = AMAZON_ICU_IM0_ISR_IR(irq_nr - INT_NUM_IM0_IRL0); /* ack */ irq_nr -= INT_NUM_IRQ0;
} else if (irq_nr <= INT_NUM_IM1_IRL31 && irq_nr >= INT_NUM_IM1_IRL0) { for (i = 0; i <= 4; i++)
/* access IM1 */ {
*AMAZON_ICU_IM1_IER &= ~AMAZON_ICU_IM1_IER_IR(irq_nr - INT_NUM_IM1_IRL0); /* mask */ if (irq_nr <= 31){
*AMAZON_ICU_IM1_ISR = AMAZON_ICU_IM1_ISR_IR(irq_nr - INT_NUM_IM1_IRL0); /* ack */ amazon_writel(amazon_readl(amazon_ier) & ~(1 << irq_nr ), amazon_ier);
} else if (irq_nr <= INT_NUM_IM2_IRL31 && irq_nr >= INT_NUM_IM2_IRL0) { amazon_writel((1 << irq_nr ), amazon_isr);
/* access IM2 */ }
*AMAZON_ICU_IM2_IER &= ~AMAZON_ICU_IM2_IER_IR(irq_nr - INT_NUM_IM2_IRL0); /* mask */ amazon_ier += 0x10;
*AMAZON_ICU_IM2_ISR = AMAZON_ICU_IM2_ISR_IR(irq_nr - INT_NUM_IM2_IRL0); /* ack */ amazon_isr += 0x10;
} else if (irq_nr <= INT_NUM_IM3_IRL31 && irq_nr >= INT_NUM_IM3_IRL0) { irq_nr -= 32;
/* access IM3 */ }
*AMAZON_ICU_IM3_IER &= ~AMAZON_ICU_IM3_IER_IR(irq_nr - INT_NUM_IM3_IRL0); /* mask */
*AMAZON_ICU_IM3_ISR = AMAZON_ICU_IM3_ISR_IR(irq_nr - INT_NUM_IM3_IRL0); /* ack */
} else if (irq_nr <= INT_NUM_IM4_IRL31 && irq_nr >= INT_NUM_IM4_IRL0) {
*AMAZON_ICU_IM4_IER &= ~AMAZON_ICU_IM4_IER_IR(irq_nr - INT_NUM_IM4_IRL0); /* mask */
*AMAZON_ICU_IM4_ISR = AMAZON_ICU_IM4_ISR_IR(irq_nr - INT_NUM_IM4_IRL0); /* ack */
} }
} }
static void amazon_enable_irq(unsigned int irq_nr) static void amazon_enable_irq(unsigned int irq_nr)
{ {
/* have to access the correct register here */ int i;
u32 amazon_ier = AMAZON_ICU_IM0_IER;
if (irq_nr <= INT_NUM_IM0_IRL11 && irq_nr >= INT_NUM_IM0_IRL0) if (irq_nr <= INT_NUM_IM0_IRL11 && irq_nr >= INT_NUM_IM0_IRL0)
/* access IM0 DMA*/ amazon_writel(amazon_readl(amazon_ier) | AMAZON_DMA_H_MASK, amazon_ier);
*AMAZON_ICU_IM0_IER |= AMAZON_DMA_H_MASK; else {
else if (irq_nr <= INT_NUM_IM0_IRL31 && irq_nr >= INT_NUM_IM0_IRL12) irq_nr -= INT_NUM_IRQ0;
/* access IM0 except DMA*/ for (i = 0; i <= 4; i++)
*AMAZON_ICU_IM0_IER |= AMAZON_ICU_IM0_IER_IR(irq_nr - INT_NUM_IM0_IRL0); {
else if (irq_nr <= INT_NUM_IM1_IRL31 && irq_nr >= INT_NUM_IM1_IRL0) if (irq_nr <= 31)
/* access IM1 */ amazon_writel(amazon_readl(amazon_ier) | (1 << irq_nr ), amazon_ier);
*AMAZON_ICU_IM1_IER |= AMAZON_ICU_IM1_IER_IR(irq_nr - INT_NUM_IM1_IRL0); amazon_ier += 0x10;
else if (irq_nr <= INT_NUM_IM2_IRL31 && irq_nr >= INT_NUM_IM2_IRL0) irq_nr -= 32;
/* access IM2 */ }
*AMAZON_ICU_IM2_IER |= AMAZON_ICU_IM2_IER_IR(irq_nr - INT_NUM_IM2_IRL0); }
else if (irq_nr <= INT_NUM_IM3_IRL31 && irq_nr >= INT_NUM_IM3_IRL0)
/* access IM3 */
*AMAZON_ICU_IM3_IER |= AMAZON_ICU_IM3_IER_IR((irq_nr - INT_NUM_IM3_IRL0));
else if (irq_nr <= INT_NUM_IM4_IRL31 && irq_nr >= INT_NUM_IM4_IRL0)
/* access IM4 */
*AMAZON_ICU_IM4_IER |= AMAZON_ICU_IM4_IER_IR((irq_nr - INT_NUM_IM4_IRL0));
} }
static unsigned int amazon_startup_irq(unsigned int irq) static unsigned int amazon_startup_irq(unsigned int irq)
@ -133,53 +121,17 @@ static struct hw_interrupt_type amazon_irq_type = {
.end = amazon_end_irq .end = amazon_end_irq
}; };
/* Cascaded interrupts from IM0 */ /* Cascaded interrupts from IM0-4 */
static inline void amazon_hw0_irqdispatch(void) static inline void amazon_hw_irqdispatch(u8 line)
{ {
u32 irq; u32 irq;
irq = (*AMAZON_ICU_IM_VEC) & AMAZON_ICU_IM0_VEC_MASK; irq = (amazon_readl(AMAZON_ICU_IM_VEC) >> (line * 5)) & AMAZON_ICU_IM0_VEC_MASK;
if (irq <= 11 && irq >= 0) { if (line == 0 && irq <= 11 && irq >= 0) {
//DMA fixed to IM0_IRL0 //DMA fixed to IM0_IRL0
irq = 0; irq = 0;
} }
do_IRQ(irq + INT_NUM_IM0_IRL0); do_IRQ(irq + INT_NUM_IRQ0 + (line * 32));
}
/* Cascaded interrupts from IM1 */
static inline void amazon_hw1_irqdispatch(void)
{
u32 irq;
irq = ((*AMAZON_ICU_IM_VEC) & AMAZON_ICU_IM1_VEC_MASK) >> 5;
do_IRQ(irq + INT_NUM_IM1_IRL0);
}
/* Cascaded interrupts from IM2 */
static inline void amazon_hw2_irqdispatch(void)
{
u32 irq;
irq = ((*AMAZON_ICU_IM_VEC) & AMAZON_ICU_IM2_VEC_MASK) >> 10;
do_IRQ(irq + INT_NUM_IM2_IRL0);
}
/* Cascaded interrupts from IM3 */
static inline void amazon_hw3_irqdispatch(void)
{
u32 irq;
irq = ((*AMAZON_ICU_IM_VEC) & AMAZON_ICU_IM3_VEC_MASK) >> 15;
do_IRQ(irq + INT_NUM_IM3_IRL0);
}
/* Cascaded interrupts from IM4 */
static inline void amazon_hw4_irqdispatch(void)
{
u32 irq;
irq = ((*AMAZON_ICU_IM_VEC) & AMAZON_ICU_IM4_VEC_MASK) >> 20;
do_IRQ(irq + INT_NUM_IM4_IRL0);
} }
asmlinkage void plat_irq_dispatch(void) asmlinkage void plat_irq_dispatch(void)
@ -187,19 +139,20 @@ asmlinkage void plat_irq_dispatch(void)
unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
if (pending & CAUSEF_IP7){ if (pending & CAUSEF_IP7){
do_IRQ(MIPS_CPU_TIMER_IRQ); do_IRQ(MIPS_CPU_TIMER_IRQ);
goto out;
} else {
unsigned int i;
for (i = 0; i <= 4; i++)
{
if(pending & (CAUSEF_IP2 << i)){
amazon_hw_irqdispatch(i);
goto out;
}
}
} }
else if (pending & CAUSEF_IP2) printk("Spurious IRQ: CAUSE=0x%08x\n", read_c0_status());
amazon_hw0_irqdispatch(); out:
else if (pending & CAUSEF_IP3) return;
amazon_hw1_irqdispatch();
else if (pending & CAUSEF_IP4)
amazon_hw2_irqdispatch();
else if (pending & CAUSEF_IP5)
amazon_hw3_irqdispatch();
else if (pending & CAUSEF_IP6)
amazon_hw4_irqdispatch();
else
printk("Spurious IRQ: CAUSE=0x%08x\n", read_c0_status());
} }
static struct irqaction cascade = { static struct irqaction cascade = {
@ -208,19 +161,14 @@ static struct irqaction cascade = {
.name = "cascade", .name = "cascade",
}; };
/* Function for careful CP0 interrupt mask access */
void __init arch_init_irq(void) void __init arch_init_irq(void)
{ {
int i; int i;
/* mask all interrupt sources */ /* mask all interrupt sources */
*AMAZON_ICU_IM0_IER = 0; for(i = 0; i <= 4; i++){
*AMAZON_ICU_IM1_IER = 0; amazon_writel(0, AMAZON_ICU_IM0_IER + (i * 0x10));
*AMAZON_ICU_IM2_IER = 0; }
*AMAZON_ICU_IM3_IER = 0;
*AMAZON_ICU_IM4_IER = 0;
mips_cpu_irq_init(); mips_cpu_irq_init();

View File

@ -24,7 +24,10 @@
the program to operate with any other programs), even if such holder or the program to operate with any other programs), even if such holder or
other party has been advised of the possibility of such damages. other party has been advised of the possibility of such damages.
******************************************************************************/ ******************************************************************************/
#define amazon_readl(a) readl(((u32*)(a)))
#define amazon_writel(a,b) writel(a, ((u32*)(b)))
/* check ADSL link status */ /* check ADSL link status */
#define AMAZON_CHECK_LINK #define AMAZON_CHECK_LINK
@ -962,119 +965,55 @@ If set and clear bit are written concurrently with 1, the associated bit is not
/* Module : ICU register address and bits */ /* Module : ICU register address and bits */
/***********************************************************************/ /***********************************************************************/
#define AMAZON_ICU (KSEG1+0x1F101000) #define AMAZON_ICU (KSEG1+0x1F101000)
/***********************************************************************/ /***********************************************************************/
/***IM0 Interrupt Status Register***/ /***IM0 Interrupt Status Register***/
#define AMAZON_ICU_IM0_ISR ((volatile u32*)(AMAZON_ICU+ 0x0010)) #define AMAZON_ICU_IM0_ISR (AMAZON_ICU + 0x0010)
#define AMAZON_ICU_IM0_ISR_IR(value) (1 << (value)) #define AMAZON_ICU_IM1_ISR (AMAZON_ICU + 0x0020)
#define AMAZON_ICU_IM2_ISR (AMAZON_ICU + 0x0030)
#define AMAZON_ICU_IM3_ISR (AMAZON_ICU + 0x0040)
/***IM1 Interrupt Status Register***/ #define AMAZON_ICU_IM4_ISR (AMAZON_ICU + 0x0050)
#define AMAZON_ICU_IM1_ISR ((volatile u32*)(AMAZON_ICU+ 0x0020))
#define AMAZON_ICU_IM1_ISR_IR(value) (1 << (value))
/***IM2 Interrupt Status Register***/
#define AMAZON_ICU_IM2_ISR ((volatile u32*)(AMAZON_ICU+ 0x0030))
#define AMAZON_ICU_IM2_ISR_IR(value) (1 << (value))
/***IM3 Interrupt Status Register***/
#define AMAZON_ICU_IM3_ISR ((volatile u32*)(AMAZON_ICU+ 0x0040))
#define AMAZON_ICU_IM3_ISR_IR(value) (1 << (value))
/***IM4 Interrupt Status Register***/
#define AMAZON_ICU_IM4_ISR ((volatile u32*)(AMAZON_ICU+ 0x0050))
#define AMAZON_ICU_IM4_ISR_IR(value) (1 << (value))
/***IM0 Interrupt Enable Register***/ /***IM0 Interrupt Enable Register***/
#define AMAZON_ICU_IM0_IER ((volatile u32*)(AMAZON_ICU+ 0x0014)) #define AMAZON_ICU_IM0_IER (AMAZON_ICU + 0x0014)
#define AMAZON_ICU_IM0_IER_IR(value) (1 << (value)) #define AMAZON_ICU_IM1_IER (AMAZON_ICU + 0x0024)
#define AMAZON_ICU_IM2_IER (AMAZON_ICU + 0x0034)
#define AMAZON_ICU_IM3_IER (AMAZON_ICU + 0x0044)
/***IM1 Interrupt Enable Register***/ #define AMAZON_ICU_IM4_IER (AMAZON_ICU + 0x0054)
#define AMAZON_ICU_IM1_IER ((volatile u32*)(AMAZON_ICU+ 0x0024))
#define AMAZON_ICU_IM1_IER_IR(value) (1 << (value))
/***IM2 Interrupt Enable Register***/
#define AMAZON_ICU_IM2_IER ((volatile u32*)(AMAZON_ICU+ 0x0034))
#define AMAZON_ICU_IM2_IER_IR(value) (1 << (value))
/***IM3 Interrupt Enable Register***/
#define AMAZON_ICU_IM3_IER ((volatile u32*)(AMAZON_ICU+ 0x0044))
#define AMAZON_ICU_IM3_IER_IR(value) (1 << (value))
/***IM4 Interrupt Enable Register***/
#define AMAZON_ICU_IM4_IER ((volatile u32*)(AMAZON_ICU+ 0x0054))
#define AMAZON_ICU_IM4_IER_IR(value) (1 << (value))
/***IM0 Interrupt Output Status Register***/ /***IM0 Interrupt Output Status Register***/
#define AMAZON_ICU_IM0_IOSR ((volatile u32*)(AMAZON_ICU+ 0x0018)) #define AMAZON_ICU_IM0_IOSR (AMAZON_ICU + 0x0018)
#define AMAZON_ICU_IM0_IOSR_IR(value) (1 << (value)) #define AMAZON_ICU_IM1_IOSR (AMAZON_ICU + 0x0028)
#define AMAZON_ICU_IM2_IOSR (AMAZON_ICU + 0x0038)
#define AMAZON_ICU_IM3_IOSR (AMAZON_ICU + 0x0048)
/***IM1 Interrupt Output Status Register***/ #define AMAZON_ICU_IM4_IOSR (AMAZON_ICU + 0x0058)
#define AMAZON_ICU_IM1_IOSR ((volatile u32*)(AMAZON_ICU+ 0x0028))
#define AMAZON_ICU_IM1_IOSR_IR(value) (1 << (value))
/***IM2 Interrupt Output Status Register***/
#define AMAZON_ICU_IM2_IOSR ((volatile u32*)(AMAZON_ICU+ 0x0038))
#define AMAZON_ICU_IM2_IOSR_IR(value) (1 << (value))
/***IM3 Interrupt Output Status Register***/
#define AMAZON_ICU_IM3_IOSR ((volatile u32*)(AMAZON_ICU+ 0x0048))
#define AMAZON_ICU_IM3_IOSR_IR(value) (1 << (value))
/***IM4 Interrupt Output Status Register***/
#define AMAZON_ICU_IM4_IOSR ((volatile u32*)(AMAZON_ICU+ 0x0058))
#define AMAZON_ICU_IM4_IOSR_IR(value) (1 << (value))
/***IM0 Interrupt Request Set Register***/ /***IM0 Interrupt Request Set Register***/
#define AMAZON_ICU_IM0_IRSR ((volatile u32*)(AMAZON_ICU+ 0x001c)) #define AMAZON_ICU_IM0_IRSR (AMAZON_ICU + 0x001c)
#define AMAZON_ICU_IM0_IRSR_IR(value) (1 << (value)) #define AMAZON_ICU_IM1_IRSR (AMAZON_ICU + 0x002c)
#define AMAZON_ICU_IM2_IRSR (AMAZON_ICU + 0x003c)
#define AMAZON_ICU_IM3_IRSR (AMAZON_ICU + 0x004c)
/***IM1 Interrupt Request Set Register***/ #define AMAZON_ICU_IM4_IRSR (AMAZON_ICU + 0x005c)
#define AMAZON_ICU_IM1_IRSR ((volatile u32*)(AMAZON_ICU+ 0x002c))
#define AMAZON_ICU_IM1_IRSR_IR(value) (1 << (value))
/***IM2 Interrupt Request Set Register***/
#define AMAZON_ICU_IM2_IRSR ((volatile u32*)(AMAZON_ICU+ 0x003c))
#define AMAZON_ICU_IM2_IRSR_IR(value) (1 << (value))
/***IM3 Interrupt Request Set Register***/
#define AMAZON_ICU_IM3_IRSR ((volatile u32*)(AMAZON_ICU+ 0x004c))
#define AMAZON_ICU_IM3_IRSR_IR(value) (1 << (value))
/***IM4 Interrupt Request Set Register***/
#define AMAZON_ICU_IM4_IRSR ((volatile u32*)(AMAZON_ICU+ 0x005c))
#define AMAZON_ICU_IM4_IRSR_IR(value) (1 << (value))
/***Interrupt Vector Value Register***/ /***Interrupt Vector Value Register***/
#define AMAZON_ICU_IM_VEC ((volatile u32*)(AMAZON_ICU+ 0x0060)) #define AMAZON_ICU_IM_VEC (AMAZON_ICU + 0x0060)
/***Interrupt Vector Value Mask***/ /***Interrupt Vector Value Mask***/
#define AMAZON_ICU_IM0_VEC_MASK 0x0000001f #define AMAZON_ICU_IM0_VEC_MASK 0x0000001f
#define AMAZON_ICU_IM1_VEC_MASK 0x000003e0 #define AMAZON_ICU_IM1_VEC_MASK 0x000003e0
#define AMAZON_ICU_IM2_VEC_MASK 0x00007c00 #define AMAZON_ICU_IM2_VEC_MASK 0x00007c00
#define AMAZON_ICU_IM3_VEC_MASK 0x000f8000 #define AMAZON_ICU_IM3_VEC_MASK 0x000f8000
#define AMAZON_ICU_IM4_VEC_MASK 0x01f00000 #define AMAZON_ICU_IM4_VEC_MASK 0x01f00000
/***DMA Interrupt Mask Value***/ /***DMA Interrupt Mask Value***/
#define AMAZON_DMA_H_MASK 0x00000fff #define AMAZON_DMA_H_MASK 0x00000fff
/***External Interrupt Control Register***/ /***External Interrupt Control Register***/
#define AMAZON_ICU_EXTINTCR ((volatile u32*)(AMAZON_ICU+ 0x0000)) #define AMAZON_ICU_EXTINTCR (AMAZON_ICU + 0x0000)
#define AMAZON_ICU_IRNICR ((volatile u32*)(AMAZON_ICU+ 0x0004)) #define AMAZON_ICU_IRNICR (AMAZON_ICU + 0x0004)
#define AMAZON_ICU_IRNCR ((volatile u32*)(AMAZON_ICU+ 0x0008)) #define AMAZON_ICU_IRNCR (AMAZON_ICU + 0x0008)
#define AMAZON_ICU_IRNEN ((volatile u32*)(AMAZON_ICU+ 0x000c)) #define AMAZON_ICU_IRNEN (AMAZON_ICU + 0x000c)
/***********************************************************************/ /***********************************************************************/
/* Module : PCI/Card-BUS/PC-Card register address and bits */ /* Module : PCI/Card-BUS/PC-Card register address and bits */