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
arm
mach-dove
irq.c
Go to the documentation of this file.
1
/*
2
* arch/arm/mach-dove/irq.c
3
*
4
* Dove IRQ handling.
5
*
6
* This file is licensed under the terms of the GNU General Public
7
* License version 2. This program is licensed "as is" without any
8
* warranty of any kind, whether express or implied.
9
*/
10
11
#include <linux/kernel.h>
12
#include <
linux/init.h
>
13
#include <
linux/irq.h
>
14
#include <
linux/gpio.h
>
15
#include <
linux/io.h
>
16
#include <
asm/mach/arch.h
>
17
#include <plat/irq.h>
18
#include <
asm/mach/irq.h
>
19
#include <mach/pm.h>
20
#include <mach/bridge-regs.h>
21
#include <
plat/orion-gpio.h
>
22
#include "
common.h
"
23
24
static
void
pmu_irq_mask(
struct
irq_data
*
d
)
25
{
26
int
pin
= irq_to_pmu(d->
irq
);
27
u32
u
;
28
29
u =
readl
(
PMU_INTERRUPT_MASK
);
30
u &= ~(1 << (pin & 31));
31
writel
(u,
PMU_INTERRUPT_MASK
);
32
}
33
34
static
void
pmu_irq_unmask(
struct
irq_data
*
d
)
35
{
36
int
pin
= irq_to_pmu(d->
irq
);
37
u32
u
;
38
39
u =
readl
(
PMU_INTERRUPT_MASK
);
40
u |= 1 << (pin & 31);
41
writel
(u,
PMU_INTERRUPT_MASK
);
42
}
43
44
static
void
pmu_irq_ack(
struct
irq_data
*
d
)
45
{
46
int
pin
= irq_to_pmu(d->
irq
);
47
u32
u
;
48
49
/*
50
* The PMU mask register is not RW0C: it is RW. This means that
51
* the bits take whatever value is written to them; if you write
52
* a '1', you will set the interrupt.
53
*
54
* Unfortunately this means there is NO race free way to clear
55
* these interrupts.
56
*
57
* So, let's structure the code so that the window is as small as
58
* possible.
59
*/
60
u = ~(1 << (pin & 31));
61
u &=
readl_relaxed
(
PMU_INTERRUPT_CAUSE
);
62
writel_relaxed(u,
PMU_INTERRUPT_CAUSE
);
63
}
64
65
static
struct
irq_chip
pmu_irq_chip = {
66
.name =
"pmu_irq"
,
67
.irq_mask = pmu_irq_mask,
68
.irq_unmask = pmu_irq_unmask,
69
.irq_ack = pmu_irq_ack,
70
};
71
72
static
void
pmu_irq_handler(
unsigned
int
irq,
struct
irq_desc
*
desc
)
73
{
74
unsigned
long
cause
=
readl
(
PMU_INTERRUPT_CAUSE
);
75
76
cause &=
readl
(
PMU_INTERRUPT_MASK
);
77
if
(cause == 0) {
78
do_bad_IRQ
(irq, desc);
79
return
;
80
}
81
82
for
(irq = 0; irq <
NR_PMU_IRQS
; irq++) {
83
if
(!(cause & (1 << irq)))
84
continue
;
85
irq = pmu_to_irq(irq);
86
generic_handle_irq
(irq);
87
}
88
}
89
90
static
int
__initdata
gpio0_irqs[4] = {
91
IRQ_DOVE_GPIO_0_7
,
92
IRQ_DOVE_GPIO_8_15
,
93
IRQ_DOVE_GPIO_16_23
,
94
IRQ_DOVE_GPIO_24_31
,
95
};
96
97
static
int
__initdata
gpio1_irqs[4] = {
98
IRQ_DOVE_HIGH_GPIO
,
99
0,
100
0,
101
0,
102
};
103
104
static
int
__initdata
gpio2_irqs[4] = {
105
0,
106
0,
107
0,
108
0,
109
};
110
111
void
__init
dove_init_irq
(
void
)
112
{
113
int
i
;
114
115
orion_irq_init
(0,
IRQ_VIRT_BASE
+
IRQ_MASK_LOW_OFF
);
116
orion_irq_init
(32,
IRQ_VIRT_BASE
+
IRQ_MASK_HIGH_OFF
);
117
118
/*
119
* Initialize gpiolib for GPIOs 0-71.
120
*/
121
orion_gpio_init
(
NULL
, 0, 32,
DOVE_GPIO_LO_VIRT_BASE
, 0,
122
IRQ_DOVE_GPIO_START
, gpio0_irqs);
123
124
orion_gpio_init
(
NULL
, 32, 32,
DOVE_GPIO_HI_VIRT_BASE
, 0,
125
IRQ_DOVE_GPIO_START
+ 32, gpio1_irqs);
126
127
orion_gpio_init
(
NULL
, 64, 8,
DOVE_GPIO2_VIRT_BASE
, 0,
128
IRQ_DOVE_GPIO_START
+ 64, gpio2_irqs);
129
130
/*
131
* Mask and clear PMU interrupts
132
*/
133
writel
(0,
PMU_INTERRUPT_MASK
);
134
writel
(0,
PMU_INTERRUPT_CAUSE
);
135
136
for
(i =
IRQ_DOVE_PMU_START
; i <
NR_IRQS
; i++) {
137
irq_set_chip_and_handler(i, &pmu_irq_chip,
handle_level_irq
);
138
irq_set_status_flags(i,
IRQ_LEVEL
);
139
set_irq_flags
(i,
IRQF_VALID
);
140
}
141
irq_set_chained_handler(
IRQ_DOVE_PMU
, pmu_irq_handler);
142
}
Generated on Thu Jan 10 2013 12:51:23 for Linux Kernel by
1.8.2