1
2
3
4
5
6
7
8
9
10
11
12#include <linux/kernel.h>
13#include <linux/types.h>
14#include <linux/mm.h>
15#include <linux/sched.h>
16#include <linux/pci.h>
17#include <linux/init.h>
18#include <linux/bitops.h>
19
20#include <asm/ptrace.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_lca.h>
28#include <asm/hwrpb.h>
29#include <asm/tlbflush.h>
30
31#include "proto.h"
32#include "irq_impl.h"
33#include "pci_impl.h"
34#include "machvec_impl.h"
35
36
37
38static unsigned int cached_irq_mask = -1;
39
40static inline void
41eb64p_update_irq_hw(unsigned int irq, unsigned long mask)
42{
43 outb(mask >> (irq >= 24 ? 24 : 16), (irq >= 24 ? 0x27 : 0x26));
44}
45
46static inline void
47eb64p_enable_irq(struct irq_data *d)
48{
49 eb64p_update_irq_hw(d->irq, cached_irq_mask &= ~(1 << d->irq));
50}
51
52static void
53eb64p_disable_irq(struct irq_data *d)
54{
55 eb64p_update_irq_hw(d->irq, cached_irq_mask |= 1 << d->irq);
56}
57
58static struct irq_chip eb64p_irq_type = {
59 .name = "EB64P",
60 .irq_unmask = eb64p_enable_irq,
61 .irq_mask = eb64p_disable_irq,
62 .irq_mask_ack = eb64p_disable_irq,
63};
64
65static void
66eb64p_device_interrupt(unsigned long vector)
67{
68 unsigned long pld;
69 unsigned int i;
70
71
72 pld = inb(0x26) | (inb(0x27) << 8);
73
74
75
76
77
78 while (pld) {
79 i = ffz(~pld);
80 pld &= pld - 1;
81
82 if (i == 5) {
83 isa_device_interrupt(vector);
84 } else {
85 handle_irq(16 + i);
86 }
87 }
88}
89
90static void __init
91eb64p_init_irq(void)
92{
93 long i;
94
95#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_CABRIOLET)
96
97
98
99
100
101 if (inw(0x806) != 0xffff) {
102 extern struct alpha_machine_vector cabriolet_mv;
103
104 printk("Detected Cabriolet: correcting HWRPB.\n");
105
106 hwrpb->sys_variation |= 2L << 10;
107 hwrpb_update_checksum(hwrpb);
108
109 alpha_mv = cabriolet_mv;
110 alpha_mv.init_irq();
111 return;
112 }
113#endif
114
115 outb(0xff, 0x26);
116 outb(0xff, 0x27);
117
118 init_i8259a_irqs();
119
120 for (i = 16; i < 32; ++i) {
121 irq_set_chip_and_handler(i, &eb64p_irq_type, handle_level_irq);
122 irq_set_status_flags(i, IRQ_LEVEL);
123 }
124
125 common_init_isa_dma();
126 setup_irq(16+5, &isa_cascade_irqaction);
127}
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171static int
172eb64p_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
173{
174 static char irq_tab[5][5] = {
175
176 {16+7, 16+7, 16+7, 16+7, 16+7},
177 {16+0, 16+0, 16+2, 16+4, 16+9},
178 {16+1, 16+1, 16+3, 16+8, 16+10},
179 { -1, -1, -1, -1, -1},
180 {16+6, 16+6, 16+6, 16+6, 16+6},
181 };
182 const long min_idsel = 5, max_idsel = 9, irqs_per_slot = 5;
183 return COMMON_TABLE_LOOKUP;
184}
185
186
187
188
189
190
191#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EB64P)
192struct alpha_machine_vector eb64p_mv __initmv = {
193 .vector_name = "EB64+",
194 DO_EV4_MMU,
195 DO_DEFAULT_RTC,
196 DO_APECS_IO,
197 .machine_check = apecs_machine_check,
198 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
199 .min_io_address = DEFAULT_IO_BASE,
200 .min_mem_address = APECS_AND_LCA_DEFAULT_MEM_BASE,
201
202 .nr_irqs = 32,
203 .device_interrupt = eb64p_device_interrupt,
204
205 .init_arch = apecs_init_arch,
206 .init_irq = eb64p_init_irq,
207 .init_rtc = common_init_rtc,
208 .init_pci = common_init_pci,
209 .kill_arch = NULL,
210 .pci_map_irq = eb64p_map_irq,
211 .pci_swizzle = common_swizzle,
212};
213ALIAS_MV(eb64p)
214#endif
215
216#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EB66)
217struct alpha_machine_vector eb66_mv __initmv = {
218 .vector_name = "EB66",
219 DO_EV4_MMU,
220 DO_DEFAULT_RTC,
221 DO_LCA_IO,
222 .machine_check = lca_machine_check,
223 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
224 .min_io_address = DEFAULT_IO_BASE,
225 .min_mem_address = APECS_AND_LCA_DEFAULT_MEM_BASE,
226
227 .nr_irqs = 32,
228 .device_interrupt = eb64p_device_interrupt,
229
230 .init_arch = lca_init_arch,
231 .init_irq = eb64p_init_irq,
232 .init_rtc = common_init_rtc,
233 .init_pci = common_init_pci,
234 .pci_map_irq = eb64p_map_irq,
235 .pci_swizzle = common_swizzle,
236};
237ALIAS_MV(eb66)
238#endif
239