]>
Commit | Line | Data |
---|---|---|
6865f0ea RS |
1 | /* |
2 | * linux/arch/sh/boards/se/7722/irq.c | |
3 | * | |
4 | * Copyright (C) 2007 Nobuhiro Iwamatsu | |
5 | * | |
6 | * Hitachi UL SolutionEngine 7722 Support. | |
7 | * | |
8 | * This file is subject to the terms and conditions of the GNU General Public | |
9 | * License. See the file "COPYING" in the main directory of this archive | |
10 | * for more details. | |
11 | */ | |
12 | #include <linux/init.h> | |
13 | #include <linux/irq.h> | |
14 | #include <linux/interrupt.h> | |
15 | #include <asm/irq.h> | |
16 | #include <asm/io.h> | |
939a24a6 | 17 | #include <mach-se/mach/se7722.h> |
6865f0ea | 18 | |
a37c6c7a PM |
19 | unsigned int se7722_fpga_irq[SE7722_FPGA_IRQ_NR] = { 0, }; |
20 | ||
6865f0ea RS |
21 | static void disable_se7722_irq(unsigned int irq) |
22 | { | |
a37c6c7a | 23 | unsigned int bit = (unsigned int)get_irq_chip_data(irq); |
9d56dd3b | 24 | __raw_writew(__raw_readw(IRQ01_MASK) | 1 << bit, IRQ01_MASK); |
6865f0ea RS |
25 | } |
26 | ||
27 | static void enable_se7722_irq(unsigned int irq) | |
28 | { | |
a37c6c7a | 29 | unsigned int bit = (unsigned int)get_irq_chip_data(irq); |
9d56dd3b | 30 | __raw_writew(__raw_readw(IRQ01_MASK) & ~(1 << bit), IRQ01_MASK); |
6865f0ea RS |
31 | } |
32 | ||
33 | static struct irq_chip se7722_irq_chip __read_mostly = { | |
493a358e | 34 | .name = "SE7722-FPGA", |
6865f0ea RS |
35 | .mask = disable_se7722_irq, |
36 | .unmask = enable_se7722_irq, | |
37 | .mask_ack = disable_se7722_irq, | |
38 | }; | |
39 | ||
493a358e | 40 | static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc) |
6865f0ea | 41 | { |
9d56dd3b | 42 | unsigned short intv = __raw_readw(IRQ01_STS); |
a37c6c7a | 43 | unsigned int ext_irq = 0; |
493a358e MD |
44 | |
45 | intv &= (1 << SE7722_FPGA_IRQ_NR) - 1; | |
6865f0ea | 46 | |
a37c6c7a PM |
47 | for (; intv; intv >>= 1, ext_irq++) { |
48 | if (!(intv & 1)) | |
49 | continue; | |
50 | ||
51 | generic_handle_irq(se7722_fpga_irq[ext_irq]); | |
6865f0ea | 52 | } |
6865f0ea | 53 | } |
493a358e | 54 | |
6865f0ea RS |
55 | /* |
56 | * Initialize IRQ setting | |
57 | */ | |
58 | void __init init_se7722_IRQ(void) | |
59 | { | |
204fc390 | 60 | int i, irq; |
493a358e | 61 | |
9d56dd3b PM |
62 | __raw_writew(0, IRQ01_MASK); /* disable all irqs */ |
63 | __raw_writew(0x2000, 0xb03fffec); /* mrshpc irq enable */ | |
6865f0ea | 64 | |
a37c6c7a | 65 | for (i = 0; i < SE7722_FPGA_IRQ_NR; i++) { |
204fc390 RK |
66 | irq = create_irq(); |
67 | if (irq < 0) | |
a37c6c7a | 68 | return; |
204fc390 | 69 | se7722_fpga_irq[i] = irq; |
a37c6c7a PM |
70 | |
71 | set_irq_chip_and_handler_name(se7722_fpga_irq[i], | |
493a358e MD |
72 | &se7722_irq_chip, |
73 | handle_level_irq, "level"); | |
74 | ||
a37c6c7a PM |
75 | set_irq_chip_data(se7722_fpga_irq[i], (void *)i); |
76 | } | |
77 | ||
493a358e MD |
78 | set_irq_chained_handler(IRQ0_IRQ, se7722_irq_demux); |
79 | set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); | |
80 | ||
81 | set_irq_chained_handler(IRQ1_IRQ, se7722_irq_demux); | |
82 | set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW); | |
6865f0ea | 83 | } |