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