Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
mips
powertv
asic
asic_int.c
Go to the documentation of this file.
1
/*
2
* Carsten Langgaard,
[email protected]
3
* Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc.
4
* Copyright (C) 2001 Ralf Baechle
5
* Portions copyright (C) 2009 Cisco Systems, Inc.
6
*
7
* This program is free software; you can distribute it and/or modify it
8
* under the terms of the GNU General Public License (Version 2) as
9
* published by the Free Software Foundation.
10
*
11
* This program is distributed in the hope it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* for more details.
15
*
16
* You should have received a copy of the GNU General Public License along
17
* with this program; if not, write to the Free Software Foundation, Inc.,
18
* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
19
*
20
* Routines for generic manipulation of the interrupts found on the PowerTV
21
* platform.
22
*
23
* The interrupt controller is located in the South Bridge a PIIX4 device
24
* with two internal 82C95 interrupt controllers.
25
*/
26
#include <
linux/init.h
>
27
#include <
linux/irq.h
>
28
#include <linux/sched.h>
29
#include <
linux/interrupt.h
>
30
#include <
linux/kernel_stat.h
>
31
#include <linux/kernel.h>
32
#include <linux/random.h>
33
34
#include <
asm/irq_cpu.h
>
35
#include <
linux/io.h
>
36
#include <asm/irq_regs.h>
37
#include <asm/setup.h>
38
#include <
asm/mips-boards/generic.h
>
39
40
#include <
asm/mach-powertv/asic_regs.h
>
41
42
static
DEFINE_RAW_SPINLOCK
(asic_irq_lock);
43
44
static
inline
int
get_int(
void
)
45
{
46
unsigned
long
flags
;
47
int
irq
;
48
49
raw_spin_lock_irqsave
(&asic_irq_lock, flags);
50
51
irq = (
asic_read
(int_int_scan) >> 4) - 1;
52
53
if
(irq == 0 || irq >=
NR_IRQS
)
54
irq = -1;
55
56
raw_spin_unlock_irqrestore
(&asic_irq_lock, flags);
57
58
return
irq;
59
}
60
61
static
void
asic_irqdispatch(
void
)
62
{
63
int
irq;
64
65
irq = get_int();
66
if
(irq < 0)
67
return
;
/* interrupt has already been cleared */
68
69
do_IRQ
(irq);
70
}
71
72
static
inline
int
clz
(
unsigned
long
x
)
73
{
74
__asm__
(
75
" .set push \n"
76
" .set mips32 \n"
77
" clz %0, %1 \n"
78
" .set pop \n"
79
:
"=r"
(x)
80
:
"r"
(x));
81
82
return
x
;
83
}
84
85
/*
86
* Version of ffs that only looks at bits 12..15.
87
*/
88
static
inline
unsigned
int
irq_ffs(
unsigned
int
pending)
89
{
90
return
fls(pending) - 1 +
CAUSEB_IP
;
91
}
92
93
/*
94
* TODO: check how it works under EIC mode.
95
*/
96
asmlinkage
void
plat_irq_dispatch
(
void
)
97
{
98
unsigned
int
pending =
read_c0_cause
() &
read_c0_status
() &
ST0_IM
;
99
int
irq;
100
101
irq = irq_ffs(pending);
102
103
if
(irq ==
CAUSEF_IP3
)
104
asic_irqdispatch();
105
else
if
(irq >= 0)
106
do_IRQ
(irq);
107
else
108
spurious_interrupt
();
109
}
110
111
void
__init
arch_init_irq
(
void
)
112
{
113
int
i
;
114
115
asic_irq_init
();
116
117
/*
118
* Initialize interrupt exception vectors.
119
*/
120
if
(
cpu_has_veic
||
cpu_has_vint
) {
121
int
nvec =
cpu_has_veic
? 64 : 8;
122
for
(i = 0; i < nvec; i++)
123
set_vi_handler
(i, asic_irqdispatch);
124
}
125
}
Generated on Thu Jan 10 2013 13:12:10 for Linux Kernel by
1.8.2