]>
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 | ||
15ff2c67 | 21 | static void disable_se7722_irq(struct irq_data *data) |
6865f0ea | 22 | { |
15ff2c67 | 23 | unsigned int bit = (unsigned int)irq_data_get_irq_chip_data(data); |
9d56dd3b | 24 | __raw_writew(__raw_readw(IRQ01_MASK) | 1 << bit, IRQ01_MASK); |
6865f0ea RS |
25 | } |
26 | ||
15ff2c67 | 27 | static void enable_se7722_irq(struct irq_data *data) |
6865f0ea | 28 | { |
15ff2c67 | 29 | unsigned int bit = (unsigned int)irq_data_get_irq_chip_data(data); |
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 = { | |
15ff2c67 PM |
34 | .name = "SE7722-FPGA", |
35 | .irq_mask = disable_se7722_irq, | |
36 | .irq_unmask = enable_se7722_irq, | |
6865f0ea RS |
37 | }; |
38 | ||
493a358e | 39 | static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc) |
6865f0ea | 40 | { |
9d56dd3b | 41 | unsigned short intv = __raw_readw(IRQ01_STS); |
a37c6c7a | 42 | unsigned int ext_irq = 0; |
493a358e MD |
43 | |
44 | intv &= (1 << SE7722_FPGA_IRQ_NR) - 1; | |
6865f0ea | 45 | |
a37c6c7a PM |
46 | for (; intv; intv >>= 1, ext_irq++) { |
47 | if (!(intv & 1)) | |
48 | continue; | |
49 | ||
50 | generic_handle_irq(se7722_fpga_irq[ext_irq]); | |
6865f0ea | 51 | } |
6865f0ea | 52 | } |
493a358e | 53 | |
6865f0ea RS |
54 | /* |
55 | * Initialize IRQ setting | |
56 | */ | |
57 | void __init init_se7722_IRQ(void) | |
58 | { | |
204fc390 | 59 | int i, irq; |
493a358e | 60 | |
9d56dd3b PM |
61 | __raw_writew(0, IRQ01_MASK); /* disable all irqs */ |
62 | __raw_writew(0x2000, 0xb03fffec); /* mrshpc irq enable */ | |
6865f0ea | 63 | |
a37c6c7a | 64 | for (i = 0; i < SE7722_FPGA_IRQ_NR; i++) { |
204fc390 RK |
65 | irq = create_irq(); |
66 | if (irq < 0) | |
a37c6c7a | 67 | return; |
204fc390 | 68 | se7722_fpga_irq[i] = irq; |
a37c6c7a PM |
69 | |
70 | set_irq_chip_and_handler_name(se7722_fpga_irq[i], | |
493a358e MD |
71 | &se7722_irq_chip, |
72 | handle_level_irq, "level"); | |
73 | ||
a37c6c7a PM |
74 | set_irq_chip_data(se7722_fpga_irq[i], (void *)i); |
75 | } | |
76 | ||
493a358e MD |
77 | set_irq_chained_handler(IRQ0_IRQ, se7722_irq_demux); |
78 | set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); | |
79 | ||
80 | set_irq_chained_handler(IRQ1_IRQ, se7722_irq_demux); | |
81 | set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW); | |
6865f0ea | 82 | } |