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