Skip to content

Commit

Permalink
Merge branch 'misc' into devel
Browse files Browse the repository at this point in the history
Conflicts:
	arch/arm/mm/init.c
  • Loading branch information
Russell King committed Jul 31, 2010
2 parents b31fc7a + 08458ef commit ceb0885
Show file tree
Hide file tree
Showing 60 changed files with 475 additions and 426 deletions.
8 changes: 7 additions & 1 deletion Documentation/arm/memory.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,13 @@ ffff0000 ffff0fff CPU vector page.

fffe0000 fffeffff XScale cache flush area. This is used
in proc-xscale.S to flush the whole data
cache. Free for other usage on non-XScale.
cache. (XScale does not have TCM.)

fffe8000 fffeffff DTCM mapping area for platforms with
DTCM mounted inside the CPU.

fffe0000 fffe7fff ITCM mapping area for platforms with
ITCM mounted inside the CPU.

fff00000 fffdffff Fixmap mapping region. Addresses provided
by fix_to_virt() will be located here.
Expand Down
30 changes: 19 additions & 11 deletions Documentation/arm/tcm.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ defines a CPUID_TCM register that you can read out from the
system control coprocessor. Documentation from ARM can be found
at http://infocenter.arm.com, search for "TCM Status Register"
to see documents for all CPUs. Reading this register you can
determine if ITCM (bit 0) and/or DTCM (bit 16) is present in the
machine.
determine if ITCM (bits 1-0) and/or DTCM (bit 17-16) is present
in the machine.

There is further a TCM region register (search for "TCM Region
Registers" at the ARM site) that can report and modify the location
Expand All @@ -35,7 +35,15 @@ The TCM memory can then be remapped to another address again using
the MMU, but notice that the TCM if often used in situations where
the MMU is turned off. To avoid confusion the current Linux
implementation will map the TCM 1 to 1 from physical to virtual
memory in the location specified by the machine.
memory in the location specified by the kernel. Currently Linux
will map ITCM to 0xfffe0000 and on, and DTCM to 0xfffe8000 and
on, supporting a maximum of 32KiB of ITCM and 32KiB of DTCM.

Newer versions of the region registers also support dividing these
TCMs in two separate banks, so for example an 8KiB ITCM is divided
into two 4KiB banks with its own control registers. The idea is to
be able to lock and hide one of the banks for use by the secure
world (TrustZone).

TCM is used for a few things:

Expand Down Expand Up @@ -65,18 +73,18 @@ in <asm/tcm.h>. Using this interface it is possible to:
memory. Such a heap is great for things like saving
device state when shutting off device power domains.

A machine that has TCM memory shall select HAVE_TCM in
arch/arm/Kconfig for itself, and then the
rest of the functionality will depend on the physical
location and size of ITCM and DTCM to be defined in
mach/memory.h for the machine. Code that needs to use
TCM shall #include <asm/tcm.h> If the TCM is not located
at the place given in memory.h it will be moved using
the TCM Region registers.
A machine that has TCM memory shall select HAVE_TCM from
arch/arm/Kconfig for itself. Code that needs to use TCM shall
#include <asm/tcm.h>

Functions to go into itcm can be tagged like this:
int __tcmfunc foo(int bar);

Since these are marked to become long_calls and you may want
to have functions called locally inside the TCM without
wasting space, there is also the __tcmlocalfunc prefix that
will make the call relative.

Variables to go into dtcm can be tagged like this:
int __tcmdata foo;

Expand Down
7 changes: 2 additions & 5 deletions arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ config GENERIC_CLOCKEVENTS
config GENERIC_CLOCKEVENTS_BROADCAST
bool
depends on GENERIC_CLOCKEVENTS
default y if SMP && !LOCAL_TIMERS
default y if SMP

config HAVE_TCM
bool
Expand Down Expand Up @@ -1263,17 +1263,14 @@ config HW_PERF_EVENTS
disabled, perf events will use software events only.

config SPARSE_IRQ
bool "Support sparse irq numbering"
depends on EXPERIMENTAL
def_bool n
help
This enables support for sparse irqs. This is useful in general
as most CPUs have a fairly sparse array of IRQ vectors, which
the irq_desc then maps directly on to. Systems with a high
number of off-chip IRQs will want to treat this as
experimental until they have been independently verified.

If you don't know what to do here, say N.

source "mm/Kconfig"

config FORCE_MAX_ZONEORDER
Expand Down
2 changes: 2 additions & 0 deletions arch/arm/include/asm/mach/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ struct map_desc {
#define MT_MEMORY 9
#define MT_ROM 10
#define MT_MEMORY_NONCACHED 11
#define MT_MEMORY_DTCM 12
#define MT_MEMORY_ITCM 13

#ifdef CONFIG_MMU
extern void iotable_init(struct map_desc *, int);
Expand Down
9 changes: 9 additions & 0 deletions arch/arm/include/asm/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,15 @@

#endif /* !CONFIG_MMU */

/*
* We fix the TCM memories max 32 KiB ITCM resp DTCM at these
* locations
*/
#ifdef CONFIG_HAVE_TCM
#define ITCM_OFFSET UL(0xfffe0000)
#define DTCM_OFFSET UL(0xfffe8000)
#endif

/*
* Physical vs virtual RAM address space conversion. These are
* private definitions which should NOT be used outside memory.h
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/include/asm/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ void arm_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,

void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
struct pt_regs *),
int sig, const char *name);
int sig, int code, const char *name);

#define xchg(ptr,x) \
((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
Expand Down
10 changes: 5 additions & 5 deletions arch/arm/kernel/machine_kexec.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,6 @@ void machine_kexec_cleanup(struct kimage *image)
{
}

void machine_shutdown(void)
{
}

void machine_crash_shutdown(struct pt_regs *regs)
{
local_irq_disable();
Expand Down Expand Up @@ -78,7 +74,11 @@ void machine_kexec(struct kimage *image)
(unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE);
printk(KERN_INFO "Bye!\n");

cpu_proc_fin();
local_irq_disable();
local_fiq_disable();
setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/
flush_cache_all();
cpu_proc_fin();
flush_cache_all();
cpu_reset(reboot_code_buffer_phys);
}
29 changes: 24 additions & 5 deletions arch/arm/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <linux/utsname.h>
#include <linux/uaccess.h>

#include <asm/cacheflush.h>
#include <asm/leds.h>
#include <asm/processor.h>
#include <asm/system.h>
Expand Down Expand Up @@ -84,10 +85,9 @@ __setup("hlt", hlt_setup);

void arm_machine_restart(char mode, const char *cmd)
{
/*
* Clean and disable cache, and turn off interrupts
*/
cpu_proc_fin();
/* Disable interrupts first */
local_irq_disable();
local_fiq_disable();

/*
* Tell the mm system that we are going to reboot -
Expand All @@ -96,6 +96,15 @@ void arm_machine_restart(char mode, const char *cmd)
*/
setup_mm_for_reboot(mode);

/* Clean and invalidate caches */
flush_cache_all();

/* Turn off caching */
cpu_proc_fin();

/* Push out any further dirty data, and ensure cache is empty */
flush_cache_all();

/*
* Now call the architecture specific reboot code.
*/
Expand Down Expand Up @@ -189,19 +198,29 @@ int __init reboot_setup(char *str)

__setup("reboot=", reboot_setup);

void machine_halt(void)
void machine_shutdown(void)
{
#ifdef CONFIG_SMP
smp_send_stop();
#endif
}

void machine_halt(void)
{
machine_shutdown();
while (1);
}

void machine_power_off(void)
{
machine_shutdown();
if (pm_power_off)
pm_power_off();
}

void machine_restart(char *cmd)
{
machine_shutdown();
arm_pm_restart(reboot_mode, cmd);
}

Expand Down
17 changes: 12 additions & 5 deletions arch/arm/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,11 @@ static void smp_timer_broadcast(const struct cpumask *mask)
{
send_ipi_message(mask, IPI_TIMER);
}
#else
#define smp_timer_broadcast NULL
#endif

#ifndef CONFIG_LOCAL_TIMERS
static void broadcast_timer_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt)
{
Expand All @@ -444,7 +448,6 @@ static void local_timer_setup(struct clock_event_device *evt)
evt->rating = 400;
evt->mult = 1;
evt->set_mode = broadcast_timer_set_mode;
evt->broadcast = smp_timer_broadcast;

clockevents_register_device(evt);
}
Expand All @@ -456,6 +459,7 @@ void __cpuinit percpu_timer_setup(void)
struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);

evt->cpumask = cpumask_of(cpu);
evt->broadcast = smp_timer_broadcast;

local_timer_setup(evt);
}
Expand All @@ -467,10 +471,13 @@ static DEFINE_SPINLOCK(stop_lock);
*/
static void ipi_cpu_stop(unsigned int cpu)
{
spin_lock(&stop_lock);
printk(KERN_CRIT "CPU%u: stopping\n", cpu);
dump_stack();
spin_unlock(&stop_lock);
if (system_state == SYSTEM_BOOTING ||
system_state == SYSTEM_RUNNING) {
spin_lock(&stop_lock);
printk(KERN_CRIT "CPU%u: stopping\n", cpu);
dump_stack();
spin_unlock(&stop_lock);
}

set_cpu_online(cpu, false);

Expand Down
3 changes: 2 additions & 1 deletion arch/arm/kernel/smp_twd.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
twd_calibrate_rate();

clk->name = "local_timer";
clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
CLOCK_EVT_FEAT_C3STOP;
clk->rating = 350;
clk->set_mode = twd_set_mode;
clk->set_next_event = twd_set_next_event;
Expand Down
Loading

0 comments on commit ceb0885

Please sign in to comment.