Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[pandora-kernel.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
9 static void iomd_ack_irq_a(struct irq_data *d)
10 {
11         unsigned int val, mask;
12
13         mask = 1 << d->irq;
14         val = iomd_readb(IOMD_IRQMASKA);
15         iomd_writeb(val & ~mask, IOMD_IRQMASKA);
16         iomd_writeb(mask, IOMD_IRQCLRA);
17 }
18
19 static void iomd_mask_irq_a(struct irq_data *d)
20 {
21         unsigned int val, mask;
22
23         mask = 1 << d->irq;
24         val = iomd_readb(IOMD_IRQMASKA);
25         iomd_writeb(val & ~mask, IOMD_IRQMASKA);
26 }
27
28 static void iomd_unmask_irq_a(struct irq_data *d)
29 {
30         unsigned int val, mask;
31
32         mask = 1 << d->irq;
33         val = iomd_readb(IOMD_IRQMASKA);
34         iomd_writeb(val | mask, IOMD_IRQMASKA);
35 }
36
37 static struct irq_chip iomd_a_chip = {
38         .irq_ack        = iomd_ack_irq_a,
39         .irq_mask       = iomd_mask_irq_a,
40         .irq_unmask     = iomd_unmask_irq_a,
41 };
42
43 static void iomd_mask_irq_b(struct irq_data *d)
44 {
45         unsigned int val, mask;
46
47         mask = 1 << (d->irq & 7);
48         val = iomd_readb(IOMD_IRQMASKB);
49         iomd_writeb(val & ~mask, IOMD_IRQMASKB);
50 }
51
52 static void iomd_unmask_irq_b(struct irq_data *d)
53 {
54         unsigned int val, mask;
55
56         mask = 1 << (d->irq & 7);
57         val = iomd_readb(IOMD_IRQMASKB);
58         iomd_writeb(val | mask, IOMD_IRQMASKB);
59 }
60
61 static struct irq_chip iomd_b_chip = {
62         .irq_ack        = iomd_mask_irq_b,
63         .irq_mask       = iomd_mask_irq_b,
64         .irq_unmask     = iomd_unmask_irq_b,
65 };
66
67 static void iomd_mask_irq_dma(struct irq_data *d)
68 {
69         unsigned int val, mask;
70
71         mask = 1 << (d->irq & 7);
72         val = iomd_readb(IOMD_DMAMASK);
73         iomd_writeb(val & ~mask, IOMD_DMAMASK);
74 }
75
76 static void iomd_unmask_irq_dma(struct irq_data *d)
77 {
78         unsigned int val, mask;
79
80         mask = 1 << (d->irq & 7);
81         val = iomd_readb(IOMD_DMAMASK);
82         iomd_writeb(val | mask, IOMD_DMAMASK);
83 }
84
85 static struct irq_chip iomd_dma_chip = {
86         .irq_ack        = iomd_mask_irq_dma,
87         .irq_mask       = iomd_mask_irq_dma,
88         .irq_unmask     = iomd_unmask_irq_dma,
89 };
90
91 static void iomd_mask_irq_fiq(struct irq_data *d)
92 {
93         unsigned int val, mask;
94
95         mask = 1 << (d->irq & 7);
96         val = iomd_readb(IOMD_FIQMASK);
97         iomd_writeb(val & ~mask, IOMD_FIQMASK);
98 }
99
100 static void iomd_unmask_irq_fiq(struct irq_data *d)
101 {
102         unsigned int val, mask;
103
104         mask = 1 << (d->irq & 7);
105         val = iomd_readb(IOMD_FIQMASK);
106         iomd_writeb(val | mask, IOMD_FIQMASK);
107 }
108
109 static struct irq_chip iomd_fiq_chip = {
110         .irq_ack        = iomd_mask_irq_fiq,
111         .irq_mask       = iomd_mask_irq_fiq,
112         .irq_unmask     = iomd_unmask_irq_fiq,
113 };
114
115 void __init rpc_init_irq(void)
116 {
117         unsigned int irq, flags;
118
119         iomd_writeb(0, IOMD_IRQMASKA);
120         iomd_writeb(0, IOMD_IRQMASKB);
121         iomd_writeb(0, IOMD_FIQMASK);
122         iomd_writeb(0, IOMD_DMAMASK);
123
124         for (irq = 0; irq < NR_IRQS; irq++) {
125                 flags = IRQF_VALID;
126
127                 if (irq <= 6 || (irq >= 9 && irq <= 15))
128                         flags |= IRQF_PROBE;
129
130                 if (irq == 21 || (irq >= 16 && irq <= 19) ||
131                     irq == IRQ_KEYBOARDTX)
132                         flags |= IRQF_NOAUTOEN;
133
134                 switch (irq) {
135                 case 0 ... 7:
136                         set_irq_chip(irq, &iomd_a_chip);
137                         set_irq_handler(irq, handle_level_irq);
138                         set_irq_flags(irq, flags);
139                         break;
140
141                 case 8 ... 15:
142                         set_irq_chip(irq, &iomd_b_chip);
143                         set_irq_handler(irq, handle_level_irq);
144                         set_irq_flags(irq, flags);
145                         break;
146
147                 case 16 ... 21:
148                         set_irq_chip(irq, &iomd_dma_chip);
149                         set_irq_handler(irq, handle_level_irq);
150                         set_irq_flags(irq, flags);
151                         break;
152
153                 case 64 ... 71:
154                         set_irq_chip(irq, &iomd_fiq_chip);
155                         set_irq_flags(irq, IRQF_VALID);
156                         break;
157                 }
158         }
159
160         init_FIQ();
161 }
162