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
4ba9dcbe
Commit
4ba9dcbe
authored
Feb 15, 2007
by
Russell King
Committed by
Russell King
Feb 15, 2007
Browse files
Options
Browse Files
Download
Plain Diff
Merge Realview GIC code
parents
382266ad
4b17244c
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
168 additions
and
26 deletions
+168
-26
arch/arm/common/gic.c
arch/arm/common/gic.c
+95
-14
arch/arm/mach-realview/Kconfig
arch/arm/mach-realview/Kconfig
+10
-0
arch/arm/mach-realview/platsmp.c
arch/arm/mach-realview/platsmp.c
+1
-1
arch/arm/mach-realview/realview_eb.c
arch/arm/mach-realview/realview_eb.c
+23
-4
arch/arm/mm/proc-v6.S
arch/arm/mm/proc-v6.S
+5
-3
include/asm-arm/arch-realview/hardware.h
include/asm-arm/arch-realview/hardware.h
+1
-1
include/asm-arm/arch-realview/irqs.h
include/asm-arm/arch-realview/irqs.h
+4
-1
include/asm-arm/arch-realview/platform.h
include/asm-arm/arch-realview/platform.h
+16
-0
include/asm-arm/arch-realview/scu.h
include/asm-arm/arch-realview/scu.h
+8
-0
include/asm-arm/hardware/arm_scu.h
include/asm-arm/hardware/arm_scu.h
+2
-0
include/asm-arm/hardware/gic.h
include/asm-arm/hardware/gic.h
+3
-2
No files found.
arch/arm/common/gic.c
View file @
4ba9dcbe
...
...
@@ -14,7 +14,9 @@
*
* o There is one CPU Interface per CPU, which sends interrupts sent
* by the Distributor, and interrupts generated locally, to the
* associated CPU.
* associated CPU. The base address of the CPU interface is usually
* aliased so that the same address points to different chips depending
* on the CPU it is accessed from.
*
* Note that IRQs 0-31 are special - they are local to each CPU.
* As such, the enable set/clear, pending set/clear and active bit
...
...
@@ -31,10 +33,38 @@
#include <asm/mach/irq.h>
#include <asm/hardware/gic.h>
static
void
__iomem
*
gic_dist_base
;
static
void
__iomem
*
gic_cpu_base
;
static
DEFINE_SPINLOCK
(
irq_controller_lock
);
struct
gic_chip_data
{
unsigned
int
irq_offset
;
void
__iomem
*
dist_base
;
void
__iomem
*
cpu_base
;
};
#ifndef MAX_GIC_NR
#define MAX_GIC_NR 1
#endif
static
struct
gic_chip_data
gic_data
[
MAX_GIC_NR
];
static
inline
void
__iomem
*
gic_dist_base
(
unsigned
int
irq
)
{
struct
gic_chip_data
*
gic_data
=
get_irq_chip_data
(
irq
);
return
gic_data
->
dist_base
;
}
static
inline
void
__iomem
*
gic_cpu_base
(
unsigned
int
irq
)
{
struct
gic_chip_data
*
gic_data
=
get_irq_chip_data
(
irq
);
return
gic_data
->
cpu_base
;
}
static
inline
unsigned
int
gic_irq
(
unsigned
int
irq
)
{
struct
gic_chip_data
*
gic_data
=
get_irq_chip_data
(
irq
);
return
irq
-
gic_data
->
irq_offset
;
}
/*
* Routines to acknowledge, disable and enable interrupts
*
...
...
@@ -55,8 +85,8 @@ static void gic_ack_irq(unsigned int irq)
u32
mask
=
1
<<
(
irq
%
32
);
spin_lock
(
&
irq_controller_lock
);
writel
(
mask
,
gic_dist_base
+
GIC_DIST_ENABLE_CLEAR
+
(
irq
/
32
)
*
4
);
writel
(
irq
,
gic_cpu_base
+
GIC_CPU_EOI
);
writel
(
mask
,
gic_dist_base
(
irq
)
+
GIC_DIST_ENABLE_CLEAR
+
(
gic_irq
(
irq
)
/
32
)
*
4
);
writel
(
gic_irq
(
irq
),
gic_cpu_base
(
irq
)
+
GIC_CPU_EOI
);
spin_unlock
(
&
irq_controller_lock
);
}
...
...
@@ -65,7 +95,7 @@ static void gic_mask_irq(unsigned int irq)
u32
mask
=
1
<<
(
irq
%
32
);
spin_lock
(
&
irq_controller_lock
);
writel
(
mask
,
gic_dist_base
+
GIC_DIST_ENABLE_CLEAR
+
(
irq
/
32
)
*
4
);
writel
(
mask
,
gic_dist_base
(
irq
)
+
GIC_DIST_ENABLE_CLEAR
+
(
gic_irq
(
irq
)
/
32
)
*
4
);
spin_unlock
(
&
irq_controller_lock
);
}
...
...
@@ -74,14 +104,14 @@ static void gic_unmask_irq(unsigned int irq)
u32
mask
=
1
<<
(
irq
%
32
);
spin_lock
(
&
irq_controller_lock
);
writel
(
mask
,
gic_dist_base
+
GIC_DIST_ENABLE_SET
+
(
irq
/
32
)
*
4
);
writel
(
mask
,
gic_dist_base
(
irq
)
+
GIC_DIST_ENABLE_SET
+
(
gic_irq
(
irq
)
/
32
)
*
4
);
spin_unlock
(
&
irq_controller_lock
);
}
#ifdef CONFIG_SMP
static
void
gic_set_cpu
(
unsigned
int
irq
,
cpumask_t
mask_val
)
{
void
__iomem
*
reg
=
gic_dist_base
+
GIC_DIST_TARGET
+
(
irq
&
~
3
);
void
__iomem
*
reg
=
gic_dist_base
(
irq
)
+
GIC_DIST_TARGET
+
(
gic_irq
(
irq
)
&
~
3
);
unsigned
int
shift
=
(
irq
%
4
)
*
8
;
unsigned
int
cpu
=
first_cpu
(
mask_val
);
u32
val
;
...
...
@@ -95,6 +125,37 @@ static void gic_set_cpu(unsigned int irq, cpumask_t mask_val)
}
#endif
static
void
fastcall
gic_handle_cascade_irq
(
unsigned
int
irq
,
struct
irq_desc
*
desc
)
{
struct
gic_chip_data
*
chip_data
=
get_irq_data
(
irq
);
struct
irq_chip
*
chip
=
get_irq_chip
(
irq
);
unsigned
int
cascade_irq
;
unsigned
long
status
;
/* primary controller ack'ing */
chip
->
ack
(
irq
);
spin_lock
(
&
irq_controller_lock
);
status
=
readl
(
chip_data
->
cpu_base
+
GIC_CPU_INTACK
);
spin_unlock
(
&
irq_controller_lock
);
cascade_irq
=
(
status
&
0x3ff
);
if
(
cascade_irq
>
1020
)
goto
out
;
if
(
cascade_irq
<
32
||
cascade_irq
>=
NR_IRQS
)
{
do_bad_IRQ
(
cascade_irq
,
desc
);
goto
out
;
}
cascade_irq
+=
chip_data
->
irq_offset
;
generic_handle_irq
(
cascade_irq
);
out:
/* primary controller unmasking */
chip
->
unmask
(
irq
);
}
static
struct
irq_chip
gic_chip
=
{
.
name
=
"GIC"
,
.
ack
=
gic_ack_irq
,
...
...
@@ -105,15 +166,29 @@ static struct irq_chip gic_chip = {
#endif
};
void
__init
gic_dist_init
(
void
__iomem
*
base
)
void
__init
gic_cascade_irq
(
unsigned
int
gic_nr
,
unsigned
int
irq
)
{
if
(
gic_nr
>=
MAX_GIC_NR
)
BUG
();
if
(
set_irq_data
(
irq
,
&
gic_data
[
gic_nr
])
!=
0
)
BUG
();
set_irq_chained_handler
(
irq
,
gic_handle_cascade_irq
);
}
void
__init
gic_dist_init
(
unsigned
int
gic_nr
,
void
__iomem
*
base
,
unsigned
int
irq_start
)
{
unsigned
int
max_irq
,
i
;
u32
cpumask
=
1
<<
smp_processor_id
();
if
(
gic_nr
>=
MAX_GIC_NR
)
BUG
();
cpumask
|=
cpumask
<<
8
;
cpumask
|=
cpumask
<<
16
;
gic_dist_base
=
base
;
gic_data
[
gic_nr
].
dist_base
=
base
;
gic_data
[
gic_nr
].
irq_offset
=
(
irq_start
-
1
)
&
~
31
;
writel
(
0
,
base
+
GIC_DIST_CTRL
);
...
...
@@ -158,8 +233,9 @@ void __init gic_dist_init(void __iomem *base)
/*
* Setup the Linux IRQ subsystem.
*/
for
(
i
=
29
;
i
<
max_irq
;
i
++
)
{
for
(
i
=
irq_start
;
i
<
gic_data
[
gic_nr
].
irq_offset
+
max_irq
;
i
++
)
{
set_irq_chip
(
i
,
&
gic_chip
);
set_irq_chip_data
(
i
,
&
gic_data
[
gic_nr
]);
set_irq_handler
(
i
,
handle_level_irq
);
set_irq_flags
(
i
,
IRQF_VALID
|
IRQF_PROBE
);
}
...
...
@@ -167,9 +243,13 @@ void __init gic_dist_init(void __iomem *base)
writel
(
1
,
base
+
GIC_DIST_CTRL
);
}
void
__cpuinit
gic_cpu_init
(
void
__iomem
*
base
)
void
__cpuinit
gic_cpu_init
(
unsigned
int
gic_nr
,
void
__iomem
*
base
)
{
gic_cpu_base
=
base
;
if
(
gic_nr
>=
MAX_GIC_NR
)
BUG
();
gic_data
[
gic_nr
].
cpu_base
=
base
;
writel
(
0xf0
,
base
+
GIC_CPU_PRIMASK
);
writel
(
1
,
base
+
GIC_CPU_CTRL
);
}
...
...
@@ -179,6 +259,7 @@ void gic_raise_softirq(cpumask_t cpumask, unsigned int irq)
{
unsigned
long
map
=
*
cpus_addr
(
cpumask
);
writel
(
map
<<
16
|
irq
,
gic_dist_base
+
GIC_DIST_SOFTINT
);
/* this always happens on GIC0 */
writel
(
map
<<
16
|
irq
,
gic_data
[
0
].
dist_base
+
GIC_DIST_SOFTINT
);
}
#endif
arch/arm/mach-realview/Kconfig
View file @
4ba9dcbe
...
...
@@ -16,4 +16,14 @@ config REALVIEW_MPCORE
kernel built with this option enabled is not compatible with
other tiles.
config REALVIEW_MPCORE_REVB
bool "Support MPcore RevB tile"
depends on REALVIEW_MPCORE
default n
help
Enable support for the MPCore RevB tile on the Realview platform.
Since there are device address differences, a
kernel built with this option enabled is not compatible with
other tiles.
endmenu
arch/arm/mach-realview/platsmp.c
View file @
4ba9dcbe
...
...
@@ -52,7 +52,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
* core (e.g. timer irq), then they will not have been enabled
* for us: do so
*/
gic_cpu_init
(
__io_address
(
REALVIEW_GIC_CPU_BASE
));
gic_cpu_init
(
0
,
__io_address
(
REALVIEW_GIC_CPU_BASE
));
/*
* let the primary processor know we're out of the
...
...
arch/arm/mach-realview/realview_eb.c
View file @
4ba9dcbe
...
...
@@ -57,7 +57,21 @@ static struct map_desc realview_eb_io_desc[] __initdata = {
.
pfn
=
__phys_to_pfn
(
REALVIEW_GIC_DIST_BASE
),
.
length
=
SZ_4K
,
.
type
=
MT_DEVICE
,
},
#ifdef CONFIG_REALVIEW_MPCORE
{
.
virtual
=
IO_ADDRESS
(
REALVIEW_GIC1_CPU_BASE
),
.
pfn
=
__phys_to_pfn
(
REALVIEW_GIC1_CPU_BASE
),
.
length
=
SZ_4K
,
.
type
=
MT_DEVICE
,
},
{
.
virtual
=
IO_ADDRESS
(
REALVIEW_GIC1_DIST_BASE
),
.
pfn
=
__phys_to_pfn
(
REALVIEW_GIC1_DIST_BASE
),
.
length
=
SZ_4K
,
.
type
=
MT_DEVICE
,
},
#endif
{
.
virtual
=
IO_ADDRESS
(
REALVIEW_SCTL_BASE
),
.
pfn
=
__phys_to_pfn
(
REALVIEW_SCTL_BASE
),
.
length
=
SZ_4K
,
...
...
@@ -138,13 +152,18 @@ static void __init gic_init_irq(void)
#ifdef CONFIG_REALVIEW_MPCORE
unsigned
int
pldctrl
;
writel
(
0x0000a05f
,
__io_address
(
REALVIEW_SYS_LOCK
));
pldctrl
=
readl
(
__io_address
(
REALVIEW_SYS_BASE
)
+
0xd8
);
pldctrl
=
readl
(
__io_address
(
REALVIEW_SYS_BASE
)
+
REALVIEW_MPCORE_SYS_PLD_CTRL1
);
pldctrl
|=
0x00800000
;
/* New irq mode */
writel
(
pldctrl
,
__io_address
(
REALVIEW_SYS_BASE
)
+
0xd8
);
writel
(
pldctrl
,
__io_address
(
REALVIEW_SYS_BASE
)
+
REALVIEW_MPCORE_SYS_PLD_CTRL1
);
writel
(
0x00000000
,
__io_address
(
REALVIEW_SYS_LOCK
));
#endif
gic_dist_init
(
__io_address
(
REALVIEW_GIC_DIST_BASE
));
gic_cpu_init
(
__io_address
(
REALVIEW_GIC_CPU_BASE
));
gic_dist_init
(
0
,
__io_address
(
REALVIEW_GIC_DIST_BASE
),
29
);
gic_cpu_init
(
0
,
__io_address
(
REALVIEW_GIC_CPU_BASE
));
#ifdef CONFIG_REALVIEW_MPCORE
gic_dist_init
(
1
,
__io_address
(
REALVIEW_GIC1_DIST_BASE
),
64
);
gic_cpu_init
(
1
,
__io_address
(
REALVIEW_GIC1_CPU_BASE
));
gic_cascade_irq
(
1
,
IRQ_EB_IRQ1
);
#endif
}
static
void
__init
realview_eb_init
(
void
)
...
...
arch/arm/mm/proc-v6.S
View file @
4ba9dcbe
...
...
@@ -14,10 +14,13 @@
#include <asm/assembler.h>
#include <asm/asm-offsets.h>
#include <asm/elf.h>
#include <asm/hardware/arm_scu.h>
#include <asm/pgtable-hwdef.h>
#include <asm/pgtable.h>
#ifdef CONFIG_SMP
#include <asm/hardware/arm_scu.h>
#endif
#include "proc-macros.S"
#define D_CACHE_LINE_SIZE 32
...
...
@@ -187,8 +190,7 @@ __v6_setup:
/
*
Set
up
the
SCU
on
core
0
only
*/
mrc
p15
,
0
,
r0
,
c0
,
c0
,
5
@
CPU
core
number
ands
r0
,
r0
,
#
15
moveq
r0
,
#
0x10000000
@
SCU_BASE
orreq
r0
,
r0
,
#
0x00100000
ldreq
r0
,
=
SCU_BASE
ldreq
r5
,
[
r0
,
#
SCU_CTRL
]
orreq
r5
,
r5
,
#
1
streq
r5
,
[
r0
,
#
SCU_CTRL
]
...
...
include/asm-arm/arch-realview/hardware.h
View file @
4ba9dcbe
...
...
@@ -26,7 +26,7 @@
#include <asm/arch/platform.h>
/* macro to get at IO space when running virtually */
#define IO_ADDRESS(x) (((
x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000
) + 0xf0000000)
#define IO_ADDRESS(x) (((
(x) & 0x0effffff) | (((x) >> 4) & 0x0f000000)
) + 0xf0000000)
#define __io_address(n) __io(IO_ADDRESS(n))
#endif
include/asm-arm/arch-realview/irqs.h
View file @
4ba9dcbe
...
...
@@ -78,6 +78,9 @@
#define IRQ_PMU_SCU6 (IRQ_GIC_START + INT_PMU_SCU6)
#define IRQ_PMU_SCU7 (IRQ_GIC_START + INT_PMU_SCU7)
#define IRQ_EB_IRQ1 (IRQ_GIC_START + INT_EB_IRQ1)
#define IRQ_EB_IRQ2 (IRQ_GIC_START + INT_EB_IRQ2)
#define IRQMASK_WDOGINT INTMASK_WDOGINT
#define IRQMASK_SOFTINT INTMASK_SOFTINT
#define IRQMASK_COMMRx INTMASK_COMMRx
...
...
@@ -115,4 +118,4 @@
#define IRQMASK_ETH INTMASK_ETH
#define IRQMASK_USB INTMASK_USB
#define NR_IRQS (IRQ_GIC_START +
64
)
#define NR_IRQS (IRQ_GIC_START +
96
)
include/asm-arm/arch-realview/platform.h
View file @
4ba9dcbe
...
...
@@ -207,11 +207,23 @@
#define REALVIEW_GIC_CPU_BASE 0x10040000
/* Generic interrupt controller CPU interface */
#define REALVIEW_GIC_DIST_BASE 0x10041000
/* Generic interrupt controller distributor */
#else
#ifdef CONFIG_REALVIEW_MPCORE_REVB
#define REALVIEW_MPCORE_SCU_BASE 0x10100000
/* SCU registers */
#define REALVIEW_GIC_CPU_BASE 0x10100100
/* Generic interrupt controller CPU interface */
#define REALVIEW_TWD_BASE 0x10100700
#define REALVIEW_TWD_SIZE 0x00000100
#define REALVIEW_GIC_DIST_BASE 0x10101000
/* Generic interrupt controller distributor */
#define REALVIEW_MPCORE_SYS_PLD_CTRL1 0xD8
/* Register offset for MPCore sysctl */
#else
#define REALVIEW_MPCORE_SCU_BASE 0x1F000000
/* SCU registers */
#define REALVIEW_GIC_CPU_BASE 0x1F000100
/* Generic interrupt controller CPU interface */
#define REALVIEW_TWD_BASE 0x1F000700
#define REALVIEW_TWD_SIZE 0x00000100
#define REALVIEW_GIC_DIST_BASE 0x1F001000
/* Generic interrupt controller distributor */
#define REALVIEW_MPCORE_SYS_PLD_CTRL1 0x74
/* Register offset for MPCore sysctl */
#endif
#define REALVIEW_GIC1_CPU_BASE 0x10040000
/* Generic interrupt controller CPU interface */
#define REALVIEW_GIC1_DIST_BASE 0x10041000
/* Generic interrupt controller distributor */
#endif
#define REALVIEW_SMC_BASE 0x10080000
/* SMC */
/* Reserved 0x10090000 - 0x100EFFFF */
...
...
@@ -306,7 +318,11 @@
#define INT_USB 29
/* USB controller */
#define INT_TSPENINT 30
/* Touchscreen pen */
#define INT_TSKPADINT 31
/* Touchscreen keypad */
#else
#define MAX_GIC_NR 2
#define INT_AACI 0
#define INT_TIMERINT0_1 1
#define INT_TIMERINT2_3 2
...
...
include/asm-arm/arch-realview/scu.h
0 → 100644
View file @
4ba9dcbe
#ifndef __ASMARM_ARCH_SCU_H
#define __ASMARM_ARCH_SCU_H
#include <asm/arch/platform.h>
#define SCU_BASE REALVIEW_MPCORE_SCU_BASE
#endif
include/asm-arm/hardware/arm_scu.h
View file @
4ba9dcbe
#ifndef ASMARM_HARDWARE_ARM_SCU_H
#define ASMARM_HARDWARE_ARM_SCU_H
#include <asm/arch/scu.h>
/*
* SCU registers
*/
...
...
include/asm-arm/hardware/gic.h
View file @
4ba9dcbe
...
...
@@ -33,8 +33,9 @@
#define GIC_DIST_SOFTINT 0xf00
#ifndef __ASSEMBLY__
void
gic_dist_init
(
void
__iomem
*
base
);
void
gic_cpu_init
(
void
__iomem
*
base
);
void
gic_dist_init
(
unsigned
int
gic_nr
,
void
__iomem
*
base
,
unsigned
int
irq_start
);
void
gic_cpu_init
(
unsigned
int
gic_nr
,
void
__iomem
*
base
);
void
gic_cascade_irq
(
unsigned
int
gic_nr
,
unsigned
int
irq
);
void
gic_raise_softirq
(
cpumask_t
cpumask
,
unsigned
int
irq
);
#endif
...
...
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