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
314d12aa
Commit
314d12aa
authored
Jun 27, 2002
by
David Gibson
Committed by
Paul Mackerras
Jun 27, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
PPC32: Update handling of the interrupt controller on the PPC405.
parent
7059bf5d
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
117 additions
and
28 deletions
+117
-28
arch/ppc/kernel/ppc4xx_pic.c
arch/ppc/kernel/ppc4xx_pic.c
+117
-28
No files found.
arch/ppc/kernel/ppc4xx_pic.c
View file @
314d12aa
...
@@ -15,10 +15,14 @@
...
@@ -15,10 +15,14 @@
* there are eight internal interrupts for the on-chip serial port
* there are eight internal interrupts for the on-chip serial port
* (SPU), DMA controller, and JTAG controller.
* (SPU), DMA controller, and JTAG controller.
*
*
* The PowerPC 405 cores' Universal Interrupt Controller (UIC) has 32
* The PowerPC 405/440 cores' Universal Interrupt Controller (UIC) has
* possible interrupts as well. There are seven, configurable external
* 32 possible interrupts as well. Depending on the core and SoC
* interrupt pins and there are 17 internal interrupts for the on-chip
* implementation, a portion of the interrrupts are used for on-chip
* serial port, DMA controller, on-chip Ethernet controller, PCI, etc.
* peripherals and a portion of the interrupts are available to be
* configured for external devices generating interrupts.
*
* The PowerNP and 440GP (and most likely future implementations) have
* cascaded UICs.
*
*
*/
*/
...
@@ -30,11 +34,9 @@
...
@@ -30,11 +34,9 @@
#include <asm/processor.h>
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/irq.h>
#include <asm/ibm4xx.h>
#include <asm/ppc4xx_pic.h>
#include <asm/ppc4xx_pic.h>
/* Global Variables */
/* Global Variables */
struct
hw_interrupt_type
*
ppc4xx_pic
;
struct
hw_interrupt_type
*
ppc4xx_pic
;
/* Six of one, half dozen of the other....#ifdefs, separate files,
/* Six of one, half dozen of the other....#ifdefs, separate files,
...
@@ -128,7 +130,11 @@ ppc403_aic_disable_and_ack(unsigned int irq)
...
@@ -128,7 +130,11 @@ ppc403_aic_disable_and_ack(unsigned int irq)
mtdcr
(
DCRN_EXISR
,
(
1
<<
(
31
-
bit
)));
mtdcr
(
DCRN_EXISR
,
(
1
<<
(
31
-
bit
)));
}
}
#else
/* !CONFIG_403 */
#else
#ifndef UIC1
#define UIC1 UIC0
#endif
static
void
static
void
ppc405_uic_enable
(
unsigned
int
irq
)
ppc405_uic_enable
(
unsigned
int
irq
)
...
@@ -137,9 +143,18 @@ ppc405_uic_enable(unsigned int irq)
...
@@ -137,9 +143,18 @@ ppc405_uic_enable(unsigned int irq)
bit
=
irq
&
0x1f
;
bit
=
irq
&
0x1f
;
word
=
irq
>>
5
;
word
=
irq
>>
5
;
#ifdef UIC_DEBUG
printk
(
"ppc405_uic_enable - irq %d word %d bit 0x%x
\n
"
,
irq
,
word
,
bit
);
#endif
ppc_cached_irq_mask
[
word
]
|=
1
<<
(
31
-
bit
);
ppc_cached_irq_mask
[
word
]
|=
1
<<
(
31
-
bit
);
mtdcr
(
DCRN_UIC0_ER
,
ppc_cached_irq_mask
[
word
]);
switch
(
word
){
case
0
:
mtdcr
(
DCRN_UIC_ER
(
UIC0
),
ppc_cached_irq_mask
[
word
]);
break
;
case
1
:
mtdcr
(
DCRN_UIC_ER
(
UIC1
),
ppc_cached_irq_mask
[
word
]);
break
;
}
}
}
static
void
static
void
...
@@ -149,9 +164,18 @@ ppc405_uic_disable(unsigned int irq)
...
@@ -149,9 +164,18 @@ ppc405_uic_disable(unsigned int irq)
bit
=
irq
&
0x1f
;
bit
=
irq
&
0x1f
;
word
=
irq
>>
5
;
word
=
irq
>>
5
;
#ifdef UIC_DEBUG
printk
(
"ppc405_uic_disable - irq %d word %d bit 0x%x
\n
"
,
irq
,
word
,
bit
);
#endif
ppc_cached_irq_mask
[
word
]
&=
~
(
1
<<
(
31
-
bit
));
ppc_cached_irq_mask
[
word
]
&=
~
(
1
<<
(
31
-
bit
));
mtdcr
(
DCRN_UIC0_ER
,
ppc_cached_irq_mask
[
word
]);
switch
(
word
){
case
0
:
mtdcr
(
DCRN_UIC_ER
(
UIC0
),
ppc_cached_irq_mask
[
word
]);
break
;
case
1
:
mtdcr
(
DCRN_UIC_ER
(
UIC1
),
ppc_cached_irq_mask
[
word
]);
break
;
}
}
}
static
void
static
void
...
@@ -162,9 +186,20 @@ ppc405_uic_disable_and_ack(unsigned int irq)
...
@@ -162,9 +186,20 @@ ppc405_uic_disable_and_ack(unsigned int irq)
bit
=
irq
&
0x1f
;
bit
=
irq
&
0x1f
;
word
=
irq
>>
5
;
word
=
irq
>>
5
;
#ifdef UIC_DEBUG
printk
(
"ppc405_uic_disable_and_ack - irq %d word %d bit 0x%x
\n
"
,
irq
,
word
,
bit
);
#endif
ppc_cached_irq_mask
[
word
]
&=
~
(
1
<<
(
31
-
bit
));
ppc_cached_irq_mask
[
word
]
&=
~
(
1
<<
(
31
-
bit
));
mtdcr
(
DCRN_UIC0_ER
,
ppc_cached_irq_mask
[
word
]);
switch
(
word
){
mtdcr
(
DCRN_UIC0_SR
,
(
1
<<
(
31
-
bit
)));
case
0
:
mtdcr
(
DCRN_UIC_ER
(
UIC0
),
ppc_cached_irq_mask
[
word
]);
mtdcr
(
DCRN_UIC_SR
(
UIC0
),
(
1
<<
(
31
-
bit
)));
break
;
case
1
:
mtdcr
(
DCRN_UIC_ER
(
UIC1
),
ppc_cached_irq_mask
[
word
]);
mtdcr
(
DCRN_UIC_SR
(
UIC1
),
(
1
<<
(
31
-
bit
)));
break
;
}
}
}
static
void
static
void
...
@@ -176,23 +211,49 @@ ppc405_uic_end(unsigned int irq)
...
@@ -176,23 +211,49 @@ ppc405_uic_end(unsigned int irq)
bit
=
irq
&
0x1f
;
bit
=
irq
&
0x1f
;
word
=
irq
>>
5
;
word
=
irq
>>
5
;
tr_bits
=
mfdcr
(
DCRN_UIC0_TR
);
#ifdef UIC_DEBUG
printk
(
"ppc405_uic_end - irq %d word %d bit 0x%x
\n
"
,
irq
,
word
,
bit
);
#endif
switch
(
word
){
case
0
:
tr_bits
=
mfdcr
(
DCRN_UIC_TR
(
UIC0
));
break
;
case
1
:
tr_bits
=
mfdcr
(
DCRN_UIC_TR
(
UIC1
));
break
;
}
if
((
tr_bits
&
(
1
<<
(
31
-
bit
)))
==
0
)
{
if
((
tr_bits
&
(
1
<<
(
31
-
bit
)))
==
0
)
{
/* level trigger */
/* level trigger */
mtdcr
(
DCRN_UIC0_SR
,
1
<<
(
31
-
bit
));
switch
(
word
){
case
0
:
mtdcr
(
DCRN_UIC_SR
(
UIC0
),
1
<<
(
31
-
bit
));
break
;
case
1
:
mtdcr
(
DCRN_UIC_SR
(
UIC1
),
1
<<
(
31
-
bit
));
break
;
}
}
}
if
(
!
(
irq_desc
[
irq
].
status
&
(
IRQ_DISABLED
|
IRQ_INPROGRESS
)))
{
if
(
!
(
irq_desc
[
irq
].
status
&
(
IRQ_DISABLED
|
IRQ_INPROGRESS
)))
{
ppc_cached_irq_mask
[
word
]
|=
1
<<
(
31
-
bit
);
ppc_cached_irq_mask
[
word
]
|=
1
<<
(
31
-
bit
);
mtdcr
(
DCRN_UIC0_ER
,
ppc_cached_irq_mask
[
word
]);
switch
(
word
){
case
0
:
mtdcr
(
DCRN_UIC_ER
(
UIC0
),
ppc_cached_irq_mask
[
word
]);
break
;
case
1
:
mtdcr
(
DCRN_UIC_ER
(
UIC1
),
ppc_cached_irq_mask
[
word
]);
break
;
}
}
}
}
}
static
struct
hw_interrupt_type
ppc405_uic
=
{
static
struct
hw_interrupt_type
ppc405_uic
=
{
#if
defined (CONFIG_405GP
)
#if
(NR_UICS == 1
)
"
405GP
UIC"
,
"
IBM
UIC"
,
#else
#else
"
NP405 UIC
"
,
"
IBM UIC Cascade
"
,
#endif
#endif
NULL
,
NULL
,
NULL
,
NULL
,
...
@@ -206,16 +267,27 @@ static struct hw_interrupt_type ppc405_uic = {
...
@@ -206,16 +267,27 @@ static struct hw_interrupt_type ppc405_uic = {
int
int
ppc405_pic_get_irq
(
struct
pt_regs
*
regs
)
ppc405_pic_get_irq
(
struct
pt_regs
*
regs
)
{
{
int
irq
;
int
irq
,
cas_irq
;
unsigned
long
bits
;
unsigned
long
bits
;
cas_irq
=
0
;
/*
/*
* Only report the status of those interrupts that are actually
* Only report the status of those interrupts that are actually
* enabled.
* enabled.
*/
*/
bits
=
mfdcr
(
DCRN_UIC0_MSR
);
bits
=
mfdcr
(
DCRN_UIC_MSR
(
UIC0
));
#if (NR_UICS > 1)
if
(
bits
&
UIC_CASCADE_MASK
){
bits
=
mfdcr
(
DCRN_UIC_MSR
(
UIC1
));
cas_irq
=
32
-
ffs
(
bits
);
irq
=
32
+
cas_irq
;
}
else
{
irq
=
32
-
ffs
(
bits
);
if
(
irq
==
32
)
irq
=
-
1
;
}
#else
/*
/*
* Walk through the interrupts from highest priority to lowest, and
* Walk through the interrupts from highest priority to lowest, and
* report the first pending interrupt found.
* report the first pending interrupt found.
...
@@ -223,10 +295,14 @@ ppc405_pic_get_irq(struct pt_regs *regs)
...
@@ -223,10 +295,14 @@ ppc405_pic_get_irq(struct pt_regs *regs)
* result from 32.
* result from 32.
*/
*/
irq
=
32
-
ffs
(
bits
);
irq
=
32
-
ffs
(
bits
);
#endif
if
(
irq
==
NR_AIC_IRQS
)
if
(
irq
==
(
NR_UIC_IRQS
*
NR_UICS
)
)
irq
=
-
1
;
irq
=
-
1
;
#ifdef UIC_DEBUG
printk
(
"ppc405_pic_get_irq - irq %d bit 0x%x
\n
"
,
irq
,
bits
);
#endif
return
(
irq
);
return
(
irq
);
}
}
#endif
#endif
...
@@ -239,18 +315,31 @@ ppc4xx_pic_init(void)
...
@@ -239,18 +315,31 @@ ppc4xx_pic_init(void)
* explicity requested.
* explicity requested.
*/
*/
ppc_cached_irq_mask
[
0
]
=
0
;
ppc_cached_irq_mask
[
0
]
=
0
;
ppc_cached_irq_mask
[
1
]
=
0
;
#if
def
CONFIG_403
#if
defined
CONFIG_403
mtdcr
(
DCRN_EXIER
,
ppc_cached_irq_mask
[
0
]);
mtdcr
(
DCRN_EXIER
,
ppc_cached_irq_mask
[
0
]);
ppc4xx_pic
=
&
ppc403_aic
;
ppc4xx_pic
=
&
ppc403_aic
;
ppc_md
.
get_irq
=
ppc403_pic_get_irq
;
ppc_md
.
get_irq
=
ppc403_pic_get_irq
;
#else
#else
mtdcr
(
DCRN_UIC0_ER
,
ppc_cached_irq_mask
[
0
]);
#if (NR_UICS > 1)
ppc_cached_irq_mask
[
0
]
|=
1
<<
(
31
-
UIC0_UIC1NC
);
/* enable cascading interrupt */
mtdcr
(
DCRN_UIC_ER
(
UIC0
),
ppc_cached_irq_mask
[
0
]);
mtdcr
(
DCRN_UIC_ER
(
UIC1
),
ppc_cached_irq_mask
[
1
]);
/* Set all interrupts to non-critical.
*/
mtdcr
(
DCRN_UIC_CR
(
UIC0
),
0
);
mtdcr
(
DCRN_UIC_CR
(
UIC1
),
0
);
#else
mtdcr
(
DCRN_UIC_ER
(
UIC0
),
ppc_cached_irq_mask
[
0
]);
/* Set all interrupts to non-critical.
/* Set all interrupts to non-critical.
*/
*/
mtdcr
(
DCRN_UIC0_CR
,
0
);
mtdcr
(
DCRN_UIC_CR
(
UIC0
),
0
);
#endif
ppc4xx_pic
=
&
ppc405_uic
;
ppc4xx_pic
=
&
ppc405_uic
;
ppc_md
.
get_irq
=
ppc405_pic_get_irq
;
ppc_md
.
get_irq
=
ppc405_pic_get_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