Merge branch 'pm-cpufreq'
[linux-2.6-block.git] / arch / arm / mach-rpc / irq.c
CommitLineData
1da177e4
LT
1#include <linux/init.h>
2#include <linux/list.h>
fced80c7 3#include <linux/io.h>
1da177e4
LT
4
5#include <asm/mach/irq.h>
6#include <asm/hardware/iomd.h>
7#include <asm/irq.h>
78cbaaca 8#include <asm/fiq.h>
1da177e4 9
9a364da7 10static void iomd_ack_irq_a(struct irq_data *d)
1da177e4
LT
11{
12 unsigned int val, mask;
13
9a364da7 14 mask = 1 << d->irq;
1da177e4
LT
15 val = iomd_readb(IOMD_IRQMASKA);
16 iomd_writeb(val & ~mask, IOMD_IRQMASKA);
17 iomd_writeb(mask, IOMD_IRQCLRA);
18}
19
9a364da7 20static void iomd_mask_irq_a(struct irq_data *d)
1da177e4
LT
21{
22 unsigned int val, mask;
23
9a364da7 24 mask = 1 << d->irq;
1da177e4
LT
25 val = iomd_readb(IOMD_IRQMASKA);
26 iomd_writeb(val & ~mask, IOMD_IRQMASKA);
27}
28
9a364da7 29static void iomd_unmask_irq_a(struct irq_data *d)
1da177e4
LT
30{
31 unsigned int val, mask;
32
9a364da7 33 mask = 1 << d->irq;
1da177e4
LT
34 val = iomd_readb(IOMD_IRQMASKA);
35 iomd_writeb(val | mask, IOMD_IRQMASKA);
36}
37
10dd5ce2 38static struct irq_chip iomd_a_chip = {
9a364da7
LB
39 .irq_ack = iomd_ack_irq_a,
40 .irq_mask = iomd_mask_irq_a,
41 .irq_unmask = iomd_unmask_irq_a,
1da177e4
LT
42};
43
9a364da7 44static void iomd_mask_irq_b(struct irq_data *d)
1da177e4
LT
45{
46 unsigned int val, mask;
47
9a364da7 48 mask = 1 << (d->irq & 7);
1da177e4
LT
49 val = iomd_readb(IOMD_IRQMASKB);
50 iomd_writeb(val & ~mask, IOMD_IRQMASKB);
51}
52
9a364da7 53static void iomd_unmask_irq_b(struct irq_data *d)
1da177e4
LT
54{
55 unsigned int val, mask;
56
9a364da7 57 mask = 1 << (d->irq & 7);
1da177e4
LT
58 val = iomd_readb(IOMD_IRQMASKB);
59 iomd_writeb(val | mask, IOMD_IRQMASKB);
60}
61
10dd5ce2 62static struct irq_chip iomd_b_chip = {
9a364da7
LB
63 .irq_ack = iomd_mask_irq_b,
64 .irq_mask = iomd_mask_irq_b,
65 .irq_unmask = iomd_unmask_irq_b,
1da177e4
LT
66};
67
9a364da7 68static void iomd_mask_irq_dma(struct irq_data *d)
1da177e4
LT
69{
70 unsigned int val, mask;
71
9a364da7 72 mask = 1 << (d->irq & 7);
1da177e4
LT
73 val = iomd_readb(IOMD_DMAMASK);
74 iomd_writeb(val & ~mask, IOMD_DMAMASK);
75}
76
9a364da7 77static void iomd_unmask_irq_dma(struct irq_data *d)
1da177e4
LT
78{
79 unsigned int val, mask;
80
9a364da7 81 mask = 1 << (d->irq & 7);
1da177e4
LT
82 val = iomd_readb(IOMD_DMAMASK);
83 iomd_writeb(val | mask, IOMD_DMAMASK);
84}
85
10dd5ce2 86static struct irq_chip iomd_dma_chip = {
9a364da7
LB
87 .irq_ack = iomd_mask_irq_dma,
88 .irq_mask = iomd_mask_irq_dma,
89 .irq_unmask = iomd_unmask_irq_dma,
1da177e4
LT
90};
91
9a364da7 92static void iomd_mask_irq_fiq(struct irq_data *d)
1da177e4
LT
93{
94 unsigned int val, mask;
95
9a364da7 96 mask = 1 << (d->irq & 7);
1da177e4
LT
97 val = iomd_readb(IOMD_FIQMASK);
98 iomd_writeb(val & ~mask, IOMD_FIQMASK);
99}
100
9a364da7 101static void iomd_unmask_irq_fiq(struct irq_data *d)
1da177e4
LT
102{
103 unsigned int val, mask;
104
9a364da7 105 mask = 1 << (d->irq & 7);
1da177e4
LT
106 val = iomd_readb(IOMD_FIQMASK);
107 iomd_writeb(val | mask, IOMD_FIQMASK);
108}
109
10dd5ce2 110static struct irq_chip iomd_fiq_chip = {
9a364da7
LB
111 .irq_ack = iomd_mask_irq_fiq,
112 .irq_mask = iomd_mask_irq_fiq,
113 .irq_unmask = iomd_unmask_irq_fiq,
1da177e4
LT
114};
115
78cbaaca
RH
116extern unsigned char rpc_default_fiq_start, rpc_default_fiq_end;
117
1da177e4
LT
118void __init rpc_init_irq(void)
119{
e8d36d5d 120 unsigned int irq, clr, set = 0;
1da177e4
LT
121
122 iomd_writeb(0, IOMD_IRQMASKA);
123 iomd_writeb(0, IOMD_IRQMASKB);
124 iomd_writeb(0, IOMD_FIQMASK);
125 iomd_writeb(0, IOMD_DMAMASK);
126
78cbaaca
RH
127 set_fiq_handler(&rpc_default_fiq_start,
128 &rpc_default_fiq_end - &rpc_default_fiq_start);
129
1da177e4 130 for (irq = 0; irq < NR_IRQS; irq++) {
e8d36d5d 131 clr = IRQ_NOREQUEST;
1da177e4
LT
132
133 if (irq <= 6 || (irq >= 9 && irq <= 15))
e8d36d5d 134 clr |= IRQ_NOPROBE;
1da177e4
LT
135
136 if (irq == 21 || (irq >= 16 && irq <= 19) ||
137 irq == IRQ_KEYBOARDTX)
e8d36d5d 138 set |= IRQ_NOAUTOEN;
1da177e4
LT
139
140 switch (irq) {
141 case 0 ... 7:
f38c02f3
TG
142 irq_set_chip_and_handler(irq, &iomd_a_chip,
143 handle_level_irq);
e8d36d5d 144 irq_modify_status(irq, clr, set);
1da177e4
LT
145 break;
146
147 case 8 ... 15:
f38c02f3
TG
148 irq_set_chip_and_handler(irq, &iomd_b_chip,
149 handle_level_irq);
e8d36d5d 150 irq_modify_status(irq, clr, set);
1da177e4
LT
151 break;
152
153 case 16 ... 21:
f38c02f3
TG
154 irq_set_chip_and_handler(irq, &iomd_dma_chip,
155 handle_level_irq);
e8d36d5d 156 irq_modify_status(irq, clr, set);
1da177e4
LT
157 break;
158
159 case 64 ... 71:
6845664a 160 irq_set_chip(irq, &iomd_fiq_chip);
e8d36d5d 161 irq_modify_status(irq, clr, set);
1da177e4
LT
162 break;
163 }
164 }
165
bc89663a 166 init_FIQ(FIQ_START);
1da177e4
LT
167}
168