Commit 493a358e authored by Magnus Damm's avatar Magnus Damm Committed by Paul Mundt

sh: clean up interrupt code for solution engine 7722 board

This patch cleans up solution engine 7722 specific interrupt code.
The main purpose is to replace the mux function with use of
set_irq_chained_handler() and replace hard coded register poking
code with set_irq_type(). The board specific interrupts are also
moved to start from SE7722_FPGA_IRQ_BASE.
Signed-off-by: default avatarMagnus Damm <damm@igel.co.jp>
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent 1b06428e
...@@ -16,95 +16,61 @@ ...@@ -16,95 +16,61 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/se7722.h> #include <asm/se7722.h>
#define INTC_INTMSK0 0xFFD00044
#define INTC_INTMSKCLR0 0xFFD00064
struct se7722_data {
unsigned char irq;
unsigned char ipr_idx;
unsigned char shift;
unsigned short priority;
unsigned long addr;
};
static void disable_se7722_irq(unsigned int irq) static void disable_se7722_irq(unsigned int irq)
{ {
struct se7722_data *p = get_irq_chip_data(irq); unsigned int bit = irq - SE7722_FPGA_IRQ_BASE;
ctrl_outw( ctrl_inw( p->addr ) | p->priority , p->addr ); ctrl_outw(ctrl_inw(IRQ01_MASK) | 1 << bit, IRQ01_MASK);
} }
static void enable_se7722_irq(unsigned int irq) static void enable_se7722_irq(unsigned int irq)
{ {
struct se7722_data *p = get_irq_chip_data(irq); unsigned int bit = irq - SE7722_FPGA_IRQ_BASE;
ctrl_outw( ctrl_inw( p->addr ) & ~p->priority , p->addr ); ctrl_outw(ctrl_inw(IRQ01_MASK) & ~(1 << bit), IRQ01_MASK);
} }
static struct irq_chip se7722_irq_chip __read_mostly = { static struct irq_chip se7722_irq_chip __read_mostly = {
.name = "SE7722", .name = "SE7722-FPGA",
.mask = disable_se7722_irq, .mask = disable_se7722_irq,
.unmask = enable_se7722_irq, .unmask = enable_se7722_irq,
.mask_ack = disable_se7722_irq, .mask_ack = disable_se7722_irq,
}; };
static struct se7722_data ipr_irq_table[] = { static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc)
/* irq ,idx,sft, priority , addr */
{ MRSHPC_IRQ0 , 0 , 0 , MRSHPC_BIT0 , IRQ01_MASK } ,
{ MRSHPC_IRQ1 , 0 , 0 , MRSHPC_BIT1 , IRQ01_MASK } ,
{ MRSHPC_IRQ2 , 0 , 0 , MRSHPC_BIT2 , IRQ01_MASK } ,
{ MRSHPC_IRQ3 , 0 , 0 , MRSHPC_BIT3 , IRQ01_MASK } ,
{ SMC_IRQ , 0 , 0 , SMC_BIT , IRQ01_MASK } ,
{ EXT_IRQ , 0 , 0 , EXT_BIT , IRQ01_MASK } ,
};
int se7722_irq_demux(int irq)
{ {
unsigned short intv = ctrl_inw(IRQ01_STS);
struct irq_desc *ext_desc;
unsigned int ext_irq = SE7722_FPGA_IRQ_BASE;
intv &= (1 << SE7722_FPGA_IRQ_NR) - 1;
if ((irq == IRQ0_IRQ)||(irq == IRQ1_IRQ)) { while (intv) {
volatile unsigned short intv = if (intv & 1) {
*(volatile unsigned short *)IRQ01_STS; ext_desc = irq_desc + ext_irq;
if (irq == IRQ0_IRQ){ handle_level_irq(ext_irq, ext_desc);
if(intv & SMC_BIT ) {
return SMC_IRQ;
} else if(intv & USB_BIT) {
return USB_IRQ;
} else {
printk("intv =%04x\n", intv);
return SMC_IRQ;
}
} else if(irq == IRQ1_IRQ){
if(intv & MRSHPC_BIT0) {
return MRSHPC_IRQ0;
} else if(intv & MRSHPC_BIT1) {
return MRSHPC_IRQ1;
} else if(intv & MRSHPC_BIT2) {
return MRSHPC_IRQ2;
} else if(intv & MRSHPC_BIT3) {
return MRSHPC_IRQ3;
} else {
printk("BIT_EXTENTION =%04x\n", intv);
return EXT_IRQ;
}
} }
intv >>= 1;
ext_irq++;
} }
return irq;
} }
/* /*
* Initialize IRQ setting * Initialize IRQ setting
*/ */
void __init init_se7722_IRQ(void) void __init init_se7722_IRQ(void)
{ {
int i = 0; int i;
ctrl_outw(0, IRQ01_MASK); /* disable all irqs */
ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */ ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */
ctrl_outl((3 << ((7 - 0) * 4))|(3 << ((7 - 1) * 4)), INTC_INTPRI0); /* irq0 pri=3,irq1,pri=3 */
ctrl_outw((2 << ((7 - 0) * 2))|(2 << ((7 - 1) * 2)), INTC_ICR1); /* irq0,1 low-level irq */
for (i = 0; i < ARRAY_SIZE(ipr_irq_table); i++) { for (i = 0; i < SE7722_FPGA_IRQ_NR; i++)
disable_irq_nosync(ipr_irq_table[i].irq); set_irq_chip_and_handler_name(SE7722_FPGA_IRQ_BASE + i,
set_irq_chip_and_handler_name( ipr_irq_table[i].irq, &se7722_irq_chip, &se7722_irq_chip,
handle_level_irq, "level"); handle_level_irq, "level");
set_irq_chip_data( ipr_irq_table[i].irq, &ipr_irq_table[i] );
disable_se7722_irq(ipr_irq_table[i].irq); set_irq_chained_handler(IRQ0_IRQ, se7722_irq_demux);
} set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
set_irq_chained_handler(IRQ1_IRQ, se7722_irq_demux);
set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW);
} }
...@@ -77,6 +77,7 @@ static struct resource cf_ide_resources[] = { ...@@ -77,6 +77,7 @@ static struct resource cf_ide_resources[] = {
}, },
[2] = { [2] = {
.start = MRSHPC_IRQ0, .start = MRSHPC_IRQ0,
.end = MRSHPC_IRQ0,
.flags = IORESOURCE_IRQ, .flags = IORESOURCE_IRQ,
}, },
}; };
...@@ -140,8 +141,6 @@ static void __init se7722_setup(char **cmdline_p) ...@@ -140,8 +141,6 @@ static void __init se7722_setup(char **cmdline_p)
static struct sh_machine_vector mv_se7722 __initmv = { static struct sh_machine_vector mv_se7722 __initmv = {
.mv_name = "Solution Engine 7722" , .mv_name = "Solution Engine 7722" ,
.mv_setup = se7722_setup , .mv_setup = se7722_setup ,
.mv_nr_irqs = 109 , .mv_nr_irqs = SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_NR,
.mv_init_irq = init_se7722_IRQ, .mv_init_irq = init_se7722_IRQ,
.mv_irq_demux = se7722_irq_demux,
}; };
...@@ -200,7 +200,7 @@ CONFIG_CPU_LITTLE_ENDIAN=y ...@@ -200,7 +200,7 @@ CONFIG_CPU_LITTLE_ENDIAN=y
CONFIG_SH_DSP=y CONFIG_SH_DSP=y
CONFIG_SH_STORE_QUEUES=y CONFIG_SH_STORE_QUEUES=y
CONFIG_CPU_HAS_INTEVT=y CONFIG_CPU_HAS_INTEVT=y
CONFIG_CPU_HAS_IPR_IRQ=y CONFIG_CPU_HAS_INTC_IRQ=y
CONFIG_CPU_HAS_SR_RB=y CONFIG_CPU_HAS_SR_RB=y
CONFIG_CPU_HAS_PTEA=y CONFIG_CPU_HAS_PTEA=y
......
...@@ -81,36 +81,32 @@ ...@@ -81,36 +81,32 @@
/* IRQ */ /* IRQ */
#define IRQ0_IRQ 32 #define IRQ0_IRQ 32
#define IRQ1_IRQ 33 #define IRQ1_IRQ 33
#define INTC_ICR0 0xA4140000UL
#define INTC_ICR1 0xA414001CUL
#define INTMSK0 0xa4140044
#define INTMSKCLR0 0xa4140064
#define INTC_INTPRI0 0xa4140010
#define IRQ01_MODE 0xb1800000 #define IRQ01_MODE 0xb1800000
#define IRQ01_STS 0xb1800004 #define IRQ01_STS 0xb1800004
#define IRQ01_MASK 0xb1800008 #define IRQ01_MASK 0xb1800008
#define EXT_BIT (0x3fc0) /* SH IRQ1 */
#define MRSHPC_BIT0 (0x0004) /* SH IRQ1 */
#define MRSHPC_BIT1 (0x0008) /* SH IRQ1 */
#define MRSHPC_BIT2 (0x0010) /* SH IRQ1 */
#define MRSHPC_BIT3 (0x0020) /* SH IRQ1 */
#define SMC_BIT (0x0002) /* SH IRQ0 */
#define USB_BIT (0x0001) /* SH IRQ0 */
#define MRSHPC_IRQ3 11
#define MRSHPC_IRQ2 12
#define MRSHPC_IRQ1 13
#define MRSHPC_IRQ0 14
#define SMC_IRQ 10
#define EXT_IRQ 5
#define USB_IRQ 6
/* Bits in IRQ01_* registers */
#define SE7722_FPGA_IRQ_USB 0 /* IRQ0 */
#define SE7722_FPGA_IRQ_SMC 1 /* IRQ0 */
#define SE7722_FPGA_IRQ_MRSHPC0 2 /* IRQ1 */
#define SE7722_FPGA_IRQ_MRSHPC1 3 /* IRQ1 */
#define SE7722_FPGA_IRQ_MRSHPC2 4 /* IRQ1 */
#define SE7722_FPGA_IRQ_MRSHPC3 5 /* IRQ1 */
#define SE7722_FPGA_IRQ_NR 6
#define SE7722_FPGA_IRQ_BASE 110
#define MRSHPC_IRQ3 (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC3)
#define MRSHPC_IRQ2 (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC2)
#define MRSHPC_IRQ1 (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC1)
#define MRSHPC_IRQ0 (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC0)
#define SMC_IRQ (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_SMC)
#define USB_IRQ (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_USB)
/* arch/sh/boards/se/7722/irq.c */ /* arch/sh/boards/se/7722/irq.c */
void init_se7722_IRQ(void); void init_se7722_IRQ(void);
int se7722_irq_demux(int);
#define __IO_PREFIX se7722 #define __IO_PREFIX se7722
#include <asm/io_generic.h> #include <asm/io_generic.h>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment