diff options
author | Magnus Damm <damm@igel.co.jp> | 2007-07-18 04:54:10 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2007-07-19 23:18:20 -0400 |
commit | 493a358e0a8992ec13098dd084223b55b05a7f03 (patch) | |
tree | ffd7480a55e21da681dbe789dc129373bef2d6cf /arch/sh/boards/se | |
parent | 1b06428ee56fadedd004bfc5e3fbb39fb8c99010 (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/boards/se')
-rw-r--r-- | arch/sh/boards/se/7722/irq.c | 96 | ||||
-rw-r--r-- | arch/sh/boards/se/7722/setup.c | 5 |
2 files changed, 33 insertions, 68 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 | |||
22 | struct 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 | |||
31 | static void disable_se7722_irq(unsigned int irq) | 19 | static 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 | ||
37 | static void enable_se7722_irq(unsigned int irq) | 25 | static 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 | ||
43 | static struct irq_chip se7722_irq_chip __read_mostly = { | 31 | static 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 | ||
50 | static struct se7722_data ipr_irq_table[] = { | 38 | static 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 | |||
60 | int 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 | */ |
96 | void __init init_se7722_IRQ(void) | 59 | void __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) | |||
140 | static struct sh_machine_vector mv_se7722 __initmv = { | 141 | static 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 | }; |