aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/boards/mach-se/7343/irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/boards/mach-se/7343/irq.c')
-rw-r--r--arch/sh/boards/mach-se/7343/irq.c56
1 files changed, 31 insertions, 25 deletions
diff --git a/arch/sh/boards/mach-se/7343/irq.c b/arch/sh/boards/mach-se/7343/irq.c
index 051c29d4eae0..76255a19417f 100644
--- a/arch/sh/boards/mach-se/7343/irq.c
+++ b/arch/sh/boards/mach-se/7343/irq.c
@@ -16,40 +16,38 @@
16#include <linux/io.h> 16#include <linux/io.h>
17#include <mach-se/mach/se7343.h> 17#include <mach-se/mach/se7343.h>
18 18
19static void disable_se7343_irq(unsigned int irq) 19unsigned int se7343_fpga_irq[SE7343_FPGA_IRQ_NR] = { 0, };
20
21static void disable_se7343_irq(struct irq_data *data)
20{ 22{
21 unsigned int bit = irq - SE7343_FPGA_IRQ_BASE; 23 unsigned int bit = (unsigned int)irq_data_get_irq_chip_data(data);
22 ctrl_outw(ctrl_inw(PA_CPLD_IMSK) | 1 << bit, PA_CPLD_IMSK); 24 __raw_writew(__raw_readw(PA_CPLD_IMSK) | 1 << bit, PA_CPLD_IMSK);
23} 25}
24 26
25static void enable_se7343_irq(unsigned int irq) 27static void enable_se7343_irq(struct irq_data *data)
26{ 28{
27 unsigned int bit = irq - SE7343_FPGA_IRQ_BASE; 29 unsigned int bit = (unsigned int)irq_data_get_irq_chip_data(data);
28 ctrl_outw(ctrl_inw(PA_CPLD_IMSK) & ~(1 << bit), PA_CPLD_IMSK); 30 __raw_writew(__raw_readw(PA_CPLD_IMSK) & ~(1 << bit), PA_CPLD_IMSK);
29} 31}
30 32
31static struct irq_chip se7343_irq_chip __read_mostly = { 33static struct irq_chip se7343_irq_chip __read_mostly = {
32 .name = "SE7343-FPGA", 34 .name = "SE7343-FPGA",
33 .mask = disable_se7343_irq, 35 .irq_mask = disable_se7343_irq,
34 .unmask = enable_se7343_irq, 36 .irq_unmask = enable_se7343_irq,
35 .mask_ack = disable_se7343_irq,
36}; 37};
37 38
38static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc) 39static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc)
39{ 40{
40 unsigned short intv = ctrl_inw(PA_CPLD_ST); 41 unsigned short intv = __raw_readw(PA_CPLD_ST);
41 struct irq_desc *ext_desc; 42 unsigned int ext_irq = 0;
42 unsigned int ext_irq = SE7343_FPGA_IRQ_BASE;
43 43
44 intv &= (1 << SE7343_FPGA_IRQ_NR) - 1; 44 intv &= (1 << SE7343_FPGA_IRQ_NR) - 1;
45 45
46 while (intv) { 46 for (; intv; intv >>= 1, ext_irq++) {
47 if (intv & 1) { 47 if (!(intv & 1))
48 ext_desc = irq_desc + ext_irq; 48 continue;
49 handle_level_irq(ext_irq, ext_desc); 49
50 } 50 generic_handle_irq(se7343_fpga_irq[ext_irq]);
51 intv >>= 1;
52 ext_irq++;
53 } 51 }
54} 52}
55 53
@@ -58,16 +56,24 @@ static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc)
58 */ 56 */
59void __init init_7343se_IRQ(void) 57void __init init_7343se_IRQ(void)
60{ 58{
61 int i; 59 int i, irq;
60
61 __raw_writew(0, PA_CPLD_IMSK); /* disable all irqs */
62 __raw_writew(0x2000, 0xb03fffec); /* mrshpc irq enable */
62 63
63 ctrl_outw(0, PA_CPLD_IMSK); /* disable all irqs */ 64 for (i = 0; i < SE7343_FPGA_IRQ_NR; i++) {
64 ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */ 65 irq = create_irq();
66 if (irq < 0)
67 return;
68 se7343_fpga_irq[i] = irq;
65 69
66 for (i = 0; i < SE7343_FPGA_IRQ_NR; i++) 70 set_irq_chip_and_handler_name(se7343_fpga_irq[i],
67 set_irq_chip_and_handler_name(SE7343_FPGA_IRQ_BASE + i,
68 &se7343_irq_chip, 71 &se7343_irq_chip,
69 handle_level_irq, "level"); 72 handle_level_irq, "level");
70 73
74 set_irq_chip_data(se7343_fpga_irq[i], (void *)i);
75 }
76
71 set_irq_chained_handler(IRQ0_IRQ, se7343_irq_demux); 77 set_irq_chained_handler(IRQ0_IRQ, se7343_irq_demux);
72 set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); 78 set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
73 set_irq_chained_handler(IRQ1_IRQ, se7343_irq_demux); 79 set_irq_chained_handler(IRQ1_IRQ, se7343_irq_demux);