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