This source file includes following definitions.
- sun4m_mask_irq
- sun4m_unmask_irq
- sun4m_startup_irq
- sun4m_shutdown_irq
- sun4m_build_device_irq
- sun4m_clear_clock_irq
- sun4m_nmi
- sun4m_unmask_profile_irq
- sun4m_clear_profile_irq
- sun4m_load_profile_irq
- sun4m_init_timers
- sun4m_init_IRQ
1
2
3
4
5
6
7
8
9
10
11
12
13 #include <linux/slab.h>
14 #include <linux/sched/debug.h>
15
16 #include <asm/timer.h>
17 #include <asm/traps.h>
18 #include <asm/pgalloc.h>
19 #include <asm/pgtable.h>
20 #include <asm/irq.h>
21 #include <asm/io.h>
22 #include <asm/cacheflush.h>
23
24 #include "irq.h"
25 #include "kernel.h"
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104 struct sun4m_irq_percpu __iomem *sun4m_irq_percpu[SUN4M_NCPUS];
105 struct sun4m_irq_global __iomem *sun4m_irq_global;
106
107 struct sun4m_handler_data {
108 bool percpu;
109 long mask;
110 };
111
112
113
114
115 #define SUN4M_INT_ENABLE 0x80000000
116 #define SUN4M_INT_E14 0x00000080
117 #define SUN4M_INT_E10 0x00080000
118
119 #define SUN4M_INT_MASKALL 0x80000000
120 #define SUN4M_INT_MODULE_ERR 0x40000000
121 #define SUN4M_INT_M2S_WRITE_ERR 0x20000000
122 #define SUN4M_INT_ECC_ERR 0x10000000
123 #define SUN4M_INT_VME_ERR 0x08000000
124 #define SUN4M_INT_FLOPPY 0x00400000
125 #define SUN4M_INT_MODULE 0x00200000
126 #define SUN4M_INT_VIDEO 0x00100000
127 #define SUN4M_INT_REALTIME 0x00080000
128 #define SUN4M_INT_SCSI 0x00040000
129 #define SUN4M_INT_AUDIO 0x00020000
130 #define SUN4M_INT_ETHERNET 0x00010000
131 #define SUN4M_INT_SERIAL 0x00008000
132 #define SUN4M_INT_KBDMS 0x00004000
133 #define SUN4M_INT_SBUSBITS 0x00003F80
134 #define SUN4M_INT_VMEBITS 0x0000007F
135
136 #define SUN4M_INT_ERROR (SUN4M_INT_MODULE_ERR | \
137 SUN4M_INT_M2S_WRITE_ERR | \
138 SUN4M_INT_ECC_ERR | \
139 SUN4M_INT_VME_ERR)
140
141 #define SUN4M_INT_SBUS(x) (1 << (x+7))
142 #define SUN4M_INT_VME(x) (1 << (x))
143
144
145 #define OBP_INT_LEVEL_SOFT 0x10
146 #define OBP_INT_LEVEL_ONBOARD 0x20
147 #define OBP_INT_LEVEL_SBUS 0x30
148 #define OBP_INT_LEVEL_VME 0x40
149
150 #define SUN4M_TIMER_IRQ (OBP_INT_LEVEL_ONBOARD | 10)
151 #define SUN4M_PROFILE_IRQ (OBP_INT_LEVEL_ONBOARD | 14)
152
153 static unsigned long sun4m_imask[0x50] = {
154
155 0, SUN4M_SOFT_INT(1),
156 SUN4M_SOFT_INT(2), SUN4M_SOFT_INT(3),
157 SUN4M_SOFT_INT(4), SUN4M_SOFT_INT(5),
158 SUN4M_SOFT_INT(6), SUN4M_SOFT_INT(7),
159 SUN4M_SOFT_INT(8), SUN4M_SOFT_INT(9),
160 SUN4M_SOFT_INT(10), SUN4M_SOFT_INT(11),
161 SUN4M_SOFT_INT(12), SUN4M_SOFT_INT(13),
162 SUN4M_SOFT_INT(14), SUN4M_SOFT_INT(15),
163
164 0, SUN4M_SOFT_INT(1),
165 SUN4M_SOFT_INT(2), SUN4M_SOFT_INT(3),
166 SUN4M_SOFT_INT(4), SUN4M_SOFT_INT(5),
167 SUN4M_SOFT_INT(6), SUN4M_SOFT_INT(7),
168 SUN4M_SOFT_INT(8), SUN4M_SOFT_INT(9),
169 SUN4M_SOFT_INT(10), SUN4M_SOFT_INT(11),
170 SUN4M_SOFT_INT(12), SUN4M_SOFT_INT(13),
171 SUN4M_SOFT_INT(14), SUN4M_SOFT_INT(15),
172
173 0, 0, 0, 0,
174 SUN4M_INT_SCSI, 0, SUN4M_INT_ETHERNET, 0,
175 SUN4M_INT_VIDEO, SUN4M_INT_MODULE,
176 SUN4M_INT_REALTIME, SUN4M_INT_FLOPPY,
177 (SUN4M_INT_SERIAL | SUN4M_INT_KBDMS),
178 SUN4M_INT_AUDIO, SUN4M_INT_E14, SUN4M_INT_MODULE_ERR,
179
180 0, 0, SUN4M_INT_SBUS(0), SUN4M_INT_SBUS(1),
181 0, SUN4M_INT_SBUS(2), 0, SUN4M_INT_SBUS(3),
182 0, SUN4M_INT_SBUS(4), 0, SUN4M_INT_SBUS(5),
183 0, SUN4M_INT_SBUS(6), 0, 0,
184
185 0, 0, SUN4M_INT_VME(0), SUN4M_INT_VME(1),
186 0, SUN4M_INT_VME(2), 0, SUN4M_INT_VME(3),
187 0, SUN4M_INT_VME(4), 0, SUN4M_INT_VME(5),
188 0, SUN4M_INT_VME(6), 0, 0
189 };
190
191 static void sun4m_mask_irq(struct irq_data *data)
192 {
193 struct sun4m_handler_data *handler_data;
194 int cpu = smp_processor_id();
195
196 handler_data = irq_data_get_irq_handler_data(data);
197 if (handler_data->mask) {
198 unsigned long flags;
199
200 local_irq_save(flags);
201 if (handler_data->percpu) {
202 sbus_writel(handler_data->mask, &sun4m_irq_percpu[cpu]->set);
203 } else {
204 sbus_writel(handler_data->mask, &sun4m_irq_global->mask_set);
205 }
206 local_irq_restore(flags);
207 }
208 }
209
210 static void sun4m_unmask_irq(struct irq_data *data)
211 {
212 struct sun4m_handler_data *handler_data;
213 int cpu = smp_processor_id();
214
215 handler_data = irq_data_get_irq_handler_data(data);
216 if (handler_data->mask) {
217 unsigned long flags;
218
219 local_irq_save(flags);
220 if (handler_data->percpu) {
221 sbus_writel(handler_data->mask, &sun4m_irq_percpu[cpu]->clear);
222 } else {
223 sbus_writel(handler_data->mask, &sun4m_irq_global->mask_clear);
224 }
225 local_irq_restore(flags);
226 }
227 }
228
229 static unsigned int sun4m_startup_irq(struct irq_data *data)
230 {
231 irq_link(data->irq);
232 sun4m_unmask_irq(data);
233 return 0;
234 }
235
236 static void sun4m_shutdown_irq(struct irq_data *data)
237 {
238 sun4m_mask_irq(data);
239 irq_unlink(data->irq);
240 }
241
242 static struct irq_chip sun4m_irq = {
243 .name = "sun4m",
244 .irq_startup = sun4m_startup_irq,
245 .irq_shutdown = sun4m_shutdown_irq,
246 .irq_mask = sun4m_mask_irq,
247 .irq_unmask = sun4m_unmask_irq,
248 };
249
250
251 static unsigned int sun4m_build_device_irq(struct platform_device *op,
252 unsigned int real_irq)
253 {
254 struct sun4m_handler_data *handler_data;
255 unsigned int irq;
256 unsigned int pil;
257
258 if (real_irq >= OBP_INT_LEVEL_VME) {
259 prom_printf("Bogus sun4m IRQ %u\n", real_irq);
260 prom_halt();
261 }
262 pil = (real_irq & 0xf);
263 irq = irq_alloc(real_irq, pil);
264
265 if (irq == 0)
266 goto out;
267
268 handler_data = irq_get_handler_data(irq);
269 if (unlikely(handler_data))
270 goto out;
271
272 handler_data = kzalloc(sizeof(struct sun4m_handler_data), GFP_ATOMIC);
273 if (unlikely(!handler_data)) {
274 prom_printf("IRQ: kzalloc(sun4m_handler_data) failed.\n");
275 prom_halt();
276 }
277
278 handler_data->mask = sun4m_imask[real_irq];
279 handler_data->percpu = real_irq < OBP_INT_LEVEL_ONBOARD;
280 irq_set_chip_and_handler_name(irq, &sun4m_irq,
281 handle_level_irq, "level");
282 irq_set_handler_data(irq, handler_data);
283
284 out:
285 return irq;
286 }
287
288 struct sun4m_timer_percpu {
289 u32 l14_limit;
290 u32 l14_count;
291 u32 l14_limit_noclear;
292 u32 user_timer_start_stop;
293 };
294
295 static struct sun4m_timer_percpu __iomem *timers_percpu[SUN4M_NCPUS];
296
297 struct sun4m_timer_global {
298 u32 l10_limit;
299 u32 l10_count;
300 u32 l10_limit_noclear;
301 u32 reserved;
302 u32 timer_config;
303 };
304
305 static struct sun4m_timer_global __iomem *timers_global;
306
307 static void sun4m_clear_clock_irq(void)
308 {
309 sbus_readl(&timers_global->l10_limit);
310 }
311
312 void sun4m_nmi(struct pt_regs *regs)
313 {
314 unsigned long afsr, afar, si;
315
316 printk(KERN_ERR "Aieee: sun4m NMI received!\n");
317
318 __asm__ __volatile__("mov 0x500, %%g1\n\t"
319 "lda [%%g1] 0x4, %0\n\t"
320 "mov 0x600, %%g1\n\t"
321 "lda [%%g1] 0x4, %1\n\t" :
322 "=r" (afsr), "=r" (afar));
323 printk(KERN_ERR "afsr=%08lx afar=%08lx\n", afsr, afar);
324 si = sbus_readl(&sun4m_irq_global->pending);
325 printk(KERN_ERR "si=%08lx\n", si);
326 if (si & SUN4M_INT_MODULE_ERR)
327 printk(KERN_ERR "Module async error\n");
328 if (si & SUN4M_INT_M2S_WRITE_ERR)
329 printk(KERN_ERR "MBus/SBus async error\n");
330 if (si & SUN4M_INT_ECC_ERR)
331 printk(KERN_ERR "ECC memory error\n");
332 if (si & SUN4M_INT_VME_ERR)
333 printk(KERN_ERR "VME async error\n");
334 printk(KERN_ERR "you lose buddy boy...\n");
335 show_regs(regs);
336 prom_halt();
337 }
338
339 void sun4m_unmask_profile_irq(void)
340 {
341 unsigned long flags;
342
343 local_irq_save(flags);
344 sbus_writel(sun4m_imask[SUN4M_PROFILE_IRQ], &sun4m_irq_global->mask_clear);
345 local_irq_restore(flags);
346 }
347
348 void sun4m_clear_profile_irq(int cpu)
349 {
350 sbus_readl(&timers_percpu[cpu]->l14_limit);
351 }
352
353 static void sun4m_load_profile_irq(int cpu, unsigned int limit)
354 {
355 unsigned int value = limit ? timer_value(limit) : 0;
356 sbus_writel(value, &timers_percpu[cpu]->l14_limit);
357 }
358
359 static void __init sun4m_init_timers(void)
360 {
361 struct device_node *dp = of_find_node_by_name(NULL, "counter");
362 int i, err, len, num_cpu_timers;
363 unsigned int irq;
364 const u32 *addr;
365
366 if (!dp) {
367 printk(KERN_ERR "sun4m_init_timers: No 'counter' node.\n");
368 return;
369 }
370
371 addr = of_get_property(dp, "address", &len);
372 of_node_put(dp);
373 if (!addr) {
374 printk(KERN_ERR "sun4m_init_timers: No 'address' prop.\n");
375 return;
376 }
377
378 num_cpu_timers = (len / sizeof(u32)) - 1;
379 for (i = 0; i < num_cpu_timers; i++) {
380 timers_percpu[i] = (void __iomem *)
381 (unsigned long) addr[i];
382 }
383 timers_global = (void __iomem *)
384 (unsigned long) addr[num_cpu_timers];
385
386
387 sbus_writel(0x00000000, &timers_global->timer_config);
388
389 #ifdef CONFIG_SMP
390 sparc_config.cs_period = SBUS_CLOCK_RATE * 2;
391 sparc_config.features |= FEAT_L14_ONESHOT;
392 #else
393 sparc_config.cs_period = SBUS_CLOCK_RATE / HZ;
394 sparc_config.features |= FEAT_L10_CLOCKEVENT;
395 #endif
396 sparc_config.features |= FEAT_L10_CLOCKSOURCE;
397 sbus_writel(timer_value(sparc_config.cs_period),
398 &timers_global->l10_limit);
399
400 master_l10_counter = &timers_global->l10_count;
401
402 irq = sun4m_build_device_irq(NULL, SUN4M_TIMER_IRQ);
403
404 err = request_irq(irq, timer_interrupt, IRQF_TIMER, "timer", NULL);
405 if (err) {
406 printk(KERN_ERR "sun4m_init_timers: Register IRQ error %d.\n",
407 err);
408 return;
409 }
410
411 for (i = 0; i < num_cpu_timers; i++)
412 sbus_writel(0, &timers_percpu[i]->l14_limit);
413 if (num_cpu_timers == 4)
414 sbus_writel(SUN4M_INT_E14, &sun4m_irq_global->mask_set);
415
416 #ifdef CONFIG_SMP
417 {
418 unsigned long flags;
419 struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (14 - 1)];
420
421
422
423
424
425 local_irq_save(flags);
426 trap_table->inst_one = lvl14_save[0];
427 trap_table->inst_two = lvl14_save[1];
428 trap_table->inst_three = lvl14_save[2];
429 trap_table->inst_four = lvl14_save[3];
430 local_ops->cache_all();
431 local_irq_restore(flags);
432 }
433 #endif
434 }
435
436 void __init sun4m_init_IRQ(void)
437 {
438 struct device_node *dp = of_find_node_by_name(NULL, "interrupt");
439 int len, i, mid, num_cpu_iregs;
440 const u32 *addr;
441
442 if (!dp) {
443 printk(KERN_ERR "sun4m_init_IRQ: No 'interrupt' node.\n");
444 return;
445 }
446
447 addr = of_get_property(dp, "address", &len);
448 of_node_put(dp);
449 if (!addr) {
450 printk(KERN_ERR "sun4m_init_IRQ: No 'address' prop.\n");
451 return;
452 }
453
454 num_cpu_iregs = (len / sizeof(u32)) - 1;
455 for (i = 0; i < num_cpu_iregs; i++) {
456 sun4m_irq_percpu[i] = (void __iomem *)
457 (unsigned long) addr[i];
458 }
459 sun4m_irq_global = (void __iomem *)
460 (unsigned long) addr[num_cpu_iregs];
461
462 local_irq_disable();
463
464 sbus_writel(~SUN4M_INT_MASKALL, &sun4m_irq_global->mask_set);
465 for (i = 0; !cpu_find_by_instance(i, NULL, &mid); i++)
466 sbus_writel(~0x17fff, &sun4m_irq_percpu[mid]->clear);
467
468 if (num_cpu_iregs == 4)
469 sbus_writel(0, &sun4m_irq_global->interrupt_target);
470
471 sparc_config.init_timers = sun4m_init_timers;
472 sparc_config.build_device_irq = sun4m_build_device_irq;
473 sparc_config.clock_rate = SBUS_CLOCK_RATE;
474 sparc_config.clear_clock_irq = sun4m_clear_clock_irq;
475 sparc_config.load_profile_irq = sun4m_load_profile_irq;
476
477
478
479 }