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/dma.h>
21#include <asm/irq.h>
22#include <asm/mmu_context.h>
23#include <asm/io.h>
24#include <asm/pgtable.h>
25#include <asm/core_apecs.h>
26#include <asm/core_lca.h>
27#include <asm/hwrpb.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 unsigned int cached_irq_mask = -1;
38
39static inline void
40eb64p_update_irq_hw(unsigned int irq, unsigned long mask)
41{
42 outb(mask >> (irq >= 24 ? 24 : 16), (irq >= 24 ? 0x27 : 0x26));
43}
44
45static inline void
46eb64p_enable_irq(struct irq_data *d)
47{
48 eb64p_update_irq_hw(d->irq, cached_irq_mask &= ~(1 << d->irq));
49}
50
51static void
52eb64p_disable_irq(struct irq_data *d)
53{
54 eb64p_update_irq_hw(d->irq, cached_irq_mask |= 1 << d->irq);
55}
56
57static struct irq_chip eb64p_irq_type = {
58 .name = "EB64P",
59 .irq_unmask = eb64p_enable_irq,
60 .irq_mask = eb64p_disable_irq,
61 .irq_mask_ack = eb64p_disable_irq,
62};
63
64static void
65eb64p_device_interrupt(unsigned long vector)
66{
67 unsigned long pld;
68 unsigned int i;
69
70
71 pld = inb(0x26) | (inb(0x27) << 8);
72
73
74
75
76
77 while (pld) {
78 i = ffz(~pld);
79 pld &= pld - 1;
80
81 if (i == 5) {
82 isa_device_interrupt(vector);
83 } else {
84 handle_irq(16 + i);
85 }
86 }
87}
88
89static void __init
90eb64p_init_irq(void)
91{
92 long i;
93
94#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_CABRIOLET)
95
96
97
98
99
100 if (inw(0x806) != 0xffff) {
101 extern struct alpha_machine_vector cabriolet_mv;
102
103 printk("Detected Cabriolet: correcting HWRPB.\n");
104
105 hwrpb->sys_variation |= 2L << 10;
106 hwrpb_update_checksum(hwrpb);
107
108 alpha_mv = cabriolet_mv;
109 alpha_mv.init_irq();
110 return;
111 }
112#endif
113
114 outb(0xff, 0x26);
115 outb(0xff, 0x27);
116
117 init_i8259a_irqs();
118
119 for (i = 16; i < 32; ++i) {
120 irq_set_chip_and_handler(i, &eb64p_irq_type, handle_level_irq);
121 irq_set_status_flags(i, IRQ_LEVEL);
122 }
123
124 common_init_isa_dma();
125 setup_irq(16+5, &isa_cascade_irqaction);
126}
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
170static int __init
171eb64p_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
172{
173 static char irq_tab[5][5] __initdata = {
174
175 {16+7, 16+7, 16+7, 16+7, 16+7},
176 {16+0, 16+0, 16+2, 16+4, 16+9},
177 {16+1, 16+1, 16+3, 16+8, 16+10},
178 { -1, -1, -1, -1, -1},
179 {16+6, 16+6, 16+6, 16+6, 16+6},
180 };
181 const long min_idsel = 5, max_idsel = 9, irqs_per_slot = 5;
182 return COMMON_TABLE_LOOKUP;
183}
184
185
186
187
188
189
190#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EB64P)
191struct alpha_machine_vector eb64p_mv __initmv = {
192 .vector_name = "EB64+",
193 DO_EV4_MMU,
194 DO_DEFAULT_RTC,
195 DO_APECS_IO,
196 .machine_check = apecs_machine_check,
197 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
198 .min_io_address = DEFAULT_IO_BASE,
199 .min_mem_address = APECS_AND_LCA_DEFAULT_MEM_BASE,
200
201 .nr_irqs = 32,
202 .device_interrupt = eb64p_device_interrupt,
203
204 .init_arch = apecs_init_arch,
205 .init_irq = eb64p_init_irq,
206 .init_rtc = common_init_rtc,
207 .init_pci = common_init_pci,
208 .kill_arch = NULL,
209 .pci_map_irq = eb64p_map_irq,
210 .pci_swizzle = common_swizzle,
211};
212ALIAS_MV(eb64p)
213#endif
214
215#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EB66)
216struct alpha_machine_vector eb66_mv __initmv = {
217 .vector_name = "EB66",
218 DO_EV4_MMU,
219 DO_DEFAULT_RTC,
220 DO_LCA_IO,
221 .machine_check = lca_machine_check,
222 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
223 .min_io_address = DEFAULT_IO_BASE,
224 .min_mem_address = APECS_AND_LCA_DEFAULT_MEM_BASE,
225
226 .nr_irqs = 32,
227 .device_interrupt = eb64p_device_interrupt,
228
229 .init_arch = lca_init_arch,
230 .init_irq = eb64p_init_irq,
231 .init_rtc = common_init_rtc,
232 .init_pci = common_init_pci,
233 .pci_map_irq = eb64p_map_irq,
234 .pci_swizzle = common_swizzle,
235};
236ALIAS_MV(eb66)
237#endif
238