1
2
3
4
5
6
7
8
9
10
11#include <linux/kernel.h>
12#include <linux/types.h>
13#include <linux/mm.h>
14#include <linux/sched.h>
15#include <linux/pci.h>
16#include <linux/init.h>
17#include <linux/bitops.h>
18
19#include <asm/ptrace.h>
20#include <asm/mce.h>
21#include <asm/dma.h>
22#include <asm/irq.h>
23#include <asm/mmu_context.h>
24#include <asm/io.h>
25#include <asm/pgtable.h>
26#include <asm/core_apecs.h>
27#include <asm/core_cia.h>
28#include <asm/tlbflush.h>
29
30#include "proto.h"
31#include "irq_impl.h"
32#include "pci_impl.h"
33#include "machvec_impl.h"
34
35
36
37static int cached_irq_mask;
38
39static inline void
40mikasa_update_irq_hw(int mask)
41{
42 outw(mask, 0x536);
43}
44
45static inline void
46mikasa_enable_irq(struct irq_data *d)
47{
48 mikasa_update_irq_hw(cached_irq_mask |= 1 << (d->irq - 16));
49}
50
51static void
52mikasa_disable_irq(struct irq_data *d)
53{
54 mikasa_update_irq_hw(cached_irq_mask &= ~(1 << (d->irq - 16)));
55}
56
57static struct irq_chip mikasa_irq_type = {
58 .name = "MIKASA",
59 .irq_unmask = mikasa_enable_irq,
60 .irq_mask = mikasa_disable_irq,
61 .irq_mask_ack = mikasa_disable_irq,
62};
63
64static void
65mikasa_device_interrupt(unsigned long vector)
66{
67 unsigned long pld;
68 unsigned int i;
69
70
71 pld = (((~inw(0x534) & 0x0000ffffUL) << 16)
72 | (((unsigned long) inb(0xa0)) << 8)
73 | inb(0x20));
74
75
76
77
78
79 while (pld) {
80 i = ffz(~pld);
81 pld &= pld - 1;
82 if (i < 16) {
83 isa_device_interrupt(vector);
84 } else {
85 handle_irq(i);
86 }
87 }
88}
89
90static void __init
91mikasa_init_irq(void)
92{
93 long i;
94
95 if (alpha_using_srm)
96 alpha_mv.device_interrupt = srm_device_interrupt;
97
98 mikasa_update_irq_hw(0);
99
100 for (i = 16; i < 32; ++i) {
101 irq_set_chip_and_handler(i, &mikasa_irq_type,
102 handle_level_irq);
103 irq_set_status_flags(i, IRQ_LEVEL);
104 }
105
106 init_i8259a_irqs();
107 common_init_isa_dma();
108}
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148static int __init
149mikasa_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
150{
151 static char irq_tab[8][5] __initdata = {
152
153 {16+12, 16+12, 16+12, 16+12, 16+12},
154 { -1, -1, -1, -1, -1},
155 { -1, -1, -1, -1, -1},
156 { -1, -1, -1, -1, -1},
157 { -1, -1, -1, -1, -1},
158 { 16+0, 16+0, 16+1, 16+2, 16+3},
159 { 16+4, 16+4, 16+5, 16+6, 16+7},
160 { 16+8, 16+8, 16+9, 16+10, 16+11},
161 };
162 const long min_idsel = 6, max_idsel = 13, irqs_per_slot = 5;
163 return COMMON_TABLE_LOOKUP;
164}
165
166
167#if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_PRIMO)
168static void
169mikasa_apecs_machine_check(unsigned long vector, unsigned long la_ptr)
170{
171#define MCHK_NO_DEVSEL 0x205U
172#define MCHK_NO_TABT 0x204U
173
174 struct el_common *mchk_header;
175 unsigned int code;
176
177 mchk_header = (struct el_common *)la_ptr;
178
179
180 mb();
181 mb();
182 draina();
183 apecs_pci_clr_err();
184 wrmces(0x7);
185 mb();
186
187 code = mchk_header->code;
188 process_mcheck_info(vector, la_ptr, "MIKASA APECS",
189 (mcheck_expected(0)
190 && (code == MCHK_NO_DEVSEL
191 || code == MCHK_NO_TABT)));
192}
193#endif
194
195
196
197
198
199
200#if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_PRIMO)
201struct alpha_machine_vector mikasa_mv __initmv = {
202 .vector_name = "Mikasa",
203 DO_EV4_MMU,
204 DO_DEFAULT_RTC,
205 DO_APECS_IO,
206 .machine_check = mikasa_apecs_machine_check,
207 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
208 .min_io_address = DEFAULT_IO_BASE,
209 .min_mem_address = APECS_AND_LCA_DEFAULT_MEM_BASE,
210
211 .nr_irqs = 32,
212 .device_interrupt = mikasa_device_interrupt,
213
214 .init_arch = apecs_init_arch,
215 .init_irq = mikasa_init_irq,
216 .init_rtc = common_init_rtc,
217 .init_pci = common_init_pci,
218 .pci_map_irq = mikasa_map_irq,
219 .pci_swizzle = common_swizzle,
220};
221ALIAS_MV(mikasa)
222#endif
223
224#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_PRIMO)
225struct alpha_machine_vector mikasa_primo_mv __initmv = {
226 .vector_name = "Mikasa-Primo",
227 DO_EV5_MMU,
228 DO_DEFAULT_RTC,
229 DO_CIA_IO,
230 .machine_check = cia_machine_check,
231 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
232 .min_io_address = DEFAULT_IO_BASE,
233 .min_mem_address = CIA_DEFAULT_MEM_BASE,
234
235 .nr_irqs = 32,
236 .device_interrupt = mikasa_device_interrupt,
237
238 .init_arch = cia_init_arch,
239 .init_irq = mikasa_init_irq,
240 .init_rtc = common_init_rtc,
241 .init_pci = cia_init_pci,
242 .kill_arch = cia_kill_arch,
243 .pci_map_irq = mikasa_map_irq,
244 .pci_swizzle = common_swizzle,
245};
246ALIAS_MV(mikasa_primo)
247#endif
248