blob: cf0e669eaf1a2be156abf3bf448a0759ddfc4bcc [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001#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
10static 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
20static 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
29static 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
38static 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
44static 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
53static 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
62static 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
68static 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
77static 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
86static 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
92static 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
101static 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
110static 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
116extern unsigned char rpc_default_fiq_start, rpc_default_fiq_end;
117
118void __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();
167}
168