Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/arm/mach-footbridge/isa-irq.c
26292 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* linux/arch/arm/mach-footbridge/irq.c
4
*
5
* Copyright (C) 1996-2000 Russell King
6
*
7
* Changelog:
8
* 22-Aug-1998 RMK Restructured IRQ routines
9
* 03-Sep-1998 PJB Merged CATS support
10
* 20-Jan-1998 RMK Started merge of EBSA286, CATS and NetWinder
11
* 26-Jan-1999 PJB Don't use IACK on CATS
12
* 16-Mar-1999 RMK Added autodetect of ISA PICs
13
*/
14
#include <linux/ioport.h>
15
#include <linux/interrupt.h>
16
#include <linux/list.h>
17
#include <linux/init.h>
18
#include <linux/io.h>
19
#include <linux/spinlock.h>
20
21
#include <asm/mach/irq.h>
22
23
#include <mach/hardware.h>
24
#include <asm/hardware/dec21285.h>
25
#include <asm/irq.h>
26
#include <asm/mach-types.h>
27
28
#include "common.h"
29
30
static void isa_mask_pic_lo_irq(struct irq_data *d)
31
{
32
unsigned int mask = 1 << (d->irq & 7);
33
34
outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO);
35
}
36
37
static void isa_ack_pic_lo_irq(struct irq_data *d)
38
{
39
unsigned int mask = 1 << (d->irq & 7);
40
41
outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO);
42
outb(0x20, PIC_LO);
43
}
44
45
static void isa_unmask_pic_lo_irq(struct irq_data *d)
46
{
47
unsigned int mask = 1 << (d->irq & 7);
48
49
outb(inb(PIC_MASK_LO) & ~mask, PIC_MASK_LO);
50
}
51
52
static struct irq_chip isa_lo_chip = {
53
.irq_ack = isa_ack_pic_lo_irq,
54
.irq_mask = isa_mask_pic_lo_irq,
55
.irq_unmask = isa_unmask_pic_lo_irq,
56
};
57
58
static void isa_mask_pic_hi_irq(struct irq_data *d)
59
{
60
unsigned int mask = 1 << (d->irq & 7);
61
62
outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI);
63
}
64
65
static void isa_ack_pic_hi_irq(struct irq_data *d)
66
{
67
unsigned int mask = 1 << (d->irq & 7);
68
69
outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI);
70
outb(0x62, PIC_LO);
71
outb(0x20, PIC_HI);
72
}
73
74
static void isa_unmask_pic_hi_irq(struct irq_data *d)
75
{
76
unsigned int mask = 1 << (d->irq & 7);
77
78
outb(inb(PIC_MASK_HI) & ~mask, PIC_MASK_HI);
79
}
80
81
static struct irq_chip isa_hi_chip = {
82
.irq_ack = isa_ack_pic_hi_irq,
83
.irq_mask = isa_mask_pic_hi_irq,
84
.irq_unmask = isa_unmask_pic_hi_irq,
85
};
86
87
static void isa_irq_handler(struct irq_desc *desc)
88
{
89
unsigned int isa_irq = *(unsigned char *)PCIIACK_BASE;
90
91
if (isa_irq < _ISA_IRQ(0) || isa_irq >= _ISA_IRQ(16)) {
92
do_bad_IRQ(desc);
93
return;
94
}
95
96
generic_handle_irq(isa_irq);
97
}
98
99
static struct resource pic1_resource = {
100
.name = "pic1",
101
.start = 0x20,
102
.end = 0x3f,
103
};
104
105
static struct resource pic2_resource = {
106
.name = "pic2",
107
.start = 0xa0,
108
.end = 0xbf,
109
};
110
111
void __init isa_init_irq(unsigned int host_irq)
112
{
113
unsigned int irq;
114
115
/*
116
* Setup, and then probe for an ISA PIC
117
* If the PIC is not there, then we
118
* ignore the PIC.
119
*/
120
outb(0x11, PIC_LO);
121
outb(_ISA_IRQ(0), PIC_MASK_LO); /* IRQ number */
122
outb(0x04, PIC_MASK_LO); /* Slave on Ch2 */
123
outb(0x01, PIC_MASK_LO); /* x86 */
124
outb(0xf5, PIC_MASK_LO); /* pattern: 11110101 */
125
126
outb(0x11, PIC_HI);
127
outb(_ISA_IRQ(8), PIC_MASK_HI); /* IRQ number */
128
outb(0x02, PIC_MASK_HI); /* Slave on Ch1 */
129
outb(0x01, PIC_MASK_HI); /* x86 */
130
outb(0xfa, PIC_MASK_HI); /* pattern: 11111010 */
131
132
outb(0x0b, PIC_LO);
133
outb(0x0b, PIC_HI);
134
135
if (inb(PIC_MASK_LO) == 0xf5 && inb(PIC_MASK_HI) == 0xfa) {
136
outb(0xff, PIC_MASK_LO);/* mask all IRQs */
137
outb(0xff, PIC_MASK_HI);/* mask all IRQs */
138
} else {
139
printk(KERN_INFO "IRQ: ISA PIC not found\n");
140
host_irq = (unsigned int)-1;
141
}
142
143
if (host_irq != (unsigned int)-1) {
144
for (irq = _ISA_IRQ(0); irq < _ISA_IRQ(8); irq++) {
145
irq_set_chip_and_handler(irq, &isa_lo_chip,
146
handle_level_irq);
147
irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);
148
}
149
150
for (irq = _ISA_IRQ(8); irq < _ISA_IRQ(16); irq++) {
151
irq_set_chip_and_handler(irq, &isa_hi_chip,
152
handle_level_irq);
153
irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);
154
}
155
156
request_resource(&ioport_resource, &pic1_resource);
157
request_resource(&ioport_resource, &pic2_resource);
158
159
irq = IRQ_ISA_CASCADE;
160
if (request_irq(irq, no_action, 0, "cascade", NULL))
161
pr_err("Failed to request irq %u (cascade)\n", irq);
162
163
irq_set_chained_handler(host_irq, isa_irq_handler);
164
165
/*
166
* On the NetWinder, don't automatically
167
* enable ISA IRQ11 when it is requested.
168
* There appears to be a missing pull-up
169
* resistor on this line.
170
*/
171
if (machine_is_netwinder())
172
irq_modify_status(_ISA_IRQ(11),
173
IRQ_NOREQUEST | IRQ_NOPROBE, IRQ_NOAUTOEN);
174
}
175
}
176
177
178
179