* [PATCH v7 2/3] Cortex-M3: Add base support for Cortex-M3
From: Uwe Kleine-König @ 2012-10-17 8:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350462872-16805-1-git-send-email-u.kleine-koenig@pengutronix.de>
From: Catalin Marinas <catalin.marinas@arm.com>
This patch adds the base support for the Cortex-M3 processor (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_V7M doesn't leak
into installed headers and a few cosmetic changes]
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
---
changes since v6:
- trivially rebased on v3.7-rc1
arch/arm/include/asm/assembler.h | 13 ++-
arch/arm/include/asm/cputype.h | 3 +
arch/arm/include/asm/glue-cache.h | 25 ++++++
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/processor.h | 7 ++
arch/arm/include/asm/ptrace.h | 8 ++
arch/arm/include/asm/system_info.h | 1 +
arch/arm/include/uapi/asm/ptrace.h | 36 ++++++--
arch/arm/kernel/asm-offsets.c | 3 +
arch/arm/kernel/head-nommu.S | 9 +-
arch/arm/kernel/setup.c | 13 ++-
arch/arm/kernel/traps.c | 2 +
arch/arm/mm/nommu.c | 2 +
arch/arm/mm/proc-v7m.S | 161 ++++++++++++++++++++++++++++++++++++
16 files changed, 303 insertions(+), 19 deletions(-)
create mode 100644 arch/arm/mm/proc-v7m.S
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 2ef9581..ab7c02c 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,10 @@
#endif
.endm
-#ifdef CONFIG_THUMB2_KERNEL
+#if defined(CONFIG_CPU_V7M)
+ .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 cb47d28..5bd8cb6 100644
--- a/arch/arm/include/asm/cputype.h
+++ b/arch/arm/include/asm/cputype.h
@@ -46,6 +46,9 @@ extern unsigned int processor_id;
: "cc"); \
__val; \
})
+#elif defined(CONFIG_CPU_V7M)
+#define read_cpuid(reg) (*(unsigned int *)0xe000ed00)
+#define read_cpuid_ext(reg) 0
#else
#define read_cpuid(reg) (processor_id)
#define read_cpuid_ext(reg) 0
diff --git a/arch/arm/include/asm/glue-cache.h b/arch/arm/include/asm/glue-cache.h
index cca9f15..ea98658 100644
--- a/arch/arm/include/asm/glue-cache.h
+++ b/arch/arm/include/asm/glue-cache.h
@@ -125,10 +125,35 @@
# endif
#endif
+#if defined(CONFIG_CPU_V7M)
+# ifdef _CACHE
+# error "Multi-cache not supported on ARMv7-M"
+# else
+# define _CACHE nop
+# endif
+#endif
+
#if !defined(_CACHE) && !defined(MULTI_CACHE)
#error Unknown cache maintenance model
#endif
+#ifndef __ASSEMBLER__
+static inline void nop_flush_icache_all(void) { }
+static inline void nop_flush_kern_cache_all(void) { }
+static inline void nop_flush_kern_cache_louis(void) { }
+static inline void nop_flush_user_cache_all(void) { }
+static inline void nop_flush_user_cache_range(unsigned long a, unsigned long b, unsigned int c) { }
+
+static inline void nop_coherent_kern_range(unsigned long a, unsigned long b) { }
+static inline int nop_coherent_user_range(unsigned long a, unsigned long b) { return 0; }
+static inline void nop_flush_kern_dcache_area(void *a, size_t s) { }
+
+static inline void nop_dma_flush_range(const void *a, const void *b) { }
+
+static inline void nop_dma_map_area(const void *s, size_t l, int f) { }
+static 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 8cacbcd..1f2339c 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 ac1dd54..f2f39bc 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 1e6cca5..3b763d6 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/processor.h b/arch/arm/include/asm/processor.h
index 06e7d50..5e61b88 100644
--- a/arch/arm/include/asm/processor.h
+++ b/arch/arm/include/asm/processor.h
@@ -49,7 +49,14 @@ struct thread_struct {
#ifdef CONFIG_MMU
#define nommu_start_thread(regs) do { } while (0)
#else
+#ifndef CONFIG_CPU_V7M
#define nommu_start_thread(regs) regs->ARM_r10 = current->mm->start_data
+#else
+#define nommu_start_thread(regs) do { \
+ regs->ARM_r10 = current->mm->start_data; \
+ regs->ARM_EXC_RET = 0xfffffffdL; \
+} while (0)
+#endif
#endif
#define start_thread(regs,pc,sp) \
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
index 3d52ee1..67661e8 100644
--- a/arch/arm/include/asm/ptrace.h
+++ b/arch/arm/include/asm/ptrace.h
@@ -14,7 +14,11 @@
#ifndef __ASSEMBLY__
struct pt_regs {
+#ifdef CONFIG_CPU_V7M
+ unsigned long uregs[20];
+#else
unsigned long uregs[18];
+#endif
};
#define user_mode(regs) \
@@ -45,6 +49,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 +72,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 dfd386d..720ea03 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/uapi/asm/ptrace.h b/arch/arm/include/uapi/asm/ptrace.h
index 96ee092..2ae7d1b 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
@@ -125,6 +144,7 @@ struct pt_regs {
#define ARM_r1 uregs[1]
#define ARM_r0 uregs[0]
#define ARM_ORIG_r0 uregs[17]
+#define ARM_EXC_RET uregs[18]
/*
* The size of the user-visible VFP state as seen by PTRACE_GET/SETVFPREGS
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index c985b48..5fe9ace 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -93,6 +93,9 @@ int main(void)
DEFINE(S_PC, offsetof(struct pt_regs, ARM_pc));
DEFINE(S_PSR, offsetof(struct pt_regs, ARM_cpsr));
DEFINE(S_OLD_R0, offsetof(struct pt_regs, ARM_ORIG_r0));
+#ifdef CONFIG_CPU_V7M
+ DEFINE(S_EXC_RET, offsetof(struct pt_regs, ARM_EXC_RET));
+#endif
DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs));
BLANK();
#ifdef CONFIG_CACHE_L2X0
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S
index 278cfc1..c391c05 100644
--- a/arch/arm/kernel/head-nommu.S
+++ b/arch/arm/kernel/head-nommu.S
@@ -44,10 +44,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, =0xe000ed00 @ CPUID register address
+ ldr r9, [r9]
+#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 da1d1aa..3cca0c8 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)
{
@@ -375,6 +384,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];
@@ -419,6 +429,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 b0179b8..12d976b 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,5 @@ void __init early_trap_init(void *vectors_base)
flush_icache_range(vectors, vectors + PAGE_SIZE);
modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
+#endif
}
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
index d51225f..4bc8ae5 100644
--- a/arch/arm/mm/nommu.c
+++ b/arch/arm/mm/nommu.c
@@ -20,12 +20,14 @@
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);
+#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 0000000..2b8eb97
--- /dev/null
+++ b/arch/arm/mm/proc-v7m.S
@@ -0,0 +1,161 @@
+/*
+ * 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 <linux/linkage.h>
+#include <asm/assembler.h>
+
+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)
+
+cpu_v7m_name:
+ .ascii "ARMv7-M Processor"
+ .align
+
+ .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, =0xe000ed08 @ vector table base address
+ ldr r12, =vector_table
+ str r12, [r0]
+
+ @ Lower the priority of the SVC and PendSV exceptions
+ ldr r0, =0xe000ed1c
+ mov r5, #0x80000000
+ str r5, [r0] @ set SVC priority
+ ldr r0, =0xe000ed20
+ mov r5, #0x00800000
+ str r5, [r0] @ set PendSV priority
+
+ @ SVC to run the kernel in this mode
+ adr r0, BSYM(1f)
+ ldr r5, [r12, #11 * 4] @ read the SVC vector entry
+ str r0, [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 r0, #1
+ msr control, r0 @ Thread mode has unpriviledged access
+
+ @ Configure the System Control Register
+ ldr r0, =0xe000ed14 @ system control register
+ ldr r12, [r0]
+ orr r12, #1 << 9 @ STKALIGN
+ str r12, [r0]
+ mov pc, lr
+ENDPROC(__v7m_setup)
+
+ .align 2
+ .type v7m_processor_functions, #object
+ENTRY(v7m_processor_functions)
+ .word nommu_early_abort
+ .word cpu_v7m_proc_init
+ .word cpu_v7m_proc_fin
+ .word cpu_v7m_reset
+ .word cpu_v7m_do_idle
+ .word cpu_v7m_dcache_clean_area
+ .word cpu_v7m_switch_mm
+ .word 0 @ cpu_v7m_set_pte_ext
+ .word legacy_pabort
+ .size v7m_processor_functions, . - v7m_processor_functions
+
+ .type cpu_arch_name, #object
+cpu_arch_name:
+ .asciz "armv7m"
+ .size cpu_arch_name, . - cpu_arch_name
+
+ .type cpu_elf_name, #object
+cpu_elf_name:
+ .asciz "v7m"
+ .size cpu_elf_name, . - cpu_elf_name
+ .align
+
+ .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_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+ .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 0 @ proc_info_list.cache
+ .size __v7m_proc_info, . - __v7m_proc_info
+
+__v7m_setup_stack:
+ .space 4 * 8 @ 8 registers
+__v7m_setup_stack_top:
--
1.7.10.4
^ permalink raw reply related
* [PATCH v7 1/3] ARM: make cr_alignment read-only #ifndef CONFIG_CPU_CP15
From: Uwe Kleine-König @ 2012-10-17 8:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350462872-16805-1-git-send-email-u.kleine-koenig@pengutronix.de>
This makes cr_alignment a constant 0 to break code that tries to modify
the value as it's likely that it's built on wrong assumption when
CONFIG_CPU_CP15 isn't defined. For code that is only reading the value 0
is more or less a fine value to report.
Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
---
unchanged since v6
arch/arm/include/asm/cp15.h | 11 ++++++++++-
arch/arm/kernel/head-common.S | 9 +++++++--
arch/arm/mm/alignment.c | 2 ++
arch/arm/mm/mmu.c | 17 +++++++++++++++++
4 files changed, 36 insertions(+), 3 deletions(-)
diff --git a/arch/arm/include/asm/cp15.h b/arch/arm/include/asm/cp15.h
index 5ef4d80..d814435 100644
--- a/arch/arm/include/asm/cp15.h
+++ b/arch/arm/include/asm/cp15.h
@@ -42,6 +42,8 @@
#define vectors_high() (0)
#endif
+#ifdef CONFIG_CPU_CP15
+
extern unsigned long cr_no_alignment; /* defined in entry-armv.S */
extern unsigned long cr_alignment; /* defined in entry-armv.S */
@@ -82,6 +84,13 @@ static inline void set_copro_access(unsigned int val)
isb();
}
-#endif
+#else /* ifdef CONFIG_CPU_CP15 */
+
+#define cr_no_alignment UL(0)
+#define cr_alignment UL(0)
+
+#endif /* ifdef CONFIG_CPU_CP15 / else */
+
+#endif /* ifndef __ASSEMBLY__ */
#endif
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
index 854bd22..2f560c5 100644
--- a/arch/arm/kernel/head-common.S
+++ b/arch/arm/kernel/head-common.S
@@ -98,8 +98,9 @@ __mmap_switched:
str r9, [r4] @ Save processor ID
str r1, [r5] @ Save machine type
str r2, [r6] @ Save atags pointer
- bic r4, r0, #CR_A @ Clear 'A' bit
- stmia r7, {r0, r4} @ Save control register values
+ cmp r7, #0
+ bicne r4, r0, #CR_A @ Clear 'A' bit
+ stmneia r7, {r0, r4} @ Save control register values
b start_kernel
ENDPROC(__mmap_switched)
@@ -113,7 +114,11 @@ __mmap_switched_data:
.long processor_id @ r4
.long __machine_arch_type @ r5
.long __atags_pointer @ r6
+#ifdef CONFIG_CPU_CP15
.long cr_alignment @ r7
+#else
+ .long 0
+#endif
.long init_thread_union + THREAD_START_SP @ sp
.size __mmap_switched_data, . - __mmap_switched_data
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index b9f60eb..5748094 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -962,12 +962,14 @@ static int __init alignment_init(void)
return -ENOMEM;
#endif
+#ifdef CONFIG_CPU_CP15
if (cpu_is_v6_unaligned()) {
cr_alignment &= ~CR_A;
cr_no_alignment &= ~CR_A;
set_cr(cr_alignment);
ai_usermode = safe_usermode(ai_usermode, false);
}
+#endif
hook_fault_code(FAULT_CODE_ALIGNMENT, do_alignment, SIGBUS, BUS_ADRALN,
"alignment exception");
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 941dfb9..b675918 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -97,6 +97,7 @@ static struct cachepolicy cache_policies[] __initdata = {
}
};
+#ifdef CONFIG_CPU_CP15
/*
* These are useful for identifying cache coherency
* problems by allowing the cache or the cache and
@@ -195,6 +196,22 @@ void adjust_cr(unsigned long mask, unsigned long set)
}
#endif
+#else
+
+static int __init early_cachepolicy(char *p)
+{
+ pr_warning("cachepolicy kernel parameter not supported without cp15\n");
+}
+early_param("cachepolicy", early_cachepolicy);
+
+static int __init noalign_setup(char *__unused)
+{
+ pr_warning("noalign kernel parameter not supported without cp15\n");
+}
+__setup("noalign", noalign_setup);
+
+#endif
+
#define PROT_PTE_DEVICE L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_XN
#define PROT_SECT_DEVICE PMD_TYPE_SECT|PMD_SECT_AP_WRITE
--
1.7.10.4
^ permalink raw reply related
* [PATCH v7 0/3] Yet another update for the Cortex-M3 series
From: Uwe Kleine-König @ 2012-10-17 8:34 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
the only change since v6 is a rebase on top of v3.7-rc1 and so on Al
Viro's changes to kernel_execve().
These patches merge just fine into today's next and I put them into my
branch that Stephen will pick for the next next.
As before this doesn't make a functional M3 port as there are still some
missing items. If you want to see the code live I also updated the efm32
branch in my repository to be based on these patches. This code works,
but isn't suitable for mainline yet. You can run it on EnergyMicro's
efm32 devboard.
Best regards
Uwe
Catalin Marinas (1):
Cortex-M3: Add base support for Cortex-M3
Uwe Kleine-K?nig (2):
ARM: make cr_alignment read-only #ifndef CONFIG_CPU_CP15
Cortex-M3: Add support for exception handling
arch/arm/include/asm/assembler.h | 13 ++-
arch/arm/include/asm/cp15.h | 11 ++-
arch/arm/include/asm/cputype.h | 3 +
arch/arm/include/asm/glue-cache.h | 25 ++++++
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/processor.h | 7 ++
arch/arm/include/asm/ptrace.h | 8 ++
arch/arm/include/asm/system_info.h | 1 +
arch/arm/include/uapi/asm/ptrace.h | 36 ++++++--
arch/arm/kernel/asm-offsets.c | 3 +
arch/arm/kernel/entry-common.S | 4 +
arch/arm/kernel/entry-header.S | 148 +++++++++++++++++++++++++++++++++
arch/arm/kernel/entry-v7m.S | 134 ++++++++++++++++++++++++++++++
arch/arm/kernel/head-common.S | 9 +-
arch/arm/kernel/head-nommu.S | 9 +-
arch/arm/kernel/process.c | 4 +
arch/arm/kernel/ptrace.c | 3 +
arch/arm/kernel/setup.c | 13 ++-
arch/arm/kernel/traps.c | 2 +
arch/arm/mm/alignment.c | 2 +
arch/arm/mm/mmu.c | 17 ++++
arch/arm/mm/nommu.c | 2 +
arch/arm/mm/proc-v7m.S | 161 ++++++++++++++++++++++++++++++++++++
25 files changed, 632 insertions(+), 22 deletions(-)
create mode 100644 arch/arm/kernel/entry-v7m.S
create mode 100644 arch/arm/mm/proc-v7m.S
--
1.7.10.4
^ permalink raw reply
* [PATCH] ARM: OMAP2: UART: fix console UART mismatched runtime PM status
From: Russell King - ARM Linux @ 2012-10-17 8:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350344998-16328-1-git-send-email-khilman@deeprootsystems.com>
On Mon, Oct 15, 2012 at 04:49:58PM -0700, Kevin Hilman wrote:
> From: Kevin Hilman <khilman@ti.com>
>
> The runtime PM framework assumes that the hardware state of devices
> when initialized is disabled. For all omap_devices, we idle/disable
> device by default. However, the console uart uses a "no idle" option
> during omap_device init in order to allow earlyprintk usage to work
> seamlessly during boot.
>
> Because the hardware is left partially enabled after init (whatever
> the bootloader settings were), the omap_device should later be fully
> initialized (including mux) and the runtime PM framework should be
> told that the device is active, and not disabled so that the hardware
> state is in sync with runtime PM state.
>
> To fix, after the device has been created/registered, call
> omap_device_enable() to finialize init and use pm_runtime_set_active()
> to tell the runtime PM core the device is enabled.
I still believe you're better off with the approach I gave. Why?
Because every driver you have contains virtually the same sequence of
runtime PM "initialization" which is to runtime PM enable the device
and then do a get on it.
Why not do that in bus code if all your drivers are doing the same
thing, and kill off a bunch of code in the drivers?
It's fairly easy to do with the BUS_NOTIFY_BIND_DRIVER / BUS_NOTIFY_UNBIND_DRIVER
bus level notifies, and you've already hooked the notifier list for
these callbacks in omap_device.c
^ permalink raw reply
* [PATCH] ARM: SAMSUNG: Add naming of s3c64xx-spi devices
From: Kukjin Kim @ 2012-10-17 8:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <507C3845.1030003@inov.pt>
Jos? Miguel Gon?alves wrote:
>
> On 15-10-2012 15:58, Sylwester Nawrocki wrote:
> > Hi Heiko,
> >
> > On 10/02/2012 02:43 PM, Heiko St?bner wrote:
> >> Commit a5238e360b71 (spi: s3c64xx: move controller information into
> driver
> >> data) introduced separate device names for the different subtypes of
> the
> >> spi controller but forgot to set these in the relevant machines.
> >>
> >> To fix this introduce a s3c64xx_spi_setname function and populate all
> >> Samsung arches with the correct names. The function resides in a new
> >> header, as the s3c64xx-spi.h contains driver platform data and should
> >> therefore at some later point move out of the Samsung include dir.
> >>
> >> Tested on a s3c2416-based machine.
> >>
> >> Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> >> Cc: stable at vger.kernel.org
> > This patch looks good to me. I've tested it on Exynos4412 SoC based
> > board. And it fixes quite serious problem - broken SPI support on
> > a all Samsung machs (non-dt) except s3c64xx in mainline v3.6 kernel.
> >
> >
> > Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> > Tested-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> > (mach-exynos only)
> >
> > Jos? Miguel, can you confirm it solves the problem for you ?
>
> The driver initialization problem is solved by this patch on my S3C2416
> based
> board. Nevertheless, I didn?t have the time yet to test an actual SPI
> device
> connected to the bus.
>
> BTW, I think the two debug messages at the end of the s3c64xx_spi_probe()
> routine
> should be promoted from dev_dbg to dev_info in order to be shown on a
> normal
> kernel boot.
>
You guys, thanks for fixing and testing.
Looks good to me, applied.
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.
^ permalink raw reply
* [PATCH v6 0/3] Updated Cortex-M3 series
From: Uwe Kleine-König @ 2012-10-17 8:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20120926192759.GC19685@pengutronix.de>
Hello,
On Wed, Sep 26, 2012 at 09:27:59PM +0200, Uwe Kleine-K?nig wrote:
> On Wed, Sep 26, 2012 at 07:03:49PM +0100, Will Deacon wrote:
> > On Tue, Sep 25, 2012 at 04:00:26PM +0100, Uwe Kleine-K?nig wrote:
> > > On Tue, Sep 25, 2012 at 03:47:26PM +0100, Jonathan Austin wrote:
> > > > Looking at the patch series at a very superficial level, I wonder why
> > > > you've chosen not to include any Kconfig/NVIC support at this stage,
> > > > especially as you've posted some before and there appears to be
> > > > something (presumably) working in your efm32 branch...
> > > >
> > > > It would be a shame to spend time on merging the basic support if there
> > > > are issues that mean the interrupt support won't follow.
> > > I plan to expand common/gic.c for interrupt support. Currently I don't
> > > do much though because getting feedback and the changes into mainline is
> > > quite hard and I don't want to spend time now and hear later that I did
> > > it wrong or something. So I put my efforts on hold and only ping from
> > > time to time. :-(
> >
> > My personal view is that merging the code without support for interrupts is
> > fairly pointless, so the nvic code should certainly be included. I
> > wouldn't worry too much about merging it with gic.c initially. That can come
> That would be ok for me, too.
I thought about that again, and I think merging with hacked irq support
isn't good. Note that even when the irq support goes in you still need
several patches to support an M3 platform. So one more patch in the
private queue doesn't hurt IMHO.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply
* [PATCH v2 v2 v2 8/8] spi/s3c64xx: use correct dma_transfer_direction type
From: Kukjin Kim @ 2012-10-17 8:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349813638-4617-9-git-send-email-arnd@arndb.de>
Arnd Bergmann wrote:
>
> There is a subtle difference between dma_transfer_direction and
> dma_data_direction: the former is used by the dmaengine framework,
> while the latter is used by the dma-mapping API. Although the
> purpose is comparable, the actual values are different and must
> not be mixed. In this case, the driver just wants to use
> dma_transfer_direction.
>
> Without this patch, building s3c6400_defconfig results in:
>
> drivers/spi/spi-s3c64xx.c: In function 's3c64xx_spi_dmacb':
> drivers/spi/spi-s3c64xx.c:239:21: warning: comparison between
> 'enum dma_data_direction' and 'enum dma_transfer_direction' [-
> Wenum-compare]
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> Cc: Ben Dooks <ben-linux@fluff.org>
> Cc: Kukjin Kim <kgene.kim@samsung.com>
Acked-by: Kukjin Kim <kgene.kim@samsung.com>
BTW, don't we need following accordingly?
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 1a81c90..a0bb55e 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1067,11 +1067,11 @@ static int __devinit s3c64xx_spi_get_dmares(
if (tx) {
dma_data = &sdd->tx_dma;
- dma_data->direction = DMA_TO_DEVICE;
+ dma_data->direction = DMA_MEM_TO_DEV;
chan_str = "tx";
} else {
dma_data = &sdd->rx_dma;
- dma_data->direction = DMA_FROM_DEVICE;
+ dma_data->direction = DMA_DEV_TO_MEM;
chan_str = "rx";
}
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-samsung-soc at vger.kernel.org
> Cc: spi-devel-general at lists.sourceforge.net
> ---
> drivers/spi/spi-s3c64xx.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
> index d1c8441f..2e44dd6 100644
> --- a/drivers/spi/spi-s3c64xx.c
> +++ b/drivers/spi/spi-s3c64xx.c
> @@ -132,7 +132,7 @@
>
> struct s3c64xx_spi_dma_data {
> unsigned ch;
> - enum dma_data_direction direction;
> + enum dma_transfer_direction direction;
> enum dma_ch dmach;
> struct property *dma_prop;
> };
> --
> 1.7.10
^ permalink raw reply related
* [PATCH] ARM: multiplatform: Add a defconfig for multi_v5
From: Tony Prisk @ 2012-10-17 8:10 UTC (permalink / raw)
To: linux-arm-kernel
This patch adds a simple multi_v5_defconfig for arch-vt8500
multiplatform.
Signed-off-by: Tony Prisk <linux@prisktech.co.nz>
---
I expect there will be a bit of comment regarding this as others will
need to add their requirements as well, and it seems overly basic.
arch/arm/configs/multi_v5_defconfig | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
create mode 100644 arch/arm/configs/multi_v5_defconfig
diff --git a/arch/arm/configs/multi_v5_defconfig b/arch/arm/configs/multi_v5_defconfig
new file mode 100644
index 0000000..b4a36a7
--- /dev/null
+++ b/arch/arm/configs/multi_v5_defconfig
@@ -0,0 +1,24 @@
+CONFIG_ARCH_MULTI_V7=n
+CONFIG_ARCH_MULTI_V5=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_ARCH_VT8500=y
+CONFIG_ARM_ARCH_TIMER=y
+CONFIG_AEABI=y
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_VFP=y
+CONFIG_NET=y
+CONFIG_SERIAL_VT8500=y
+CONFIG_SERIAL_VT8500_CONSOLE=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_VT8500=y
+CONFIG_FB=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FB_VT8500=y
+CONFIG_FB_WM8505=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_UHCI_HCD=y
+CONFIG_USB_UHCI_PLATFORM=y
+CONFIG_PWM_VT8500=y
+CONFIG_RTC_DRV_VT8500=y
--
1.7.9.5
^ permalink raw reply related
* multi_v5_defconfig problem
From: Tony Prisk @ 2012-10-17 8:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350460703.13436.2.camel@gitbox>
On Wed, 2012-10-17 at 20:58 +1300, Tony Prisk wrote:
> I tried to prepare a basic multi_v5_defconfig for arch-vt8500 containing
> the following, except that it builds v7 platforms rather than v5.
>
> I also tried adding CONFIG_ARCH_MULTI_V5 (and CONFIG_ARCH_MULTIPLATFORM)
> but neither made a difference.
>
> Help please :)
>
> CONFIG_EXPERIMENTAL=y
> CONFIG_HIGH_RES_TIMERS=y
> CONFIG_ARCH_VT8500=y
> CONFIG_ARM_ARCH_TIMER=y
> CONFIG_AEABI=y
> CONFIG_ARM_APPENDED_DTB=y
> CONFIG_VFP=y
> CONFIG_NET=y
> CONFIG_SERIAL_VT8500=y
> CONFIG_SERIAL_VT8500_CONSOLE=y
> CONFIG_GPIOLIB=y
> CONFIG_GPIO_VT8500=y
> CONFIG_FB=y
> CONFIG_FRAMEBUFFER_CONSOLE=y
> CONFIG_FB_VT8500=y
> CONFIG_FB_WM8505=y
> CONFIG_USB=y
> CONFIG_USB_EHCI_HCD=y
> CONFIG_USB_UHCI_HCD=y
> CONFIG_USB_UHCI_PLATFORM=y
> CONFIG_PWM_VT8500=y
> CONFIG_RTC_DRV_VT8500=y
>
> Regards
> Tony P
Hmph... gave up about a minute too soon.
CONFIG_ARCH_MULTI_V7=n fixes the problem. I assume this is because its
default y and you can't select MULTI_V5 with MULTI_V7.
Regards
Tony P
^ permalink raw reply
* multi_v5_defconfig problem
From: Tony Prisk @ 2012-10-17 7:58 UTC (permalink / raw)
To: linux-arm-kernel
I tried to prepare a basic multi_v5_defconfig for arch-vt8500 containing
the following, except that it builds v7 platforms rather than v5.
I also tried adding CONFIG_ARCH_MULTI_V5 (and CONFIG_ARCH_MULTIPLATFORM)
but neither made a difference.
Help please :)
CONFIG_EXPERIMENTAL=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_ARCH_VT8500=y
CONFIG_ARM_ARCH_TIMER=y
CONFIG_AEABI=y
CONFIG_ARM_APPENDED_DTB=y
CONFIG_VFP=y
CONFIG_NET=y
CONFIG_SERIAL_VT8500=y
CONFIG_SERIAL_VT8500_CONSOLE=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_VT8500=y
CONFIG_FB=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FB_VT8500=y
CONFIG_FB_WM8505=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_UHCI_HCD=y
CONFIG_USB_UHCI_PLATFORM=y
CONFIG_PWM_VT8500=y
CONFIG_RTC_DRV_VT8500=y
Regards
Tony P
^ permalink raw reply
* [PATCH 1/2] regulator: gpio-regulator: Allow use of GPIO controlled regulators though DT
From: Mark Brown @ 2012-10-17 7:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121016080109.GH7662@gmail.com>
On Tue, Oct 16, 2012 at 09:01:09AM +0100, Lee Jones wrote:
> I'm assuming it's just the documentation patch you're missing.
> Let me resend it as a single patch.
This should really be part of the patch adding the bindings...
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121017/1d91450f/attachment.sig>
^ permalink raw reply
* [PATCH 8/8] ARM: S3C64XX: Add handset module to probed Glenfarclas modules
From: Mark Brown @ 2012-10-17 7:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350459519-20462-1-git-send-email-broonie@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
arch/arm/mach-s3c64xx/mach-crag6410.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c
index 7e35523..2abe95d 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410.c
@@ -711,6 +711,7 @@ static struct i2c_board_info i2c_devs1[] __devinitdata = {
.irq = S3C_EINT(0),
.platform_data = &glenfarclas_pmic_pdata },
+ { I2C_BOARD_INFO("wlf-gf-module", 0x20) },
{ I2C_BOARD_INFO("wlf-gf-module", 0x22) },
{ I2C_BOARD_INFO("wlf-gf-module", 0x24) },
{ I2C_BOARD_INFO("wlf-gf-module", 0x25) },
--
1.7.10.4
^ permalink raw reply related
* [PATCH 7/8] ARM: S3C64XX: Add WM2200 module for Cragganmore
From: Mark Brown @ 2012-10-17 7:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350459519-20462-1-git-send-email-broonie@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
arch/arm/mach-s3c64xx/mach-crag6410-module.c | 15 +++++++++++++++
arch/arm/mach-s3c64xx/mach-crag6410.c | 5 +++++
2 files changed, 20 insertions(+)
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
index fc758b1..4744c42 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
@@ -21,6 +21,7 @@
#include <linux/regulator/machine.h>
#include <sound/wm0010.h>
+#include <sound/wm2200.h>
#include <sound/wm5100.h>
#include <sound/wm8996.h>
#include <sound/wm8962.h>
@@ -277,6 +278,18 @@ static const struct i2c_board_info wm6230_i2c_devs[] = {
.platform_data = &wm9081_pdata, },
};
+static struct wm2200_pdata wm2200_pdata = {
+ .ldo_ena = S3C64XX_GPN(7),
+ .gpio_defaults = {
+ [2] = 0x0005, /* GPIO3 24.576MHz output clock */
+ },
+};
+
+static const struct i2c_board_info wm2200_i2c[] = {
+ { I2C_BOARD_INFO("wm2200", 0x3a),
+ .platform_data = &wm2200_pdata, },
+};
+
static __devinitdata const struct {
u8 id;
u8 rev;
@@ -326,6 +339,8 @@ static __devinitdata const struct {
{ .id = 0x3e, .rev = -1, .name = "WM5102-6271-EV1-CS127 Amrut",
.spi_devs = wm5102_spi_devs,
.num_spi_devs = ARRAY_SIZE(wm5102_spi_devs) },
+ { .id = 0x3f, .rev = -1, .name = "WM2200-6271-CS90-M-REV1",
+ .i2c_devs = wm2200_i2c, .num_i2c_devs = ARRAY_SIZE(wm2200_i2c) },
};
static __devinit int wlf_gf_module_probe(struct i2c_client *i2c,
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c
index 6d5b2c6..7e35523 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410.c
@@ -629,6 +629,11 @@ static struct regulator_consumer_supply pvdd_1v8_consumers[] __devinitdata = {
REGULATOR_SUPPLY("DCVDD", "1-001a"),
REGULATOR_SUPPLY("AVDD", "1-001a"),
REGULATOR_SUPPLY("DBVDD", "spi0.0"),
+
+ REGULATOR_SUPPLY("DBVDD", "1-003a"),
+ REGULATOR_SUPPLY("LDOVDD", "1-003a"),
+ REGULATOR_SUPPLY("CPVDD", "1-003a"),
+ REGULATOR_SUPPLY("AVDD", "1-003a"),
REGULATOR_SUPPLY("DBVDD1", "spi0.1"),
REGULATOR_SUPPLY("DBVDD2", "spi0.1"),
REGULATOR_SUPPLY("DBVDD3", "spi0.1"),
--
1.7.10.4
^ permalink raw reply related
* [PATCH 6/8] ARM: S3C64XX: Add hookup for Deanston module on Cragganmore
From: Mark Brown @ 2012-10-17 7:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350459519-20462-1-git-send-email-broonie@opensource.wolfsonmicro.com>
This carries a WM5110, the system integration for which is essentially
the same as the rev A WM5102 module.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
arch/arm/mach-s3c64xx/mach-crag6410-module.c | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
index a6c156d..fc758b1 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
@@ -215,7 +215,7 @@ static struct arizona_pdata wm5102_reva_pdata = {
},
};
-static struct s3c64xx_spi_csinfo wm5102_spi_csinfo = {
+static struct s3c64xx_spi_csinfo codec_spi_csinfo = {
.line = S3C64XX_GPN(5),
};
@@ -228,7 +228,7 @@ static struct spi_board_info wm5102_reva_spi_devs[] = {
.mode = SPI_MODE_0,
.irq = GLENFARCLAS_PMIC_IRQ_BASE +
WM831X_IRQ_GPIO_2,
- .controller_data = &wm5102_spi_csinfo,
+ .controller_data = &codec_spi_csinfo,
.platform_data = &wm5102_reva_pdata,
},
};
@@ -253,11 +253,25 @@ static struct spi_board_info wm5102_spi_devs[] = {
.mode = SPI_MODE_0,
.irq = GLENFARCLAS_PMIC_IRQ_BASE +
WM831X_IRQ_GPIO_2,
- .controller_data = &wm5102_spi_csinfo,
+ .controller_data = &codec_spi_csinfo,
.platform_data = &wm5102_pdata,
},
};
+static struct spi_board_info wm5110_spi_devs[] = {
+ [0] = {
+ .modalias = "wm5110",
+ .max_speed_hz = 10 * 1000 * 1000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .mode = SPI_MODE_0,
+ .irq = GLENFARCLAS_PMIC_IRQ_BASE +
+ WM831X_IRQ_GPIO_2,
+ .controller_data = &codec_spi_csinfo,
+ .platform_data = &wm5102_reva_pdata,
+ },
+};
+
static const struct i2c_board_info wm6230_i2c_devs[] = {
{ I2C_BOARD_INFO("wm9081", 0x6c),
.platform_data = &wm9081_pdata, },
@@ -276,7 +290,9 @@ static __devinitdata const struct {
{ .id = 0x02, .rev = 0xff, .name = "1251-EV1 Jura" },
{ .id = 0x03, .rev = 0xff, .name = "1252-EV1 Glenlivet" },
{ .id = 0x06, .rev = 0xff, .name = "WM8997-6721-CS96-EV1 Lapraoig" },
- { .id = 0x07, .rev = 0xff, .name = "WM5110-6271 Deanston" },
+ { .id = 0x07, .rev = 0xff, .name = "WM5110-6271 Deanston",
+ .spi_devs = wm5110_spi_devs,
+ .num_spi_devs = ARRAY_SIZE(wm5110_spi_devs) },
{ .id = 0x08, .rev = 0xff, .name = "WM8903-6102 Tamdhu" },
{ .id = 0x09, .rev = 0xff, .name = "WM1811A-6305 Adelphi" },
{ .id = 0x0a, .rev = 0xff, .name = "WM8996-6272 Blackadder" },
--
1.7.10.4
^ permalink raw reply related
* [PATCH 5/8] ARM: S3C64XX: Handle new Amrut modules on Cragganmore
From: Mark Brown @ 2012-10-17 7:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350459519-20462-1-git-send-email-broonie@opensource.wolfsonmicro.com>
These use a different GPIO for the jack polarity selection.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
arch/arm/mach-s3c64xx/mach-crag6410-module.c | 35 +++++++++++++++++++++++---
1 file changed, 32 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
index 15e0c13..a6c156d 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
@@ -187,12 +187,13 @@ static struct regulator_init_data wm8994_ldo2 = {
static struct wm8994_pdata wm8994_pdata = {
.gpio_base = CODEC_GPIO_BASE,
+ .micb2_delay = 150,
.gpio_defaults = {
0x3, /* IRQ out, active high, CMOS */
},
.ldo = {
- { .init_data = &wm8994_ldo1, },
- { .init_data = &wm8994_ldo2, },
+ { .enable = S3C64XX_GPN(6), .init_data = &wm8994_ldo1, },
+ { .enable = S3C64XX_GPN(4), .init_data = &wm8994_ldo2, },
},
};
@@ -203,7 +204,7 @@ static const struct i2c_board_info wm1277_devs[] = {
},
};
-static struct arizona_pdata wm5102_pdata = {
+static struct arizona_pdata wm5102_reva_pdata = {
.ldoena = S3C64XX_GPN(7),
.gpio_base = CODEC_GPIO_BASE,
.irq_active_high = true,
@@ -218,6 +219,31 @@ static struct s3c64xx_spi_csinfo wm5102_spi_csinfo = {
.line = S3C64XX_GPN(5),
};
+static struct spi_board_info wm5102_reva_spi_devs[] = {
+ [0] = {
+ .modalias = "wm5102",
+ .max_speed_hz = 10 * 1000 * 1000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .mode = SPI_MODE_0,
+ .irq = GLENFARCLAS_PMIC_IRQ_BASE +
+ WM831X_IRQ_GPIO_2,
+ .controller_data = &wm5102_spi_csinfo,
+ .platform_data = &wm5102_reva_pdata,
+ },
+};
+
+static struct arizona_pdata wm5102_pdata = {
+ .ldoena = S3C64XX_GPN(7),
+ .gpio_base = CODEC_GPIO_BASE,
+ .irq_active_high = true,
+ .micd_pol_gpio = CODEC_GPIO_BASE + 2,
+ .gpio_defaults = {
+ [2] = 0x10000, /* AIF3TXLRCLK */
+ [3] = 0x4, /* OPCLK */
+ },
+};
+
static struct spi_board_info wm5102_spi_devs[] = {
[0] = {
.modalias = "wm5102",
@@ -278,6 +304,9 @@ static __devinitdata const struct {
{ .id = 0x3c, .rev = 0xff, .name = "1273-EV1 Longmorn" },
{ .id = 0x3d, .rev = 0xff, .name = "1277-EV1 Littlemill",
.i2c_devs = wm1277_devs, .num_i2c_devs = ARRAY_SIZE(wm1277_devs) },
+ { .id = 0x3e, .rev = 0, .name = "WM5102-6271-EV1-CS127 Amrut",
+ .spi_devs = wm5102_reva_spi_devs,
+ .num_spi_devs = ARRAY_SIZE(wm5102_reva_spi_devs) },
{ .id = 0x3e, .rev = -1, .name = "WM5102-6271-EV1-CS127 Amrut",
.spi_devs = wm5102_spi_devs,
.num_spi_devs = ARRAY_SIZE(wm5102_spi_devs) },
--
1.7.10.4
^ permalink raw reply related
* [PATCH 4/8] ARM: S3C64XX: Handle revision-specific differences in Cragganmore modules
From: Mark Brown @ 2012-10-17 7:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350459519-20462-1-git-send-email-broonie@opensource.wolfsonmicro.com>
Allow us to supply different configurations depending on the board
revision, catering for changes that are visible to software.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
arch/arm/mach-s3c64xx/mach-crag6410-module.c | 52 +++++++++++++-------------
1 file changed, 27 insertions(+), 25 deletions(-)
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
index 32b82c0..15e0c13 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
@@ -239,45 +239,46 @@ static const struct i2c_board_info wm6230_i2c_devs[] = {
static __devinitdata const struct {
u8 id;
+ u8 rev;
const char *name;
const struct i2c_board_info *i2c_devs;
int num_i2c_devs;
const struct spi_board_info *spi_devs;
int num_spi_devs;
} gf_mods[] = {
- { .id = 0x01, .name = "1250-EV1 Springbank" },
- { .id = 0x02, .name = "1251-EV1 Jura" },
- { .id = 0x03, .name = "1252-EV1 Glenlivet" },
- { .id = 0x06, .name = "WM8997-6721-CS96-EV1 Lapraoig" },
- { .id = 0x07, .name = "WM5110-6271 Deanston" },
- { .id = 0x08, .name = "WM8903-6102 Tamdhu" },
- { .id = 0x09, .name = "WM1811A-6305 Adelphi" },
- { .id = 0x0a, .name = "WM8996-6272 Blackadder" },
- { .id = 0x0b, .name = "WM8994-6235 Benromach" },
- { .id = 0x11, .name = "6249-EV2 Glenfarclas", },
- { .id = 0x14, .name = "6271-EV1 Lochnagar" },
- { .id = 0x15, .name = "6320-EV1 Bells",
+ { .id = 0x01, .rev = 0xff, .name = "1250-EV1 Springbank" },
+ { .id = 0x02, .rev = 0xff, .name = "1251-EV1 Jura" },
+ { .id = 0x03, .rev = 0xff, .name = "1252-EV1 Glenlivet" },
+ { .id = 0x06, .rev = 0xff, .name = "WM8997-6721-CS96-EV1 Lapraoig" },
+ { .id = 0x07, .rev = 0xff, .name = "WM5110-6271 Deanston" },
+ { .id = 0x08, .rev = 0xff, .name = "WM8903-6102 Tamdhu" },
+ { .id = 0x09, .rev = 0xff, .name = "WM1811A-6305 Adelphi" },
+ { .id = 0x0a, .rev = 0xff, .name = "WM8996-6272 Blackadder" },
+ { .id = 0x0b, .rev = 0xff, .name = "WM8994-6235 Benromach" },
+ { .id = 0x11, .rev = 0xff, .name = "6249-EV2 Glenfarclas", },
+ { .id = 0x14, .rev = 0xff, .name = "6271-EV1 Lochnagar" },
+ { .id = 0x15, .rev = 0xff, .name = "6320-EV1 Bells",
.i2c_devs = wm6230_i2c_devs,
.num_i2c_devs = ARRAY_SIZE(wm6230_i2c_devs) },
- { .id = 0x21, .name = "1275-EV1 Mortlach" },
- { .id = 0x25, .name = "1274-EV1 Glencadam" },
- { .id = 0x31, .name = "1253-EV1 Tomatin",
+ { .id = 0x21, .rev = 0xff, .name = "1275-EV1 Mortlach" },
+ { .id = 0x25, .rev = 0xff, .name = "1274-EV1 Glencadam" },
+ { .id = 0x31, .rev = 0xff, .name = "1253-EV1 Tomatin",
.spi_devs = wm1253_devs, .num_spi_devs = ARRAY_SIZE(wm1253_devs) },
- { .id = 0x32, .name = "XXXX-EV1 Caol Illa" },
- { .id = 0x33, .name = "XXXX-EV1 Oban" },
- { .id = 0x34, .name = "WM0010-6320-CS42 Balblair",
+ { .id = 0x32, .rev = 0xff, .name = "XXXX-EV1 Caol Illa" },
+ { .id = 0x33, .rev = 0xff, .name = "XXXX-EV1 Oban" },
+ { .id = 0x34, .rev = 0xff, .name = "WM0010-6320-CS42 Balblair",
.spi_devs = balblair_devs,
.num_spi_devs = ARRAY_SIZE(balblair_devs) },
- { .id = 0x39, .name = "1254-EV1 Dallas Dhu",
+ { .id = 0x39, .rev = 0xff, .name = "1254-EV1 Dallas Dhu",
.i2c_devs = wm1254_devs, .num_i2c_devs = ARRAY_SIZE(wm1254_devs) },
- { .id = 0x3a, .name = "1259-EV1 Tobermory",
+ { .id = 0x3a, .rev = 0xff, .name = "1259-EV1 Tobermory",
.i2c_devs = wm1259_devs, .num_i2c_devs = ARRAY_SIZE(wm1259_devs) },
- { .id = 0x3b, .name = "1255-EV1 Kilchoman",
+ { .id = 0x3b, .rev = 0xff, .name = "1255-EV1 Kilchoman",
.i2c_devs = wm1255_devs, .num_i2c_devs = ARRAY_SIZE(wm1255_devs) },
- { .id = 0x3c, .name = "1273-EV1 Longmorn" },
- { .id = 0x3d, .name = "1277-EV1 Littlemill",
+ { .id = 0x3c, .rev = 0xff, .name = "1273-EV1 Longmorn" },
+ { .id = 0x3d, .rev = 0xff, .name = "1277-EV1 Littlemill",
.i2c_devs = wm1277_devs, .num_i2c_devs = ARRAY_SIZE(wm1277_devs) },
- { .id = 0x3e, .name = "WM5102-6271-EV1-CS127 Amrut",
+ { .id = 0x3e, .rev = -1, .name = "WM5102-6271-EV1-CS127 Amrut",
.spi_devs = wm5102_spi_devs,
.num_spi_devs = ARRAY_SIZE(wm5102_spi_devs) },
};
@@ -296,7 +297,8 @@ static __devinit int wlf_gf_module_probe(struct i2c_client *i2c,
id = (ret & 0xfe) >> 2;
rev = ret & 0x3;
for (i = 0; i < ARRAY_SIZE(gf_mods); i++)
- if (id == gf_mods[i].id)
+ if (id == gf_mods[i].id && (gf_mods[i].rev == 0xff ||
+ rev == gf_mods[i].rev))
break;
if (i < ARRAY_SIZE(gf_mods)) {
--
1.7.10.4
^ permalink raw reply related
* [PATCH 3/8] ARM: S3C64XX: Provide platform data for Tomatin/Balblair on Cragganmore
From: Mark Brown @ 2012-10-17 7:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350459519-20462-1-git-send-email-broonie@opensource.wolfsonmicro.com>
This is required for operation of the WM0010 on the boards.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
arch/arm/mach-s3c64xx/mach-crag6410-module.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
index 89f5e7d..32b82c0 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
@@ -20,6 +20,7 @@
#include <linux/regulator/machine.h>
+#include <sound/wm0010.h>
#include <sound/wm5100.h>
#include <sound/wm8996.h>
#include <sound/wm8962.h>
@@ -33,14 +34,34 @@ static struct s3c64xx_spi_csinfo wm0010_spi_csinfo = {
.line = S3C64XX_GPC(3),
};
+static struct wm0010_pdata wm0010_pdata = {
+ .gpio_reset = S3C64XX_GPN(6),
+ .reset_active_high = 1, /* Active high for Glenfarclas Rev 2 */
+};
+
static struct spi_board_info wm1253_devs[] = {
[0] = {
.modalias = "wm0010",
+ .max_speed_hz = 26 * 1000 * 1000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ .irq = S3C_EINT(5),
+ .controller_data = &wm0010_spi_csinfo,
+ .platform_data = &wm0010_pdata,
+ },
+};
+
+static struct spi_board_info balblair_devs[] = {
+ [0] = {
+ .modalias = "wm0010",
+ .max_speed_hz = 26 * 1000 * 1000,
.bus_num = 0,
.chip_select = 0,
.mode = SPI_MODE_0,
.irq = S3C_EINT(5),
.controller_data = &wm0010_spi_csinfo,
+ .platform_data = &wm0010_pdata,
},
};
@@ -244,7 +265,9 @@ static __devinitdata const struct {
.spi_devs = wm1253_devs, .num_spi_devs = ARRAY_SIZE(wm1253_devs) },
{ .id = 0x32, .name = "XXXX-EV1 Caol Illa" },
{ .id = 0x33, .name = "XXXX-EV1 Oban" },
- { .id = 0x34, .name = "WM0010-6320-CS42 Balblair" },
+ { .id = 0x34, .name = "WM0010-6320-CS42 Balblair",
+ .spi_devs = balblair_devs,
+ .num_spi_devs = ARRAY_SIZE(balblair_devs) },
{ .id = 0x39, .name = "1254-EV1 Dallas Dhu",
.i2c_devs = wm1254_devs, .num_i2c_devs = ARRAY_SIZE(wm1254_devs) },
{ .id = 0x3a, .name = "1259-EV1 Tobermory",
--
1.7.10.4
^ permalink raw reply related
* [PATCH 2/8] ARM: S3C64XX: Update hookup for Arizona class devices
From: Mark Brown @ 2012-10-17 7:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350459519-20462-1-git-send-email-broonie@opensource.wolfsonmicro.com>
Renumber to use SPI /CS 1 instead of 0 to allow coexistance with DSPs.
Also add additional supplies for the devices while we're at it.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
arch/arm/mach-s3c64xx/mach-crag6410-module.c | 2 +-
arch/arm/mach-s3c64xx/mach-crag6410.c | 23 ++++++++++++++++++++++-
2 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
index 3364fab..89f5e7d 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
@@ -202,7 +202,7 @@ static struct spi_board_info wm5102_spi_devs[] = {
.modalias = "wm5102",
.max_speed_hz = 10 * 1000 * 1000,
.bus_num = 0,
- .chip_select = 0,
+ .chip_select = 1,
.mode = SPI_MODE_0,
.irq = GLENFARCLAS_PMIC_IRQ_BASE +
WM831X_IRQ_GPIO_2,
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c
index 13b7eaa..6d5b2c6 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410.c
@@ -304,6 +304,13 @@ static struct regulator_consumer_supply wallvdd_consumers[] = {
REGULATOR_SUPPLY("SPKVDDL", "1-001a"),
REGULATOR_SUPPLY("SPKVDDR", "1-001a"),
+ REGULATOR_SUPPLY("SPKVDDL", "spi0.1"),
+ REGULATOR_SUPPLY("SPKVDDR", "spi0.1"),
+ REGULATOR_SUPPLY("SPKVDDL", "wm5102-codec"),
+ REGULATOR_SUPPLY("SPKVDDR", "wm5102-codec"),
+ REGULATOR_SUPPLY("SPKVDDL", "wm5110-codec"),
+ REGULATOR_SUPPLY("SPKVDDR", "wm5110-codec"),
+
REGULATOR_SUPPLY("DC1VDD", "0-0034"),
REGULATOR_SUPPLY("DC2VDD", "0-0034"),
REGULATOR_SUPPLY("DC3VDD", "0-0034"),
@@ -597,6 +604,7 @@ static struct s3c2410_platform_i2c i2c0_pdata = {
static struct regulator_consumer_supply pvdd_1v2_consumers[] __devinitdata = {
REGULATOR_SUPPLY("DCVDD", "spi0.0"),
REGULATOR_SUPPLY("AVDD", "spi0.0"),
+ REGULATOR_SUPPLY("AVDD", "spi0.1"),
};
static struct regulator_init_data pvdd_1v2 __devinitdata = {
@@ -621,6 +629,19 @@ static struct regulator_consumer_supply pvdd_1v8_consumers[] __devinitdata = {
REGULATOR_SUPPLY("DCVDD", "1-001a"),
REGULATOR_SUPPLY("AVDD", "1-001a"),
REGULATOR_SUPPLY("DBVDD", "spi0.0"),
+ REGULATOR_SUPPLY("DBVDD1", "spi0.1"),
+ REGULATOR_SUPPLY("DBVDD2", "spi0.1"),
+ REGULATOR_SUPPLY("DBVDD3", "spi0.1"),
+ REGULATOR_SUPPLY("LDOVDD", "spi0.1"),
+ REGULATOR_SUPPLY("CPVDD", "spi0.1"),
+
+ REGULATOR_SUPPLY("DBVDD2", "wm5102-codec"),
+ REGULATOR_SUPPLY("DBVDD3", "wm5102-codec"),
+ REGULATOR_SUPPLY("CPVDD", "wm5102-codec"),
+
+ REGULATOR_SUPPLY("DBVDD2", "wm5110-codec"),
+ REGULATOR_SUPPLY("DBVDD3", "wm5110-codec"),
+ REGULATOR_SUPPLY("CPVDD", "wm5110-codec"),
};
static struct regulator_init_data pvdd_1v8 __devinitdata = {
@@ -810,7 +831,7 @@ static void __init crag6410_machine_init(void)
i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
samsung_keypad_set_platdata(&crag6410_keypad_data);
- s3c64xx_spi0_set_platdata(NULL, 0, 1);
+ s3c64xx_spi0_set_platdata(NULL, 0, 2);
platform_add_devices(crag6410_devices, ARRAY_SIZE(crag6410_devices));
--
1.7.10.4
^ permalink raw reply related
* [PATCH] mfd: wm5102: Mark some more status registers as volatile
From: Mark Brown @ 2012-10-17 7:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350459519-20462-1-git-send-email-broonie@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
drivers/mfd/wm5102-tables.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/mfd/wm5102-tables.c b/drivers/mfd/wm5102-tables.c
index 14490cc..e1dc022 100644
--- a/drivers/mfd/wm5102-tables.c
+++ b/drivers/mfd/wm5102-tables.c
@@ -1814,6 +1814,9 @@ static bool wm5102_volatile_register(struct device *dev, unsigned int reg)
case ARIZONA_SOFTWARE_RESET:
case ARIZONA_DEVICE_REVISION:
case ARIZONA_OUTPUT_STATUS_1:
+ case ARIZONA_RAW_OUTPUT_STATUS_1:
+ case ARIZONA_SLIMBUS_RX_PORT_STATUS:
+ case ARIZONA_SLIMBUS_TX_PORT_STATUS:
case ARIZONA_SAMPLE_RATE_1_STATUS:
case ARIZONA_SAMPLE_RATE_2_STATUS:
case ARIZONA_SAMPLE_RATE_3_STATUS:
--
1.7.10.4
^ permalink raw reply related
* [PATCH 1/8] ARM: S3C64XX: Add more Glenfarclas module ID strings
From: Mark Brown @ 2012-10-17 7:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121017073813.GI14199@opensource.wolfsonmicro.com>
No bindings for the devices yet, just names.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
arch/arm/mach-s3c64xx/mach-crag6410-module.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
index 4e3fe57..3364fab 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
@@ -227,6 +227,12 @@ static __devinitdata const struct {
{ .id = 0x01, .name = "1250-EV1 Springbank" },
{ .id = 0x02, .name = "1251-EV1 Jura" },
{ .id = 0x03, .name = "1252-EV1 Glenlivet" },
+ { .id = 0x06, .name = "WM8997-6721-CS96-EV1 Lapraoig" },
+ { .id = 0x07, .name = "WM5110-6271 Deanston" },
+ { .id = 0x08, .name = "WM8903-6102 Tamdhu" },
+ { .id = 0x09, .name = "WM1811A-6305 Adelphi" },
+ { .id = 0x0a, .name = "WM8996-6272 Blackadder" },
+ { .id = 0x0b, .name = "WM8994-6235 Benromach" },
{ .id = 0x11, .name = "6249-EV2 Glenfarclas", },
{ .id = 0x14, .name = "6271-EV1 Lochnagar" },
{ .id = 0x15, .name = "6320-EV1 Bells",
--
1.7.10.4
^ permalink raw reply related
* [PATCH 0/8] Cragganmore updates
From: Mark Brown @ 2012-10-17 7:38 UTC (permalink / raw)
To: linux-arm-kernel
The following changes since commit ddffeb8c4d0331609ef2581d84de4d763607bd37:
Linux 3.7-rc1 (2012-10-14 14:41:04 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/misc.git tags/crag6410
for you to fetch changes up to c8a825563eae03e657b191c2b4948f7613ae91b6:
ARM: S3C64XX: Add handset module to probed Glenfarclas modules (2012-10-16 14:09:01 +0900)
----------------------------------------------------------------
ARM: S3C64XX: Cragganmore updates
There's a bunch of things in here (some have been posted before I
believe), the main thing is the update to support muliple board
revisions but there's also some new modules added.
----------------------------------------------------------------
Mark Brown (8):
ARM: S3C64XX: Add more Glenfarclas module ID strings
ARM: S3C64XX: Update hookup for Arizona class devices
ARM: S3C64XX: Provide platform data for Tomatin/Balblair on Cragganmore
ARM: S3C64XX: Handle revision-specific differences in Cragganmore modules
ARM: S3C64XX: Handle new Amrut modules on Cragganmore
ARM: S3C64XX: Add hookup for Deanston module on Cragganmore
ARM: S3C64XX: Add WM2200 module for Cragganmore
ARM: S3C64XX: Add handset module to probed Glenfarclas modules
arch/arm/mach-s3c64xx/mach-crag6410-module.c | 141 +++++++++++++++++++++-----
arch/arm/mach-s3c64xx/mach-crag6410.c | 29 +++++-
2 files changed, 144 insertions(+), 26 deletions(-)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121017/62e1e0ed/attachment.sig>
^ permalink raw reply
* [PATCH] i2c: at91: add dma support
From: Nicolas Ferre @ 2012-10-17 7:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349876587-31182-1-git-send-email-ludovic.desroches@atmel.com>
On 10/10/2012 03:43 PM, ludovic.desroches at atmel.com :
> From: Ludovic Desroches <ludovic.desroches@atmel.com>
>
> Add dma support for Atmel TWI which is available on sam9x5 and later.
>
> When using dma for reception, you have to read only n-2 bytes. The last
> two bytes are read manually. Don't doing this should cause to send the
> STOP command too late and then to get extra data in the receive
> register.
>
> Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Nice work Ludo ;-) !
Bye,
> ---
> drivers/i2c/busses/i2c-at91.c | 326 ++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 314 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
> index aa59a25..33219f8 100644
> --- a/drivers/i2c/busses/i2c-at91.c
> +++ b/drivers/i2c/busses/i2c-at91.c
> @@ -19,6 +19,8 @@
>
> #include <linux/clk.h>
> #include <linux/completion.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/dmaengine.h>
> #include <linux/err.h>
> #include <linux/i2c.h>
> #include <linux/interrupt.h>
> @@ -30,6 +32,8 @@
> #include <linux/platform_device.h>
> #include <linux/slab.h>
>
> +#include <mach/at_hdmac.h>
> +
> #define TWI_CLK_HZ 100000 /* max 400 Kbits/s */
> #define AT91_I2C_TIMEOUT msecs_to_jiffies(100) /* transfer timeout */
>
> @@ -65,9 +69,21 @@
> #define AT91_TWI_THR 0x0034 /* Transmit Holding Register */
>
> struct at91_twi_pdata {
> - unsigned clk_max_div;
> - unsigned clk_offset;
> - bool has_unre_flag;
> + unsigned clk_max_div;
> + unsigned clk_offset;
> + bool has_unre_flag;
> + bool has_dma_support;
> + struct at_dma_slave dma_slave;
> +};
> +
> +struct at91_twi_dma {
> + struct dma_chan *chan_rx;
> + struct dma_chan *chan_tx;
> + struct scatterlist sg;
> + struct dma_async_tx_descriptor *data_desc;
> + enum dma_data_direction direction;
> + bool buf_mapped;
> + bool xfer_in_progress;
> };
>
> struct at91_twi_dev {
> @@ -79,10 +95,13 @@ struct at91_twi_dev {
> size_t buf_len;
> struct i2c_msg *msg;
> int irq;
> + unsigned imr;
> unsigned transfer_status;
> struct i2c_adapter adapter;
> unsigned twi_cwgr_reg;
> struct at91_twi_pdata *pdata;
> + bool use_dma;
> + struct at91_twi_dma dma;
> };
>
> static unsigned at91_twi_read(struct at91_twi_dev *dev, unsigned reg)
> @@ -98,7 +117,18 @@ static void at91_twi_write(struct at91_twi_dev *dev, unsigned reg, unsigned val)
> static void at91_disable_twi_interrupts(struct at91_twi_dev *dev)
> {
> at91_twi_write(dev, AT91_TWI_IDR,
> - AT91_TWI_TXCOMP | AT91_TWI_RXRDY | AT91_TWI_TXRDY);
> + AT91_TWI_TXCOMP | AT91_TWI_RXRDY | AT91_TWI_TXRDY);
> +}
> +
> +static void at91_twi_irq_save(struct at91_twi_dev *dev)
> +{
> + dev->imr = at91_twi_read(dev, AT91_TWI_IMR) & 0x7;
> + at91_disable_twi_interrupts(dev);
> +}
> +
> +static void at91_twi_irq_restore(struct at91_twi_dev *dev)
> +{
> + at91_twi_write(dev, AT91_TWI_IER, dev->imr);
> }
>
> static void at91_init_twi_bus(struct at91_twi_dev *dev)
> @@ -137,6 +167,30 @@ static void __devinit at91_calc_twi_clock(struct at91_twi_dev *dev, int twi_clk)
> dev_dbg(dev->dev, "cdiv %d ckdiv %d\n", cdiv, ckdiv);
> }
>
> +static void at91_twi_dma_cleanup(struct at91_twi_dev *dev)
> +{
> + struct at91_twi_dma *dma = &dev->dma;
> +
> + at91_twi_irq_save(dev);
> +
> + if (dma->xfer_in_progress) {
> + if (dma->direction == DMA_FROM_DEVICE)
> + dma->chan_rx->device->device_control(dma->chan_rx,
> + DMA_TERMINATE_ALL, 0);
> + else
> + dma->chan_tx->device->device_control(dma->chan_tx,
> + DMA_TERMINATE_ALL, 0);
> + dma->xfer_in_progress = false;
> + }
> + if (dma->buf_mapped) {
> + dma_unmap_single(dev->dev, sg_dma_address(&dma->sg),
> + dev->buf_len, dma->direction);
> + dma->buf_mapped = false;
> + }
> +
> + at91_twi_irq_restore(dev);
> +}
> +
> static void at91_twi_write_next_byte(struct at91_twi_dev *dev)
> {
> if (dev->buf_len <= 0)
> @@ -153,6 +207,65 @@ static void at91_twi_write_next_byte(struct at91_twi_dev *dev)
> ++dev->buf;
> }
>
> +static void at91_twi_write_data_dma_callback(void *data)
> +{
> + struct at91_twi_dev *dev = (struct at91_twi_dev *)data;
> +
> + dma_unmap_single(dev->dev, sg_dma_address(&dev->dma.sg),
> + dev->buf_len, DMA_TO_DEVICE);
> +
> + at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_STOP);
> +}
> +
> +static void at91_twi_write_data_dma(struct at91_twi_dev *dev)
> +{
> + dma_addr_t dma_addr;
> + dma_cookie_t cookie;
> + struct dma_async_tx_descriptor *txdesc;
> + struct at91_twi_dma *dma = &dev->dma;
> + struct dma_chan *chan_tx = dma->chan_tx;
> +
> + if (dev->buf_len <= 0)
> + return;
> +
> + dma->direction = DMA_TO_DEVICE;
> +
> + at91_twi_irq_save(dev);
> + dma_addr = dma_map_single(dev->dev, dev->buf, dev->buf_len,
> + DMA_TO_DEVICE);
> + if (dma_mapping_error(dev->dev, dma_addr)) {
> + dev_err(dev->dev, "dma map failed\n");
> + return;
> + }
> + dma->buf_mapped = true;
> + at91_twi_irq_restore(dev);
> + sg_dma_len(&dma->sg) = dev->buf_len;
> + sg_dma_address(&dma->sg) = dma_addr;
> +
> + txdesc = chan_tx->device->device_prep_slave_sg(chan_tx, &dma->sg,
> + 1, DMA_TO_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK, NULL);
> + if (!txdesc) {
> + dev_err(dev->dev, "dma prep slave sg failed\n");
> + goto error;
> + }
> +
> + txdesc->callback = at91_twi_write_data_dma_callback;
> + txdesc->callback_param = dev;
> +
> + dma->xfer_in_progress = true;
> + cookie = txdesc->tx_submit(txdesc);
> + if (dma_submit_error(cookie)) {
> + dev_err(dev->dev, "dma submit error\n");
> + goto error;
> + }
> + dma->chan_tx->device->device_issue_pending(chan_tx);
> +
> + return;
> +
> +error:
> + at91_twi_dma_cleanup(dev);
> +}
> +
> static void at91_twi_read_next_byte(struct at91_twi_dev *dev)
> {
> if (dev->buf_len <= 0)
> @@ -178,6 +291,66 @@ static void at91_twi_read_next_byte(struct at91_twi_dev *dev)
> ++dev->buf;
> }
>
> +static void at91_twi_read_data_dma_callback(void *data)
> +{
> + struct at91_twi_dev *dev = (struct at91_twi_dev *)data;
> +
> + dma_unmap_single(dev->dev, sg_dma_address(&dev->dma.sg),
> + dev->buf_len, DMA_FROM_DEVICE);
> +
> + /* The last two bytes have to be read without using dma */
> + dev->buf += dev->buf_len - 2;
> + dev->buf_len = 2;
> + at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_RXRDY);
> +}
> +
> +static void at91_twi_read_data_dma(struct at91_twi_dev *dev)
> +{
> + dma_addr_t dma_addr;
> + dma_cookie_t cookie;
> + struct dma_async_tx_descriptor *rxdesc;
> + struct at91_twi_dma *dma = &dev->dma;
> + struct dma_chan *chan_rx = dma->chan_rx;
> +
> + dma->direction = DMA_FROM_DEVICE;
> +
> + /* Keep in mind that we won't use dma to read the last two bytes */
> + at91_twi_irq_save(dev);
> + dma_addr = dma_map_single(dev->dev, dev->buf, dev->buf_len - 2,
> + DMA_FROM_DEVICE);
> + if (dma_mapping_error(dev->dev, dma_addr)) {
> + dev_err(dev->dev, "dma map failed\n");
> + return;
> + }
> + dma->buf_mapped = true;
> + at91_twi_irq_restore(dev);
> + dma->sg.dma_address = dma_addr;
> + sg_dma_len(&dma->sg) = dev->buf_len - 2;
> +
> + rxdesc = chan_rx->device->device_prep_slave_sg(chan_rx, &dma->sg,
> + 1, DMA_FROM_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK, NULL);
> + if (!rxdesc) {
> + dev_err(dev->dev, "dma prep slave sg failed\n");
> + goto error;
> + }
> +
> + rxdesc->callback = at91_twi_read_data_dma_callback;
> + rxdesc->callback_param = dev;
> +
> + dma->xfer_in_progress = true;
> + cookie = rxdesc->tx_submit(rxdesc);
> + if (dma_submit_error(cookie)) {
> + dev_err(dev->dev, "dma submit error\n");
> + goto error;
> + }
> + dma->chan_rx->device->device_issue_pending(dma->chan_rx);
> +
> + return;
> +
> +error:
> + at91_twi_dma_cleanup(dev);
> +}
> +
> static irqreturn_t atmel_twi_interrupt(int irq, void *dev_id)
> {
> struct at91_twi_dev *dev = dev_id;
> @@ -224,12 +397,36 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
> if (dev->buf_len <= 1 && !(dev->msg->flags & I2C_M_RECV_LEN))
> start_flags |= AT91_TWI_STOP;
> at91_twi_write(dev, AT91_TWI_CR, start_flags);
> - at91_twi_write(dev, AT91_TWI_IER,
> + /*
> + * When using dma, the last byte has to be read manually in
> + * order to not send the stop command too late and then
> + * to receive extra data. In practice, there are some issues
> + * if you use the dma to read n-1 bytes because of latency.
> + * Reading n-2 bytes with dma and the two last ones manually
> + * seems to be the best solution.
> + */
> + if (dev->use_dma && (dev->buf_len > 2)) {
> + at91_twi_read_data_dma(dev);
> + /*
> + * It is important to enable TXCOMP irq here because
> + * doing it only when transferring the last two bytes
> + * will mask NACK errors since TXCOMP is set when a
> + * NACK occurs.
> + */
> + at91_twi_write(dev, AT91_TWI_IER,
> + AT91_TWI_TXCOMP);
> + } else
> + at91_twi_write(dev, AT91_TWI_IER,
> AT91_TWI_TXCOMP | AT91_TWI_RXRDY);
> } else {
> - at91_twi_write_next_byte(dev);
> - at91_twi_write(dev, AT91_TWI_IER,
> - AT91_TWI_TXCOMP | AT91_TWI_TXRDY);
> + if (dev->use_dma) {
> + at91_twi_write_data_dma(dev);
> + at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_TXCOMP);
> + } else {
> + at91_twi_write_next_byte(dev);
> + at91_twi_write(dev, AT91_TWI_IER,
> + AT91_TWI_TXCOMP | AT91_TWI_TXRDY);
> + }
> }
>
> ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
> @@ -237,23 +434,31 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
> if (ret == 0) {
> dev_err(dev->dev, "controller timed out\n");
> at91_init_twi_bus(dev);
> - return -ETIMEDOUT;
> + ret = -ETIMEDOUT;
> + goto error;
> }
> if (dev->transfer_status & AT91_TWI_NACK) {
> dev_dbg(dev->dev, "received nack\n");
> - return -EREMOTEIO;
> + ret = -EREMOTEIO;
> + goto error;
> }
> if (dev->transfer_status & AT91_TWI_OVRE) {
> dev_err(dev->dev, "overrun while reading\n");
> - return -EIO;
> + ret = -EIO;
> + goto error;
> }
> if (has_unre_flag && dev->transfer_status & AT91_TWI_UNRE) {
> dev_err(dev->dev, "underrun while writing\n");
> - return -EIO;
> + ret = -EIO;
> + goto error;
> }
> dev_dbg(dev->dev, "transfer complete\n");
>
> return 0;
> +
> +error:
> + at91_twi_dma_cleanup(dev);
> + return ret;
> }
>
> static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num)
> @@ -324,36 +529,42 @@ static struct at91_twi_pdata at91rm9200_config = {
> .clk_max_div = 5,
> .clk_offset = 3,
> .has_unre_flag = true,
> + .has_dma_support = false,
> };
>
> static struct at91_twi_pdata at91sam9261_config = {
> .clk_max_div = 5,
> .clk_offset = 4,
> .has_unre_flag = false,
> + .has_dma_support = false,
> };
>
> static struct at91_twi_pdata at91sam9260_config = {
> .clk_max_div = 7,
> .clk_offset = 4,
> .has_unre_flag = false,
> + .has_dma_support = false,
> };
>
> static struct at91_twi_pdata at91sam9g20_config = {
> .clk_max_div = 7,
> .clk_offset = 4,
> .has_unre_flag = false,
> + .has_dma_support = false,
> };
>
> static struct at91_twi_pdata at91sam9g10_config = {
> .clk_max_div = 7,
> .clk_offset = 4,
> .has_unre_flag = false,
> + .has_dma_support = false,
> };
>
> static struct at91_twi_pdata at91sam9x5_config = {
> .clk_max_div = 7,
> .clk_offset = 4,
> .has_unre_flag = false,
> + .has_dma_support = true,
> };
>
> static const struct platform_device_id at91_twi_devtypes[] = {
> @@ -400,6 +611,90 @@ MODULE_DEVICE_TABLE(of, atmel_twi_dt_ids);
> #define atmel_twi_dt_ids NULL
> #endif
>
> +static bool __devinit filter(struct dma_chan *chan, void *slave)
> +{
> + struct at_dma_slave *sl = slave;
> +
> + if (sl->dma_dev == chan->device->dev) {
> + chan->private = sl;
> + return true;
> + } else {
> + return false;
> + }
> +}
> +
> +static int __devinit at91_twi_configure_dma(struct at91_twi_dev *dev, u32 phy_addr)
> +{
> + int ret = 0;
> + struct at_dma_slave *sdata;
> + struct dma_slave_config slave_config;
> + struct at91_twi_dma *dma = &dev->dma;
> +
> + sdata = &dev->pdata->dma_slave;
> +
> + memset(&slave_config, 0, sizeof(slave_config));
> + slave_config.src_addr = (dma_addr_t)phy_addr + AT91_TWI_RHR;
> + slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
> + slave_config.src_maxburst = 1;
> + slave_config.dst_addr = (dma_addr_t)phy_addr + AT91_TWI_THR;
> + slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
> + slave_config.dst_maxburst = 1;
> + slave_config.device_fc = false;
> +
> + if (sdata && sdata->dma_dev) {
> + dma_cap_mask_t mask;
> +
> + dma_cap_zero(mask);
> + dma_cap_set(DMA_SLAVE, mask);
> + dma->chan_tx = dma_request_channel(mask, filter, sdata);
> + if (!dma->chan_tx) {
> + dev_err(dev->dev, "no DMA channel available for tx\n");
> + ret = -EBUSY;
> + goto error;
> + }
> + dma->chan_rx = dma_request_channel(mask, filter, sdata);
> + if (!dma->chan_rx) {
> + dev_err(dev->dev, "no DMA channel available for rx\n");
> + ret = -EBUSY;
> + goto error;
> + }
> + } else {
> + ret = -EINVAL;
> + goto error;
> + }
> +
> + slave_config.direction = DMA_TO_DEVICE;
> + if (dmaengine_slave_config(dma->chan_tx, &slave_config)) {
> + dev_err(dev->dev, "failed to configure tx channel\n");
> + ret = -EINVAL;
> + goto error;
> + }
> +
> + slave_config.direction = DMA_FROM_DEVICE;
> + if (dmaengine_slave_config(dma->chan_rx, &slave_config)) {
> + dev_err(dev->dev, "failed to configure rx channel\n");
> + ret = -EINVAL;
> + goto error;
> + }
> +
> + sg_init_table(&dma->sg, 1);
> + dma->buf_mapped = false;
> + dma->xfer_in_progress = false;
> +
> + dev_info(dev->dev, "using %s (tx) and %s (rx) for DMA transfers\n",
> + dma_chan_name(dma->chan_tx), dma_chan_name(dma->chan_rx));
> +
> + return ret;
> +
> +error:
> + dev_info(dev->dev, "can't use DMA\n");
> + if (dma->chan_rx)
> + dma_release_channel(dma->chan_rx);
> + if (dma->chan_tx)
> + dma_release_channel(dma->chan_tx);
> + return ret;
> +}
> +
> static struct at91_twi_pdata * __devinit at91_twi_get_driver_data(
> struct platform_device *pdev)
> {
> @@ -418,6 +713,7 @@ static int __devinit at91_twi_probe(struct platform_device *pdev)
> struct at91_twi_dev *dev;
> struct resource *mem;
> int rc;
> + u32 phy_addr;
>
> dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
> if (!dev)
> @@ -428,6 +724,7 @@ static int __devinit at91_twi_probe(struct platform_device *pdev)
> mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> if (!mem)
> return -ENODEV;
> + phy_addr = mem->start;
>
> dev->pdata = at91_twi_get_driver_data(pdev);
> if (!dev->pdata)
> @@ -457,6 +754,11 @@ static int __devinit at91_twi_probe(struct platform_device *pdev)
> }
> clk_prepare_enable(dev->clk);
>
> + if (dev->pdata->has_dma_support) {
> + if (at91_twi_configure_dma(dev, phy_addr) == 0)
> + dev->use_dma = true;
> + }
> +
> at91_calc_twi_clock(dev, TWI_CLK_HZ);
> at91_init_twi_bus(dev);
>
>
--
Nicolas Ferre
^ permalink raw reply
* [PATCH 1/2] spi: mxs: Assign message status after transfer finished
From: Mark Brown @ 2012-10-17 7:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350181976-18233-1-git-send-email-marex@denx.de>
On Sun, Oct 14, 2012 at 04:32:55AM +0200, Marek Vasut wrote:
> In the current code implementing the MXS SPI driver, every transferred
> message had assigned status = 0, which is not correct. Properly assign
> status returned from the I/O functions.
Applied both, thanks.
^ permalink raw reply
* [PATCH 1/2] Revert "spi/pl022: fix spi-pl022 pm enable at probe"
From: Mark Brown @ 2012-10-17 6:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349452272-4002-1-git-send-email-ulf.hansson@stericsson.com>
On Fri, Oct 05, 2012 at 05:51:11PM +0200, Ulf Hansson wrote:
> From: Ulf Hansson <ulf.hansson@linaro.org>
>
> This reverts commit 6887237cd7da904184dab2750504040c68f3a080.
Applied, thanks.
^ permalink raw reply
* discrepancy while save and restore of debounce registers
From: Hebbar, Gururaja @ 2012-10-17 6:13 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
I came across a peculiar issue while updating GPIO debounce registers on
OMAP platform.
According to mainline commit ae547354a8ed59f19b57f7e1de9c7816edfc3537
gpio/omap: save and restore debounce registers
GPIO debounce registers need to be saved and restored for proper functioning
of driver.
...
@@ -1363,6 +1369,12 @@ static void omap_gpio_restore_context(struct gpio_bank *bank)
__raw_writel(bank->context.fallingdetect,
bank->base + bank->regs->fallingdetect);
__raw_writel(bank->context.dataout, bank->base + bank->regs->dataout);
+ if (bank->dbck_enable_mask) {
+ __raw_writel(bank->context.debounce, bank->base +
+ bank->regs->debounce);
+ __raw_writel(bank->context.debounce_en,
+ bank->base + bank->regs->debounce_en);
+ }
}
Due to copy/paste of this commit into my local tree, I missed the check for
bank->dbck_enable_mask, and directly restored the saved value from context.
After this, I saw random crashes when accessing different registers (sometimes
its OE register and sometime its DATAOUT register).
These crashes were seen across 2nd and subsequent suspend/resume.
My doubt/questions are
1. Why should debounce registers be updated only when it's accessed previously?
2. What is the relation between updating debounce registers and crash seen on
others registers?
Thanks in advance for the support.
Regards
Gururaja
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox