]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - arch/arm/mach-rpc/irq.c
Merge branch 'cpuidle' into release
[karo-tx-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, clr, set = 0;
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                 clr = IRQ_NOREQUEST;
132
133                 if (irq <= 6 || (irq >= 9 && irq <= 15))
134                         clr |= IRQ_NOPROBE;
135
136                 if (irq == 21 || (irq >= 16 && irq <= 19) ||
137                     irq == IRQ_KEYBOARDTX)
138                         set |= IRQ_NOAUTOEN;
139
140                 switch (irq) {
141                 case 0 ... 7:
142                         irq_set_chip_and_handler(irq, &iomd_a_chip,
143                                                  handle_level_irq);
144                         irq_modify_status(irq, clr, set);
145                         break;
146
147                 case 8 ... 15:
148                         irq_set_chip_and_handler(irq, &iomd_b_chip,
149                                                  handle_level_irq);
150                         irq_modify_status(irq, clr, set);
151                         break;
152
153                 case 16 ... 21:
154                         irq_set_chip_and_handler(irq, &iomd_dma_chip,
155                                                  handle_level_irq);
156                         irq_modify_status(irq, clr, set);
157                         break;
158
159                 case 64 ... 71:
160                         irq_set_chip(irq, &iomd_fiq_chip);
161                         irq_modify_status(irq, clr, set);
162                         break;
163                 }
164         }
165
166         init_FIQ(FIQ_START);
167 }
168