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
nexedi
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 @@
...
@@ -26,6 +26,8 @@
#include <linux/irq.h>
#include <linux/irq.h>
#include <io_ports.h>
/*
/*
* This is the 'legacy' 8259A Programmable Interrupt Controller,
* This is the 'legacy' 8259A Programmable Interrupt Controller,
* present in the majority of PC/AT boxes.
* present in the majority of PC/AT boxes.
...
@@ -93,9 +95,9 @@ void disable_8259A_irq(unsigned int irq)
...
@@ -93,9 +95,9 @@ void disable_8259A_irq(unsigned int irq)
spin_lock_irqsave
(
&
i8259A_lock
,
flags
);
spin_lock_irqsave
(
&
i8259A_lock
,
flags
);
cached_irq_mask
|=
mask
;
cached_irq_mask
|=
mask
;
if
(
irq
&
8
)
if
(
irq
&
8
)
outb
(
cached_
A1
,
0xA1
);
outb
(
cached_
slave_mask
,
PIC_SLAVE_IMR
);
else
else
outb
(
cached_
21
,
0x21
);
outb
(
cached_
master_mask
,
PIC_MASTER_IMR
);
spin_unlock_irqrestore
(
&
i8259A_lock
,
flags
);
spin_unlock_irqrestore
(
&
i8259A_lock
,
flags
);
}
}
...
@@ -107,9 +109,9 @@ void enable_8259A_irq(unsigned int irq)
...
@@ -107,9 +109,9 @@ void enable_8259A_irq(unsigned int irq)
spin_lock_irqsave
(
&
i8259A_lock
,
flags
);
spin_lock_irqsave
(
&
i8259A_lock
,
flags
);
cached_irq_mask
&=
mask
;
cached_irq_mask
&=
mask
;
if
(
irq
&
8
)
if
(
irq
&
8
)
outb
(
cached_
A1
,
0xA1
);
outb
(
cached_
slave_mask
,
PIC_SLAVE_IMR
);
else
else
outb
(
cached_
21
,
0x21
);
outb
(
cached_
master_mask
,
PIC_MASTER_IMR
);
spin_unlock_irqrestore
(
&
i8259A_lock
,
flags
);
spin_unlock_irqrestore
(
&
i8259A_lock
,
flags
);
}
}
...
@@ -121,9 +123,9 @@ int i8259A_irq_pending(unsigned int irq)
...
@@ -121,9 +123,9 @@ int i8259A_irq_pending(unsigned int irq)
spin_lock_irqsave
(
&
i8259A_lock
,
flags
);
spin_lock_irqsave
(
&
i8259A_lock
,
flags
);
if
(
irq
<
8
)
if
(
irq
<
8
)
ret
=
inb
(
0x20
)
&
mask
;
ret
=
inb
(
PIC_MASTER_CMD
)
&
mask
;
else
else
ret
=
inb
(
0xA0
)
&
(
mask
>>
8
);
ret
=
inb
(
PIC_SLAVE_CMD
)
&
(
mask
>>
8
);
spin_unlock_irqrestore
(
&
i8259A_lock
,
flags
);
spin_unlock_irqrestore
(
&
i8259A_lock
,
flags
);
return
ret
;
return
ret
;
...
@@ -149,14 +151,14 @@ static inline int i8259A_irq_real(unsigned int irq)
...
@@ -149,14 +151,14 @@ static inline int i8259A_irq_real(unsigned int irq)
int
irqmask
=
1
<<
irq
;
int
irqmask
=
1
<<
irq
;
if
(
irq
<
8
)
{
if
(
irq
<
8
)
{
outb
(
0x0B
,
0x20
);
/* ISR register */
outb
(
0x0B
,
PIC_MASTER_CMD
);
/* ISR register */
value
=
inb
(
0x20
)
&
irqmask
;
value
=
inb
(
PIC_MASTER_CMD
)
&
irqmask
;
outb
(
0x0A
,
0x20
);
/* back to the IRR register */
outb
(
0x0A
,
PIC_MASTER_CMD
);
/* back to the IRR register */
return
value
;
return
value
;
}
}
outb
(
0x0B
,
0xA0
);
/* ISR register */
outb
(
0x0B
,
PIC_SLAVE_CMD
);
/* ISR register */
value
=
inb
(
0xA0
)
&
(
irqmask
>>
8
);
value
=
inb
(
PIC_SLAVE_CMD
)
&
(
irqmask
>>
8
);
outb
(
0x0A
,
0xA0
);
/* back to the IRR register */
outb
(
0x0A
,
PIC_SLAVE_CMD
);
/* back to the IRR register */
return
value
;
return
value
;
}
}
...
@@ -193,14 +195,14 @@ void mask_and_ack_8259A(unsigned int irq)
...
@@ -193,14 +195,14 @@ void mask_and_ack_8259A(unsigned int irq)
handle_real_irq:
handle_real_irq:
if
(
irq
&
8
)
{
if
(
irq
&
8
)
{
inb
(
0xA1
);
/* DUMMY - (do we need this?) */
inb
(
PIC_SLAVE_IMR
);
/* DUMMY - (do we need this?) */
outb
(
cached_
A1
,
0xA1
);
outb
(
cached_
slave_mask
,
PIC_SLAVE_IMR
);
outb
(
0x60
+
(
irq
&
7
),
0xA0
);
/* 'Specific EOI' to slave */
outb
(
0x60
+
(
irq
&
7
),
PIC_SLAVE_CMD
);
/* 'Specific EOI' to slave */
outb
(
0x6
2
,
0x20
);
/* 'Specific EOI' to master-IRQ2 */
outb
(
0x6
0
+
PIC_CASCADE_IR
,
PIC_MASTER_CMD
);
/* 'Specific EOI' to master-IRQ2 */
}
else
{
}
else
{
inb
(
0x21
);
/* DUMMY - (do we need this?) */
inb
(
PIC_MASTER_IMR
);
/* DUMMY - (do we need this?) */
outb
(
cached_
21
,
0x21
);
outb
(
cached_
master_mask
,
PIC_MASTER_IMR
);
outb
(
0x60
+
irq
,
0x20
);
/* 'Specific EOI'
to master */
outb
(
0x60
+
irq
,
PIC_MASTER_CMD
);
/* 'Specific EOI
to master */
}
}
spin_unlock_irqrestore
(
&
i8259A_lock
,
flags
);
spin_unlock_irqrestore
(
&
i8259A_lock
,
flags
);
return
;
return
;
...
@@ -272,26 +274,24 @@ void init_8259A(int auto_eoi)
...
@@ -272,26 +274,24 @@ void init_8259A(int auto_eoi)
spin_lock_irqsave
(
&
i8259A_lock
,
flags
);
spin_lock_irqsave
(
&
i8259A_lock
,
flags
);
outb
(
0xff
,
0x21
);
/* mask all of 8259A-1 */
outb
(
0xff
,
PIC_MASTER_IMR
);
/* mask all of 8259A-1 */
outb
(
0xff
,
0xA1
);
/* mask all of 8259A-2 */
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 - this has to work on a wide range of PC hardware.
*/
*/
outb_p
(
0x11
,
0x20
);
/* ICW1: select 8259A-1 init */
outb_p
(
0x11
,
PIC_MASTER_CMD
);
/* ICW1: select 8259A-1 init */
outb_p
(
0x20
+
0
,
0x21
);
/* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */
outb_p
(
0x20
+
0
,
PIC_MASTER_IMR
);
/* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */
outb_p
(
0x04
,
0x21
);
/* 8259A-1 (the master) has a slave on IR2 */
outb_p
(
1U
<<
PIC_CASCADE_IR
,
PIC_MASTER_IMR
);
/* 8259A-1 (the master) has a slave on IR2 */
if
(
auto_eoi
)
if
(
auto_eoi
)
/* master does Auto EOI */
outb_p
(
0x03
,
0x21
);
/* master does Auto EOI */
outb_p
(
MASTER_ICW4_DEFAULT
|
PIC_ICW4_AEOI
,
PIC_MASTER_IMR
);
else
else
/* master expects normal EOI */
outb_p
(
0x01
,
0x21
);
/* master expects normal EOI */
outb_p
(
MASTER_ICW4_DEFAULT
,
PIC_MASTER_IMR
);
outb_p
(
0x11
,
0xA0
);
/* ICW1: select 8259A-2 init */
outb_p
(
0x11
,
PIC_SLAVE_CMD
);
/* ICW1: select 8259A-2 init */
outb_p
(
0x20
+
8
,
0xA1
);
/* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */
outb_p
(
0x20
+
8
,
PIC_SLAVE_IMR
);
/* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */
outb_p
(
0x02
,
0xA1
);
/* 8259A-2 is a slave on master's IR2 */
outb_p
(
PIC_CASCADE_IR
,
PIC_SLAVE_IMR
);
/* 8259A-2 is a slave on master's IR2 */
outb_p
(
0x01
,
0xA1
);
/* (slave's support for AEOI in flat mode
outb_p
(
SLAVE_ICW4_DEFAULT
,
PIC_SLAVE_IMR
);
/* (slave's support for AEOI in flat mode is to be investigated) */
is to be investigated) */
if
(
auto_eoi
)
if
(
auto_eoi
)
/*
/*
* in AEOI mode we just have to mask the interrupt
* in AEOI mode we just have to mask the interrupt
...
@@ -303,8 +303,8 @@ void init_8259A(int auto_eoi)
...
@@ -303,8 +303,8 @@ void init_8259A(int auto_eoi)
udelay
(
100
);
/* wait for 8259A to initialize */
udelay
(
100
);
/* wait for 8259A to initialize */
outb
(
cached_
21
,
0x21
);
/* restore master IRQ mask */
outb
(
cached_
master_mask
,
PIC_MASTER_IMR
);
/* restore master IRQ mask */
outb
(
cached_
A1
,
0xA1
);
/* restore slave IRQ mask */
outb
(
cached_
slave_mask
,
PIC_SLAVE_IMR
);
/* restore slave IRQ mask */
spin_unlock_irqrestore
(
&
i8259A_lock
,
flags
);
spin_unlock_irqrestore
(
&
i8259A_lock
,
flags
);
}
}
...
@@ -321,11 +321,17 @@ void init_8259A(int auto_eoi)
...
@@ -321,11 +321,17 @@ void init_8259A(int auto_eoi)
* be shot.
* 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
)
static
void
math_error_irq
(
int
cpl
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
{
extern
void
math_error
(
void
*
);
extern
void
math_error
(
void
*
);
#ifndef CONFIG_X86_PC9800
outb
(
0
,
0xF0
);
outb
(
0
,
0xF0
);
if
(
ignore_irq13
||
!
boot_cpu_data
.
hard_math
)
#endif
if
(
ignore_fpu_irq
||
!
boot_cpu_data
.
hard_math
)
return
;
return
;
math_error
((
void
*
)
regs
->
eip
);
math_error
((
void
*
)
regs
->
eip
);
}
}
...
@@ -334,7 +340,7 @@ static void math_error_irq(int cpl, void *dev_id, struct pt_regs *regs)
...
@@ -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,
* New motherboards sometimes make IRQ 13 be a PCI interrupt,
* so allow interrupt sharing.
* 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
)
void
__init
init_ISA_irqs
(
void
)
{
{
...
@@ -366,11 +372,11 @@ void __init init_ISA_irqs (void)
...
@@ -366,11 +372,11 @@ void __init init_ISA_irqs (void)
static
void
setup_timer
(
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
);
udelay
(
10
);
outb_p
(
LATCH
&
0xff
,
0x4
0
);
/* LSB */
outb_p
(
LATCH
&
0xff
,
PIT_CH
0
);
/* LSB */
udelay
(
10
);
udelay
(
10
);
outb
(
LATCH
>>
8
,
0x4
0
);
/* MSB */
outb
(
LATCH
>>
8
,
PIT_CH
0
);
/* MSB */
}
}
static
int
timer_resume
(
struct
device
*
dev
,
u32
level
)
static
int
timer_resume
(
struct
device
*
dev
,
u32
level
)
...
@@ -437,5 +443,5 @@ void __init init_IRQ(void)
...
@@ -437,5 +443,5 @@ void __init init_IRQ(void)
* original braindamaged IBM FERR coupling.
* original braindamaged IBM FERR coupling.
*/
*/
if
(
boot_cpu_data
.
hard_math
&&
!
cpu_has_fpu
)
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