diff options
Diffstat (limited to 'arch/sh/boards/mach-se/7724/irq.c')
-rw-r--r-- | arch/sh/boards/mach-se/7724/irq.c | 62 |
1 files changed, 39 insertions, 23 deletions
diff --git a/arch/sh/boards/mach-se/7724/irq.c b/arch/sh/boards/mach-se/7724/irq.c index f76cf3b49f23..0942be2daef6 100644 --- a/arch/sh/boards/mach-se/7724/irq.c +++ b/arch/sh/boards/mach-se/7724/irq.c | |||
@@ -72,14 +72,14 @@ static void disable_se7724_irq(unsigned int irq) | |||
72 | { | 72 | { |
73 | struct fpga_irq set = get_fpga_irq(fpga2irq(irq)); | 73 | struct fpga_irq set = get_fpga_irq(fpga2irq(irq)); |
74 | unsigned int bit = irq - set.base; | 74 | unsigned int bit = irq - set.base; |
75 | ctrl_outw(ctrl_inw(set.mraddr) | 0x0001 << bit, set.mraddr); | 75 | __raw_writew(__raw_readw(set.mraddr) | 0x0001 << bit, set.mraddr); |
76 | } | 76 | } |
77 | 77 | ||
78 | static void enable_se7724_irq(unsigned int irq) | 78 | static void enable_se7724_irq(unsigned int irq) |
79 | { | 79 | { |
80 | struct fpga_irq set = get_fpga_irq(fpga2irq(irq)); | 80 | struct fpga_irq set = get_fpga_irq(fpga2irq(irq)); |
81 | unsigned int bit = irq - set.base; | 81 | unsigned int bit = irq - set.base; |
82 | ctrl_outw(ctrl_inw(set.mraddr) & ~(0x0001 << bit), set.mraddr); | 82 | __raw_writew(__raw_readw(set.mraddr) & ~(0x0001 << bit), set.mraddr); |
83 | } | 83 | } |
84 | 84 | ||
85 | static struct irq_chip se7724_irq_chip __read_mostly = { | 85 | static struct irq_chip se7724_irq_chip __read_mostly = { |
@@ -92,19 +92,16 @@ static struct irq_chip se7724_irq_chip __read_mostly = { | |||
92 | static void se7724_irq_demux(unsigned int irq, struct irq_desc *desc) | 92 | static void se7724_irq_demux(unsigned int irq, struct irq_desc *desc) |
93 | { | 93 | { |
94 | struct fpga_irq set = get_fpga_irq(irq); | 94 | struct fpga_irq set = get_fpga_irq(irq); |
95 | unsigned short intv = ctrl_inw(set.sraddr); | 95 | unsigned short intv = __raw_readw(set.sraddr); |
96 | struct irq_desc *ext_desc; | ||
97 | unsigned int ext_irq = set.base; | 96 | unsigned int ext_irq = set.base; |
98 | 97 | ||
99 | intv &= set.mask; | 98 | intv &= set.mask; |
100 | 99 | ||
101 | while (intv) { | 100 | for (; intv; intv >>= 1, ext_irq++) { |
102 | if (intv & 0x0001) { | 101 | if (!(intv & 1)) |
103 | ext_desc = irq_desc + ext_irq; | 102 | continue; |
104 | handle_level_irq(ext_irq, ext_desc); | 103 | |
105 | } | 104 | generic_handle_irq(ext_irq); |
106 | intv >>= 1; | ||
107 | ext_irq++; | ||
108 | } | 105 | } |
109 | } | 106 | } |
110 | 107 | ||
@@ -113,20 +110,39 @@ static void se7724_irq_demux(unsigned int irq, struct irq_desc *desc) | |||
113 | */ | 110 | */ |
114 | void __init init_se7724_IRQ(void) | 111 | void __init init_se7724_IRQ(void) |
115 | { | 112 | { |
116 | int i; | 113 | int i, nid = cpu_to_node(boot_cpu_data); |
117 | 114 | ||
118 | ctrl_outw(0xffff, IRQ0_MR); /* mask all */ | 115 | __raw_writew(0xffff, IRQ0_MR); /* mask all */ |
119 | ctrl_outw(0xffff, IRQ1_MR); /* mask all */ | 116 | __raw_writew(0xffff, IRQ1_MR); /* mask all */ |
120 | ctrl_outw(0xffff, IRQ2_MR); /* mask all */ | 117 | __raw_writew(0xffff, IRQ2_MR); /* mask all */ |
121 | ctrl_outw(0x0000, IRQ0_SR); /* clear irq */ | 118 | __raw_writew(0x0000, IRQ0_SR); /* clear irq */ |
122 | ctrl_outw(0x0000, IRQ1_SR); /* clear irq */ | 119 | __raw_writew(0x0000, IRQ1_SR); /* clear irq */ |
123 | ctrl_outw(0x0000, IRQ2_SR); /* clear irq */ | 120 | __raw_writew(0x0000, IRQ2_SR); /* clear irq */ |
124 | ctrl_outw(0x002a, IRQ_MODE); /* set irq type */ | 121 | __raw_writew(0x002a, IRQ_MODE); /* set irq type */ |
125 | 122 | ||
126 | for (i = 0; i < SE7724_FPGA_IRQ_NR; i++) | 123 | for (i = 0; i < SE7724_FPGA_IRQ_NR; i++) { |
127 | set_irq_chip_and_handler_name(SE7724_FPGA_IRQ_BASE + i, | 124 | int irq, wanted; |
125 | |||
126 | wanted = SE7724_FPGA_IRQ_BASE + i; | ||
127 | |||
128 | irq = create_irq_nr(wanted, nid); | ||
129 | if (unlikely(irq == 0)) { | ||
130 | pr_err("%s: failed hooking irq %d for FPGA\n", | ||
131 | __func__, wanted); | ||
132 | return; | ||
133 | } | ||
134 | |||
135 | if (unlikely(irq != wanted)) { | ||
136 | pr_err("%s: got irq %d but wanted %d, bailing.\n", | ||
137 | __func__, irq, wanted); | ||
138 | destroy_irq(irq); | ||
139 | return; | ||
140 | } | ||
141 | |||
142 | set_irq_chip_and_handler_name(irq, | ||
128 | &se7724_irq_chip, | 143 | &se7724_irq_chip, |
129 | handle_level_irq, "level"); | 144 | handle_level_irq, "level"); |
145 | } | ||
130 | 146 | ||
131 | set_irq_chained_handler(IRQ0_IRQ, se7724_irq_demux); | 147 | set_irq_chained_handler(IRQ0_IRQ, se7724_irq_demux); |
132 | set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); | 148 | set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); |