Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/arm/mach-rpc/irq.c
10817 views
1
#include <linux/init.h>
2
#include <linux/list.h>
3
#include <linux/io.h>
4
5
#include <asm/mach/irq.h>
6
#include <asm/hardware/iomd.h>
7
#include <asm/irq.h>
8
9
static void iomd_ack_irq_a(struct irq_data *d)
10
{
11
unsigned int val, mask;
12
13
mask = 1 << d->irq;
14
val = iomd_readb(IOMD_IRQMASKA);
15
iomd_writeb(val & ~mask, IOMD_IRQMASKA);
16
iomd_writeb(mask, IOMD_IRQCLRA);
17
}
18
19
static void iomd_mask_irq_a(struct irq_data *d)
20
{
21
unsigned int val, mask;
22
23
mask = 1 << d->irq;
24
val = iomd_readb(IOMD_IRQMASKA);
25
iomd_writeb(val & ~mask, IOMD_IRQMASKA);
26
}
27
28
static void iomd_unmask_irq_a(struct irq_data *d)
29
{
30
unsigned int val, mask;
31
32
mask = 1 << d->irq;
33
val = iomd_readb(IOMD_IRQMASKA);
34
iomd_writeb(val | mask, IOMD_IRQMASKA);
35
}
36
37
static struct irq_chip iomd_a_chip = {
38
.irq_ack = iomd_ack_irq_a,
39
.irq_mask = iomd_mask_irq_a,
40
.irq_unmask = iomd_unmask_irq_a,
41
};
42
43
static void iomd_mask_irq_b(struct irq_data *d)
44
{
45
unsigned int val, mask;
46
47
mask = 1 << (d->irq & 7);
48
val = iomd_readb(IOMD_IRQMASKB);
49
iomd_writeb(val & ~mask, IOMD_IRQMASKB);
50
}
51
52
static void iomd_unmask_irq_b(struct irq_data *d)
53
{
54
unsigned int val, mask;
55
56
mask = 1 << (d->irq & 7);
57
val = iomd_readb(IOMD_IRQMASKB);
58
iomd_writeb(val | mask, IOMD_IRQMASKB);
59
}
60
61
static struct irq_chip iomd_b_chip = {
62
.irq_ack = iomd_mask_irq_b,
63
.irq_mask = iomd_mask_irq_b,
64
.irq_unmask = iomd_unmask_irq_b,
65
};
66
67
static void iomd_mask_irq_dma(struct irq_data *d)
68
{
69
unsigned int val, mask;
70
71
mask = 1 << (d->irq & 7);
72
val = iomd_readb(IOMD_DMAMASK);
73
iomd_writeb(val & ~mask, IOMD_DMAMASK);
74
}
75
76
static void iomd_unmask_irq_dma(struct irq_data *d)
77
{
78
unsigned int val, mask;
79
80
mask = 1 << (d->irq & 7);
81
val = iomd_readb(IOMD_DMAMASK);
82
iomd_writeb(val | mask, IOMD_DMAMASK);
83
}
84
85
static struct irq_chip iomd_dma_chip = {
86
.irq_ack = iomd_mask_irq_dma,
87
.irq_mask = iomd_mask_irq_dma,
88
.irq_unmask = iomd_unmask_irq_dma,
89
};
90
91
static void iomd_mask_irq_fiq(struct irq_data *d)
92
{
93
unsigned int val, mask;
94
95
mask = 1 << (d->irq & 7);
96
val = iomd_readb(IOMD_FIQMASK);
97
iomd_writeb(val & ~mask, IOMD_FIQMASK);
98
}
99
100
static void iomd_unmask_irq_fiq(struct irq_data *d)
101
{
102
unsigned int val, mask;
103
104
mask = 1 << (d->irq & 7);
105
val = iomd_readb(IOMD_FIQMASK);
106
iomd_writeb(val | mask, IOMD_FIQMASK);
107
}
108
109
static struct irq_chip iomd_fiq_chip = {
110
.irq_ack = iomd_mask_irq_fiq,
111
.irq_mask = iomd_mask_irq_fiq,
112
.irq_unmask = iomd_unmask_irq_fiq,
113
};
114
115
void __init rpc_init_irq(void)
116
{
117
unsigned int irq, flags;
118
119
iomd_writeb(0, IOMD_IRQMASKA);
120
iomd_writeb(0, IOMD_IRQMASKB);
121
iomd_writeb(0, IOMD_FIQMASK);
122
iomd_writeb(0, IOMD_DMAMASK);
123
124
for (irq = 0; irq < NR_IRQS; irq++) {
125
flags = IRQF_VALID;
126
127
if (irq <= 6 || (irq >= 9 && irq <= 15))
128
flags |= IRQF_PROBE;
129
130
if (irq == 21 || (irq >= 16 && irq <= 19) ||
131
irq == IRQ_KEYBOARDTX)
132
flags |= IRQF_NOAUTOEN;
133
134
switch (irq) {
135
case 0 ... 7:
136
irq_set_chip_and_handler(irq, &iomd_a_chip,
137
handle_level_irq);
138
set_irq_flags(irq, flags);
139
break;
140
141
case 8 ... 15:
142
irq_set_chip_and_handler(irq, &iomd_b_chip,
143
handle_level_irq);
144
set_irq_flags(irq, flags);
145
break;
146
147
case 16 ... 21:
148
irq_set_chip_and_handler(irq, &iomd_dma_chip,
149
handle_level_irq);
150
set_irq_flags(irq, flags);
151
break;
152
153
case 64 ... 71:
154
irq_set_chip(irq, &iomd_fiq_chip);
155
set_irq_flags(irq, IRQF_VALID);
156
break;
157
}
158
}
159
160
init_FIQ();
161
}
162
163
164