aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/boards/mach-se/7724/irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/boards/mach-se/7724/irq.c')
-rw-r--r--arch/sh/boards/mach-se/7724/irq.c62
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 f76cf3b49f2..0942be2daef 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
78static void enable_se7724_irq(unsigned int irq) 78static 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
85static struct irq_chip se7724_irq_chip __read_mostly = { 85static struct irq_chip se7724_irq_chip __read_mostly = {
@@ -92,19 +92,16 @@ static struct irq_chip se7724_irq_chip __read_mostly = {
92static void se7724_irq_demux(unsigned int irq, struct irq_desc *desc) 92static 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 */
114void __init init_se7724_IRQ(void) 111void __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);