Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
1ffee2cd
Commit
1ffee2cd
authored
Apr 17, 2003
by
Alan Cox
Committed by
Linus Torvalds
Apr 17, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] generalise PIC locations, PIT and FPU IRQ
parent
a1b123ad
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
49 additions
and
43 deletions
+49
-43
arch/i386/kernel/i8259.c
arch/i386/kernel/i8259.c
+49
-43
No files found.
arch/i386/kernel/i8259.c
View file @
1ffee2cd
...
...
@@ -26,6 +26,8 @@
#include <linux/irq.h>
#include <io_ports.h>
/*
* This is the 'legacy' 8259A Programmable Interrupt Controller,
* present in the majority of PC/AT boxes.
...
...
@@ -93,9 +95,9 @@ void disable_8259A_irq(unsigned int irq)
spin_lock_irqsave
(
&
i8259A_lock
,
flags
);
cached_irq_mask
|=
mask
;
if
(
irq
&
8
)
outb
(
cached_
A1
,
0xA1
);
outb
(
cached_
slave_mask
,
PIC_SLAVE_IMR
);
else
outb
(
cached_
21
,
0x21
);
outb
(
cached_
master_mask
,
PIC_MASTER_IMR
);
spin_unlock_irqrestore
(
&
i8259A_lock
,
flags
);
}
...
...
@@ -107,9 +109,9 @@ void enable_8259A_irq(unsigned int irq)
spin_lock_irqsave
(
&
i8259A_lock
,
flags
);
cached_irq_mask
&=
mask
;
if
(
irq
&
8
)
outb
(
cached_
A1
,
0xA1
);
outb
(
cached_
slave_mask
,
PIC_SLAVE_IMR
);
else
outb
(
cached_
21
,
0x21
);
outb
(
cached_
master_mask
,
PIC_MASTER_IMR
);
spin_unlock_irqrestore
(
&
i8259A_lock
,
flags
);
}
...
...
@@ -121,9 +123,9 @@ int i8259A_irq_pending(unsigned int irq)
spin_lock_irqsave
(
&
i8259A_lock
,
flags
);
if
(
irq
<
8
)
ret
=
inb
(
0x20
)
&
mask
;
ret
=
inb
(
PIC_MASTER_CMD
)
&
mask
;
else
ret
=
inb
(
0xA0
)
&
(
mask
>>
8
);
ret
=
inb
(
PIC_SLAVE_CMD
)
&
(
mask
>>
8
);
spin_unlock_irqrestore
(
&
i8259A_lock
,
flags
);
return
ret
;
...
...
@@ -149,14 +151,14 @@ static inline int i8259A_irq_real(unsigned int irq)
int
irqmask
=
1
<<
irq
;
if
(
irq
<
8
)
{
outb
(
0x0B
,
0x20
);
/* ISR register */
value
=
inb
(
0x20
)
&
irqmask
;
outb
(
0x0A
,
0x20
);
/* back to the IRR register */
outb
(
0x0B
,
PIC_MASTER_CMD
);
/* ISR register */
value
=
inb
(
PIC_MASTER_CMD
)
&
irqmask
;
outb
(
0x0A
,
PIC_MASTER_CMD
);
/* back to the IRR register */
return
value
;
}
outb
(
0x0B
,
0xA0
);
/* ISR register */
value
=
inb
(
0xA0
)
&
(
irqmask
>>
8
);
outb
(
0x0A
,
0xA0
);
/* back to the IRR register */
outb
(
0x0B
,
PIC_SLAVE_CMD
);
/* ISR register */
value
=
inb
(
PIC_SLAVE_CMD
)
&
(
irqmask
>>
8
);
outb
(
0x0A
,
PIC_SLAVE_CMD
);
/* back to the IRR register */
return
value
;
}
...
...
@@ -193,14 +195,14 @@ void mask_and_ack_8259A(unsigned int irq)
handle_real_irq:
if
(
irq
&
8
)
{
inb
(
0xA1
);
/* DUMMY - (do we need this?) */
outb
(
cached_
A1
,
0xA1
);
outb
(
0x60
+
(
irq
&
7
),
0xA0
);
/* 'Specific EOI' to slave */
outb
(
0x6
2
,
0x20
);
/* 'Specific EOI' to master-IRQ2 */
inb
(
PIC_SLAVE_IMR
);
/* DUMMY - (do we need this?) */
outb
(
cached_
slave_mask
,
PIC_SLAVE_IMR
);
outb
(
0x60
+
(
irq
&
7
),
PIC_SLAVE_CMD
);
/* 'Specific EOI' to slave */
outb
(
0x6
0
+
PIC_CASCADE_IR
,
PIC_MASTER_CMD
);
/* 'Specific EOI' to master-IRQ2 */
}
else
{
inb
(
0x21
);
/* DUMMY - (do we need this?) */
outb
(
cached_
21
,
0x21
);
outb
(
0x60
+
irq
,
0x20
);
/* 'Specific EOI'
to master */
inb
(
PIC_MASTER_IMR
);
/* DUMMY - (do we need this?) */
outb
(
cached_
master_mask
,
PIC_MASTER_IMR
);
outb
(
0x60
+
irq
,
PIC_MASTER_CMD
);
/* 'Specific EOI
to master */
}
spin_unlock_irqrestore
(
&
i8259A_lock
,
flags
);
return
;
...
...
@@ -272,26 +274,24 @@ void init_8259A(int auto_eoi)
spin_lock_irqsave
(
&
i8259A_lock
,
flags
);
outb
(
0xff
,
0x21
);
/* mask all of 8259A-1 */
outb
(
0xff
,
0xA1
);
/* mask all of 8259A-2 */
outb
(
0xff
,
PIC_MASTER_IMR
);
/* mask all of 8259A-1 */
outb
(
0xff
,
PIC_SLAVE_IMR
);
/* mask all of 8259A-2 */
/*
* outb_p - this has to work on a wide range of PC hardware.
*/
outb_p
(
0x11
,
0x20
);
/* ICW1: select 8259A-1 init */
outb_p
(
0x20
+
0
,
0x21
);
/* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */
outb_p
(
0x04
,
0x21
);
/* 8259A-1 (the master) has a slave on IR2 */
if
(
auto_eoi
)
outb_p
(
0x03
,
0x21
);
/* master does Auto EOI */
else
outb_p
(
0x01
,
0x21
);
/* master expects normal EOI */
outb_p
(
0x11
,
0xA0
);
/* ICW1: select 8259A-2 init */
outb_p
(
0x20
+
8
,
0xA1
);
/* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */
outb_p
(
0x02
,
0xA1
);
/* 8259A-2 is a slave on master's IR2 */
outb_p
(
0x01
,
0xA1
);
/* (slave's support for AEOI in flat mode
is to be investigated) */
outb_p
(
0x11
,
PIC_MASTER_CMD
);
/* ICW1: select 8259A-1 init */
outb_p
(
0x20
+
0
,
PIC_MASTER_IMR
);
/* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */
outb_p
(
1U
<<
PIC_CASCADE_IR
,
PIC_MASTER_IMR
);
/* 8259A-1 (the master) has a slave on IR2 */
if
(
auto_eoi
)
/* master does Auto EOI */
outb_p
(
MASTER_ICW4_DEFAULT
|
PIC_ICW4_AEOI
,
PIC_MASTER_IMR
);
else
/* master expects normal EOI */
outb_p
(
MASTER_ICW4_DEFAULT
,
PIC_MASTER_IMR
);
outb_p
(
0x11
,
PIC_SLAVE_CMD
);
/* ICW1: select 8259A-2 init */
outb_p
(
0x20
+
8
,
PIC_SLAVE_IMR
);
/* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */
outb_p
(
PIC_CASCADE_IR
,
PIC_SLAVE_IMR
);
/* 8259A-2 is a slave on master's IR2 */
outb_p
(
SLAVE_ICW4_DEFAULT
,
PIC_SLAVE_IMR
);
/* (slave's support for AEOI in flat mode is to be investigated) */
if
(
auto_eoi
)
/*
* in AEOI mode we just have to mask the interrupt
...
...
@@ -303,8 +303,8 @@ void init_8259A(int auto_eoi)
udelay
(
100
);
/* wait for 8259A to initialize */
outb
(
cached_
21
,
0x21
);
/* restore master IRQ mask */
outb
(
cached_
A1
,
0xA1
);
/* restore slave IRQ mask */
outb
(
cached_
master_mask
,
PIC_MASTER_IMR
);
/* restore master IRQ mask */
outb
(
cached_
slave_mask
,
PIC_SLAVE_IMR
);
/* restore slave IRQ mask */
spin_unlock_irqrestore
(
&
i8259A_lock
,
flags
);
}
...
...
@@ -321,11 +321,17 @@ void init_8259A(int auto_eoi)
* be shot.
*/
/*
* =PC9800NOTE= In NEC PC-9800, we use irq8 instead of irq13!
*/
static
void
math_error_irq
(
int
cpl
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
extern
void
math_error
(
void
*
);
#ifndef CONFIG_X86_PC9800
outb
(
0
,
0xF0
);
if
(
ignore_irq13
||
!
boot_cpu_data
.
hard_math
)
#endif
if
(
ignore_fpu_irq
||
!
boot_cpu_data
.
hard_math
)
return
;
math_error
((
void
*
)
regs
->
eip
);
}
...
...
@@ -334,7 +340,7 @@ static void math_error_irq(int cpl, void *dev_id, struct pt_regs *regs)
* New motherboards sometimes make IRQ 13 be a PCI interrupt,
* so allow interrupt sharing.
*/
static
struct
irqaction
irq13
=
{
math_error_irq
,
0
,
0
,
"fpu"
,
NULL
,
NULL
};
static
struct
irqaction
fpu_irq
=
{
math_error_irq
,
0
,
0
,
"fpu"
,
NULL
,
NULL
};
void
__init
init_ISA_irqs
(
void
)
{
...
...
@@ -366,11 +372,11 @@ void __init init_ISA_irqs (void)
static
void
setup_timer
(
void
)
{
outb_p
(
0x34
,
0x43
);
/* binary, mode 2, LSB/MSB, ch 0 */
outb_p
(
0x34
,
PIT_MODE
);
/* binary, mode 2, LSB/MSB, ch 0 */
udelay
(
10
);
outb_p
(
LATCH
&
0xff
,
0x4
0
);
/* LSB */
outb_p
(
LATCH
&
0xff
,
PIT_CH
0
);
/* LSB */
udelay
(
10
);
outb
(
LATCH
>>
8
,
0x4
0
);
/* MSB */
outb
(
LATCH
>>
8
,
PIT_CH
0
);
/* MSB */
}
static
int
timer_resume
(
struct
device
*
dev
,
u32
level
)
...
...
@@ -437,5 +443,5 @@ void __init init_IRQ(void)
* original braindamaged IBM FERR coupling.
*/
if
(
boot_cpu_data
.
hard_math
&&
!
cpu_has_fpu
)
setup_irq
(
13
,
&
irq13
);
setup_irq
(
FPU_IRQ
,
&
fpu_irq
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment