aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorMagnus Damm <damm@igel.co.jp>2007-07-18 04:54:10 -0400
committerPaul Mundt <lethal@linux-sh.org>2007-07-19 23:18:20 -0400
commit493a358e0a8992ec13098dd084223b55b05a7f03 (patch)
treeffd7480a55e21da681dbe789dc129373bef2d6cf /arch/sh
parent1b06428ee56fadedd004bfc5e3fbb39fb8c99010 (diff)
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: Magnus Damm <damm@igel.co.jp> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/boards/se/7722/irq.c96
-rw-r--r--arch/sh/boards/se/7722/setup.c5
-rw-r--r--arch/sh/configs/se7722_defconfig2
3 files changed, 34 insertions, 69 deletions
diff --git a/arch/sh/boards/se/7722/irq.c b/arch/sh/boards/se/7722/irq.c
index 26cff0efda40..0b03f3f610b8 100644
--- a/arch/sh/boards/se/7722/irq.c
+++ b/arch/sh/boards/se/7722/irq.c
@@ -16,95 +16,61 @@
16#include <asm/io.h> 16#include <asm/io.h>
17#include <asm/se7722.h> 17#include <asm/se7722.h>
18 18
19#define INTC_INTMSK0 0xFFD00044
20#define INTC_INTMSKCLR0 0xFFD00064
21
22struct se7722_data {
23 unsigned char irq;
24 unsigned char ipr_idx;
25 unsigned char shift;
26 unsigned short priority;
27 unsigned long addr;
28};
29
30
31static void disable_se7722_irq(unsigned int irq) 19static void disable_se7722_irq(unsigned int irq)
32{ 20{
33 struct se7722_data *p = get_irq_chip_data(irq); 21 unsigned int bit = irq - SE7722_FPGA_IRQ_BASE;
34 ctrl_outw( ctrl_inw( p->addr ) | p->priority , p->addr ); 22 ctrl_outw(ctrl_inw(IRQ01_MASK) | 1 << bit, IRQ01_MASK);
35} 23}
36 24
37static void enable_se7722_irq(unsigned int irq) 25static void enable_se7722_irq(unsigned int irq)
38{ 26{
39 struct se7722_data *p = get_irq_chip_data(irq); 27 unsigned int bit = irq - SE7722_FPGA_IRQ_BASE;
40 ctrl_outw( ctrl_inw( p->addr ) & ~p->priority , p->addr ); 28 ctrl_outw(ctrl_inw(IRQ01_MASK) & ~(1 << bit), IRQ01_MASK);
41} 29}
42 30
43static struct irq_chip se7722_irq_chip __read_mostly = { 31static struct irq_chip se7722_irq_chip __read_mostly = {
44 .name = "SE7722", 32 .name = "SE7722-FPGA",
45 .mask = disable_se7722_irq, 33 .mask = disable_se7722_irq,
46 .unmask = enable_se7722_irq, 34 .unmask = enable_se7722_irq,
47 .mask_ack = disable_se7722_irq, 35 .mask_ack = disable_se7722_irq,
48}; 36};
49 37
50static struct se7722_data ipr_irq_table[] = { 38static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc)
51 /* irq ,idx,sft, priority , addr */
52 { MRSHPC_IRQ0 , 0 , 0 , MRSHPC_BIT0 , IRQ01_MASK } ,
53 { MRSHPC_IRQ1 , 0 , 0 , MRSHPC_BIT1 , IRQ01_MASK } ,
54 { MRSHPC_IRQ2 , 0 , 0 , MRSHPC_BIT2 , IRQ01_MASK } ,
55 { MRSHPC_IRQ3 , 0 , 0 , MRSHPC_BIT3 , IRQ01_MASK } ,
56 { SMC_IRQ , 0 , 0 , SMC_BIT , IRQ01_MASK } ,
57 { EXT_IRQ , 0 , 0 , EXT_BIT , IRQ01_MASK } ,
58};
59
60int se7722_irq_demux(int irq)
61{ 39{
40 unsigned short intv = ctrl_inw(IRQ01_STS);
41 struct irq_desc *ext_desc;
42 unsigned int ext_irq = SE7722_FPGA_IRQ_BASE;
43
44 intv &= (1 << SE7722_FPGA_IRQ_NR) - 1;
62 45
63 if ((irq == IRQ0_IRQ)||(irq == IRQ1_IRQ)) { 46 while (intv) {
64 volatile unsigned short intv = 47 if (intv & 1) {
65 *(volatile unsigned short *)IRQ01_STS; 48 ext_desc = irq_desc + ext_irq;
66 if (irq == IRQ0_IRQ){ 49 handle_level_irq(ext_irq, ext_desc);
67 if(intv & SMC_BIT ) {
68 return SMC_IRQ;
69 } else if(intv & USB_BIT) {
70 return USB_IRQ;
71 } else {
72 printk("intv =%04x\n", intv);
73 return SMC_IRQ;
74 }
75 } else if(irq == IRQ1_IRQ){
76 if(intv & MRSHPC_BIT0) {
77 return MRSHPC_IRQ0;
78 } else if(intv & MRSHPC_BIT1) {
79 return MRSHPC_IRQ1;
80 } else if(intv & MRSHPC_BIT2) {
81 return MRSHPC_IRQ2;
82 } else if(intv & MRSHPC_BIT3) {
83 return MRSHPC_IRQ3;
84 } else {
85 printk("BIT_EXTENTION =%04x\n", intv);
86 return EXT_IRQ;
87 }
88 } 50 }
51 intv >>= 1;
52 ext_irq++;
89 } 53 }
90 return irq;
91
92} 54}
55
93/* 56/*
94 * Initialize IRQ setting 57 * Initialize IRQ setting
95 */ 58 */
96void __init init_se7722_IRQ(void) 59void __init init_se7722_IRQ(void)
97{ 60{
98 int i = 0; 61 int i;
62
63 ctrl_outw(0, IRQ01_MASK); /* disable all irqs */
99 ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */ 64 ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */
100 ctrl_outl((3 << ((7 - 0) * 4))|(3 << ((7 - 1) * 4)), INTC_INTPRI0); /* irq0 pri=3,irq1,pri=3 */
101 ctrl_outw((2 << ((7 - 0) * 2))|(2 << ((7 - 1) * 2)), INTC_ICR1); /* irq0,1 low-level irq */
102 65
103 for (i = 0; i < ARRAY_SIZE(ipr_irq_table); i++) { 66 for (i = 0; i < SE7722_FPGA_IRQ_NR; i++)
104 disable_irq_nosync(ipr_irq_table[i].irq); 67 set_irq_chip_and_handler_name(SE7722_FPGA_IRQ_BASE + i,
105 set_irq_chip_and_handler_name( ipr_irq_table[i].irq, &se7722_irq_chip, 68 &se7722_irq_chip,
106 handle_level_irq, "level"); 69 handle_level_irq, "level");
107 set_irq_chip_data( ipr_irq_table[i].irq, &ipr_irq_table[i] ); 70
108 disable_se7722_irq(ipr_irq_table[i].irq); 71 set_irq_chained_handler(IRQ0_IRQ, se7722_irq_demux);
109 } 72 set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
73
74 set_irq_chained_handler(IRQ1_IRQ, se7722_irq_demux);
75 set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW);
110} 76}
diff --git a/arch/sh/boards/se/7722/setup.c b/arch/sh/boards/se/7722/setup.c
index 6cca6cbc8069..495fc7e2b60f 100644
--- a/arch/sh/boards/se/7722/setup.c
+++ b/arch/sh/boards/se/7722/setup.c
@@ -77,6 +77,7 @@ static struct resource cf_ide_resources[] = {
77 }, 77 },
78 [2] = { 78 [2] = {
79 .start = MRSHPC_IRQ0, 79 .start = MRSHPC_IRQ0,
80 .end = MRSHPC_IRQ0,
80 .flags = IORESOURCE_IRQ, 81 .flags = IORESOURCE_IRQ,
81 }, 82 },
82}; 83};
@@ -140,8 +141,6 @@ static void __init se7722_setup(char **cmdline_p)
140static struct sh_machine_vector mv_se7722 __initmv = { 141static struct sh_machine_vector mv_se7722 __initmv = {
141 .mv_name = "Solution Engine 7722" , 142 .mv_name = "Solution Engine 7722" ,
142 .mv_setup = se7722_setup , 143 .mv_setup = se7722_setup ,
143 .mv_nr_irqs = 109 , 144 .mv_nr_irqs = SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_NR,
144 .mv_init_irq = init_se7722_IRQ, 145 .mv_init_irq = init_se7722_IRQ,
145 .mv_irq_demux = se7722_irq_demux,
146
147}; 146};
diff --git a/arch/sh/configs/se7722_defconfig b/arch/sh/configs/se7722_defconfig
index 122b67da73cf..8e6a6baf5d27 100644
--- a/arch/sh/configs/se7722_defconfig
+++ b/arch/sh/configs/se7722_defconfig
@@ -200,7 +200,7 @@ CONFIG_CPU_LITTLE_ENDIAN=y
200CONFIG_SH_DSP=y 200CONFIG_SH_DSP=y
201CONFIG_SH_STORE_QUEUES=y 201CONFIG_SH_STORE_QUEUES=y
202CONFIG_CPU_HAS_INTEVT=y 202CONFIG_CPU_HAS_INTEVT=y
203CONFIG_CPU_HAS_IPR_IRQ=y 203CONFIG_CPU_HAS_INTC_IRQ=y
204CONFIG_CPU_HAS_SR_RB=y 204CONFIG_CPU_HAS_SR_RB=y
205CONFIG_CPU_HAS_PTEA=y 205CONFIG_CPU_HAS_PTEA=y
206 206