1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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
105
106
107
108
109
110
111
112
113
114
115
116
|
/*
* Portions copyright (C) 2005-2009 Scientific Atlanta
* Portions copyright (C) 2009 Cisco Systems, Inc.
*
* Modified from arch/mips/kernel/irq-rm7000.c:
* Copyright (C) 2003 Ralf Baechle
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/irq.h>
#include <asm/irq_cpu.h>
#include <asm/mipsregs.h>
#include <asm/system.h>
#include <asm/mach-powertv/asic_regs.h>
static inline void unmask_asic_irq(struct irq_data *d)
{
unsigned long enable_bit;
unsigned int irq = d->irq;
enable_bit = (1 << (irq & 0x1f));
switch (irq >> 5) {
case 0:
asic_write(asic_read(ien_int_0) | enable_bit, ien_int_0);
break;
case 1:
asic_write(asic_read(ien_int_1) | enable_bit, ien_int_1);
break;
case 2:
asic_write(asic_read(ien_int_2) | enable_bit, ien_int_2);
break;
case 3:
asic_write(asic_read(ien_int_3) | enable_bit, ien_int_3);
break;
default:
BUG();
}
}
static inline void mask_asic_irq(struct irq_data *d)
{
unsigned long disable_mask;
unsigned int irq = d->irq;
disable_mask = ~(1 << (irq & 0x1f));
switch (irq >> 5) {
case 0:
asic_write(asic_read(ien_int_0) & disable_mask, ien_int_0);
break;
case 1:
asic_write(asic_read(ien_int_1) & disable_mask, ien_int_1);
break;
case 2:
asic_write(asic_read(ien_int_2) & disable_mask, ien_int_2);
break;
case 3:
asic_write(asic_read(ien_int_3) & disable_mask, ien_int_3);
break;
default:
BUG();
}
}
static struct irq_chip asic_irq_chip = {
.name = "ASIC Level",
.irq_mask = mask_asic_irq,
.irq_unmask = unmask_asic_irq,
};
void __init asic_irq_init(void)
{
int i;
/* set priority to 0 */
write_c0_status(read_c0_status() & ~(0x0000fc00));
asic_write(0, ien_int_0);
asic_write(0, ien_int_1);
asic_write(0, ien_int_2);
asic_write(0, ien_int_3);
asic_write(0x0fffffff, int_level_3_3);
asic_write(0xffffffff, int_level_3_2);
asic_write(0xffffffff, int_level_3_1);
asic_write(0xffffffff, int_level_3_0);
asic_write(0xffffffff, int_level_2_3);
asic_write(0xffffffff, int_level_2_2);
asic_write(0xffffffff, int_level_2_1);
asic_write(0xffffffff, int_level_2_0);
asic_write(0xffffffff, int_level_1_3);
asic_write(0xffffffff, int_level_1_2);
asic_write(0xffffffff, int_level_1_1);
asic_write(0xffffffff, int_level_1_0);
asic_write(0xffffffff, int_level_0_3);
asic_write(0xffffffff, int_level_0_2);
asic_write(0xffffffff, int_level_0_1);
asic_write(0xffffffff, int_level_0_0);
asic_write(0xf, int_int_scan);
/*
* Initialize interrupt handlers.
*/
for (i = 0; i < NR_IRQS; i++)
set_irq_chip_and_handler(i, &asic_irq_chip, handle_level_irq);
}
|