From 72433ebada5a270899a7b1b1fa5afdc40d24998c Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Wed, 13 Feb 2013 14:25:24 +0530 Subject: ARM: OMAP4: PM: Avoid expensive cpu_suspend() path for all CPU power states except off Current CPU PM code code make use of common cpu_suspend() path for all the CPU power states which is not optimal. In fact cpu_suspend() path is needed only when we put CPU power domain to off state where the CPU context is lost. Update the code accordingly so that the expensive cpu_suspend() path can be avoided for the shallow CPU power states like CPU PD INA/CSWR. The patch has been tested on OMAP4430 and OMAP5430(with few out of tree patches) devices for suspend and CPUidle. Cc: Kevin Hilman Reported-by: Richard Woodruff Signed-off-by: Santosh Shilimkar Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/omap-mpuss-lowpower.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index 8bcb64bcdcd..d650f91f15d 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c @@ -246,7 +246,10 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) /* * Call low level function with targeted low power state. */ - cpu_suspend(save_state, omap4_finish_suspend); + if (save_state) + cpu_suspend(save_state, omap4_finish_suspend); + else + omap4_finish_suspend(save_state); /* * Restore the CPUx power state to ON otherwise CPUx -- cgit v1.2.3-18-g5258 From 9f192cf7dad8f362e937badb890dc0ab03b03b81 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Fri, 5 Apr 2013 18:29:00 +0530 Subject: ARM: OMAP4+: PM: Consolidate MPU subsystem PM code for re-use OMAP5 and future OMAP based SOCs has backward compatible MPUSS IP block with OMAP4. It's programming model is mostly similar. Hence consolidate the OMAP MPUSS code so that it can be re-used on OMAP5 and future SOCs. No functional change. Acked-by: Nishanth Menon Signed-off-by: Santosh Shilimkar Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/omap-mpuss-lowpower.c | 62 +++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index d650f91f15d..8e7029269d8 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c @@ -71,10 +71,43 @@ struct omap4_cpu_pm_info { void (*secondary_startup)(void); }; +/** + * struct cpu_pm_ops - CPU pm operations + * @finish_suspend: CPU suspend finisher function pointer + * @resume: CPU resume function pointer + * @scu_prepare: CPU Snoop Control program function pointer + * + * Structure holds functions pointer for CPU low power operations like + * suspend, resume and scu programming. + */ +struct cpu_pm_ops { + int (*finish_suspend)(unsigned long cpu_state); + void (*resume)(void); + void (*scu_prepare)(unsigned int cpu_id, unsigned int cpu_state); +}; + static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info); static struct powerdomain *mpuss_pd; static void __iomem *sar_base; +static int default_finish_suspend(unsigned long cpu_state) +{ + omap_do_wfi(); + return 0; +} + +static void dummy_cpu_resume(void) +{} + +static void dummy_scu_prepare(unsigned int cpu_id, unsigned int cpu_state) +{} + +struct cpu_pm_ops omap_pm_ops = { + .finish_suspend = default_finish_suspend, + .resume = dummy_cpu_resume, + .scu_prepare = dummy_scu_prepare, +}; + /* * Program the wakeup routine address for the CPU0 and CPU1 * used for OFF or DORMANT wakeup. @@ -172,11 +205,12 @@ static void save_l2x0_context(void) { u32 val; void __iomem *l2x0_base = omap4_get_l2cache_base(); - - val = __raw_readl(l2x0_base + L2X0_AUX_CTRL); - __raw_writel(val, sar_base + L2X0_AUXCTRL_OFFSET); - val = __raw_readl(l2x0_base + L2X0_PREFETCH_CTRL); - __raw_writel(val, sar_base + L2X0_PREFETCH_CTRL_OFFSET); + if (l2x0_base) { + val = __raw_readl(l2x0_base + L2X0_AUX_CTRL); + __raw_writel(val, sar_base + L2X0_AUXCTRL_OFFSET); + val = __raw_readl(l2x0_base + L2X0_PREFETCH_CTRL); + __raw_writel(val, sar_base + L2X0_PREFETCH_CTRL_OFFSET); + } } #else static void save_l2x0_context(void) @@ -239,17 +273,17 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) cpu_clear_prev_logic_pwrst(cpu); pwrdm_set_next_pwrst(pm_info->pwrdm, power_state); - set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume)); - scu_pwrst_prepare(cpu, power_state); + set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.resume)); + omap_pm_ops.scu_prepare(cpu, power_state); l2x0_pwrst_prepare(cpu, save_state); /* * Call low level function with targeted low power state. */ if (save_state) - cpu_suspend(save_state, omap4_finish_suspend); + cpu_suspend(save_state, omap_pm_ops.finish_suspend); else - omap4_finish_suspend(save_state); + omap_pm_ops.finish_suspend(save_state); /* * Restore the CPUx power state to ON otherwise CPUx @@ -285,14 +319,14 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) pwrdm_clear_all_prev_pwrst(pm_info->pwrdm); pwrdm_set_next_pwrst(pm_info->pwrdm, power_state); set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup)); - scu_pwrst_prepare(cpu, power_state); + omap_pm_ops.scu_prepare(cpu, power_state); /* * CPU never retuns back if targeted power state is OFF mode. * CPU ONLINE follows normal CPU ONLINE ptah via * omap_secondary_startup(). */ - omap4_finish_suspend(cpu_state); + omap_pm_ops.finish_suspend(cpu_state); pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON); return 0; @@ -369,6 +403,12 @@ int __init omap4_mpuss_init(void) save_l2x0_context(); + if (cpu_is_omap44xx()) { + omap_pm_ops.finish_suspend = omap4_finish_suspend; + omap_pm_ops.resume = omap4_cpu_resume; + omap_pm_ops.scu_prepare = scu_pwrst_prepare; + } + return 0; } -- cgit v1.2.3-18-g5258 From baf4b7d3436be7e8c8ff5bd58acc51a9b07e1871 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Fri, 5 Apr 2013 18:29:02 +0530 Subject: ARM: OMAP4+: Make secondary_startup function name more consistent Current code has rather inconsistent function names for 'secondary_startup' routines. Update it to make it more consistent. Suggested by Kevin Hilman as part of OMAP5 PM patch review. Cc: Kevin Hilman Signed-off-by: Santosh Shilimkar Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/common.h | 4 ++-- arch/arm/mach-omap2/omap-headsmp.S | 8 ++++---- arch/arm/mach-omap2/omap-mpuss-lowpower.c | 6 +++--- arch/arm/mach-omap2/omap-smp.c | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 40f4a03d728..1a568482a10 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -230,8 +230,8 @@ extern void omap_do_wfi(void); #ifdef CONFIG_SMP /* Needed for secondary core boot */ -extern void omap_secondary_startup(void); -extern void omap_secondary_startup_4460(void); +extern void omap4_secondary_startup(void); +extern void omap4460_secondary_startup(void); extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask); extern void omap_auxcoreboot_addr(u32 cpu_addr); extern u32 omap_read_auxcoreboot0(void); diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S index 0ea09faf327..4ea30811416 100644 --- a/arch/arm/mach-omap2/omap-headsmp.S +++ b/arch/arm/mach-omap2/omap-headsmp.S @@ -49,7 +49,7 @@ END(omap5_secondary_startup) * The primary core will update this flag using a hardware * register AuxCoreBoot0. */ -ENTRY(omap_secondary_startup) +ENTRY(omap4_secondary_startup) hold: ldr r12,=0x103 dsb smc #0 @ read from AuxCoreBoot0 @@ -64,9 +64,9 @@ hold: ldr r12,=0x103 * should now contain the SVC stack for this core */ b secondary_startup -ENDPROC(omap_secondary_startup) +ENDPROC(omap4_secondary_startup) -ENTRY(omap_secondary_startup_4460) +ENTRY(omap4460_secondary_startup) hold_2: ldr r12,=0x103 dsb smc #0 @ read from AuxCoreBoot0 @@ -101,4 +101,4 @@ hold_2: ldr r12,=0x103 * should now contain the SVC stack for this core */ b secondary_startup -ENDPROC(omap_secondary_startup_4460) +ENDPROC(omap4460_secondary_startup) diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index 8e7029269d8..d4322aa3192 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c @@ -324,7 +324,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) /* * CPU never retuns back if targeted power state is OFF mode. * CPU ONLINE follows normal CPU ONLINE ptah via - * omap_secondary_startup(). + * omap4_secondary_startup(). */ omap_pm_ops.finish_suspend(cpu_state); @@ -370,9 +370,9 @@ int __init omap4_mpuss_init(void) pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET; pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1; if (cpu_is_omap446x()) - pm_info->secondary_startup = omap_secondary_startup_4460; + pm_info->secondary_startup = omap4460_secondary_startup; else - pm_info->secondary_startup = omap_secondary_startup; + pm_info->secondary_startup = omap4_secondary_startup; pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm"); if (!pm_info->pwrdm) { diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index 0cbb677c4df..5b201653ca3 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -93,7 +93,7 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct * /* * Update the AuxCoreBoot0 with boot state for secondary core. - * omap_secondary_startup() routine will hold the secondary core till + * omap4_secondary_startup() routine will hold the secondary core till * the AuxCoreBoot1 register is updated with cpu state * A barrier is added to ensure that write buffer is drained */ @@ -199,7 +199,7 @@ static void __init omap4_smp_init_cpus(void) static void __init omap4_smp_prepare_cpus(unsigned int max_cpus) { - void *startup_addr = omap_secondary_startup; + void *startup_addr = omap4_secondary_startup; void __iomem *base = omap_get_wakeupgen_base(); /* @@ -210,7 +210,7 @@ static void __init omap4_smp_prepare_cpus(unsigned int max_cpus) scu_enable(scu_base); if (cpu_is_omap446x()) { - startup_addr = omap_secondary_startup_4460; + startup_addr = omap4460_secondary_startup; pm44xx_errata |= PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD; } -- cgit v1.2.3-18-g5258 From 705814b5ea6ff69d4da8ad581c3da5d26d1eae83 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Thu, 12 Apr 2012 16:51:47 +0530 Subject: ARM: OMAP4+: PM: Consolidate OMAP4 PM code to re-use it for OMAP5 OMAP5 has backward compatible PRCM block and it's programming model is mostly similar to OMAP4. Same is going to be maintained for future OMAP4 based SOCs. Hence consolidate the OMAP4 power management code so that it can be re-used on OMAP5 and later devices. While at it, update the kernel-doc for omap4_pm_init(). Acked-by: Nishanth Menon Signed-off-by: Santosh Shilimkar Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm44xx.c | 58 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 5ba6d888d6f..228deca8fb9 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -1,7 +1,7 @@ /* - * OMAP4 Power Management Routines + * OMAP4+ Power Management Routines * - * Copyright (C) 2010-2011 Texas Instruments, Inc. + * Copyright (C) 2010-2013 Texas Instruments, Inc. * Rajendra Nayak * Santosh Shilimkar * @@ -135,16 +135,16 @@ static void omap_default_idle(void) } /** - * omap4_pm_init - Init routine for OMAP4 PM + * omap4_init_static_deps - Add OMAP4 static dependencies * - * Initializes all powerdomain and clockdomain target states - * and all PRCM settings. + * Add needed static clockdomain dependencies on OMAP4 devices. + * Return: 0 on success or 'err' on failures */ -int __init omap4_pm_init(void) +static inline int omap4_init_static_deps(void) { - int ret; struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm; struct clockdomain *ducati_clkdm, *l3_2_clkdm; + int ret = 0; if (omap_rev() == OMAP4430_REV_ES1_0) { WARN(1, "Power Management not supported on OMAP4430 ES1.0\n"); @@ -163,7 +163,7 @@ int __init omap4_pm_init(void) ret = pwrdm_for_each(pwrdms_setup, NULL); if (ret) { pr_err("Failed to setup powerdomains\n"); - goto err2; + return ret; } /* @@ -171,6 +171,10 @@ int __init omap4_pm_init(void) * MPUSS -> L4_PER/L3_* and DUCATI -> L3_* doesn't work as * expected. The hardware recommendation is to enable static * dependencies for these to avoid system lock ups or random crashes. + * The L4 wakeup depedency is added to workaround the OCP sync hardware + * BUG with 32K synctimer which lead to incorrect timer value read + * from the 32K counter. The BUG applies for GPTIMER1 and WDT2 which + * are part of L4 wakeup clockdomain. */ mpuss_clkdm = clkdm_lookup("mpuss_clkdm"); emif_clkdm = clkdm_lookup("l3_emif_clkdm"); @@ -179,7 +183,7 @@ int __init omap4_pm_init(void) ducati_clkdm = clkdm_lookup("ducati_clkdm"); if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) || (!l3_2_clkdm) || (!ducati_clkdm)) - goto err2; + return -EINVAL; ret = clkdm_add_wkdep(mpuss_clkdm, emif_clkdm); ret |= clkdm_add_wkdep(mpuss_clkdm, l3_1_clkdm); @@ -188,9 +192,42 @@ int __init omap4_pm_init(void) ret |= clkdm_add_wkdep(ducati_clkdm, l3_2_clkdm); if (ret) { pr_err("Failed to add MPUSS -> L3/EMIF/L4PER, DUCATI -> L3 wakeup dependency\n"); + return -EINVAL; + } + + return ret; +} + +/** + * omap4_pm_init - Init routine for OMAP4+ devices + * + * Initializes all powerdomain and clockdomain target states + * and all PRCM settings. + * Return: Returns the error code returned by called functions. + */ +int __init omap4_pm_init(void) +{ + int ret = 0; + + if (omap_rev() == OMAP4430_REV_ES1_0) { + WARN(1, "Power Management not supported on OMAP4430 ES1.0\n"); + return -ENODEV; + } + + pr_info("Power Management for TI OMAP4+ devices.\n"); + + ret = pwrdm_for_each(pwrdms_setup, NULL); + if (ret) { + pr_err("Failed to setup powerdomains.\n"); goto err2; } + if (cpu_is_omap44xx()) { + ret = omap4_init_static_deps(); + if (ret) + goto err2; + } + ret = omap4_mpuss_init(); if (ret) { pr_err("Failed to initialise OMAP4 MPUSS\n"); @@ -206,7 +243,8 @@ int __init omap4_pm_init(void) /* Overwrite the default cpu_do_idle() */ arm_pm_idle = omap_default_idle; - omap4_idle_init(); + if (cpu_is_omap44xx()) + omap4_idle_init(); err2: return ret; -- cgit v1.2.3-18-g5258 From 55bdd694116597d2f16510b121463cd579ba78da Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Fri, 21 May 2010 18:06:41 +0100 Subject: ARM: Add base support for ARMv7-M MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds the base support for the ARMv7-M architecture. It consists of the corresponding arch/arm/mm/ files and various #ifdef's around the kernel. Exception handling is implemented by a subsequent patch. [ukleinek: squash in some changes originating from commit b5717ba (Cortex-M3: Add support for the Microcontroller Prototyping System) from the v2.6.33-arm1 patch stack, port to post 3.6, drop zImage support, drop reorganisation of pt_regs, assert CONFIG_CPU_V7M doesn't leak into installed headers and a few cosmetic changes] Signed-off-by: Catalin Marinas Reviewed-by: Jonathan Austin Tested-by: Jonathan Austin Signed-off-by: Uwe Kleine-König --- arch/arm/include/asm/assembler.h | 17 +++- arch/arm/include/asm/cputype.h | 12 ++- arch/arm/include/asm/glue-cache.h | 27 +++++++ arch/arm/include/asm/glue-df.h | 8 ++ arch/arm/include/asm/glue-proc.h | 9 +++ arch/arm/include/asm/irqflags.h | 22 ++++-- arch/arm/include/asm/ptrace.h | 4 + arch/arm/include/asm/system_info.h | 1 + arch/arm/include/asm/v7m.h | 44 +++++++++++ arch/arm/include/uapi/asm/ptrace.h | 35 +++++++-- arch/arm/kernel/head-nommu.S | 10 ++- arch/arm/kernel/setup.c | 17 +++- arch/arm/kernel/traps.c | 8 ++ arch/arm/mm/cache-nop.S | 50 ++++++++++++ arch/arm/mm/nommu.c | 7 ++ arch/arm/mm/proc-v7m.S | 157 +++++++++++++++++++++++++++++++++++++ 16 files changed, 407 insertions(+), 21 deletions(-) create mode 100644 arch/arm/include/asm/v7m.h create mode 100644 arch/arm/mm/cache-nop.S create mode 100644 arch/arm/mm/proc-v7m.S (limited to 'arch') diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index 05ee9eebad6..a5fef710af3 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h @@ -136,7 +136,11 @@ * assumes FIQs are enabled, and that the processor is in SVC mode. */ .macro save_and_disable_irqs, oldcpsr +#ifdef CONFIG_CPU_V7M + mrs \oldcpsr, primask +#else mrs \oldcpsr, cpsr +#endif disable_irq .endm @@ -150,7 +154,11 @@ * guarantee that this will preserve the flags. */ .macro restore_irqs_notrace, oldcpsr +#ifdef CONFIG_CPU_V7M + msr primask, \oldcpsr +#else msr cpsr_c, \oldcpsr +#endif .endm .macro restore_irqs, oldcpsr @@ -229,7 +237,14 @@ #endif .endm -#ifdef CONFIG_THUMB2_KERNEL +#if defined(CONFIG_CPU_V7M) + /* + * setmode is used to assert to be in svc mode during boot. For v7-M + * this is done in __v7m_setup, so setmode can be empty here. + */ + .macro setmode, mode, reg + .endm +#elif defined(CONFIG_THUMB2_KERNEL) .macro setmode, mode, reg mov \reg, #\mode msr cpsr_c, \reg diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h index 7652712d1d1..4eb94a3add3 100644 --- a/arch/arm/include/asm/cputype.h +++ b/arch/arm/include/asm/cputype.h @@ -106,7 +106,17 @@ static inline unsigned int __attribute_const__ read_cpuid_id(void) return read_cpuid(CPUID_ID); } -#else /* ifdef CONFIG_CPU_CP15 */ +#elif defined(CONFIG_CPU_V7M) + +#include +#include + +static inline unsigned int __attribute_const__ read_cpuid_id(void) +{ + return readl(BASEADDR_V7M_SCB + V7M_SCB_CPUID); +} + +#else /* ifdef CONFIG_CPU_CP15 / elif defined(CONFIG_CPU_V7M) */ static inline unsigned int __attribute_const__ read_cpuid_id(void) { diff --git a/arch/arm/include/asm/glue-cache.h b/arch/arm/include/asm/glue-cache.h index cca9f15704e..65c9faf7a34 100644 --- a/arch/arm/include/asm/glue-cache.h +++ b/arch/arm/include/asm/glue-cache.h @@ -125,10 +125,37 @@ # endif #endif +#if defined(CONFIG_CPU_V7M) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE nop +# endif +#endif + #if !defined(_CACHE) && !defined(MULTI_CACHE) #error Unknown cache maintenance model #endif +#ifndef __ASSEMBLER__ +extern inline void nop_flush_icache_all(void) { } +extern inline void nop_flush_kern_cache_all(void) { } +extern inline void nop_flush_kern_cache_louis(void) { } +extern inline void nop_flush_user_cache_all(void) { } +extern inline void nop_flush_user_cache_range(unsigned long a, + unsigned long b, unsigned int c) { } + +extern inline void nop_coherent_kern_range(unsigned long a, unsigned long b) { } +extern inline int nop_coherent_user_range(unsigned long a, + unsigned long b) { return 0; } +extern inline void nop_flush_kern_dcache_area(void *a, size_t s) { } + +extern inline void nop_dma_flush_range(const void *a, const void *b) { } + +extern inline void nop_dma_map_area(const void *s, size_t l, int f) { } +extern inline void nop_dma_unmap_area(const void *s, size_t l, int f) { } +#endif + #ifndef MULTI_CACHE #define __cpuc_flush_icache_all __glue(_CACHE,_flush_icache_all) #define __cpuc_flush_kern_all __glue(_CACHE,_flush_kern_cache_all) diff --git a/arch/arm/include/asm/glue-df.h b/arch/arm/include/asm/glue-df.h index b6e9f2c108b..6b70f1b46a6 100644 --- a/arch/arm/include/asm/glue-df.h +++ b/arch/arm/include/asm/glue-df.h @@ -95,6 +95,14 @@ # endif #endif +#ifdef CONFIG_CPU_ABRT_NOMMU +# ifdef CPU_DABORT_HANDLER +# define MULTI_DABORT 1 +# else +# define CPU_DABORT_HANDLER nommu_early_abort +# endif +#endif + #ifndef CPU_DABORT_HANDLER #error Unknown data abort handler type #endif diff --git a/arch/arm/include/asm/glue-proc.h b/arch/arm/include/asm/glue-proc.h index ac1dd54724b..f2f39bcf794 100644 --- a/arch/arm/include/asm/glue-proc.h +++ b/arch/arm/include/asm/glue-proc.h @@ -230,6 +230,15 @@ # endif #endif +#ifdef CONFIG_CPU_V7M +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_v7m +# endif +#endif + #ifndef MULTI_CPU #define cpu_proc_init __glue(CPU_NAME,_proc_init) #define cpu_proc_fin __glue(CPU_NAME,_proc_fin) diff --git a/arch/arm/include/asm/irqflags.h b/arch/arm/include/asm/irqflags.h index 1e6cca55c75..3b763d6652a 100644 --- a/arch/arm/include/asm/irqflags.h +++ b/arch/arm/include/asm/irqflags.h @@ -8,6 +8,16 @@ /* * CPU interrupt mask handling. */ +#ifdef CONFIG_CPU_V7M +#define IRQMASK_REG_NAME_R "primask" +#define IRQMASK_REG_NAME_W "primask" +#define IRQMASK_I_BIT 1 +#else +#define IRQMASK_REG_NAME_R "cpsr" +#define IRQMASK_REG_NAME_W "cpsr_c" +#define IRQMASK_I_BIT PSR_I_BIT +#endif + #if __LINUX_ARM_ARCH__ >= 6 static inline unsigned long arch_local_irq_save(void) @@ -15,7 +25,7 @@ static inline unsigned long arch_local_irq_save(void) unsigned long flags; asm volatile( - " mrs %0, cpsr @ arch_local_irq_save\n" + " mrs %0, " IRQMASK_REG_NAME_R " @ arch_local_irq_save\n" " cpsid i" : "=r" (flags) : : "memory", "cc"); return flags; @@ -129,7 +139,7 @@ static inline unsigned long arch_local_save_flags(void) { unsigned long flags; asm volatile( - " mrs %0, cpsr @ local_save_flags" + " mrs %0, " IRQMASK_REG_NAME_R " @ local_save_flags" : "=r" (flags) : : "memory", "cc"); return flags; } @@ -140,7 +150,7 @@ static inline unsigned long arch_local_save_flags(void) static inline void arch_local_irq_restore(unsigned long flags) { asm volatile( - " msr cpsr_c, %0 @ local_irq_restore" + " msr " IRQMASK_REG_NAME_W ", %0 @ local_irq_restore" : : "r" (flags) : "memory", "cc"); @@ -148,8 +158,8 @@ static inline void arch_local_irq_restore(unsigned long flags) static inline int arch_irqs_disabled_flags(unsigned long flags) { - return flags & PSR_I_BIT; + return flags & IRQMASK_I_BIT; } -#endif -#endif +#endif /* ifdef __KERNEL__ */ +#endif /* ifndef __ASM_ARM_IRQFLAGS_H */ diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h index 3d52ee1bfb3..04c99f36ff7 100644 --- a/arch/arm/include/asm/ptrace.h +++ b/arch/arm/include/asm/ptrace.h @@ -45,6 +45,7 @@ struct pt_regs { */ static inline int valid_user_regs(struct pt_regs *regs) { +#ifndef CONFIG_CPU_V7M unsigned long mode = regs->ARM_cpsr & MODE_MASK; /* @@ -67,6 +68,9 @@ static inline int valid_user_regs(struct pt_regs *regs) regs->ARM_cpsr |= USR_MODE; return 0; +#else /* ifndef CONFIG_CPU_V7M */ + return 1; +#endif } static inline long regs_return_value(struct pt_regs *regs) diff --git a/arch/arm/include/asm/system_info.h b/arch/arm/include/asm/system_info.h index dfd386d0c02..720ea0320a6 100644 --- a/arch/arm/include/asm/system_info.h +++ b/arch/arm/include/asm/system_info.h @@ -11,6 +11,7 @@ #define CPU_ARCH_ARMv5TEJ 7 #define CPU_ARCH_ARMv6 8 #define CPU_ARCH_ARMv7 9 +#define CPU_ARCH_ARMv7M 10 #ifndef __ASSEMBLY__ diff --git a/arch/arm/include/asm/v7m.h b/arch/arm/include/asm/v7m.h new file mode 100644 index 00000000000..fa88d09fa3d --- /dev/null +++ b/arch/arm/include/asm/v7m.h @@ -0,0 +1,44 @@ +/* + * Common defines for v7m cpus + */ +#define V7M_SCS_ICTR IOMEM(0xe000e004) +#define V7M_SCS_ICTR_INTLINESNUM_MASK 0x0000000f + +#define BASEADDR_V7M_SCB IOMEM(0xe000ed00) + +#define V7M_SCB_CPUID 0x00 + +#define V7M_SCB_ICSR 0x04 +#define V7M_SCB_ICSR_PENDSVSET (1 << 28) +#define V7M_SCB_ICSR_PENDSVCLR (1 << 27) +#define V7M_SCB_ICSR_RETTOBASE (1 << 11) + +#define V7M_SCB_VTOR 0x08 + +#define V7M_SCB_SCR 0x10 +#define V7M_SCB_SCR_SLEEPDEEP (1 << 2) + +#define V7M_SCB_CCR 0x14 +#define V7M_SCB_CCR_STKALIGN (1 << 9) + +#define V7M_SCB_SHPR2 0x1c +#define V7M_SCB_SHPR3 0x20 + +#define V7M_SCB_SHCSR 0x24 +#define V7M_SCB_SHCSR_USGFAULTENA (1 << 18) +#define V7M_SCB_SHCSR_BUSFAULTENA (1 << 17) +#define V7M_SCB_SHCSR_MEMFAULTENA (1 << 16) + +#define V7M_xPSR_FRAMEPTRALIGN 0x00000200 +#define V7M_xPSR_EXCEPTIONNO 0x000001ff + +/* + * When branching to an address that has bits [31:28] == 0xf an exception return + * occurs. Bits [27:5] are reserved (SBOP). If the processor implements the FP + * extension Bit [4] defines if the exception frame has space allocated for FP + * state information, SBOP otherwise. Bit [3] defines the mode that is returned + * to (0 -> handler mode; 1 -> thread mode). Bit [2] defines which sp is used + * (0 -> msp; 1 -> psp). Bits [1:0] are fixed to 0b01. + */ +#define EXC_RET_STACK_MASK 0x00000004 +#define EXC_RET_THREADMODE_PROCESSSTACK 0xfffffffd diff --git a/arch/arm/include/uapi/asm/ptrace.h b/arch/arm/include/uapi/asm/ptrace.h index 96ee0929790..5af0ed1b825 100644 --- a/arch/arm/include/uapi/asm/ptrace.h +++ b/arch/arm/include/uapi/asm/ptrace.h @@ -34,28 +34,47 @@ /* * PSR bits + * Note on V7M there is no mode contained in the PSR */ #define USR26_MODE 0x00000000 #define FIQ26_MODE 0x00000001 #define IRQ26_MODE 0x00000002 #define SVC26_MODE 0x00000003 +#if defined(__KERNEL__) && defined(CONFIG_CPU_V7M) +/* + * Use 0 here to get code right that creates a userspace + * or kernel space thread. + */ +#define USR_MODE 0x00000000 +#define SVC_MODE 0x00000000 +#else #define USR_MODE 0x00000010 +#define SVC_MODE 0x00000013 +#endif #define FIQ_MODE 0x00000011 #define IRQ_MODE 0x00000012 -#define SVC_MODE 0x00000013 #define ABT_MODE 0x00000017 #define HYP_MODE 0x0000001a #define UND_MODE 0x0000001b #define SYSTEM_MODE 0x0000001f #define MODE32_BIT 0x00000010 #define MODE_MASK 0x0000001f -#define PSR_T_BIT 0x00000020 -#define PSR_F_BIT 0x00000040 -#define PSR_I_BIT 0x00000080 -#define PSR_A_BIT 0x00000100 -#define PSR_E_BIT 0x00000200 -#define PSR_J_BIT 0x01000000 -#define PSR_Q_BIT 0x08000000 + +#define V4_PSR_T_BIT 0x00000020 /* >= V4T, but not V7M */ +#define V7M_PSR_T_BIT 0x01000000 +#if defined(__KERNEL__) && defined(CONFIG_CPU_V7M) +#define PSR_T_BIT V7M_PSR_T_BIT +#else +/* for compatibility */ +#define PSR_T_BIT V4_PSR_T_BIT +#endif + +#define PSR_F_BIT 0x00000040 /* >= V4, but not V7M */ +#define PSR_I_BIT 0x00000080 /* >= V4, but not V7M */ +#define PSR_A_BIT 0x00000100 /* >= V6, but not V7M */ +#define PSR_E_BIT 0x00000200 /* >= V6, but not V7M */ +#define PSR_J_BIT 0x01000000 /* >= V5J, but not V7M */ +#define PSR_Q_BIT 0x08000000 /* >= V5E, including V7M */ #define PSR_V_BIT 0x10000000 #define PSR_C_BIT 0x20000000 #define PSR_Z_BIT 0x40000000 diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S index 6a2e09c952c..8812ce88f7a 100644 --- a/arch/arm/kernel/head-nommu.S +++ b/arch/arm/kernel/head-nommu.S @@ -19,6 +19,7 @@ #include #include #include +#include /* * Kernel startup entry point. @@ -50,10 +51,13 @@ ENTRY(stext) setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode @ and irqs disabled -#ifndef CONFIG_CPU_CP15 - ldr r9, =CONFIG_PROCESSOR_ID -#else +#if defined(CONFIG_CPU_CP15) mrc p15, 0, r9, c0, c0 @ get processor id +#elif defined(CONFIG_CPU_V7M) + ldr r9, =BASEADDR_V7M_SCB + ldr r9, [r9, V7M_SCB_CPUID] +#else + ldr r9, =CONFIG_PROCESSOR_ID #endif bl __lookup_processor_type @ r5=procinfo r9=cpuid movs r10, r5 @ invalid processor (r5=0)? diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 1cc9e179641..829124590e4 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -128,7 +128,9 @@ struct stack { u32 und[3]; } ____cacheline_aligned; +#ifndef CONFIG_CPU_V7M static struct stack stacks[NR_CPUS]; +#endif char elf_platform[ELF_PLATFORM_SIZE]; EXPORT_SYMBOL(elf_platform); @@ -207,7 +209,7 @@ static const char *proc_arch[] = { "5TEJ", "6TEJ", "7", - "?(11)", + "7M", "?(12)", "?(13)", "?(14)", @@ -216,6 +218,12 @@ static const char *proc_arch[] = { "?(17)", }; +#ifdef CONFIG_CPU_V7M +static int __get_cpu_architecture(void) +{ + return CPU_ARCH_ARMv7M; +} +#else static int __get_cpu_architecture(void) { int cpu_arch; @@ -248,6 +256,7 @@ static int __get_cpu_architecture(void) return cpu_arch; } +#endif int __pure cpu_architecture(void) { @@ -293,7 +302,9 @@ static void __init cacheid_init(void) { unsigned int arch = cpu_architecture(); - if (arch >= CPU_ARCH_ARMv6) { + if (arch == CPU_ARCH_ARMv7M) { + cacheid = 0; + } else if (arch >= CPU_ARCH_ARMv6) { unsigned int cachetype = read_cpuid_cachetype(); if ((cachetype & (7 << 29)) == 4 << 29) { /* ARMv7 register format */ @@ -375,6 +386,7 @@ static void __init feat_v6_fixup(void) */ void cpu_init(void) { +#ifndef CONFIG_CPU_V7M unsigned int cpu = smp_processor_id(); struct stack *stk = &stacks[cpu]; @@ -425,6 +437,7 @@ void cpu_init(void) "I" (offsetof(struct stack, und[0])), PLC (PSR_F_BIT | PSR_I_BIT | SVC_MODE) : "r14"); +#endif } int __cpu_logical_map[NR_CPUS]; diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 1c089119b2d..ec64571462d 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -819,6 +819,7 @@ static void __init kuser_get_tls_init(unsigned long vectors) void __init early_trap_init(void *vectors_base) { +#ifndef CONFIG_CPU_V7M unsigned long vectors = (unsigned long)vectors_base; extern char __stubs_start[], __stubs_end[]; extern char __vectors_start[], __vectors_end[]; @@ -850,4 +851,11 @@ void __init early_trap_init(void *vectors_base) flush_icache_range(vectors, vectors + PAGE_SIZE); modify_domain(DOMAIN_USER, DOMAIN_CLIENT); +#else /* ifndef CONFIG_CPU_V7M */ + /* + * on V7-M there is no need to copy the vector table to a dedicated + * memory area. The address is configurable and so a table in the kernel + * image can be used. + */ +#endif } diff --git a/arch/arm/mm/cache-nop.S b/arch/arm/mm/cache-nop.S new file mode 100644 index 00000000000..8e12ddca003 --- /dev/null +++ b/arch/arm/mm/cache-nop.S @@ -0,0 +1,50 @@ +/* + * 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 +#include + +#include "proc-macros.S" + +ENTRY(nop_flush_icache_all) + mov pc, lr +ENDPROC(nop_flush_icache_all) + + .globl nop_flush_kern_cache_all + .equ nop_flush_kern_cache_all, nop_flush_icache_all + + .globl nop_flush_kern_cache_louis + .equ nop_flush_kern_cache_louis, nop_flush_icache_all + + .globl nop_flush_user_cache_all + .equ nop_flush_user_cache_all, nop_flush_icache_all + + .globl nop_flush_user_cache_range + .equ nop_flush_user_cache_range, nop_flush_icache_all + + .globl nop_coherent_kern_range + .equ nop_coherent_kern_range, nop_flush_icache_all + +ENTRY(nop_coherent_user_range) + mov r0, 0 + mov pc, lr +ENDPROC(nop_coherent_user_range) + + .globl nop_flush_kern_dcache_area + .equ nop_flush_kern_dcache_area, nop_flush_icache_all + + .globl nop_dma_flush_range + .equ nop_dma_flush_range, nop_flush_icache_all + + .globl nop_dma_map_area + .equ nop_dma_map_area, nop_flush_icache_all + + .globl nop_dma_unmap_area + .equ nop_dma_unmap_area, nop_flush_icache_all + + __INITDATA + + @ define struct cpu_cache_fns (see and proc-macros.S) + define_cache_functions nop diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index d51225f90ae..dd3a6c670f0 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c @@ -20,12 +20,19 @@ void __init arm_mm_memblock_reserve(void) { +#ifndef CONFIG_CPU_V7M /* * Register the exception vector page. * some architectures which the DRAM is the exception vector to trap, * alloc_page breaks with error, although it is not NULL, but "0." */ memblock_reserve(CONFIG_VECTORS_BASE, PAGE_SIZE); +#else /* ifndef CONFIG_CPU_V7M */ + /* + * There is no dedicated vector page on V7-M. So nothing needs to be + * reserved here. + */ +#endif } void __init sanity_check_meminfo(void) diff --git a/arch/arm/mm/proc-v7m.S b/arch/arm/mm/proc-v7m.S new file mode 100644 index 00000000000..000499cfceb --- /dev/null +++ b/arch/arm/mm/proc-v7m.S @@ -0,0 +1,157 @@ +/* + * linux/arch/arm/mm/proc-v7m.S + * + * Copyright (C) 2008 ARM Ltd. + * Copyright (C) 2001 Deep Blue Solutions Ltd. + * + * 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. + * + * This is the "shell" of the ARMv7-M processor support. + */ +#include +#include +#include +#include "proc-macros.S" + +ENTRY(cpu_v7m_proc_init) + mov pc, lr +ENDPROC(cpu_v7m_proc_init) + +ENTRY(cpu_v7m_proc_fin) + mov pc, lr +ENDPROC(cpu_v7m_proc_fin) + +/* + * cpu_v7m_reset(loc) + * + * Perform a soft reset of the system. Put the CPU into the + * same state as it would be if it had been reset, and branch + * to what would be the reset vector. + * + * - loc - location to jump to for soft reset + */ + .align 5 +ENTRY(cpu_v7m_reset) + mov pc, r0 +ENDPROC(cpu_v7m_reset) + +/* + * cpu_v7m_do_idle() + * + * Idle the processor (eg, wait for interrupt). + * + * IRQs are already disabled. + */ +ENTRY(cpu_v7m_do_idle) + wfi + mov pc, lr +ENDPROC(cpu_v7m_do_idle) + +ENTRY(cpu_v7m_dcache_clean_area) + mov pc, lr +ENDPROC(cpu_v7m_dcache_clean_area) + +/* + * There is no MMU, so here is nothing to do. + */ +ENTRY(cpu_v7m_switch_mm) + mov pc, lr +ENDPROC(cpu_v7m_switch_mm) + +.globl cpu_v7m_suspend_size +.equ cpu_v7m_suspend_size, 0 + +#ifdef CONFIG_ARM_CPU_SUSPEND +ENTRY(cpu_v7m_do_suspend) + mov pc, lr +ENDPROC(cpu_v7m_do_suspend) + +ENTRY(cpu_v7m_do_resume) + mov pc, lr +ENDPROC(cpu_v7m_do_resume) +#endif + + .section ".text.init", #alloc, #execinstr + +/* + * __v7m_setup + * + * This should be able to cover all ARMv7-M cores. + */ +__v7m_setup: + @ Configure the vector table base address + ldr r0, =BASEADDR_V7M_SCB + ldr r12, =vector_table + str r12, [r0, V7M_SCB_VTOR] + + @ enable UsageFault, BusFault and MemManage fault. + ldr r5, [r0, #V7M_SCB_SHCSR] + orr r5, #(V7M_SCB_SHCSR_USGFAULTENA | V7M_SCB_SHCSR_BUSFAULTENA | V7M_SCB_SHCSR_MEMFAULTENA) + str r5, [r0, #V7M_SCB_SHCSR] + + @ Lower the priority of the SVC and PendSV exceptions + mov r5, #0x80000000 + str r5, [r0, V7M_SCB_SHPR2] @ set SVC priority + mov r5, #0x00800000 + str r5, [r0, V7M_SCB_SHPR3] @ set PendSV priority + + @ SVC to run the kernel in this mode + adr r1, BSYM(1f) + ldr r5, [r12, #11 * 4] @ read the SVC vector entry + str r1, [r12, #11 * 4] @ write the temporary SVC vector entry + mov r6, lr @ save LR + mov r7, sp @ save SP + ldr sp, =__v7m_setup_stack_top + cpsie i + svc #0 +1: cpsid i + str r5, [r12, #11 * 4] @ restore the original SVC vector entry + mov lr, r6 @ restore LR + mov sp, r7 @ restore SP + + @ Special-purpose control register + mov r1, #1 + msr control, r1 @ Thread mode has unpriviledged access + + @ Configure the System Control Register to ensure 8-byte stack alignment + @ Note the STKALIGN bit is either RW or RAO. + ldr r12, [r0, V7M_SCB_CCR] @ system control register + orr r12, #V7M_SCB_CCR_STKALIGN + str r12, [r0, V7M_SCB_CCR] + mov pc, lr +ENDPROC(__v7m_setup) + + define_processor_functions v7m, dabort=nommu_early_abort, pabort=legacy_pabort, nommu=1 + + .section ".rodata" + string cpu_arch_name, "armv7m" + string cpu_elf_name "v7m" + string cpu_v7m_name "ARMv7-M" + + .section ".proc.info.init", #alloc, #execinstr + + /* + * Match any ARMv7-M processor core. + */ + .type __v7m_proc_info, #object +__v7m_proc_info: + .long 0x000f0000 @ Required ID value + .long 0x000f0000 @ Mask for ID + .long 0 @ proc_info_list.__cpu_mm_mmu_flags + .long 0 @ proc_info_list.__cpu_io_mmu_flags + b __v7m_setup @ proc_info_list.__cpu_flush + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_IDIVT + .long cpu_v7m_name + .long v7m_processor_functions @ proc_info_list.proc + .long 0 @ proc_info_list.tlb + .long 0 @ proc_info_list.user + .long nop_cache_fns @ proc_info_list.cache + .size __v7m_proc_info, . - __v7m_proc_info + +__v7m_setup_stack: + .space 4 * 8 @ 8 registers +__v7m_setup_stack_top: -- cgit v1.2.3-18-g5258 From 19c4d593f0b4bd46f6d923a3e514719982a22058 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 21 May 2010 18:06:42 +0100 Subject: ARM: ARMv7-M: Add support for exception handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch implements the exception handling for the ARMv7-M architecture (pretty different from the A or R profiles). It bases on work done earlier by Catalin for 2.6.33 but was nearly completely rewritten to use a pt_regs layout compatible to the A profile. Signed-off-by: Catalin Marinas Reviewed-by: Jonathan Austin Tested-by: Jonathan Austin Signed-off-by: Uwe Kleine-König --- arch/arm/kernel/entry-common.S | 4 ++ arch/arm/kernel/entry-header.S | 124 +++++++++++++++++++++++++++++++++++ arch/arm/kernel/entry-v7m.S | 143 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 271 insertions(+) create mode 100644 arch/arm/kernel/entry-v7m.S (limited to 'arch') diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 3248cde504e..c45e0027613 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -339,6 +339,9 @@ ENDPROC(ftrace_stub) .align 5 ENTRY(vector_swi) +#ifdef CONFIG_CPU_V7M + v7m_exception_entry +#else sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ Calling r0 - r12 ARM( add r8, sp, #S_PC ) @@ -349,6 +352,7 @@ ENTRY(vector_swi) str lr, [sp, #S_PC] @ Save calling PC str r8, [sp, #S_PSR] @ Save CPSR str r0, [sp, #S_OLD_R0] @ Save OLD_R0 +#endif zero_fp /* diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S index 9a8531eadd3..b02e1394dc5 100644 --- a/arch/arm/kernel/entry-header.S +++ b/arch/arm/kernel/entry-header.S @@ -5,6 +5,7 @@ #include #include #include +#include @ Bad Abort numbers @ ----------------- @@ -44,6 +45,116 @@ #endif .endm +#ifdef CONFIG_CPU_V7M +/* + * ARMv7-M exception entry/exit macros. + * + * xPSR, ReturnAddress(), LR (R14), R12, R3, R2, R1, and R0 are + * automatically saved on the current stack (32 words) before + * switching to the exception stack (SP_main). + * + * If exception is taken while in user mode, SP_main is + * empty. Otherwise, SP_main is aligned to 64 bit automatically + * (CCR.STKALIGN set). + * + * Linux assumes that the interrupts are disabled when entering an + * exception handler and it may BUG if this is not the case. Interrupts + * are disabled during entry and reenabled in the exit macro. + * + * v7m_exception_slow_exit is used when returning from SVC or PendSV. + * When returning to kernel mode, we don't return from exception. + */ + .macro v7m_exception_entry + @ determine the location of the registers saved by the core during + @ exception entry. Depending on the mode the cpu was in when the + @ exception happend that is either on the main or the process stack. + @ Bit 2 of EXC_RETURN stored in the lr register specifies which stack + @ was used. + tst lr, #EXC_RET_STACK_MASK + mrsne r12, psp + moveq r12, sp + + @ we cannot rely on r0-r3 and r12 matching the value saved in the + @ exception frame because of tail-chaining. So these have to be + @ reloaded. + ldmia r12!, {r0-r3} + + @ Linux expects to have irqs off. Do it here before taking stack space + cpsid i + + sub sp, #S_FRAME_SIZE-S_IP + stmdb sp!, {r0-r11} + + @ load saved r12, lr, return address and xPSR. + @ r0-r7 are used for signals and never touched from now on. Clobbering + @ r8-r12 is OK. + mov r9, r12 + ldmia r9!, {r8, r10-r12} + + @ calculate the original stack pointer value. + @ r9 currently points to the memory location just above the auto saved + @ xPSR. + @ The cpu might automatically 8-byte align the stack. Bit 9 + @ of the saved xPSR specifies if stack aligning took place. In this case + @ another 32-bit value is included in the stack. + + tst r12, V7M_xPSR_FRAMEPTRALIGN + addne r9, r9, #4 + + @ store saved r12 using str to have a register to hold the base for stm + str r8, [sp, #S_IP] + add r8, sp, #S_SP + @ store r13-r15, xPSR + stmia r8!, {r9-r12} + @ store old_r0 + str r0, [r8] + .endm + + /* + * PENDSV and SVCALL are configured to have the same exception + * priorities. As a kernel thread runs at SVCALL execution priority it + * can never be preempted and so we will never have to return to a + * kernel thread here. + */ + .macro v7m_exception_slow_exit ret_r0 + cpsid i + ldr lr, =EXC_RET_THREADMODE_PROCESSSTACK + + @ read original r12, sp, lr, pc and xPSR + add r12, sp, #S_IP + ldmia r12, {r1-r5} + + @ an exception frame is always 8-byte aligned. To tell the hardware if + @ the sp to be restored is aligned or not set bit 9 of the saved xPSR + @ accordingly. + tst r2, #4 + subne r2, r2, #4 + orrne r5, V7M_xPSR_FRAMEPTRALIGN + biceq r5, V7M_xPSR_FRAMEPTRALIGN + + @ write basic exception frame + stmdb r2!, {r1, r3-r5} + ldmia sp, {r1, r3-r5} + .if \ret_r0 + stmdb r2!, {r0, r3-r5} + .else + stmdb r2!, {r1, r3-r5} + .endif + + @ restore process sp + msr psp, r2 + + @ restore original r4-r11 + ldmia sp!, {r0-r11} + + @ restore main sp + add sp, sp, #S_FRAME_SIZE-S_IP + + cpsie i + bx lr + .endm +#endif /* CONFIG_CPU_V7M */ + @ @ Store/load the USER SP and LR registers by switching to the SYS @ mode. Useful in Thumb-2 mode where "stm/ldm rd, {sp, lr}^" is not @@ -131,6 +242,18 @@ rfeia sp! .endm +#ifdef CONFIG_CPU_V7M + /* + * Note we don't need to do clrex here as clearing the local monitor is + * part of each exception entry and exit sequence. + */ + .macro restore_user_regs, fast = 0, offset = 0 + .if \offset + add sp, #\offset + .endif + v7m_exception_slow_exit ret_r0 = \fast + .endm +#else /* ifdef CONFIG_CPU_V7M */ .macro restore_user_regs, fast = 0, offset = 0 clrex @ clear the exclusive monitor mov r2, sp @@ -147,6 +270,7 @@ add sp, sp, #S_FRAME_SIZE - S_SP movs pc, lr @ return & move spsr_svc into cpsr .endm +#endif /* ifdef CONFIG_CPU_V7M / else */ .macro get_thread_info, rd mov \rd, sp diff --git a/arch/arm/kernel/entry-v7m.S b/arch/arm/kernel/entry-v7m.S new file mode 100644 index 00000000000..e00621f1403 --- /dev/null +++ b/arch/arm/kernel/entry-v7m.S @@ -0,0 +1,143 @@ +/* + * linux/arch/arm/kernel/entry-v7m.S + * + * Copyright (C) 2008 ARM Ltd. + * + * 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. + * + * Low-level vector interface routines for the ARMv7-M architecture + */ +#include +#include +#include +#include + +#include + +#include "entry-header.S" + +#ifdef CONFIG_TRACE_IRQFLAGS +#error "CONFIG_TRACE_IRQFLAGS not supported on the current ARMv7M implementation" +#endif + +__invalid_entry: + v7m_exception_entry + adr r0, strerr + mrs r1, ipsr + mov r2, lr + bl printk + mov r0, sp + bl show_regs +1: b 1b +ENDPROC(__invalid_entry) + +strerr: .asciz "\nUnhandled exception: IPSR = %08lx LR = %08lx\n" + + .align 2 +__irq_entry: + v7m_exception_entry + + @ + @ Invoke the IRQ handler + @ + mrs r0, ipsr + ldr r1, =V7M_xPSR_EXCEPTIONNO + and r0, r1 + sub r0, #16 + mov r1, sp + stmdb sp!, {lr} + @ routine called with r0 = irq number, r1 = struct pt_regs * + bl nvic_do_IRQ + + pop {lr} + @ + @ Check for any pending work if returning to user + @ + ldr r1, =BASEADDR_V7M_SCB + ldr r0, [r1, V7M_SCB_ICSR] + tst r0, V7M_SCB_ICSR_RETTOBASE + beq 2f + + get_thread_info tsk + ldr r2, [tsk, #TI_FLAGS] + tst r2, #_TIF_WORK_MASK + beq 2f @ no work pending + mov r0, #V7M_SCB_ICSR_PENDSVSET + str r0, [r1, V7M_SCB_ICSR] @ raise PendSV + +2: + @ registers r0-r3 and r12 are automatically restored on exception + @ return. r4-r7 were not clobbered in v7m_exception_entry so for + @ correctness they don't need to be restored. So only r8-r11 must be + @ restored here. The easiest way to do so is to restore r0-r7, too. + ldmia sp!, {r0-r11} + add sp, #S_FRAME_SIZE-S_IP + cpsie i + bx lr +ENDPROC(__irq_entry) + +__pendsv_entry: + v7m_exception_entry + + ldr r1, =BASEADDR_V7M_SCB + mov r0, #V7M_SCB_ICSR_PENDSVCLR + str r0, [r1, V7M_SCB_ICSR] @ clear PendSV + + @ execute the pending work, including reschedule + get_thread_info tsk + mov why, #0 + b ret_to_user +ENDPROC(__pendsv_entry) + +/* + * Register switch for ARMv7-M processors. + * r0 = previous task_struct, r1 = previous thread_info, r2 = next thread_info + * previous and next are guaranteed not to be the same. + */ +ENTRY(__switch_to) + .fnstart + .cantunwind + add ip, r1, #TI_CPU_SAVE + stmia ip!, {r4 - r11} @ Store most regs on stack + str sp, [ip], #4 + str lr, [ip], #4 + mov r5, r0 + add r4, r2, #TI_CPU_SAVE + ldr r0, =thread_notify_head + mov r1, #THREAD_NOTIFY_SWITCH + bl atomic_notifier_call_chain + mov ip, r4 + mov r0, r5 + ldmia ip!, {r4 - r11} @ Load all regs saved previously + ldr sp, [ip] + ldr pc, [ip, #4]! + .fnend +ENDPROC(__switch_to) + + .data + .align 8 +/* + * Vector table (64 words => 256 bytes natural alignment) + */ +ENTRY(vector_table) + .long 0 @ 0 - Reset stack pointer + .long __invalid_entry @ 1 - Reset + .long __invalid_entry @ 2 - NMI + .long __invalid_entry @ 3 - HardFault + .long __invalid_entry @ 4 - MemManage + .long __invalid_entry @ 5 - BusFault + .long __invalid_entry @ 6 - UsageFault + .long __invalid_entry @ 7 - Reserved + .long __invalid_entry @ 8 - Reserved + .long __invalid_entry @ 9 - Reserved + .long __invalid_entry @ 10 - Reserved + .long vector_swi @ 11 - SVCall + .long __invalid_entry @ 12 - Debug Monitor + .long __invalid_entry @ 13 - Reserved + .long __pendsv_entry @ 14 - PendSV + .long __invalid_entry @ 15 - SysTick + .rept 64 - 16 + .long __irq_entry @ 16..64 - External Interrupts + .endr -- cgit v1.2.3-18-g5258 From 4477ca45fb368880bf77b10ed3b24b03f0cc82da Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 21 Mar 2013 21:02:37 +0100 Subject: ARM: ARMv7-M: Allow the building of new kernel port MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch modifies the required Kconfig and Makefile files to allow the building of kernel for Cortex-M3. Signed-off-by: Catalin Marinas Reviewed-by: Jonathan Austin Tested-by: Jonathan Austin Signed-off-by: Uwe Kleine-König --- arch/arm/Kconfig | 4 ++-- arch/arm/Kconfig-nommu | 2 +- arch/arm/Makefile | 1 + arch/arm/kernel/Makefile | 8 +++++++- arch/arm/mm/Kconfig | 21 ++++++++++++++++++++- arch/arm/mm/Makefile | 2 ++ 6 files changed, 33 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index dedf02b6f32..7c8c6079f94 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -9,7 +9,7 @@ config ARM select BUILDTIME_EXTABLE_SORT if MMU select CPU_PM if (SUSPEND || CPU_IDLE) select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && !CPU_BIG_ENDIAN && MMU - select GENERIC_ATOMIC64 if (CPU_V6 || !CPU_32v6K || !AEABI) + select GENERIC_ATOMIC64 if (CPU_V7M || CPU_V6 || !CPU_32v6K || !AEABI) select GENERIC_CLOCKEVENTS_BROADCAST if SMP select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW @@ -1685,7 +1685,7 @@ config SCHED_HRTICK config THUMB2_KERNEL bool "Compile the kernel in Thumb-2 mode" if !CPU_THUMBONLY - depends on CPU_V7 && !CPU_V6 && !CPU_V6K + depends on (CPU_V7 || CPU_V7M) && !CPU_V6 && !CPU_V6K default y if CPU_THUMBONLY select AEABI select ARM_ASM_UNIFIED diff --git a/arch/arm/Kconfig-nommu b/arch/arm/Kconfig-nommu index 2cef8e13f9f..c859495da48 100644 --- a/arch/arm/Kconfig-nommu +++ b/arch/arm/Kconfig-nommu @@ -28,7 +28,7 @@ config FLASH_SIZE config PROCESSOR_ID hex 'Hard wire the processor ID' default 0x00007700 - depends on !CPU_CP15 + depends on !(CPU_CP15 || CPU_V7M) help If processor has no CP15 register, this processor ID is used instead of the auto-probing which utilizes the register. diff --git a/arch/arm/Makefile b/arch/arm/Makefile index ee4605f400b..f11b8da1767 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -59,6 +59,7 @@ comma = , # Note that GCC does not numerically define an architecture version # macro, but instead defines a whole series of macros which makes # testing for a specific architecture or later rather impossible. +arch-$(CONFIG_CPU_32v7M) :=-D__LINUX_ARM_ARCH__=7 -march=armv7-m -Wa,-march=armv7-m arch-$(CONFIG_CPU_32v7) :=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7-a,-march=armv5t -Wa$(comma)-march=armv7-a) arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6) # Only override the compiler option if ARMv6. The ARMv6K extensions are diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 5f3338eacad..00d703c49f8 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -15,7 +15,7 @@ CFLAGS_REMOVE_return_address.o = -pg # Object file lists. -obj-y := elf.o entry-armv.o entry-common.o irq.o opcodes.o \ +obj-y := elf.o entry-common.o irq.o opcodes.o \ process.o ptrace.o return_address.o sched_clock.o \ setup.o signal.o stacktrace.o sys_arm.o time.o traps.o @@ -23,6 +23,12 @@ obj-$(CONFIG_ATAGS) += atags_parse.o obj-$(CONFIG_ATAGS_PROC) += atags_proc.o obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += atags_compat.o +ifeq ($(CONFIG_CPU_V7M),y) +obj-y += entry-v7m.o +else +obj-y += entry-armv.o +endif + obj-$(CONFIG_OC_ETM) += etm.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o obj-$(CONFIG_ISA_DMA_API) += dma.o diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index cb812a13e29..cce78b07082 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -397,6 +397,15 @@ config CPU_V7 select CPU_PABRT_V7 select CPU_TLB_V7 if MMU +# ARMv7M +config CPU_V7M + bool + select CPU_32v7M + select CPU_ABRT_NOMMU + select CPU_CACHE_NOP + select CPU_PABRT_LEGACY + select CPU_THUMBONLY + config CPU_THUMBONLY bool # There are no CPUs available with MMU that don't implement an ARM ISA: @@ -441,6 +450,9 @@ config CPU_32v6K config CPU_32v7 bool +config CPU_32v7M + bool + # The abort model config CPU_ABRT_NOMMU bool @@ -494,6 +506,9 @@ config CPU_CACHE_V6 config CPU_CACHE_V7 bool +config CPU_CACHE_NOP + bool + config CPU_CACHE_VIVT bool @@ -616,7 +631,11 @@ config ARCH_DMA_ADDR_T_64BIT config ARM_THUMB bool "Support Thumb user binaries" if !CPU_THUMBONLY - depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_V6 || CPU_V6K || CPU_V7 || CPU_FEROCEON + depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || \ + CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || \ + CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || \ + CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_V6 || CPU_V6K || \ + CPU_V7 || CPU_FEROCEON || CPU_V7M default y help Say Y if you want to include kernel support for running user space diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 4e333fa2756..317b5755934 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_CPU_CACHE_V4WB) += cache-v4wb.o obj-$(CONFIG_CPU_CACHE_V6) += cache-v6.o obj-$(CONFIG_CPU_CACHE_V7) += cache-v7.o obj-$(CONFIG_CPU_CACHE_FA) += cache-fa.o +obj-$(CONFIG_CPU_CACHE_NOP) += cache-nop.o AFLAGS_cache-v6.o :=-Wa,-march=armv6 AFLAGS_cache-v7.o :=-Wa,-march=armv7-a @@ -88,6 +89,7 @@ obj-$(CONFIG_CPU_FEROCEON) += proc-feroceon.o obj-$(CONFIG_CPU_V6) += proc-v6.o obj-$(CONFIG_CPU_V6K) += proc-v6.o obj-$(CONFIG_CPU_V7) += proc-v7.o +obj-$(CONFIG_CPU_V7M) += proc-v7m.o AFLAGS_proc-v6.o :=-Wa,-march=armv6 AFLAGS_proc-v7.o :=-Wa,-march=armv7-a -- cgit v1.2.3-18-g5258 From 366c0b76416ed15feb90ba4ef0bd8f03d62d1091 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Wed, 17 Apr 2013 16:51:34 -0300 Subject: ARM: mvebu: Add support for USB storage class in mvebu_defconfig Some boards can have built-in USB storage class controllers so it's better to have this option included by default. Currently this option is needed to support built-in USB MMC controller found in Globalscale Mirabox board. Signed-off-by: Ezequiel Garcia Signed-off-by: Jason Cooper --- arch/arm/configs/mvebu_defconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/configs/mvebu_defconfig b/arch/arm/configs/mvebu_defconfig index f3e8ae001ff..083782973e3 100644 --- a/arch/arm/configs/mvebu_defconfig +++ b/arch/arm/configs/mvebu_defconfig @@ -60,6 +60,7 @@ CONFIG_USB_SUPPORT=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_STORAGE=y CONFIG_MMC=y CONFIG_MMC_MVSDIO=y CONFIG_NEW_LEDS=y -- cgit v1.2.3-18-g5258 From e37f6110459d9edbf88b230cf67fe4345de4f32d Mon Sep 17 00:00:00 2001 From: Jason Cooper Date: Wed, 15 May 2013 00:45:56 +0000 Subject: ARM: kirkwood: enable Sheevaplug DT in defconfig Signed-off-by: Jason Cooper --- arch/arm/configs/kirkwood_defconfig | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/configs/kirkwood_defconfig b/arch/arm/configs/kirkwood_defconfig index a1d8252e9ec..1916da6e035 100644 --- a/arch/arm/configs/kirkwood_defconfig +++ b/arch/arm/configs/kirkwood_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -50,6 +49,7 @@ CONFIG_MACH_NETSPACE_V2_DT=y CONFIG_MACH_NSA310_DT=y CONFIG_MACH_OPENBLOCKS_A6_DT=y CONFIG_MACH_READYNAS_DT=y +CONFIG_MACH_SHEEVAPLUG_DT=y CONFIG_MACH_TOPKICK_DT=y CONFIG_MACH_TS219_DT=y # CONFIG_CPU_FEROCEON_OLD_ID is not set @@ -68,14 +68,12 @@ CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y # CONFIG_IPV6 is not set -CONFIG_NET_DSA=y CONFIG_NET_PKTGEN=m CONFIG_CFG80211=y CONFIG_MAC80211=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_JEDECPROBE=y -- cgit v1.2.3-18-g5258 From c064521b2a3b09febe061ae7d476331923fb00bd Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Tue, 14 May 2013 16:42:24 +0200 Subject: ARM: Kirkwood: Enable USB 3.0 in kirkwood_defconfig Some QNAP devices has a USB 3.0 host controller on a PCIe bus. Enable the driver for this in the default configuration. Reported-by: Marek Vasut Signed-off-by: Andrew Lunn Signed-off-by: Jason Cooper --- arch/arm/configs/kirkwood_defconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/configs/kirkwood_defconfig b/arch/arm/configs/kirkwood_defconfig index 1916da6e035..bb1d4b843f0 100644 --- a/arch/arm/configs/kirkwood_defconfig +++ b/arch/arm/configs/kirkwood_defconfig @@ -138,6 +138,7 @@ CONFIG_HID_TOPSEED=y CONFIG_HID_THRUSTMASTER=y CONFIG_HID_ZEROPLUS=y CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_PRINTER=m -- cgit v1.2.3-18-g5258 From 6fae9cdafc92ae9958a3a45dd68205f72e3ad900 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 6 May 2013 11:35:42 +0200 Subject: ARM: ARMv7-M: implement read_cpuid_ext MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On v7-M the extended cpuid registers are not available from CP15 but they are memory mapped in the System Control Space. There isn't an equivalent available for CPUID_{CACHETYPE,TCM,TLBTYPE,MPIDR}. Signed-off-by: Uwe Kleine-König --- arch/arm/include/asm/cputype.h | 38 ++++++++++++++++++++++++++++++++++---- arch/arm/mm/proc-v7m.S | 2 +- 2 files changed, 35 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h index 4eb94a3add3..ec635ff32f4 100644 --- a/arch/arm/include/asm/cputype.h +++ b/arch/arm/include/asm/cputype.h @@ -10,6 +10,22 @@ #define CPUID_TLBTYPE 3 #define CPUID_MPIDR 5 +#ifdef CONFIG_CPU_V7M +#define CPUID_EXT_PFR0 0x40 +#define CPUID_EXT_PFR1 0x44 +#define CPUID_EXT_DFR0 0x48 +#define CPUID_EXT_AFR0 0x4c +#define CPUID_EXT_MMFR0 0x50 +#define CPUID_EXT_MMFR1 0x54 +#define CPUID_EXT_MMFR2 0x58 +#define CPUID_EXT_MMFR3 0x5c +#define CPUID_EXT_ISAR0 0x60 +#define CPUID_EXT_ISAR1 0x64 +#define CPUID_EXT_ISAR2 0x68 +#define CPUID_EXT_ISAR3 0x6c +#define CPUID_EXT_ISAR4 0x70 +#define CPUID_EXT_ISAR5 0x74 +#else #define CPUID_EXT_PFR0 "c1, 0" #define CPUID_EXT_PFR1 "c1, 1" #define CPUID_EXT_DFR0 "c1, 2" @@ -24,6 +40,7 @@ #define CPUID_EXT_ISAR3 "c2, 3" #define CPUID_EXT_ISAR4 "c2, 4" #define CPUID_EXT_ISAR5 "c2, 5" +#endif #define MPIDR_SMP_BITMASK (0x3 << 30) #define MPIDR_SMP_VALUE (0x2 << 30) @@ -79,7 +96,23 @@ extern unsigned int processor_id; __val; \ }) -#else /* ifdef CONFIG_CPU_CP15 */ +#elif defined(CONFIG_CPU_V7M) + +#include +#include + +#define read_cpuid(reg) \ + ({ \ + WARN_ON_ONCE(1); \ + 0; \ + }) + +static inline unsigned int __attribute_const__ read_cpuid_ext(unsigned offset) +{ + return readl(BASEADDR_V7M_SCB + offset); +} + +#else /* ifdef CONFIG_CPU_CP15 / elif defined (CONFIG_CPU_V7M) */ /* * read_cpuid and read_cpuid_ext should only ever be called on machines that @@ -108,9 +141,6 @@ static inline unsigned int __attribute_const__ read_cpuid_id(void) #elif defined(CONFIG_CPU_V7M) -#include -#include - static inline unsigned int __attribute_const__ read_cpuid_id(void) { return readl(BASEADDR_V7M_SCB + V7M_SCB_CPUID); diff --git a/arch/arm/mm/proc-v7m.S b/arch/arm/mm/proc-v7m.S index 000499cfceb..0c93588fcb9 100644 --- a/arch/arm/mm/proc-v7m.S +++ b/arch/arm/mm/proc-v7m.S @@ -144,7 +144,7 @@ __v7m_proc_info: b __v7m_setup @ proc_info_list.__cpu_flush .long cpu_arch_name .long cpu_elf_name - .long HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_IDIVT + .long HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT .long cpu_v7m_name .long v7m_processor_functions @ proc_info_list.proc .long 0 @ proc_info_list.tlb -- cgit v1.2.3-18-g5258 From b39f38c4d27f04fbc3ee8ce9a5fb04673047d5a0 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Sun, 12 May 2013 10:26:49 +0000 Subject: ARM: tegra: emc: correction of ram-code parsing from dt Change tegra_emc_ramcode_devnode() to get ram-code from child node instead of parent. Signed-off-by: Dmitry Osipenko Signed-off-by: Stephen Warren --- arch/arm/mach-tegra/tegra2_emc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-tegra/tegra2_emc.c b/arch/arm/mach-tegra/tegra2_emc.c index 9e8bdfa2b36..25f0189889b 100644 --- a/arch/arm/mach-tegra/tegra2_emc.c +++ b/arch/arm/mach-tegra/tegra2_emc.c @@ -183,7 +183,7 @@ static struct device_node *tegra_emc_ramcode_devnode(struct device_node *np) u32 reg; for_each_child_of_node(np, iter) { - if (of_property_read_u32(np, "nvidia,ram-code", ®)) + if (of_property_read_u32(iter, "nvidia,ram-code", ®)) continue; if (reg == tegra_bct_strapping) return of_node_get(iter); -- cgit v1.2.3-18-g5258 From 3207792e62498f872d64f12e2fc368aa9d7e3795 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Wed, 15 May 2013 16:04:59 +0200 Subject: arm: kirkwood: use the default of match table mach-kirkwood/board-dt.c defines its own OF matching table, but in fact, it is the same to the default of_default_bus_match_table[] which is already used by mach-mvebu, mach-dove and mach-orion5x. This patch therefore makes mach-kirkwood use the same default OF matching table. Signed-off-by: Thomas Petazzoni Signed-off-by: Jason Cooper --- arch/arm/mach-kirkwood/board-dt.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c index e9647b80cb5..a8dae114b53 100644 --- a/arch/arm/mach-kirkwood/board-dt.c +++ b/arch/arm/mach-kirkwood/board-dt.c @@ -25,11 +25,6 @@ #include #include "common.h" -static struct of_device_id kirkwood_dt_match_table[] __initdata = { - { .compatible = "simple-bus", }, - { } -}; - /* * There are still devices that doesn't know about DT yet. Get clock * gates here and add a clock lookup alias, so that old platform @@ -159,7 +154,7 @@ static void __init kirkwood_dt_init(void) if (of_machine_is_compatible("usi,topkick")) usi_topkick_init(); - of_platform_populate(NULL, kirkwood_dt_match_table, NULL, NULL); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } static const char * const kirkwood_dt_board_compat[] = { -- cgit v1.2.3-18-g5258 From dcb5eb8569a5fc5fe7dd434708b0936b1cf03675 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 16 May 2013 17:55:24 +0200 Subject: arm: mvebu: update defconfig with PCI and USB support Now that we have the necessary drivers and Device Tree informations to support PCIe on Armada 370 and Armada XP, enable the CONFIG_PCI option. Also, since the Armada 370 Mirabox has a built-in USB XHCI controller connected on the PCIe bus, enable the corresponding options as well. Signed-off-by: Thomas Petazzoni Signed-off-by: Jason Cooper --- arch/arm/configs/mvebu_defconfig | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/arm/configs/mvebu_defconfig b/arch/arm/configs/mvebu_defconfig index 083782973e3..804b1dae433 100644 --- a/arch/arm/configs/mvebu_defconfig +++ b/arch/arm/configs/mvebu_defconfig @@ -13,6 +13,8 @@ CONFIG_MACH_ARMADA_370=y CONFIG_MACH_ARMADA_XP=y # CONFIG_CACHE_L2X0 is not set # CONFIG_SWP_EMULATE is not set +CONFIG_PCI=y +CONFIG_PCI_MVEBU=y CONFIG_SMP=y CONFIG_AEABI=y CONFIG_HIGHMEM=y @@ -61,6 +63,7 @@ CONFIG_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_STORAGE=y +CONFIG_USB_XHCI_HCD=y CONFIG_MMC=y CONFIG_MMC_MVSDIO=y CONFIG_NEW_LEDS=y -- cgit v1.2.3-18-g5258 From 4c4e9759a6fa63c61f0d269150741feccdd33f06 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 21 May 2013 01:01:33 +0900 Subject: ARM: S3C24XX: split s3c2412 spi dma channels While s3c24xx before s3c2412 (2410, 2440, 2442) use one dma channel for both sending and receiving spi data, all later s3c24xx socs use separate channels. To keep with the structure of "one spi channel" s3c2412 introduced a channel_rx attribute to the map and selects the correct request channel depending on the dma direction, hiding the underlying separ