aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sh/Kconfig2
-rw-r--r--arch/sh/boards/mach-se/7724/irq.c38
2 files changed, 28 insertions, 12 deletions
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index bae53831c06b..0f023bb62f99 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -731,7 +731,7 @@ config GUSA_RB
731config SPARSE_IRQ 731config SPARSE_IRQ
732 def_bool y 732 def_bool y
733 depends on SUPERH32 && !SH_DREAMCAST && !SH_HIGHLANDER && \ 733 depends on SUPERH32 && !SH_DREAMCAST && !SH_HIGHLANDER && \
734 !SH_RTS7751R2D && !HD64461 && !SH_7724_SOLUTION_ENGINE 734 !SH_RTS7751R2D && !HD64461
735 help 735 help
736 This enables support for sparse irqs. This is useful in general 736 This enables support for sparse irqs. This is useful in general
737 as most CPUs have a fairly sparse array of IRQ vectors, which 737 as most CPUs have a fairly sparse array of IRQ vectors, which
diff --git a/arch/sh/boards/mach-se/7724/irq.c b/arch/sh/boards/mach-se/7724/irq.c
index e5e021a7d1e6..0942be2daef6 100644
--- a/arch/sh/boards/mach-se/7724/irq.c
+++ b/arch/sh/boards/mach-se/7724/irq.c
@@ -93,18 +93,15 @@ 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 = __raw_readw(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,7 +110,7 @@ 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 __raw_writew(0xffff, IRQ0_MR); /* mask all */ 115 __raw_writew(0xffff, IRQ0_MR); /* mask all */
119 __raw_writew(0xffff, IRQ1_MR); /* mask all */ 116 __raw_writew(0xffff, IRQ1_MR); /* mask all */
@@ -123,10 +120,29 @@ void __init init_se7724_IRQ(void)
123 __raw_writew(0x0000, IRQ2_SR); /* clear irq */ 120 __raw_writew(0x0000, IRQ2_SR); /* clear irq */
124 __raw_writew(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);