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
be6eb9b7
Commit
be6eb9b7
authored
Nov 09, 2005
by
Russell King
Committed by
Russell King
Nov 09, 2005
Browse files
Options
Browse Files
Download
Plain Diff
Merge with ARM SMP tree
parents
c906107b
97a63ecf
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
293 additions
and
5 deletions
+293
-5
arch/arm/Kconfig
arch/arm/Kconfig
+1
-1
arch/arm/mach-realview/Makefile
arch/arm/mach-realview/Makefile
+2
-0
arch/arm/mach-realview/core.c
arch/arm/mach-realview/core.c
+1
-1
arch/arm/mach-realview/hotplug.c
arch/arm/mach-realview/hotplug.c
+138
-0
arch/arm/mach-realview/localtimer.c
arch/arm/mach-realview/localtimer.c
+130
-0
arch/arm/mach-realview/platsmp.c
arch/arm/mach-realview/platsmp.c
+5
-0
include/asm-arm/arch-realview/entry-macro.S
include/asm-arm/arch-realview/entry-macro.S
+11
-0
include/asm-arm/arch-realview/irqs.h
include/asm-arm/arch-realview/irqs.h
+3
-0
include/asm-arm/arch-realview/platform.h
include/asm-arm/arch-realview/platform.h
+2
-3
No files found.
arch/arm/Kconfig
View file @
be6eb9b7
...
...
@@ -358,7 +358,7 @@ config HOTPLUG_CPU
config LOCAL_TIMERS
bool "Use local timer interrupts"
depends on SMP &&
n
depends on SMP &&
REALVIEW_MPCORE
default y
help
Enable support for local timers on SMP platforms, rather then the
...
...
arch/arm/mach-realview/Makefile
View file @
be6eb9b7
...
...
@@ -5,3 +5,5 @@
obj-y
:=
core.o clock.o
obj-$(CONFIG_MACH_REALVIEW_EB)
+=
realview_eb.o
obj-$(CONFIG_SMP)
+=
platsmp.o headsmp.o
obj-$(CONFIG_HOTPLUG_CPU)
+=
hotplug.o
obj-$(CONFIG_LOCAL_TIMERS)
+=
localtimer.o
arch/arm/mach-realview/core.c
View file @
be6eb9b7
...
...
@@ -550,7 +550,7 @@ static irqreturn_t realview_timer_interrupt(int irq, void *dev_id, struct pt_reg
timer_tick
(
regs
);
#if
def CONFIG_SMP
#if
defined(CONFIG_SMP) && !defined(CONFIG_LOCAL_TIMERS)
smp_send_timer
();
update_process_times
(
user_mode
(
regs
));
#endif
...
...
arch/arm/mach-realview/hotplug.c
0 → 100644
View file @
be6eb9b7
/*
* linux/arch/arm/mach-realview/hotplug.c
*
* Copyright (C) 2002 ARM Ltd.
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/smp.h>
#include <linux/completion.h>
extern
volatile
int
pen_release
;
static
DECLARE_COMPLETION
(
cpu_killed
);
static
inline
void
cpu_enter_lowpower
(
void
)
{
unsigned
int
v
;
asm
volatile
(
"mcr p15, 0, %1, c7, c14, 0
\n
"
" mcr p15, 0, %1, c7, c5, 0
\n
"
" mcr p15, 0, %1, c7, c10, 4
\n
"
/*
* Turn off coherency
*/
" mrc p15, 0, %0, c1, c0, 1
\n
"
" bic %0, %0, #0x20
\n
"
" mcr p15, 0, %0, c1, c0, 1
\n
"
" mrc p15, 0, %0, c1, c0, 0
\n
"
" bic %0, %0, #0x04
\n
"
" mcr p15, 0, %0, c1, c0, 0
\n
"
:
"=&r"
(
v
)
:
"r"
(
0
)
:
"cc"
);
}
static
inline
void
cpu_leave_lowpower
(
void
)
{
unsigned
int
v
;
asm
volatile
(
"mrc p15, 0, %0, c1, c0, 0
\n
"
" orr %0, %0, #0x04
\n
"
" mcr p15, 0, %0, c1, c0, 0
\n
"
" mrc p15, 0, %0, c1, c0, 1
\n
"
" orr %0, %0, #0x20
\n
"
" mcr p15, 0, %0, c1, c0, 1
\n
"
:
"=&r"
(
v
)
:
:
"cc"
);
}
static
inline
void
platform_do_lowpower
(
unsigned
int
cpu
)
{
/*
* there is no power-control hardware on this platform, so all
* we can do is put the core into WFI; this is safe as the calling
* code will have already disabled interrupts
*/
for
(;;)
{
/*
* here's the WFI
*/
asm
(
".word 0xe320f003
\n
"
:
:
:
"memory"
,
"cc"
);
if
(
pen_release
==
cpu
)
{
/*
* OK, proper wakeup, we're done
*/
break
;
}
/*
* getting here, means that we have come out of WFI without
* having been woken up - this shouldn't happen
*
* The trouble is, letting people know about this is not really
* possible, since we are currently running incoherently, and
* therefore cannot safely call printk() or anything else
*/
#ifdef DEBUG
printk
(
"CPU%u: spurious wakeup call
\n
"
,
cpu
);
#endif
}
}
int
platform_cpu_kill
(
unsigned
int
cpu
)
{
return
wait_for_completion_timeout
(
&
cpu_killed
,
5000
);
}
/*
* platform-specific code to shutdown a CPU
*
* Called with IRQs disabled
*/
void
platform_cpu_die
(
unsigned
int
cpu
)
{
#ifdef DEBUG
unsigned
int
this_cpu
=
hard_smp_processor_id
();
if
(
cpu
!=
this_cpu
)
{
printk
(
KERN_CRIT
"Eek! platform_cpu_die running on %u, should be %u
\n
"
,
this_cpu
,
cpu
);
BUG
();
}
#endif
printk
(
KERN_NOTICE
"CPU%u: shutdown
\n
"
,
cpu
);
complete
(
&
cpu_killed
);
/*
* we're ready for shutdown now, so do it
*/
cpu_enter_lowpower
();
platform_do_lowpower
(
cpu
);
/*
* bring this CPU back into the world of cache
* coherency, and then restore interrupts
*/
cpu_leave_lowpower
();
}
int
mach_cpu_disable
(
unsigned
int
cpu
)
{
/*
* we don't allow CPU 0 to be shutdown (it is still too special
* e.g. clock tick interrupts)
*/
return
cpu
==
0
?
-
EPERM
:
0
;
}
arch/arm/mach-realview/localtimer.c
0 → 100644
View file @
be6eb9b7
/*
* linux/arch/arm/mach-realview/localtimer.c
*
* Copyright (C) 2002 ARM Ltd.
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/smp.h>
#include <asm/mach/time.h>
#include <asm/hardware/arm_twd.h>
#include <asm/hardware/gic.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
#include "core.h"
#define TWD_BASE(cpu) (__io_address(REALVIEW_TWD_BASE) + \
((cpu) * REALVIEW_TWD_SIZE))
static
unsigned
long
mpcore_timer_rate
;
/*
* local_timer_ack: checks for a local timer interrupt.
*
* If a local timer interrupt has occured, acknowledge and return 1.
* Otherwise, return 0.
*/
int
local_timer_ack
(
void
)
{
void
__iomem
*
base
=
TWD_BASE
(
smp_processor_id
());
if
(
__raw_readl
(
base
+
TWD_TIMER_INTSTAT
))
{
__raw_writel
(
1
,
base
+
TWD_TIMER_INTSTAT
);
return
1
;
}
return
0
;
}
void
__cpuinit
local_timer_setup
(
unsigned
int
cpu
)
{
void
__iomem
*
base
=
TWD_BASE
(
cpu
);
unsigned
int
load
,
offset
;
u64
waitjiffies
;
unsigned
int
count
;
/*
* If this is the first time round, we need to work out how fast
* the timer ticks
*/
if
(
mpcore_timer_rate
==
0
)
{
printk
(
"Calibrating local timer... "
);
/* Wait for a tick to start */
waitjiffies
=
get_jiffies_64
()
+
1
;
while
(
get_jiffies_64
()
<
waitjiffies
)
udelay
(
10
);
/* OK, now the tick has started, let's get the timer going */
waitjiffies
+=
5
;
/* enable, no interrupt or reload */
__raw_writel
(
0x1
,
base
+
TWD_TIMER_CONTROL
);
/* maximum value */
__raw_writel
(
0xFFFFFFFFU
,
base
+
TWD_TIMER_COUNTER
);
while
(
get_jiffies_64
()
<
waitjiffies
)
udelay
(
10
);
count
=
__raw_readl
(
base
+
TWD_TIMER_COUNTER
);
mpcore_timer_rate
=
(
0xFFFFFFFFU
-
count
)
*
(
HZ
/
5
);
printk
(
"%lu.%02luMHz.
\n
"
,
mpcore_timer_rate
/
1000000
,
(
mpcore_timer_rate
/
100000
)
%
100
);
}
load
=
mpcore_timer_rate
/
HZ
;
__raw_writel
(
load
,
base
+
TWD_TIMER_LOAD
);
__raw_writel
(
0x7
,
base
+
TWD_TIMER_CONTROL
);
/*
* Now maneuver our local tick into the right part of the jiffy.
* Start by working out where within the tick our local timer
* interrupt should go.
*/
offset
=
((
mpcore_timer_rate
/
HZ
)
/
(
NR_CPUS
+
1
))
*
(
cpu
+
1
);
/*
* gettimeoffset() will return a number of us since the last tick.
* Convert this number of us to a local timer tick count.
* Be careful of integer overflow whilst keeping maximum precision.
*
* with HZ=100 and 1MHz (fpga) ~ 1GHz processor:
* load = 1 ~ 10,000
* mpcore_timer_rate/10000 = 100 ~ 100,000
*
* so the multiply value will be less than 10^9 always.
*/
load
=
(
system_timer
->
offset
()
*
(
mpcore_timer_rate
/
10000
))
/
100
;
/* Add on our offset to get the load value */
load
=
(
load
+
offset
)
%
(
mpcore_timer_rate
/
HZ
);
__raw_writel
(
load
,
base
+
TWD_TIMER_COUNTER
);
/* Make sure our local interrupt controller has this enabled */
__raw_writel
(
1
<<
IRQ_LOCALTIMER
,
__io_address
(
REALVIEW_GIC_DIST_BASE
)
+
GIC_DIST_ENABLE_SET
);
}
/*
* take a local timer down
*/
void
__cpuexit
local_timer_stop
(
unsigned
int
cpu
)
{
__raw_writel
(
0
,
TWD_BASE
(
cpu
)
+
TWD_TIMER_CONTROL
);
}
arch/arm/mach-realview/platsmp.c
View file @
be6eb9b7
...
...
@@ -174,6 +174,11 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
if
(
max_cpus
>
ncores
)
max_cpus
=
ncores
;
/*
* Enable the local timer for primary CPU
*/
local_timer_setup
(
cpu
);
/*
* Initialise the possible/present maps.
* cpu_possible_map describes the set of CPUs which may be present
...
...
include/asm-arm/arch-realview/entry-macro.S
View file @
be6eb9b7
...
...
@@ -61,3 +61,14 @@
strcc
\
irqstat
,
[
\
base
,
#
GIC_CPU_EOI
]
cmpcs
\
irqnr
,
\
irqnr
.
endm
/
*
As
above
,
this
assumes
that
irqstat
and
base
are
preserved
..
*/
.
macro
test_for_ltirq
,
irqnr
,
irqstat
,
base
,
tmp
bic
\
irqnr
,
\
irqstat
,
#
0x1c00
mov
\
tmp
,
#
0
cmp
\
irqnr
,
#
29
moveq
\
tmp
,
#
1
streq
\
irqstat
,
[
\
base
,
#
GIC_CPU_EOI
]
cmp
\
tmp
,
#
0
.
endm
include/asm-arm/arch-realview/irqs.h
View file @
be6eb9b7
...
...
@@ -21,6 +21,9 @@
#include <asm/arch/platform.h>
#define IRQ_LOCALTIMER 29
#define IRQ_LOCALWDOG 30
/*
* IRQ interrupts definitions are the same the INT definitions
* held within platform.h
...
...
include/asm-arm/arch-realview/platform.h
View file @
be6eb9b7
...
...
@@ -209,6 +209,8 @@
#else
#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 */
#endif
#define REALVIEW_SMC_BASE 0x10080000
/* SMC */
...
...
@@ -305,9 +307,6 @@
#define INT_TSPENINT 30
/* Touchscreen pen */
#define INT_TSKPADINT 31
/* Touchscreen keypad */
#else
#define INT_LOCALTIMER 29
#define INT_LOCALWDOG 30
#define INT_AACI 0
#define INT_TIMERINT0_1 1
#define INT_TIMERINT2_3 2
...
...
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