* [PATCHv2 08/11] arm64: smp: prepare for smp_processor_id() rework
From: Mark Rutland @ 2016-11-03 20:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478204593-29145-1-git-send-email-mark.rutland@arm.com>
Subsequent patches will make smp_processor_id() use a percpu variable.
This will make smp_processor_id() dependent on the percpu offset, and
thus we cannot use smp_processor_id() to figure out what to initialise
the offset to.
Prepare for this by initialising the percpu offset based on
current::cpu, which will work regardless of how smp_processor_id() is
implemented. Also, make this relationship obvious by placing this code
together at the start of secondary_start_kernel().
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Tested-by: Laura Abbott <labbott@redhat.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
arch/arm64/kernel/smp.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 8507703..f64401f 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -208,7 +208,10 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
asmlinkage void secondary_start_kernel(void)
{
struct mm_struct *mm = &init_mm;
- unsigned int cpu = smp_processor_id();
+ unsigned int cpu;
+
+ cpu = task_cpu(current);
+ set_my_cpu_offset(per_cpu_offset(cpu));
/*
* All kernel threads share the same mm context; grab a
@@ -217,8 +220,6 @@ asmlinkage void secondary_start_kernel(void)
atomic_inc(&mm->mm_count);
current->active_mm = mm;
- set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
-
/*
* TTBR0 is only used for the identity mapping at this stage. Make it
* point to zero page to avoid speculatively fetching new entries.
--
2.7.4
^ permalink raw reply related
* [PATCHv2 09/11] arm64: make cpu number a percpu variable
From: Mark Rutland @ 2016-11-03 20:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478204593-29145-1-git-send-email-mark.rutland@arm.com>
In the absence of CONFIG_THREAD_INFO_IN_TASK, core code maintains
thread_info::cpu, and low-level architecture code can access this to
build raw_smp_processor_id(). With CONFIG_THREAD_INFO_IN_TASK, core code
maintains task_struct::cpu, which for reasons of hte header soup is not
accessible to low-level arch code.
Instead, we can maintain a percpu variable containing the cpu number.
For both the old and new implementation of raw_smp_processor_id(), we
read a syreg into a GPR, add an offset, and load the result. As the
offset is now larger, it may not be folded into the load, but otherwise
the assembly shouldn't change much.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Tested-by: Laura Abbott <labbott@redhat.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
arch/arm64/include/asm/smp.h | 11 ++++++++++-
arch/arm64/kernel/smp.c | 5 +++++
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
index 0226447..968b08d 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -29,11 +29,20 @@
#ifndef __ASSEMBLY__
+#include <asm/percpu.h>
+
#include <linux/threads.h>
#include <linux/cpumask.h>
#include <linux/thread_info.h>
-#define raw_smp_processor_id() (current_thread_info()->cpu)
+DECLARE_PER_CPU_READ_MOSTLY(int, cpu_number);
+
+/*
+ * We don't use this_cpu_read(cpu_number) as that has implicit writes to
+ * preempt_count, and associated (compiler) barriers, that we'd like to avoid
+ * the expense of. If we're preemptible, the value can be stale at use anyway.
+ */
+#define raw_smp_processor_id() (*this_cpu_ptr(&cpu_number))
struct seq_file;
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index f64401f..6f42c68 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -58,6 +58,9 @@
#define CREATE_TRACE_POINTS
#include <trace/events/ipi.h>
+DEFINE_PER_CPU_READ_MOSTLY(int, cpu_number);
+EXPORT_PER_CPU_SYMBOL(cpu_number);
+
/*
* as from 2.5, kernels no longer have an init_tasks structure
* so we need some other way of telling a new secondary core
@@ -719,6 +722,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
*/
for_each_possible_cpu(cpu) {
+ per_cpu(cpu_number, cpu) = cpu;
+
if (cpu == smp_processor_id())
continue;
--
2.7.4
^ permalink raw reply related
* [PATCHv2 10/11] arm64: assembler: introduce ldr_this_cpu
From: Mark Rutland @ 2016-11-03 20:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478204593-29145-1-git-send-email-mark.rutland@arm.com>
Shortly we will want to load a percpu variable in the return from
userspace path. We can save an instruction by folding the addition of
the percpu offset into the load instruction, and this patch adds a new
helper to do so.
At the same time, we clean up this_cpu_ptr for consistency. As with
{adr,ldr,str}_l, we change the template to take the destination register
first, and name this dst. Secondly, we rename the macro to adr_this_cpu,
following the scheme of adr_l, and matching the newly added
ldr_this_cpu.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Tested-by: Laura Abbott <labbott@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
arch/arm64/include/asm/assembler.h | 19 +++++++++++++++----
arch/arm64/kernel/entry.S | 2 +-
2 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index 28bfe61..128a9ca 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -202,14 +202,25 @@ lr .req x30 // link register
.endm
/*
+ * @dst: Result of per_cpu(sym, smp_processor_id())
* @sym: The name of the per-cpu variable
- * @reg: Result of per_cpu(sym, smp_processor_id())
* @tmp: scratch register
*/
- .macro this_cpu_ptr, sym, reg, tmp
- adr_l \reg, \sym
+ .macro adr_this_cpu, dst, sym, tmp
+ adr_l \dst, \sym
mrs \tmp, tpidr_el1
- add \reg, \reg, \tmp
+ add \dst, \dst, \tmp
+ .endm
+
+ /*
+ * @dst: Result of READ_ONCE(per_cpu(sym, smp_processor_id()))
+ * @sym: The name of the per-cpu variable
+ * @tmp: scratch register
+ */
+ .macro ldr_this_cpu dst, sym, tmp
+ adr_l \dst, \sym
+ mrs \tmp, tpidr_el1
+ ldr \dst, [\dst, \tmp]
.endm
/*
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 223d54a..2d4c83b 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -200,7 +200,7 @@ alternative_else_nop_endif
cmp x25, tsk
b.ne 9998f
- this_cpu_ptr irq_stack, x25, x26
+ adr_this_cpu x25, irq_stack, x26
mov x26, #IRQ_STACK_START_SP
add x26, x25, x26
--
2.7.4
^ permalink raw reply related
* [PATCHv2 11/11] arm64: split thread_info from task stack
From: Mark Rutland @ 2016-11-03 20:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478204593-29145-1-git-send-email-mark.rutland@arm.com>
This patch moves arm64's struct thread_info from the task stack into
task_struct. This protects thread_info from corruption in the case of
stack overflows, and makes its address harder to determine if stack
addresses are leaked, making a number of attacks more difficult. Precise
detection and handling of overflow is left for subsequent patches.
Largely, this involves changing code to store the task_struct in sp_el0,
and acquire the thread_info from the task struct. Core code now
implements current_thread_info(), and as noted in <linux/sched.h> this
relies on offsetof(task_struct, thread_info) == 0, enforced by core
code.
This change means that the 'tsk' register used in entry.S now points to
a task_struct, rather than a thread_info as it used to. To make this
clear, the TI_* field offsets are renamed to TSK_TI_*, with asm-offsets
appropriately updated to account for the structural change.
Userspace clobbers sp_el0, and we can no longer restore this from the
stack. Instead, the current task is cached in a per-cpu variable that we
can safely access from early assembly as interrupts are disabled (and we
are thus not preemptible).
Both secondary entry and idle are updated to stash the sp and task
pointer separately.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Tested-by: Laura Abbott <labbott@redhat.com>
Cc: AKASHI Takahiro <takahiro.akashi@linaro.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
arch/arm64/Kconfig | 1 +
arch/arm64/include/asm/Kbuild | 1 -
arch/arm64/include/asm/current.h | 22 +++++++++++++++++++
arch/arm64/include/asm/smp.h | 1 +
arch/arm64/include/asm/thread_info.h | 24 ---------------------
arch/arm64/kernel/asm-offsets.c | 8 ++++---
arch/arm64/kernel/entry.S | 41 ++++++++++++++++++------------------
arch/arm64/kernel/head.S | 11 +++++-----
arch/arm64/kernel/process.c | 16 ++++++++++++++
arch/arm64/kernel/smp.c | 2 ++
10 files changed, 73 insertions(+), 54 deletions(-)
create mode 100644 arch/arm64/include/asm/current.h
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 969ef88..2a6fcec 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -109,6 +109,7 @@ config ARM64
select POWER_SUPPLY
select SPARSE_IRQ
select SYSCTL_EXCEPTION_TRACE
+ select THREAD_INFO_IN_TASK
help
ARM 64-bit (AArch64) Linux support.
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
index 44e1d7f..28196b1 100644
--- a/arch/arm64/include/asm/Kbuild
+++ b/arch/arm64/include/asm/Kbuild
@@ -1,7 +1,6 @@
generic-y += bugs.h
generic-y += clkdev.h
generic-y += cputime.h
-generic-y += current.h
generic-y += delay.h
generic-y += div64.h
generic-y += dma.h
diff --git a/arch/arm64/include/asm/current.h b/arch/arm64/include/asm/current.h
new file mode 100644
index 0000000..f2bcbe2
--- /dev/null
+++ b/arch/arm64/include/asm/current.h
@@ -0,0 +1,22 @@
+#ifndef __ASM_CURRENT_H
+#define __ASM_CURRENT_H
+
+#include <linux/compiler.h>
+
+#include <asm/sysreg.h>
+
+#ifndef __ASSEMBLY__
+
+struct task_struct;
+
+static __always_inline struct task_struct *get_current(void)
+{
+ return (struct task_struct *)read_sysreg(sp_el0);
+}
+
+#define current get_current()
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_CURRENT_H */
+
diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
index 968b08d..a62db95 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -82,6 +82,7 @@ asmlinkage void secondary_start_kernel(void);
*/
struct secondary_data {
void *stack;
+ struct task_struct *task;
long status;
};
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 3a4f85d..7a4e0e4 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -47,41 +47,17 @@ typedef unsigned long mm_segment_t;
struct thread_info {
unsigned long flags; /* low level flags */
mm_segment_t addr_limit; /* address limit */
- struct task_struct *task; /* main task structure */
int preempt_count; /* 0 => preemptable, <0 => bug */
- int cpu; /* cpu */
};
#define INIT_THREAD_INFO(tsk) \
{ \
- .task = &tsk, \
- .flags = 0, \
.preempt_count = INIT_PREEMPT_COUNT, \
.addr_limit = KERNEL_DS, \
}
#define init_stack (init_thread_union.stack)
-/*
- * how to get the thread information struct from C
- */
-static inline struct thread_info *current_thread_info(void) __attribute_const__;
-
-/*
- * struct thread_info can be accessed directly via sp_el0.
- *
- * We don't use read_sysreg() as we want the compiler to cache the value where
- * possible.
- */
-static inline struct thread_info *current_thread_info(void)
-{
- unsigned long sp_el0;
-
- asm ("mrs %0, sp_el0" : "=r" (sp_el0));
-
- return (struct thread_info *)sp_el0;
-}
-
#define thread_saved_pc(tsk) \
((unsigned long)(tsk->thread.cpu_context.pc))
#define thread_saved_sp(tsk) \
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index d30b232..c2dc9fa 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -36,9 +36,10 @@ int main(void)
{
DEFINE(TSK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
BLANK();
- DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
- DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
- DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit));
+ DEFINE(TSK_TI_FLAGS, offsetof(struct task_struct, thread_info.flags));
+ DEFINE(TSK_TI_PREEMPT, offsetof(struct task_struct, thread_info.preempt_count));
+ DEFINE(TSK_TI_ADDR_LIMIT, offsetof(struct task_struct, thread_info.addr_limit));
+ DEFINE(TSK_STACK, offsetof(struct task_struct, stack));
BLANK();
DEFINE(THREAD_CPU_CONTEXT, offsetof(struct task_struct, thread.cpu_context));
BLANK();
@@ -121,6 +122,7 @@ int main(void)
DEFINE(TZ_DSTTIME, offsetof(struct timezone, tz_dsttime));
BLANK();
DEFINE(CPU_BOOT_STACK, offsetof(struct secondary_data, stack));
+ DEFINE(CPU_BOOT_TASK, offsetof(struct secondary_data, task));
BLANK();
#ifdef CONFIG_KVM_ARM_HOST
DEFINE(VCPU_CONTEXT, offsetof(struct kvm_vcpu, arch.ctxt));
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 2d4c83b..6349a83 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -90,9 +90,8 @@
.if \el == 0
mrs x21, sp_el0
- mov tsk, sp
- and tsk, tsk, #~(THREAD_SIZE - 1) // Ensure MDSCR_EL1.SS is clear,
- ldr x19, [tsk, #TI_FLAGS] // since we can unmask debug
+ ldr_this_cpu tsk, __entry_task, x20 // Ensure MDSCR_EL1.SS is clear,
+ ldr x19, [tsk, #TSK_TI_FLAGS] // since we can unmask debug
disable_step_tsk x19, x20 // exceptions when scheduling.
mov x29, xzr // fp pointed to user-space
@@ -100,10 +99,10 @@
add x21, sp, #S_FRAME_SIZE
get_thread_info tsk
/* Save the task's original addr_limit and set USER_DS (TASK_SIZE_64) */
- ldr x20, [tsk, #TI_ADDR_LIMIT]
+ ldr x20, [tsk, #TSK_TI_ADDR_LIMIT]
str x20, [sp, #S_ORIG_ADDR_LIMIT]
mov x20, #TASK_SIZE_64
- str x20, [tsk, #TI_ADDR_LIMIT]
+ str x20, [tsk, #TSK_TI_ADDR_LIMIT]
/* No need to reset PSTATE.UAO, hardware's already set it to 0 for us */
.endif /* \el == 0 */
mrs x22, elr_el1
@@ -139,7 +138,7 @@
.if \el != 0
/* Restore the task's original addr_limit. */
ldr x20, [sp, #S_ORIG_ADDR_LIMIT]
- str x20, [tsk, #TI_ADDR_LIMIT]
+ str x20, [tsk, #TSK_TI_ADDR_LIMIT]
/* No need to restore UAO, it will be restored from SPSR_EL1 */
.endif
@@ -192,13 +191,14 @@ alternative_else_nop_endif
mov x19, sp // preserve the original sp
/*
- * Compare sp with the current thread_info, if the top
- * ~(THREAD_SIZE - 1) bits match, we are on a task stack, and
- * should switch to the irq stack.
+ * Compare sp with the base of the task stack.
+ * If the top ~(THREAD_SIZE - 1) bits match, we are on a task stack,
+ * and should switch to the irq stack.
*/
- and x25, x19, #~(THREAD_SIZE - 1)
- cmp x25, tsk
- b.ne 9998f
+ ldr x25, [tsk, TSK_STACK]
+ eor x25, x25, x19
+ and x25, x25, #~(THREAD_SIZE - 1)
+ cbnz x25, 9998f
adr_this_cpu x25, irq_stack, x26
mov x26, #IRQ_STACK_START_SP
@@ -427,9 +427,9 @@ el1_irq:
irq_handler
#ifdef CONFIG_PREEMPT
- ldr w24, [tsk, #TI_PREEMPT] // get preempt count
+ ldr w24, [tsk, #TSK_TI_PREEMPT] // get preempt count
cbnz w24, 1f // preempt count != 0
- ldr x0, [tsk, #TI_FLAGS] // get flags
+ ldr x0, [tsk, #TSK_TI_FLAGS] // get flags
tbz x0, #TIF_NEED_RESCHED, 1f // needs rescheduling?
bl el1_preempt
1:
@@ -444,7 +444,7 @@ ENDPROC(el1_irq)
el1_preempt:
mov x24, lr
1: bl preempt_schedule_irq // irq en/disable is done inside
- ldr x0, [tsk, #TI_FLAGS] // get new tasks TI_FLAGS
+ ldr x0, [tsk, #TSK_TI_FLAGS] // get new tasks TI_FLAGS
tbnz x0, #TIF_NEED_RESCHED, 1b // needs rescheduling?
ret x24
#endif
@@ -674,8 +674,7 @@ ENTRY(cpu_switch_to)
ldp x29, x9, [x8], #16
ldr lr, [x8]
mov sp, x9
- and x9, x9, #~(THREAD_SIZE - 1)
- msr sp_el0, x9
+ msr sp_el0, x1
ret
ENDPROC(cpu_switch_to)
@@ -686,7 +685,7 @@ ENDPROC(cpu_switch_to)
ret_fast_syscall:
disable_irq // disable interrupts
str x0, [sp, #S_X0] // returned x0
- ldr x1, [tsk, #TI_FLAGS] // re-check for syscall tracing
+ ldr x1, [tsk, #TSK_TI_FLAGS] // re-check for syscall tracing
and x2, x1, #_TIF_SYSCALL_WORK
cbnz x2, ret_fast_syscall_trace
and x2, x1, #_TIF_WORK_MASK
@@ -706,14 +705,14 @@ work_pending:
#ifdef CONFIG_TRACE_IRQFLAGS
bl trace_hardirqs_on // enabled while in userspace
#endif
- ldr x1, [tsk, #TI_FLAGS] // re-check for single-step
+ ldr x1, [tsk, #TSK_TI_FLAGS] // re-check for single-step
b finish_ret_to_user
/*
* "slow" syscall return path.
*/
ret_to_user:
disable_irq // disable interrupts
- ldr x1, [tsk, #TI_FLAGS]
+ ldr x1, [tsk, #TSK_TI_FLAGS]
and x2, x1, #_TIF_WORK_MASK
cbnz x2, work_pending
finish_ret_to_user:
@@ -746,7 +745,7 @@ el0_svc_naked: // compat entry point
enable_dbg_and_irq
ct_user_exit 1
- ldr x16, [tsk, #TI_FLAGS] // check for syscall hooks
+ ldr x16, [tsk, #TSK_TI_FLAGS] // check for syscall hooks
tst x16, #_TIF_SYSCALL_WORK
b.ne __sys_trace
cmp scno, sc_nr // check upper syscall limit
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 332e331..eaafb25 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -428,7 +428,8 @@ ENDPROC(__create_page_tables)
__primary_switched:
adrp x4, init_thread_union
add sp, x4, #THREAD_SIZE
- msr sp_el0, x4 // Save thread_info
+ adr_l x5, init_task
+ msr sp_el0, x5 // Save thread_info
adr_l x8, vectors // load VBAR_EL1 with virtual
msr vbar_el1, x8 // vector table address
@@ -699,10 +700,10 @@ __secondary_switched:
isb
adr_l x0, secondary_data
- ldr x0, [x0, #CPU_BOOT_STACK] // get secondary_data.stack
- mov sp, x0
- and x0, x0, #~(THREAD_SIZE - 1)
- msr sp_el0, x0 // save thread_info
+ ldr x1, [x0, #CPU_BOOT_STACK] // get secondary_data.stack
+ mov sp, x1
+ ldr x2, [x0, #CPU_BOOT_TASK]
+ msr sp_el0, x2
mov x29, #0
b secondary_start_kernel
ENDPROC(__secondary_switched)
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index ec7b9c0..a98b743 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -45,6 +45,7 @@
#include <linux/personality.h>
#include <linux/notifier.h>
#include <trace/events/power.h>
+#include <linux/percpu.h>
#include <asm/alternative.h>
#include <asm/compat.h>
@@ -322,6 +323,20 @@ void uao_thread_switch(struct task_struct *next)
}
/*
+ * We store our current task in sp_el0, which is clobbered by userspace. Keep a
+ * shadow copy so that we can restore this upon entry from userspace.
+ *
+ * This is *only* for exception entry from EL0, and is not valid until we
+ * __switch_to() a user task.
+ */
+DEFINE_PER_CPU(struct task_struct *, __entry_task);
+
+static void entry_task_switch(struct task_struct *next)
+{
+ __this_cpu_write(__entry_task, next);
+}
+
+/*
* Thread switching.
*/
struct task_struct *__switch_to(struct task_struct *prev,
@@ -333,6 +348,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
tls_thread_switch(next);
hw_breakpoint_thread_switch(next);
contextidr_thread_switch(next);
+ entry_task_switch(next);
uao_thread_switch(next);
/*
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 6f42c68..cb87234 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -149,6 +149,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
* We need to tell the secondary core where to find its stack and the
* page tables.
*/
+ secondary_data.task = idle;
secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
update_cpu_boot_status(CPU_MMU_OFF);
__flush_dcache_area(&secondary_data, sizeof(secondary_data));
@@ -173,6 +174,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
pr_err("CPU%u: failed to boot: %d\n", cpu, ret);
}
+ secondary_data.task = NULL;
secondary_data.stack = NULL;
status = READ_ONCE(secondary_data.status);
if (ret && status) {
--
2.7.4
^ permalink raw reply related
* Applied "ASoC: sun4i-codec: Add support for A31 Line In playback" to the asoc tree
From: Mark Brown @ 2016-11-03 20:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161003110804.28235-7-wens@csie.org>
The patch
ASoC: sun4i-codec: Add support for A31 Line In playback
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From dff5051250674fce575fa36c22b2f007363e42d0 Mon Sep 17 00:00:00 2001
From: Chen-Yu Tsai <wens@csie.org>
Date: Thu, 3 Nov 2016 15:55:49 +0800
Subject: [PATCH] ASoC: sun4i-codec: Add support for A31 Line In playback
The A31 integrated codec has a stereo "Line In" input. Add support for
it to the playback paths.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
sound/soc/sunxi/sun4i-codec.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
index d4b2186b5d84..72a84f76aa57 100644
--- a/sound/soc/sunxi/sun4i-codec.c
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -772,6 +772,10 @@ static const struct snd_kcontrol_new sun6i_codec_mixer_controls[] = {
SUN6I_CODEC_OM_DACA_CTRL,
SUN6I_CODEC_OM_DACA_CTRL_LMIX_DACR,
SUN6I_CODEC_OM_DACA_CTRL_RMIX_DACL, 1, 0),
+ SOC_DAPM_DOUBLE("Line In Playback Switch",
+ SUN6I_CODEC_OM_DACA_CTRL,
+ SUN6I_CODEC_OM_DACA_CTRL_LMIX_LINEINL,
+ SUN6I_CODEC_OM_DACA_CTRL_RMIX_LINEINR, 1, 0),
};
/* headphone controls */
@@ -793,6 +797,8 @@ static const struct snd_kcontrol_new sun6i_codec_hp_src[] = {
/* volume / mute controls */
static const DECLARE_TLV_DB_SCALE(sun6i_codec_dvol_scale, -7308, 116, 0);
static const DECLARE_TLV_DB_SCALE(sun6i_codec_hp_vol_scale, -6300, 100, 1);
+static const DECLARE_TLV_DB_SCALE(sun6i_codec_out_mixer_pregain_scale,
+ -450, 150, 0);
static const struct snd_kcontrol_new sun6i_codec_codec_widgets[] = {
SOC_SINGLE_TLV("DAC Playback Volume", SUN4I_CODEC_DAC_DPC,
@@ -806,9 +812,16 @@ static const struct snd_kcontrol_new sun6i_codec_codec_widgets[] = {
SUN6I_CODEC_OM_DACA_CTRL,
SUN6I_CODEC_OM_DACA_CTRL_LHPPAMUTE,
SUN6I_CODEC_OM_DACA_CTRL_RHPPAMUTE, 1, 0),
+ /* Mixer pre-gains */
+ SOC_SINGLE_TLV("Line In Playback Volume",
+ SUN6I_CODEC_OM_PA_CTRL, SUN6I_CODEC_OM_PA_CTRL_LINEING,
+ 0x7, 0, sun6i_codec_out_mixer_pregain_scale),
};
static const struct snd_soc_dapm_widget sun6i_codec_codec_dapm_widgets[] = {
+ /* Line In */
+ SND_SOC_DAPM_INPUT("LINEIN"),
+
/* Digital parts of the DACs */
SND_SOC_DAPM_SUPPLY("DAC Enable", SUN4I_CODEC_DAC_DPC,
SUN4I_CODEC_DAC_DPC_EN_DA, 0,
@@ -850,10 +863,12 @@ static const struct snd_soc_dapm_route sun6i_codec_codec_dapm_routes[] = {
/* Left Mixer Routes */
{ "Left Mixer", "DAC Playback Switch", "Left DAC" },
{ "Left Mixer", "DAC Reversed Playback Switch", "Right DAC" },
+ { "Left Mixer", "Line In Playback Switch", "LINEIN" },
/* Right Mixer Routes */
{ "Right Mixer", "DAC Playback Switch", "Right DAC" },
{ "Right Mixer", "DAC Reversed Playback Switch", "Left DAC" },
+ { "Right Mixer", "Line In Playback Switch", "LINEIN" },
/* Headphone Routes */
{ "Headphone Source Playback Route", "DAC", "Left DAC" },
--
2.10.1
^ permalink raw reply related
* Applied "ASoC: sun4i-codec: Add support for A31 playback through headphone output" to the asoc tree
From: Mark Brown @ 2016-11-03 20:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161103075556.29018-7-wens@csie.org>
The patch
ASoC: sun4i-codec: Add support for A31 playback through headphone output
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From 8d9e4c9e993f34e7f74bf36f417920a01a42c4b0 Mon Sep 17 00:00:00 2001
From: Chen-Yu Tsai <wens@csie.org>
Date: Thu, 3 Nov 2016 15:55:48 +0800
Subject: [PATCH] ASoC: sun4i-codec: Add support for A31 playback through
headphone output
The A31 has a similar codec to the A10/A20. The PCM parts are very
similar, with different register offsets. The analog paths are very
different. There are more inputs and outputs. The ADC mux has been
replaced with a proper mixer.
This patch adds support for the basic playback path of the A31 codec,
from the DAC to the headphones. Headphone detection, microphone,
signaling, other inputs/outputs and capture will be added later.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
.../devicetree/bindings/sound/sun4i-codec.txt | 22 +-
sound/soc/sunxi/sun4i-codec.c | 271 ++++++++++++++++++++-
2 files changed, 287 insertions(+), 6 deletions(-)
diff --git a/Documentation/devicetree/bindings/sound/sun4i-codec.txt b/Documentation/devicetree/bindings/sound/sun4i-codec.txt
index 0dce690f78f5..bf480e9683a3 100644
--- a/Documentation/devicetree/bindings/sound/sun4i-codec.txt
+++ b/Documentation/devicetree/bindings/sound/sun4i-codec.txt
@@ -1,8 +1,10 @@
* Allwinner A10 Codec
Required properties:
-- compatible: must be either "allwinner,sun4i-a10-codec" or
- "allwinner,sun7i-a20-codec"
+- compatible: must be one of the following compatibles:
+ - "allwinner,sun4i-a10-codec"
+ - "allwinner,sun6i-a31-codec"
+ - "allwinner,sun7i-a20-codec"
- reg: must contain the registers location and length
- interrupts: must contain the codec interrupt
- dmas: DMA channels for tx and rx dma. See the DMA client binding,
@@ -17,6 +19,10 @@ Required properties:
Optional properties:
- allwinner,pa-gpios: gpio to enable external amplifier
+Required properties for the following compatibles:
+ - "allwinner,sun6i-a31-codec"
+- resets: phandle to the reset control for this device
+
Example:
codec: codec at 01c22c00 {
#sound-dai-cells = <0>;
@@ -28,3 +34,15 @@ codec: codec at 01c22c00 {
dmas = <&dma 0 19>, <&dma 0 19>;
dma-names = "rx", "tx";
};
+
+codec: codec at 01c22c00 {
+ #sound-dai-cells = <0>;
+ compatible = "allwinner,sun6i-a31-codec";
+ reg = <0x01c22c00 0x98>;
+ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_APB1_CODEC>, <&ccu CLK_CODEC>;
+ clock-names = "apb", "codec";
+ resets = <&ccu RST_APB1_CODEC>;
+ dmas = <&dma 15>, <&dma 15>;
+ dma-names = "rx", "tx";
+};
diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
index d867b96d367b..d4b2186b5d84 100644
--- a/sound/soc/sunxi/sun4i-codec.c
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -109,6 +109,109 @@
/* Microphone controls (sun7i only) */
#define SUN7I_CODEC_AC_MIC_PHONE_CAL (0x3c)
+/*
+ * sun6i specific registers
+ *
+ * sun6i shares the same digital control and FIFO registers as sun4i,
+ * but only the DAC digital controls are at the same offset. The others
+ * have been moved around to accommodate extra analog controls.
+ */
+
+/* Codec DAC digital controls and FIFO registers */
+#define SUN6I_CODEC_ADC_FIFOC (0x10)
+#define SUN6I_CODEC_ADC_FIFOC_EN_AD (28)
+#define SUN6I_CODEC_ADC_FIFOS (0x14)
+#define SUN6I_CODEC_ADC_RXDATA (0x18)
+
+/* Output mixer and gain controls */
+#define SUN6I_CODEC_OM_DACA_CTRL (0x20)
+#define SUN6I_CODEC_OM_DACA_CTRL_DACAREN (31)
+#define SUN6I_CODEC_OM_DACA_CTRL_DACALEN (30)
+#define SUN6I_CODEC_OM_DACA_CTRL_RMIXEN (29)
+#define SUN6I_CODEC_OM_DACA_CTRL_LMIXEN (28)
+#define SUN6I_CODEC_OM_DACA_CTRL_RMIX_MIC1 (23)
+#define SUN6I_CODEC_OM_DACA_CTRL_RMIX_MIC2 (22)
+#define SUN6I_CODEC_OM_DACA_CTRL_RMIX_PHONE (21)
+#define SUN6I_CODEC_OM_DACA_CTRL_RMIX_PHONEP (20)
+#define SUN6I_CODEC_OM_DACA_CTRL_RMIX_LINEINR (19)
+#define SUN6I_CODEC_OM_DACA_CTRL_RMIX_DACR (18)
+#define SUN6I_CODEC_OM_DACA_CTRL_RMIX_DACL (17)
+#define SUN6I_CODEC_OM_DACA_CTRL_LMIX_MIC1 (16)
+#define SUN6I_CODEC_OM_DACA_CTRL_LMIX_MIC2 (15)
+#define SUN6I_CODEC_OM_DACA_CTRL_LMIX_PHONE (14)
+#define SUN6I_CODEC_OM_DACA_CTRL_LMIX_PHONEN (13)
+#define SUN6I_CODEC_OM_DACA_CTRL_LMIX_LINEINL (12)
+#define SUN6I_CODEC_OM_DACA_CTRL_LMIX_DACL (11)
+#define SUN6I_CODEC_OM_DACA_CTRL_LMIX_DACR (10)
+#define SUN6I_CODEC_OM_DACA_CTRL_RHPIS (9)
+#define SUN6I_CODEC_OM_DACA_CTRL_LHPIS (8)
+#define SUN6I_CODEC_OM_DACA_CTRL_RHPPAMUTE (7)
+#define SUN6I_CODEC_OM_DACA_CTRL_LHPPAMUTE (6)
+#define SUN6I_CODEC_OM_DACA_CTRL_HPVOL (0)
+#define SUN6I_CODEC_OM_PA_CTRL (0x24)
+#define SUN6I_CODEC_OM_PA_CTRL_HPPAEN (31)
+#define SUN6I_CODEC_OM_PA_CTRL_HPCOM_CTL (29)
+#define SUN6I_CODEC_OM_PA_CTRL_COMPTEN (28)
+#define SUN6I_CODEC_OM_PA_CTRL_MIC1G (15)
+#define SUN6I_CODEC_OM_PA_CTRL_MIC2G (12)
+#define SUN6I_CODEC_OM_PA_CTRL_LINEING (9)
+#define SUN6I_CODEC_OM_PA_CTRL_PHONEG (6)
+#define SUN6I_CODEC_OM_PA_CTRL_PHONEPG (3)
+#define SUN6I_CODEC_OM_PA_CTRL_PHONENG (0)
+
+/* Microphone, line out and phone out controls */
+#define SUN6I_CODEC_MIC_CTRL (0x28)
+#define SUN6I_CODEC_MIC_CTRL_HBIASEN (31)
+#define SUN6I_CODEC_MIC_CTRL_MBIASEN (30)
+#define SUN6I_CODEC_MIC_CTRL_MIC1AMPEN (28)
+#define SUN6I_CODEC_MIC_CTRL_MIC1BOOST (25)
+#define SUN6I_CODEC_MIC_CTRL_MIC2AMPEN (24)
+#define SUN6I_CODEC_MIC_CTRL_MIC2BOOST (21)
+#define SUN6I_CODEC_MIC_CTRL_MIC2SLT (20)
+#define SUN6I_CODEC_MIC_CTRL_LINEOUTLEN (19)
+#define SUN6I_CODEC_MIC_CTRL_LINEOUTREN (18)
+#define SUN6I_CODEC_MIC_CTRL_LINEOUTLSRC (17)
+#define SUN6I_CODEC_MIC_CTRL_LINEOUTRSRC (16)
+#define SUN6I_CODEC_MIC_CTRL_LINEOUTVC (11)
+#define SUN6I_CODEC_MIC_CTRL_PHONEPREG (8)
+
+/* ADC mixer controls */
+#define SUN6I_CODEC_ADC_ACTL (0x2c)
+#define SUN6I_CODEC_ADC_ACTL_ADCREN (31)
+#define SUN6I_CODEC_ADC_ACTL_ADCLEN (30)
+#define SUN6I_CODEC_ADC_ACTL_ADCRG (27)
+#define SUN6I_CODEC_ADC_ACTL_ADCLG (24)
+#define SUN6I_CODEC_ADC_ACTL_RADCMIX_MIC1 (13)
+#define SUN6I_CODEC_ADC_ACTL_RADCMIX_MIC2 (12)
+#define SUN6I_CODEC_ADC_ACTL_RADCMIX_PHONE (11)
+#define SUN6I_CODEC_ADC_ACTL_RADCMIX_PHONEP (10)
+#define SUN6I_CODEC_ADC_ACTL_RADCMIX_LINEINR (9)
+#define SUN6I_CODEC_ADC_ACTL_RADCMIX_OMIXR (8)
+#define SUN6I_CODEC_ADC_ACTL_RADCMIX_OMIXL (7)
+#define SUN6I_CODEC_ADC_ACTL_LADCMIX_MIC1 (6)
+#define SUN6I_CODEC_ADC_ACTL_LADCMIX_MIC2 (5)
+#define SUN6I_CODEC_ADC_ACTL_LADCMIX_PHONE (4)
+#define SUN6I_CODEC_ADC_ACTL_LADCMIX_PHONEN (3)
+#define SUN6I_CODEC_ADC_ACTL_LADCMIX_LINEINL (2)
+#define SUN6I_CODEC_ADC_ACTL_LADCMIX_OMIXL (1)
+#define SUN6I_CODEC_ADC_ACTL_LADCMIX_OMIXR (0)
+
+/* Analog performance tuning controls */
+#define SUN6I_CODEC_ADDA_TUNE (0x30)
+
+/* Calibration controls */
+#define SUN6I_CODEC_CALIBRATION (0x34)
+
+/* FIFO counters */
+#define SUN6I_CODEC_DAC_TXCNT (0x40)
+#define SUN6I_CODEC_ADC_RXCNT (0x44)
+
+/* headset jack detection and button support registers */
+#define SUN6I_CODEC_HMIC_CTL (0x50)
+#define SUN6I_CODEC_HMIC_DATA (0x54)
+
+/* TODO sun6i DAP (Digital Audio Processing) bits */
+
struct sun4i_codec {
struct device *dev;
struct regmap *regmap;
@@ -214,9 +317,14 @@ static int sun4i_codec_prepare_capture(struct snd_pcm_substream *substream,
* Allwinner's code mentions that it is related
* related to microphone gain
*/
- regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_ACTL,
- 0x3 << 25,
- 0x1 << 25);
+ if (of_device_is_compatible(scodec->dev->of_node,
+ "allwinner,sun4i-a10-codec") ||
+ of_device_is_compatible(scodec->dev->of_node,
+ "allwinner,sun7i-a20-codec")) {
+ regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_ACTL,
+ 0x3 << 25,
+ 0x1 << 25);
+ }
if (of_device_is_compatible(scodec->dev->of_node,
"allwinner,sun7i-a20-codec"))
@@ -516,7 +624,7 @@ static struct snd_soc_dai_driver sun4i_codec_dai = {
},
};
-/*** Codec ***/
+/*** sun4i Codec ***/
static const struct snd_kcontrol_new sun4i_codec_pa_mute =
SOC_DAPM_SINGLE("Switch", SUN4I_CODEC_DAC_ACTL,
SUN4I_CODEC_DAC_ACTL_PA_MUTE, 1, 0);
@@ -652,6 +760,122 @@ static struct snd_soc_codec_driver sun4i_codec_codec = {
},
};
+/*** sun6i Codec ***/
+
+/* mixer controls */
+static const struct snd_kcontrol_new sun6i_codec_mixer_controls[] = {
+ SOC_DAPM_DOUBLE("DAC Playback Switch",
+ SUN6I_CODEC_OM_DACA_CTRL,
+ SUN6I_CODEC_OM_DACA_CTRL_LMIX_DACL,
+ SUN6I_CODEC_OM_DACA_CTRL_RMIX_DACR, 1, 0),
+ SOC_DAPM_DOUBLE("DAC Reversed Playback Switch",
+ SUN6I_CODEC_OM_DACA_CTRL,
+ SUN6I_CODEC_OM_DACA_CTRL_LMIX_DACR,
+ SUN6I_CODEC_OM_DACA_CTRL_RMIX_DACL, 1, 0),
+};
+
+/* headphone controls */
+static const char * const sun6i_codec_hp_src_enum_text[] = {
+ "DAC", "Mixer",
+};
+
+static SOC_ENUM_DOUBLE_DECL(sun6i_codec_hp_src_enum,
+ SUN6I_CODEC_OM_DACA_CTRL,
+ SUN6I_CODEC_OM_DACA_CTRL_LHPIS,
+ SUN6I_CODEC_OM_DACA_CTRL_RHPIS,
+ sun6i_codec_hp_src_enum_text);
+
+static const struct snd_kcontrol_new sun6i_codec_hp_src[] = {
+ SOC_DAPM_ENUM("Headphone Source Playback Route",
+ sun6i_codec_hp_src_enum),
+};
+
+/* volume / mute controls */
+static const DECLARE_TLV_DB_SCALE(sun6i_codec_dvol_scale, -7308, 116, 0);
+static const DECLARE_TLV_DB_SCALE(sun6i_codec_hp_vol_scale, -6300, 100, 1);
+
+static const struct snd_kcontrol_new sun6i_codec_codec_widgets[] = {
+ SOC_SINGLE_TLV("DAC Playback Volume", SUN4I_CODEC_DAC_DPC,
+ SUN4I_CODEC_DAC_DPC_DVOL, 0x3f, 1,
+ sun6i_codec_dvol_scale),
+ SOC_SINGLE_TLV("Headphone Playback Volume",
+ SUN6I_CODEC_OM_DACA_CTRL,
+ SUN6I_CODEC_OM_DACA_CTRL_HPVOL, 0x3f, 0,
+ sun6i_codec_hp_vol_scale),
+ SOC_DOUBLE("Headphone Playback Switch",
+ SUN6I_CODEC_OM_DACA_CTRL,
+ SUN6I_CODEC_OM_DACA_CTRL_LHPPAMUTE,
+ SUN6I_CODEC_OM_DACA_CTRL_RHPPAMUTE, 1, 0),
+};
+
+static const struct snd_soc_dapm_widget sun6i_codec_codec_dapm_widgets[] = {
+ /* Digital parts of the DACs */
+ SND_SOC_DAPM_SUPPLY("DAC Enable", SUN4I_CODEC_DAC_DPC,
+ SUN4I_CODEC_DAC_DPC_EN_DA, 0,
+ NULL, 0),
+
+ /* Analog parts of the DACs */
+ SND_SOC_DAPM_DAC("Left DAC", "Codec Playback",
+ SUN6I_CODEC_OM_DACA_CTRL,
+ SUN6I_CODEC_OM_DACA_CTRL_DACALEN, 0),
+ SND_SOC_DAPM_DAC("Right DAC", "Codec Playback",
+ SUN6I_CODEC_OM_DACA_CTRL,
+ SUN6I_CODEC_OM_DACA_CTRL_DACAREN, 0),
+
+ /* Mixers */
+ SOC_MIXER_ARRAY("Left Mixer", SUN6I_CODEC_OM_DACA_CTRL,
+ SUN6I_CODEC_OM_DACA_CTRL_LMIXEN, 0,
+ sun6i_codec_mixer_controls),
+ SOC_MIXER_ARRAY("Right Mixer", SUN6I_CODEC_OM_DACA_CTRL,
+ SUN6I_CODEC_OM_DACA_CTRL_RMIXEN, 0,
+ sun6i_codec_mixer_controls),
+
+ /* Headphone output path */
+ SND_SOC_DAPM_MUX("Headphone Source Playback Route",
+ SND_SOC_NOPM, 0, 0, sun6i_codec_hp_src),
+ SND_SOC_DAPM_OUT_DRV("Headphone Amp", SUN6I_CODEC_OM_PA_CTRL,
+ SUN6I_CODEC_OM_PA_CTRL_HPPAEN, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("HPCOM Protection", SUN6I_CODEC_OM_PA_CTRL,
+ SUN6I_CODEC_OM_PA_CTRL_COMPTEN, 0, NULL, 0),
+ SND_SOC_DAPM_REG(snd_soc_dapm_supply, "HPCOM", SUN6I_CODEC_OM_PA_CTRL,
+ SUN6I_CODEC_OM_PA_CTRL_HPCOM_CTL, 0x3, 0x3, 0),
+ SND_SOC_DAPM_OUTPUT("HP"),
+};
+
+static const struct snd_soc_dapm_route sun6i_codec_codec_dapm_routes[] = {
+ /* DAC Routes */
+ { "Left DAC", NULL, "DAC Enable" },
+ { "Right DAC", NULL, "DAC Enable" },
+
+ /* Left Mixer Routes */
+ { "Left Mixer", "DAC Playback Switch", "Left DAC" },
+ { "Left Mixer", "DAC Reversed Playback Switch", "Right DAC" },
+
+ /* Right Mixer Routes */
+ { "Right Mixer", "DAC Playback Switch", "Right DAC" },
+ { "Right Mixer", "DAC Reversed Playback Switch", "Left DAC" },
+
+ /* Headphone Routes */
+ { "Headphone Source Playback Route", "DAC", "Left DAC" },
+ { "Headphone Source Playback Route", "DAC", "Right DAC" },
+ { "Headphone Source Playback Route", "Mixer", "Left Mixer" },
+ { "Headphone Source Playback Route", "Mixer", "Right Mixer" },
+ { "Headphone Amp", NULL, "Headphone Source Playback Route" },
+ { "HP", NULL, "Headphone Amp" },
+ { "HPCOM", NULL, "HPCOM Protection" },
+};
+
+static struct snd_soc_codec_driver sun6i_codec_codec = {
+ .component_driver = {
+ .controls = sun6i_codec_codec_widgets,
+ .num_controls = ARRAY_SIZE(sun6i_codec_codec_widgets),
+ .dapm_widgets = sun6i_codec_codec_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(sun6i_codec_codec_dapm_widgets),
+ .dapm_routes = sun6i_codec_codec_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(sun6i_codec_codec_dapm_routes),
+ },
+};
+
static const struct snd_soc_component_driver sun4i_codec_component = {
.name = "sun4i-codec",
};
@@ -756,6 +980,24 @@ static struct snd_soc_card *sun4i_codec_create_card(struct device *dev)
return card;
};
+static struct snd_soc_card *sun6i_codec_create_card(struct device *dev)
+{
+ struct snd_soc_card *card;
+
+ card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
+ if (!card)
+ return ERR_PTR(-ENOMEM);
+
+ card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
+ if (!card->dai_link)
+ return ERR_PTR(-ENOMEM);
+
+ card->dev = dev;
+ card->name = "A31 Audio Codec";
+
+ return card;
+};
+
static const struct regmap_config sun4i_codec_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
@@ -763,6 +1005,13 @@ static const struct regmap_config sun4i_codec_regmap_config = {
.max_register = SUN4I_CODEC_ADC_RXCNT,
};
+static const struct regmap_config sun6i_codec_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = SUN6I_CODEC_HMIC_DATA,
+};
+
static const struct regmap_config sun7i_codec_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
@@ -788,6 +1037,16 @@ static const struct sun4i_codec_quirks sun4i_codec_quirks = {
.reg_adc_rxdata = SUN4I_CODEC_ADC_RXDATA,
};
+static const struct sun4i_codec_quirks sun6i_a31_codec_quirks = {
+ .regmap_config = &sun6i_codec_regmap_config,
+ .codec = &sun6i_codec_codec,
+ .create_card = sun6i_codec_create_card,
+ .reg_adc_fifoc = REG_FIELD(SUN6I_CODEC_ADC_FIFOC, 0, 31),
+ .reg_dac_txdata = SUN4I_CODEC_DAC_TXDATA,
+ .reg_adc_rxdata = SUN6I_CODEC_ADC_RXDATA,
+ .has_reset = true,
+};
+
static const struct sun4i_codec_quirks sun7i_codec_quirks = {
.regmap_config = &sun7i_codec_regmap_config,
.codec = &sun4i_codec_codec,
@@ -803,6 +1062,10 @@ static const struct of_device_id sun4i_codec_of_match[] = {
.data = &sun4i_codec_quirks,
},
{
+ .compatible = "allwinner,sun6i-a31-codec",
+ .data = &sun6i_a31_codec_quirks,
+ },
+ {
.compatible = "allwinner,sun7i-a20-codec",
.data = &sun7i_codec_quirks,
},
--
2.10.1
^ permalink raw reply related
* Applied "ASoC: sun4i-codec: Increase DMA max burst to 8" to the asoc tree
From: Mark Brown @ 2016-11-03 20:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161103075556.29018-5-wens@csie.org>
The patch
ASoC: sun4i-codec: Increase DMA max burst to 8
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From 730e2dd0cbc7a7ec10174d9d291cdd8e8082a948 Mon Sep 17 00:00:00 2001
From: Chen-Yu Tsai <wens@csie.org>
Date: Thu, 3 Nov 2016 15:55:46 +0800
Subject: [PATCH] ASoC: sun4i-codec: Increase DMA max burst to 8
According to the DMA engine API documentation, maxburst denotes the
largest possible size of a single transfer, so as not to overflow
destination FIFOs as explained in this excerpt from dmaengine.h
* @src_maxburst: the maximum number of words (note: words, as in
* units of the src_addr_width member, not bytes) that can be sent
* in one burst to the device. Typically something like half the
* FIFO depth on I/O peripherals so you don't overflow it. This
* may or may not be applicable on memory sources.
* @dst_maxburst: same as src_maxburst but for destination target
* mutatis mutandis.
The TX FIFO is 64 samples deep for stereo, and the RX FIFO is 16
samples deep. So maxburst could be 32 and 8 for TX and RX respectively.
Unfortunately the sunxi DMA controller driver takes maxburst as
the requested burst size, rather than a limit, and returns an error
for unsupported values. The original value was 4, but some later
SoCs do not officially support this burst size.
This patch increases maxburst on the TX side to 8, which is supported
by all variants of the sunxi DMA controller.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
sound/soc/sunxi/sun4i-codec.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
index 61ae502a5061..d867b96d367b 100644
--- a/sound/soc/sunxi/sun4i-codec.c
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -886,12 +886,12 @@ static int sun4i_codec_probe(struct platform_device *pdev)
/* DMA configuration for TX FIFO */
scodec->playback_dma_data.addr = res->start + quirks->reg_dac_txdata;
- scodec->playback_dma_data.maxburst = 4;
+ scodec->playback_dma_data.maxburst = 8;
scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
/* DMA configuration for RX FIFO */
scodec->capture_dma_data.addr = res->start + quirks->reg_adc_rxdata;
- scodec->capture_dma_data.maxburst = 4;
+ scodec->capture_dma_data.maxburst = 8;
scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
ret = snd_soc_register_codec(&pdev->dev, quirks->codec,
--
2.10.1
^ permalink raw reply related
* Applied "ASoC: sun4i-codec: Expand quirks to handle register offsets and card creation" to the asoc tree
From: Mark Brown @ 2016-11-03 20:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161103075556.29018-3-wens@csie.org>
The patch
ASoC: sun4i-codec: Expand quirks to handle register offsets and card creation
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From bc03f0d576000739694ed95e89c71cda78964224 Mon Sep 17 00:00:00 2001
From: Chen-Yu Tsai <wens@csie.org>
Date: Thu, 3 Nov 2016 15:55:44 +0800
Subject: [PATCH] ASoC: sun4i-codec: Expand quirks to handle register offsets
and card creation
The A31 has a similar codec to the A10/A20. The PCM parts are very
similar, with just different register offsets. The analog paths are
very different. There are more inputs and outputs.
The A31s, A23, and H3 have a similar PCM interface, again with register
offsets slightly rearranged. The analog path controls, while very
similar between them and the A31, have been moved a separate bus which
is accessed through a message box like interface in the PRCM address
range. This would be handled by a separate auxiliary device tied in
through the device tree in its supporting create_card function.
The quirks structure is expanded to include different register offsets
and separate callbacks for creating the ASoC card. The regmap_config,
quirks, and of_device_match tables have been moved to facilitate this.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
sound/soc/sunxi/sun4i-codec.c | 87 +++++++++++++++++++++++++++++--------------
1 file changed, 60 insertions(+), 27 deletions(-)
diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
index 5ff071fd4996..61ae502a5061 100644
--- a/sound/soc/sunxi/sun4i-codec.c
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -3,6 +3,7 @@
* Copyright 2014 Jon Smirl <jonsmirl@gmail.com>
* Copyright 2015 Maxime Ripard <maxime.ripard@free-electrons.com>
* Copyright 2015 Adam Sampson <ats@offog.org>
+ * Copyright 2016 Chen-Yu Tsai <wens@csie.org>
*
* Based on the Allwinner SDK driver, released under the GPL.
*
@@ -24,8 +25,9 @@
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/of.h>
-#include <linux/of_platform.h>
#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
#include <linux/clk.h>
#include <linux/regmap.h>
#include <linux/gpio/consumer.h>
@@ -114,6 +116,9 @@ struct sun4i_codec {
struct clk *clk_module;
struct gpio_desc *gpio_pa;
+ /* ADC_FIFOC register is at different offset on different SoCs */
+ struct regmap_field *reg_adc_fifoc;
+
struct snd_dmaengine_dai_dma_data capture_dma_data;
struct snd_dmaengine_dai_dma_data playback_dma_data;
};
@@ -142,16 +147,16 @@ static void sun4i_codec_stop_playback(struct sun4i_codec *scodec)
static void sun4i_codec_start_capture(struct sun4i_codec *scodec)
{
/* Enable ADC DRQ */
- regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
- BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN),
- BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN));
+ regmap_field_update_bits(scodec->reg_adc_fifoc,
+ BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN),
+ BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN));
}
static void sun4i_codec_stop_capture(struct sun4i_codec *scodec)
{
/* Disable ADC DRQ */
- regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
- BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN), 0);
+ regmap_field_update_bits(scodec->reg_adc_fifoc,
+ BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN), 0);
}
static int sun4i_codec_trigger(struct snd_pcm_substream *substream, int cmd,
@@ -194,15 +199,15 @@ static int sun4i_codec_prepare_capture(struct snd_pcm_substream *substream,
/* Flush RX FIFO */
- regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
- BIT(SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH),
- BIT(SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH));
+ regmap_field_update_bits(scodec->reg_adc_fifoc,
+ BIT(SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH),
+ BIT(SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH));
/* Set RX FIFO trigger level */
- regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
- 0xf << SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL,
- 0x7 << SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL);
+ regmap_field_update_bits(scodec->reg_adc_fifoc,
+ 0xf << SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL,
+ 0x7 << SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL);
/*
* FIXME: Undocumented in the datasheet, but
@@ -221,9 +226,9 @@ static int sun4i_codec_prepare_capture(struct snd_pcm_substream *substream,
0x1 << 8);
/* Fill most significant bits with valid data MSB */
- regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
- BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE),
- BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE));
+ regmap_field_update_bits(scodec->reg_adc_fifoc,
+ BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE),
+ BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE));
return 0;
}
@@ -350,18 +355,19 @@ static int sun4i_codec_hw_params_capture(struct sun4i_codec *scodec,
unsigned int hwrate)
{
/* Set ADC sample rate */
- regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
- 7 << SUN4I_CODEC_ADC_FIFOC_ADC_FS,
- hwrate << SUN4I_CODEC_ADC_FIFOC_ADC_FS);
+ regmap_field_update_bits(scodec->reg_adc_fifoc,
+ 7 << SUN4I_CODEC_ADC_FIFOC_ADC_FS,
+ hwrate << SUN4I_CODEC_ADC_FIFOC_ADC_FS);
/* Set the number of channels we want to use */
if (params_channels(params) == 1)
- regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
- BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN),
- BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN));
+ regmap_field_update_bits(scodec->reg_adc_fifoc,
+ BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN),
+ BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN));
else
- regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
- BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN), 0);
+ regmap_field_update_bits(scodec->reg_adc_fifoc,
+ BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN),
+ 0);
return 0;
}
@@ -766,14 +772,29 @@ static const struct regmap_config sun7i_codec_regmap_config = {
struct sun4i_codec_quirks {
const struct regmap_config *regmap_config;
+ const struct snd_soc_codec_driver *codec;
+ struct snd_soc_card * (*create_card)(struct device *dev);
+ struct reg_field reg_adc_fifoc; /* used for regmap_field */
+ unsigned int reg_dac_txdata; /* TX FIFO offset for DMA config */
+ unsigned int reg_adc_rxdata; /* RX FIFO offset for DMA config */
};
static const struct sun4i_codec_quirks sun4i_codec_quirks = {
.regmap_config = &sun4i_codec_regmap_config,
+ .codec = &sun4i_codec_codec,
+ .create_card = sun4i_codec_create_card,
+ .reg_adc_fifoc = REG_FIELD(SUN4I_CODEC_ADC_FIFOC, 0, 31),
+ .reg_dac_txdata = SUN4I_CODEC_DAC_TXDATA,
+ .reg_adc_rxdata = SUN4I_CODEC_ADC_RXDATA,
};
static const struct sun4i_codec_quirks sun7i_codec_quirks = {
.regmap_config = &sun7i_codec_regmap_config,
+ .codec = &sun4i_codec_codec,
+ .create_card = sun4i_codec_create_card,
+ .reg_adc_fifoc = REG_FIELD(SUN4I_CODEC_ADC_FIFOC, 0, 31),
+ .reg_dac_txdata = SUN4I_CODEC_DAC_TXDATA,
+ .reg_adc_rxdata = SUN4I_CODEC_ADC_RXDATA,
};
static const struct of_device_id sun4i_codec_of_match[] = {
@@ -846,6 +867,17 @@ static int sun4i_codec_probe(struct platform_device *pdev)
return ret;
}
+ /* reg_field setup */
+ scodec->reg_adc_fifoc = devm_regmap_field_alloc(&pdev->dev,
+ scodec->regmap,
+ quirks->reg_adc_fifoc);
+ if (IS_ERR(scodec->reg_adc_fifoc)) {
+ ret = PTR_ERR(scodec->reg_adc_fifoc);
+ dev_err(&pdev->dev, "Failed to create regmap fields: %d\n",
+ ret);
+ return ret;
+ }
+
/* Enable the bus clock */
if (clk_prepare_enable(scodec->clk_apb)) {
dev_err(&pdev->dev, "Failed to enable the APB clock\n");
@@ -853,16 +885,16 @@ static int sun4i_codec_probe(struct platform_device *pdev)
}
/* DMA configuration for TX FIFO */
- scodec->playback_dma_data.addr = res->start + SUN4I_CODEC_DAC_TXDATA;
+ scodec->playback_dma_data.addr = res->start + quirks->reg_dac_txdata;
scodec->playback_dma_data.maxburst = 4;
scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
/* DMA configuration for RX FIFO */
- scodec->capture_dma_data.addr = res->start + SUN4I_CODEC_ADC_RXDATA;
+ scodec->capture_dma_data.addr = res->start + quirks->reg_adc_rxdata;
scodec->capture_dma_data.maxburst = 4;
scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
- ret = snd_soc_register_codec(&pdev->dev, &sun4i_codec_codec,
+ ret = snd_soc_register_codec(&pdev->dev, quirks->codec,
&sun4i_codec_dai, 1);
if (ret) {
dev_err(&pdev->dev, "Failed to register our codec\n");
@@ -883,7 +915,7 @@ static int sun4i_codec_probe(struct platform_device *pdev)
goto err_unregister_codec;
}
- card = sun4i_codec_create_card(&pdev->dev);
+ card = quirks->create_card(&pdev->dev);
if (IS_ERR(card)) {
ret = PTR_ERR(card);
dev_err(&pdev->dev, "Failed to create our card\n");
@@ -934,4 +966,5 @@ MODULE_DESCRIPTION("Allwinner A10 codec driver");
MODULE_AUTHOR("Emilio L??pez <emilio@elopez.com.ar>");
MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
+MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
MODULE_LICENSE("GPL");
--
2.10.1
^ permalink raw reply related
* Applied "ASoC: sun4i-codec: Revise comments for register definition macros" to the asoc tree
From: Mark Brown @ 2016-11-03 20:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161103075556.29018-4-wens@csie.org>
The patch
ASoC: sun4i-codec: Revise comments for register definition macros
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From bd720ecf4ec6923207b4059ff4b4a43ee25ac891 Mon Sep 17 00:00:00 2001
From: Chen-Yu Tsai <wens@csie.org>
Date: Thu, 3 Nov 2016 15:55:45 +0800
Subject: [PATCH] ASoC: sun4i-codec: Revise comments for register definition
macros
This revises existing comments in the register definition macros
section, and adds a few more, so that readers can clearly identify
the types of control registers.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
sound/soc/sunxi/sun4i-codec.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
index 7b78f4045d38..969d86b4cd44 100644
--- a/sound/soc/sunxi/sun4i-codec.c
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -38,7 +38,7 @@
#include <sound/initval.h>
#include <sound/dmaengine_pcm.h>
-/* Codec DAC register offsets and bit fields */
+/* Codec DAC digital controls and FIFO registers */
#define SUN4I_CODEC_DAC_DPC (0x00)
#define SUN4I_CODEC_DAC_DPC_EN_DA (31)
#define SUN4I_CODEC_DAC_DPC_DVOL (12)
@@ -55,6 +55,8 @@
#define SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH (0)
#define SUN4I_CODEC_DAC_FIFOS (0x08)
#define SUN4I_CODEC_DAC_TXDATA (0x0c)
+
+/* Codec DAC side analog signal controls */
#define SUN4I_CODEC_DAC_ACTL (0x10)
#define SUN4I_CODEC_DAC_ACTL_DACAENR (31)
#define SUN4I_CODEC_DAC_ACTL_DACAENL (30)
@@ -69,7 +71,7 @@
#define SUN4I_CODEC_DAC_TUNE (0x14)
#define SUN4I_CODEC_DAC_DEBUG (0x18)
-/* Codec ADC register offsets and bit fields */
+/* Codec ADC digital controls and FIFO registers */
#define SUN4I_CODEC_ADC_FIFOC (0x1c)
#define SUN4I_CODEC_ADC_FIFOC_ADC_FS (29)
#define SUN4I_CODEC_ADC_FIFOC_EN_AD (28)
@@ -81,6 +83,8 @@
#define SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH (0)
#define SUN4I_CODEC_ADC_FIFOS (0x20)
#define SUN4I_CODEC_ADC_RXDATA (0x24)
+
+/* Codec ADC side analog signal controls */
#define SUN4I_CODEC_ADC_ACTL (0x28)
#define SUN4I_CODEC_ADC_ACTL_ADC_R_EN (31)
#define SUN4I_CODEC_ADC_ACTL_ADC_L_EN (30)
@@ -93,10 +97,14 @@
#define SUN4I_CODEC_ADC_ACTL_DDE (3)
#define SUN4I_CODEC_ADC_DEBUG (0x2c)
-/* Other various ADC registers */
+/* FIFO counters */
#define SUN4I_CODEC_DAC_TXCNT (0x30)
#define SUN4I_CODEC_ADC_RXCNT (0x34)
+
+/* Calibration register (sun7i only) */
#define SUN7I_CODEC_AC_DAC_CAL (0x38)
+
+/* Microphone controls (sun7i only) */
#define SUN7I_CODEC_AC_MIC_PHONE_CAL (0x3c)
struct sun4i_codec {
--
2.10.1
^ permalink raw reply related
* [PATCH] iommu/arm-smmu: Check that iommu_fwspecs are ours
From: Joerg Roedel @ 2016-11-03 20:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <b3680f58498efd0914c5d7887737a7ef9b733982.1478107892.git.robin.murphy@arm.com>
On Wed, Nov 02, 2016 at 05:31:32PM +0000, Robin Murphy wrote:
> We seem to have forgotten to check that iommu_fwspecs actually belong to
> us before we go ahead and dereference their private data. Oops.
>
> Fixes: 021bb8420d44 ("iommu/arm-smmu: Wire up generic configuration support")
> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
> ---
> drivers/iommu/arm-smmu.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)a
Applied to iommu/fixes, thanks.
^ permalink raw reply
* [PATCHv2] PCI: QDF2432 32 bit config space accessors
From: Bjorn Helgaas @ 2016-11-03 20:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <aa8bc916-9363-2de7-2997-4ce470562b2c@codeaurora.org>
On Thu, Nov 03, 2016 at 12:58:10PM -0400, Sinan Kaya wrote:
>
> On 11/3/2016 10:00 AM, Bjorn Helgaas wrote:
> > On Wed, Nov 02, 2016 at 12:36:16PM -0400, Sinan Kaya wrote:
> >> Hi Bjorn,
> >>
> >> On 11/2/2016 12:08 PM, Bjorn Helgaas wrote:
> >>> On Tue, Nov 01, 2016 at 07:06:31AM -0600, cov at codeaurora.org wrote:
> >>>> Hi Bjorn,
> >>>>
> >>>> On 2016-10-31 15:48, Bjorn Helgaas wrote:
> >>>>> On Wed, Sep 21, 2016 at 06:38:05PM -0400, Christopher Covington wrote:
> >>>>>> The Qualcomm Technologies QDF2432 SoC does not support accesses
> >>>>>> smaller
> >>>>>> than 32 bits to the PCI configuration space. Register the appropriate
> >>>>>> quirk.
> >>>>>>
> >>>>>> Signed-off-by: Christopher Covington <cov@codeaurora.org>
> >>>>>
> >>>>> Hi Christopher,
> >>>>>
> >>>>> Can you rebase this against v4.9-rc1? It no longer applies to my tree.
> >>>>
> >>>> I apologize for not being clearer. This patch depends on:
> >>>>
> >>>> PCI/ACPI: Extend pci_mcfg_lookup() responsibilities
> >>>> PCI/ACPI: Check platform-specific ECAM quirks
> >>>>
> >>>> These patches from Tomasz Nowicki were previously in your pci/ecam-v6
> >>>> branch, but that seems to have come and gone. How would you like to
> >>>> proceed?
> >>>
> >>> Oh yes, that's right, I forgot that connection. I'm afraid I kind of
> >>> dropped the ball on that thread, so I went back and read through it
> >>> again.
> >>>
> >>> I *think* the current state is:
> >>>
> >>> - I'm OK with the first two patches that add the quirk
> >>> infrastructure.
> >>>
> >>> - My issue with the last three patches that add ThunderX quirks is
> >>> that there's no generic description of the ECAM address space.
> >>>
> >>> So if I understand correctly, your Qualcomm patch depends only on the
> >>> first two patches.
> >>>
> >>> Then the question is how the Qualcomm ECAM address space is described.
> >>> Your quirk overrides the default pci_generic_ecam_ops with the
> >>> &pci_32b_ops, but it doesn't touch the address space part, so I assume
> >>> the bus ranges and corresponding address space in your MCFG is
> >>> correct. So far, so good.
> >>
> >> Qualcomm ECAM space includes both the root port and the endpoint address
> >> space with a single contiguous 256 MB address space described in MCFG table.
> >> There is no need to describe additional resources like PNP0C02.
> >
> > This is the crucial point I have failed to communicate clearly: the
> > PNP0C02 resource is *always* required, even if the MCFG is correct.
> >
>
> Interesting...
>
> It looks like there is a lot of lessons learnt here from history.
>
> I think this requirement is only true if your system DDR space and PCIe
> space overlaps in the memory map. I understand that Intel systems allow
> sharing of these two memory ranges. An OS could potentially reclaim this
> address range.
>
> If there is no overlap and PCI is not enabled, there can't be any SW entity
> to reclaim this space.
No, this isn't really anything to do with DDR/PCIe overlaps. This is
just a fundamental part of the ACPI model: the firmware should
communicate all address space usage to the OS either via ACPI or via
standard self-describing mechanisms like PCI BARs.
You can argue that this isn't "necessary", but that's an assumption
based on your knowledge of this particular system, and we don't want
the OS to have to make that assumption. For example, ACPI allows the
hot-addition of new ACPI devices, and we may have to assign address
space for them, and we don't want to collide with existing devices.
Bjorn
^ permalink raw reply
* [PATCH] iommu: arm-smmu: Set SMTNMB_TLBEN in ACR to enable caching of bypass entries
From: Stuart Yoder @ 2016-11-03 20:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478219244-7815-1-git-send-email-nipun.gupta@nxp.com>
> -----Original Message-----
> From: Nipun Gupta [mailto:nipun.gupta at nxp.com]
> Sent: Thursday, November 03, 2016 7:27 PM
> To: robin.murphy at arm.com; will.deacon at arm.com; linux-arm-kernel at lists.infradead.org; iommu at lists.linux-
> foundation.org
> Cc: Stuart Yoder <stuart.yoder@nxp.com>; Nipun Gupta <nipun.gupta@nxp.com>
> Subject: [PATCH] iommu: arm-smmu: Set SMTNMB_TLBEN in ACR to enable caching of bypass entries
When you respin a patch, put the version number in the patch subject:
[PATCH v2] iommu: arm-smmu: Set SMTNMB_TLBEN in ACR to enable caching of bypass entries
Stuart
^ permalink raw reply
* [PATCHv2] ARM: OMAP3: Fix formatting of features printed
From: Sebastian Reichel @ 2016-11-03 21:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161103173439.20657-1-tony@atomide.com>
Hi,
On Thu, Nov 03, 2016 at 10:34:39AM -0700, Tony Lindgren wrote:
> With the printk cleanups merged into v4.9-rc1, we now get the omap
> revision printed on multiple lines. Let's fix that and also remove the
> extra empty space at the end of the features. And let's update things
> to use scnprintf as suggested by Ivaylo Dimitrov
> <ivo.g.dimitrov.75@gmail.com>.
>
> Reported-by: Adam Ford <aford173@gmail.com>
> Cc: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
> Signed-off-by: Tony Lindgren <tony@atomide.com>
> ---
> arch/arm/mach-omap2/id.c | 16 +++++++++++-----
> 1 file changed, 11 insertions(+), 5 deletions(-)
Reviewed-By: Sebastian Reichel <sre@kernel.org>
-- Sebastian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161103/cb911b5c/attachment.sig>
^ permalink raw reply
* [PATCH 0/5] drm/sun4i: Handle TV overscan
From: Sean Paul @ 2016-11-03 21:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161103090106.dq2bn4z7m2hzhi53@lukather>
On Thu, Nov 3, 2016 at 3:01 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Hi Russell,
>
> On Mon, Oct 31, 2016 at 08:42:34AM +0000, Russell King - ARM Linux wrote:
>> On Tue, Oct 18, 2016 at 12:03:49PM +0200, Maxime Ripard wrote:
>> > The first one is that this overscanning should be reported by the
>> > connector I guess? but this is really TV specific, so we need one way
>> > to let the user tell how the image is displayed on its side, and we
>> > cannot really autodetect it, and this needs to be done at runtime so
>> > that we can present some shiny interface to let it select which
>> > overscan ratio works for him/her.
>>
>> See xbmc... they go through a nice shiny setup which includes adjusting
>> the visible area. From what I remember, it has pointers on each corner
>> which you can adjust to be just visible on the screen, so xbmc knows
>> how much overscan there is, and xbmc itself reduces down to the user
>> set size.
>
> Yes. And that is an XBMC only solution, that doesn't work with the
> fbdev emulation and is probably doing an additional composition to
> scale down and center their frames through OpenGL.
>
> We might not have a GPU in the system, and we might not even have an
> entire graphic stack on top either, so I don't think fixing at the
> user-space level is a good option (especially since we already have an
> overscan property in DRM).
>
Hi Maxime,
I took a quick look at the first 2 patches in the series and they look
good at first glance. I have them in my queue to review more
carefully.
Can you explain why you can't fix this by specifying a new mode with
big porches (as Russell suggested)?
Sean
>> > The second one is that we still need to expose the reduced modes to
>> > userspace, and not only the displayed size, so that the applications
>> > know what they must draw on. But I guess this could be adjusted by the
>> > core too.
>> >
>> > In order to work consistently, I think all planes should be adjusted
>> > that way, so that relative coordinates are from the primary plane
>> > origin, and not the display origin. But that could be adjusted too by
>> > the core I guess.
>>
>> I'm not sure about that - we want the graphics to be visible, but that
>> may not be appropriate for an video overlay frame. It's quite common
>> for (eg) broadcast video to contain dead pixels or other artifacts on
>> the right hand side, and the broadcast video expects overscan to be
>> present.
>>
>> I know this because I have run my TV with overscan disabled, even for
>> broadcast TV.
>
> I know, but on this particular hardware, composite really is just
> another video output. There's not even a TV receiver in it, so I don't
> think we have to worry about it.
>
>> > The fourth one being the major one. Every time I raised the issue on
>> > IRC, the answer basically was "we don't care about analog", so I'm a
>> > bit pessimistic about whether dealing with this in the core would be
>> > accepted, hence why I chose to deal with this at the driver level.
>>
>> Yea, that's quite sad, "analog" has become a dirty word, but really
>> this has nothing to do with "analog" at all - there are LCD TVs (and
>> some monitors) out there which take HDMI signals but refuse to
>> disable overscan no matter what you do to them if you provide them
>> with a "broadcast" mode - so the analog excuse is very poor.
>
> I'd agree with you, but I was also told to not turn that into a
> generic code and deal with that in my driver.
>
> Do you have any suggestions?
>
> Thanks,
> Maxime
>
> --
> Maxime Ripard, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com
^ permalink raw reply
* [RFC PATCH 00/10] ARM: dts: exynos: Fix invalid GIC interrupt flags
From: Krzysztof Kozlowski @ 2016-11-03 21:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1474054971-16831-1-git-send-email-krzk@kernel.org>
On Fri, Sep 16, 2016 at 09:42:41PM +0200, Krzysztof Kozlowski wrote:
> Hi,
>
> Marek (internally), Geert and Alban reported errors like:
> genirq: Setting trigger mode 0 for irq 16 failed (gic_set_type+0x0/0x68)
> The patchset fixes this issue.
>
> Tested on:
> 1. Exynos4412: Odroid U3,
> 2. Exynos5410: Odroid XU,
> 3. Exynos5422: Odroid XU3.
>
> Other platforms not tested so testing would be highly appreciated.
Applied entire patchset for v4.10. Let it boil for some time in
linux-next.
Best regards,
Krzysztof
^ permalink raw reply
* [PATCH v10 03/11] remoteproc: Update Kconfig setup to 'depends on REMOTEPROC'
From: Bjorn Andersson @ 2016-11-03 21:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475931154-1021-4-git-send-email-peter.griffin@linaro.org>
On Sat 08 Oct 05:52 PDT 2016, Peter Griffin wrote:
> Make REMOTEPROC core a selectable kconfig option, and update
> remoteproc client drivers to 'depends on' the core. This avoids
> some nasty Kconfig recursive dependency issues. Also when using
> menuconfig client drivers will be hidden until the core has been
> enabled.
>
> Documentation/kbuild/kconfig-language.txt:
>
> Note:
> select should be used with care. select will force
> a symbol to a value without visiting the dependencies.
> By abusing select you are able to select a symbol FOO even
> if FOO depends on BAR that is not set.
> In general use select only for non-visible symbols
> (no prompts anywhere) and for symbols with no dependencies.
> That will limit the usefulness but on the other hand avoid
> the illegal configurations all over.
>
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
Sorry, I missed this patch in the set - but spotted it in linux-next.
I still don't like the change, but remoteproc has dependencies so I
guess I have to pick it until we fix that.
It's however not okay to take this patch through the DMA tree, as it
effectively stops me from introducing any changes in the rproc tree.
Further more, it's not based on v4.9, so it currently introduces another
Kconfig dependency problem - that I can't fix in my tree without
conflicting with Vinod's.
So, Vinod, can you please drop this patch from your tree? I'll pick it
up for now.
Regards,
Bjorn
> ---
> drivers/remoteproc/Kconfig | 21 ++++++++++++---------
> 1 file changed, 12 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
> index a7bedc6..decdcbe 100644
> --- a/drivers/remoteproc/Kconfig
> +++ b/drivers/remoteproc/Kconfig
> @@ -1,20 +1,21 @@
> menu "Remoteproc drivers"
>
> -# REMOTEPROC gets selected by whoever wants it
> config REMOTEPROC
> - tristate
> + tristate "Support for Remote Processor subsystem"
> depends on HAS_DMA
> select CRC32
> select FW_LOADER
> select VIRTIO
> select VIRTUALIZATION
>
> +if REMOTEPROC
> +
> config OMAP_REMOTEPROC
> tristate "OMAP remoteproc support"
> depends on HAS_DMA
> depends on ARCH_OMAP4 || SOC_OMAP5
> depends on OMAP_IOMMU
> - select REMOTEPROC
> + depends on REMOTEPROC
> select MAILBOX
> select OMAP2PLUS_MBOX
> select RPMSG
> @@ -34,7 +35,7 @@ config OMAP_REMOTEPROC
> config STE_MODEM_RPROC
> tristate "STE-Modem remoteproc support"
> depends on HAS_DMA
> - select REMOTEPROC
> + depends on REMOTEPROC
> default n
> help
> Say y or m here to support STE-Modem shared memory driver.
> @@ -44,7 +45,7 @@ config STE_MODEM_RPROC
> config WKUP_M3_RPROC
> tristate "AMx3xx Wakeup M3 remoteproc support"
> depends on SOC_AM33XX || SOC_AM43XX
> - select REMOTEPROC
> + depends on REMOTEPROC
> help
> Say y here to support Wakeup M3 remote processor on TI AM33xx
> and AM43xx family of SoCs.
> @@ -57,8 +58,8 @@ config WKUP_M3_RPROC
> config DA8XX_REMOTEPROC
> tristate "DA8xx/OMAP-L13x remoteproc support"
> depends on ARCH_DAVINCI_DA8XX
> + depends on REMOTEPROC
> select CMA if MMU
> - select REMOTEPROC
> select RPMSG
> help
> Say y here to support DA8xx/OMAP-L13x remote processors via the
> @@ -84,9 +85,9 @@ config QCOM_Q6V5_PIL
> tristate "Qualcomm Hexagon V5 Peripherial Image Loader"
> depends on OF && ARCH_QCOM
> depends on QCOM_SMEM
> + depends on REMOTEPROC
> select MFD_SYSCON
> select QCOM_MDT_LOADER
> - select REMOTEPROC
> help
> Say y here to support the Qualcomm Peripherial Image Loader for the
> Hexagon V5 based remote processors.
> @@ -94,7 +95,7 @@ config QCOM_Q6V5_PIL
> config ST_REMOTEPROC
> tristate "ST remoteproc support"
> depends on ARCH_STI
> - select REMOTEPROC
> + depends on REMOTEPROC
> help
> Say y here to support ST's adjunct processors via the remote
> processor framework.
> @@ -102,6 +103,8 @@ config ST_REMOTEPROC
>
> config ST_SLIM_REMOTEPROC
> tristate
> - select REMOTEPROC
> + depends on REMOTEPROC
> +
> +endif # REMOTEPROC
>
> endmenu
> --
> 1.9.1
>
^ permalink raw reply
* [RFC] fpga mgr: Introduce FPGA capabilities
From: Moritz Fischer @ 2016-11-03 21:27 UTC (permalink / raw)
To: linux-arm-kernel
Add FPGA capabilities as a way to express the capabilities
of a given FPGA manager.
Removes code duplication by comparing the low-level driver's
capabilities at the framework level rather than having each driver
check for supported operations in the write_init() callback.
This allows for extending with additional capabilities, similar
to the the dmaengine framework's implementation.
Signed-off-by: Moritz Fischer <moritz.fischer@ettus.com>
Cc: Alan Tull <atull@opensource.altera.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: S?ren Brinkmann <soren.brinkmann@xilinx.com>
Cc: linux-kernel at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
---
Hi all,
this is another RFC (this one is against mainline) implementing
fpga capabilities to centralize the checks for different operations.
If we agree this is the way forward, I'll rebase it on top of Alan's
series once that went in (and add potential drivers we added by then.
Cheers,
Moritz
PS: I'm not sure if the checkpatch warning is a false positive ...
---
drivers/fpga/fpga-mgr.c | 14 +++++++++++++
drivers/fpga/socfpga.c | 10 +++++-----
drivers/fpga/zynq-fpga.c | 7 ++++++-
include/linux/fpga/fpga-mgr.h | 46 ++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 70 insertions(+), 7 deletions(-)
diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c
index 953dc91..21c508a 100644
--- a/drivers/fpga/fpga-mgr.c
+++ b/drivers/fpga/fpga-mgr.c
@@ -49,6 +49,18 @@ int fpga_mgr_buf_load(struct fpga_manager *mgr, u32 flags, const char *buf,
struct device *dev = &mgr->dev;
int ret;
+ if (flags & FPGA_MGR_PARTIAL_RECONFIG &&
+ !fpga_mgr_has_cap(FPGA_MGR_CAP_PARTIAL_RECONF, mgr->caps)) {
+ dev_err(dev, "Partial reconfiguration not supported\n");
+ return -ENOTSUPP;
+ }
+
+ if (flags & FPGA_MGR_FULL_RECONFIG &&
+ !fpga_mgr_has_cap(FPGA_MGR_CAP_FULL_RECONF, mgr->caps)) {
+ dev_err(dev, "Full reconfiguration not supported\n");
+ return -ENOTSUPP;
+ }
+
/*
* Call the low level driver's write_init function. This will do the
* device-specific things to get the FPGA into the state where it is
@@ -245,12 +257,14 @@ EXPORT_SYMBOL_GPL(fpga_mgr_put);
* @dev: fpga manager device from pdev
* @name: fpga manager name
* @mops: pointer to structure of fpga manager ops
+ * @caps: fpga manager capabilites
* @priv: fpga manager private data
*
* Return: 0 on success, negative error code otherwise.
*/
int fpga_mgr_register(struct device *dev, const char *name,
const struct fpga_manager_ops *mops,
+ fpga_mgr_cap_mask_t caps,
void *priv)
{
struct fpga_manager *mgr;
diff --git a/drivers/fpga/socfpga.c b/drivers/fpga/socfpga.c
index 27d2ff2..fd9760c 100644
--- a/drivers/fpga/socfpga.c
+++ b/drivers/fpga/socfpga.c
@@ -413,10 +413,6 @@ static int socfpga_fpga_ops_configure_init(struct fpga_manager *mgr, u32 flags,
struct socfpga_fpga_priv *priv = mgr->priv;
int ret;
- if (flags & FPGA_MGR_PARTIAL_RECONFIG) {
- dev_err(&mgr->dev, "Partial reconfiguration not supported.\n");
- return -EINVAL;
- }
/* Steps 1 - 5: Reset the FPGA */
ret = socfpga_fpga_reset(mgr);
if (ret)
@@ -555,6 +551,7 @@ static int socfpga_fpga_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct socfpga_fpga_priv *priv;
struct resource *res;
+ fpga_mgr_cap_mask_t caps;
int ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -580,8 +577,11 @@ static int socfpga_fpga_probe(struct platform_device *pdev)
if (ret)
return ret;
+ fpga_mgr_cap_zero(&caps);
+ fpga_mgr_cap_set(FPGA_MGR_CAP_FULL_RECONF, caps);
+
return fpga_mgr_register(dev, "Altera SOCFPGA FPGA Manager",
- &socfpga_fpga_ops, priv);
+ &socfpga_fpga_ops, caps, priv);
}
static int socfpga_fpga_remove(struct platform_device *pdev)
diff --git a/drivers/fpga/zynq-fpga.c b/drivers/fpga/zynq-fpga.c
index c2fb412..1d37ff0 100644
--- a/drivers/fpga/zynq-fpga.c
+++ b/drivers/fpga/zynq-fpga.c
@@ -410,6 +410,7 @@ static int zynq_fpga_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct zynq_fpga_priv *priv;
struct resource *res;
+ fpga_mgr_cap_mask_t caps;
int err;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -461,9 +462,13 @@ static int zynq_fpga_probe(struct platform_device *pdev)
zynq_fpga_write(priv, UNLOCK_OFFSET, UNLOCK_MASK);
clk_disable(priv->clk);
+ fpga_mgr_cap_zero(&caps);
+ fpga_mgr_cap_set(FPGA_MGR_CAP_FULL_RECONF, caps);
+ fpga_mgr_cap_set(FPGA_MGR_CAP_PARTIAL_RECONF, caps);
+
err = fpga_mgr_register(dev, "Xilinx Zynq FPGA Manager",
- &zynq_fpga_ops, priv);
+ &zynq_fpga_ops, caps, priv);
if (err) {
dev_err(dev, "unable to register FPGA manager");
clk_unprepare(priv->clk);
diff --git a/include/linux/fpga/fpga-mgr.h b/include/linux/fpga/fpga-mgr.h
index 0940bf4..a0bf750 100644
--- a/include/linux/fpga/fpga-mgr.h
+++ b/include/linux/fpga/fpga-mgr.h
@@ -67,6 +67,47 @@ enum fpga_mgr_states {
* FPGA_MGR_PARTIAL_RECONFIG: do partial reconfiguration if supported
*/
#define FPGA_MGR_PARTIAL_RECONFIG BIT(0)
+#define FPGA_MGR_FULL_RECONFIG BIT(1)
+
+enum fpga_manager_capability {
+ FPGA_MGR_CAP_PARTIAL_RECONF,
+ FPGA_MGR_CAP_FULL_RECONF,
+
+/* last capability type for creation of the capabilities mask */
+ FPGA_MGR_CAP_END,
+};
+
+typedef struct { DECLARE_BITMAP(bits, FPGA_MGR_CAP_END); } fpga_mgr_cap_mask_t;
+
+#define fpga_mgr_has_cap(cap, mask) __fpga_mgr_has_cap((cap), &(mask))
+static inline int __fpga_mgr_has_cap(enum fpga_manager_capability cap,
+ fpga_mgr_cap_mask_t *mask)
+{
+ return test_bit(cap, mask->bits);
+}
+
+#define fpga_mgr_cap_zero(mask) __fpga_mgr_cap_zero(mask)
+static inline void __fpga_mgr_cap_zero(fpga_mgr_cap_mask_t *mask)
+{
+ bitmap_zero(mask->bits, FPGA_MGR_CAP_END);
+}
+
+#define fpga_mgr_cap_clear(cap, mask) __fpga_mgr_cap_clear((cap), &(mask))
+static inline void __fpga_mgr_cap_clear(enum fpga_manager_capability cap,
+ fpga_mgr_cap_mask_t *mask)
+
+{
+ clear_bit(cap, mask->bits);
+}
+
+#define fpga_mgr_cap_set(cap, mask) __fpga_mgr_cap_set((cap), &(mask))
+static inline void __fpga_mgr_cap_set(enum fpga_manager_capability cap,
+ fpga_mgr_cap_mask_t *mask)
+
+{
+ set_bit(cap, mask->bits);
+}
+
/**
* struct fpga_manager_ops - ops for low level fpga manager drivers
@@ -105,6 +146,7 @@ struct fpga_manager {
enum fpga_mgr_states state;
const struct fpga_manager_ops *mops;
void *priv;
+ fpga_mgr_cap_mask_t caps;
};
#define to_fpga_manager(d) container_of(d, struct fpga_manager, dev)
@@ -120,7 +162,9 @@ struct fpga_manager *of_fpga_mgr_get(struct device_node *node);
void fpga_mgr_put(struct fpga_manager *mgr);
int fpga_mgr_register(struct device *dev, const char *name,
- const struct fpga_manager_ops *mops, void *priv);
+ const struct fpga_manager_ops *mops,
+ fpga_mgr_cap_mask_t caps,
+ void *priv);
void fpga_mgr_unregister(struct device *dev);
--
2.10.0
^ permalink raw reply related
* [PATCH v10 01/11] remoteproc: st_slim_rproc: add a slimcore rproc driver
From: Bjorn Andersson @ 2016-11-03 21:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1476783556-2501-2-git-send-email-peter.griffin@linaro.org>
On Tue 18 Oct 02:39 PDT 2016, Peter Griffin wrote:
> slim core is used as a basis for many IPs in the STi
> chipsets such as fdma and demux. To avoid duplicating
> the elf loading code in each device driver a slim
> rproc driver has been created.
>
> This driver is designed to be used by other device drivers
> such as fdma, or demux whose IP is based around a slim core.
> The device driver can call slim_rproc_alloc() to allocate
> a slim rproc and slim_rproc_put() when finished.
>
> This driver takes care of ioremapping the slim
> registers (dmem, imem, slimcore, peripherals), whose offsets
> and sizes can change between IP's. It also obtains and enables
> any clocks used by the device. This approach avoids having
> a double mapping of the registers as slim_rproc does not register
> its own platform device. It also maps well to device tree
> abstraction as it allows us to have one dt node for the whole
> device.
>
> All of the generic rproc elf loading code can be reused, and
> we provide start() stop() hooks to start and stop the slim
> core once the firmware has been loaded. This has been tested
> successfully with fdma driver.
>
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> ---
> drivers/remoteproc/Kconfig | 7 +-
> drivers/remoteproc/Makefile | 1 +
> drivers/remoteproc/st_slim_rproc.c | 364 +++++++++++++++++++++++++++++++
> include/linux/remoteproc/st_slim_rproc.h | 58 +++++
> 4 files changed, 428 insertions(+), 2 deletions(-)
> create mode 100644 drivers/remoteproc/st_slim_rproc.c
> create mode 100644 include/linux/remoteproc/st_slim_rproc.h
>
> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
> index f396bfe..9270c8e 100644
> --- a/drivers/remoteproc/Kconfig
> +++ b/drivers/remoteproc/Kconfig
> @@ -58,7 +58,6 @@ config DA8XX_REMOTEPROC
> tristate "DA8xx/OMAP-L13x remoteproc support"
> depends on ARCH_DAVINCI_DA8XX
> select CMA if MMU
> - select REMOTEPROC
No, this is an unrelated change to this patch.
> select RPMSG_VIRTIO
> help
> Say y here to support DA8xx/OMAP-L13x remote processors via the
> @@ -99,10 +98,10 @@ config QCOM_WCNSS_PIL
> tristate "Qualcomm WCNSS Peripheral Image Loader"
> depends on OF && ARCH_QCOM
> depends on QCOM_SMEM
> + depends on REMOTEPROC
> select QCOM_MDT_LOADER
> select QCOM_SCM
> select QCOM_WCNSS_IRIS
> - select REMOTEPROC
Dito.
As you now make changes to the entire remoteproc Kconfig file, rather
than simply add a Kconfig symbol we can't bring this in via Vinod's tree
without providing Linus with a messy merge conflict.
So the remoteproc parts now has to go through my tree.
> help
> Say y here to support the Peripheral Image Loader for the Qualcomm
> Wireless Connectivity Subsystem.
> @@ -116,4 +115,8 @@ config ST_REMOTEPROC
> processor framework.
> This can be either built-in or a loadable module.
>
> +config ST_SLIM_REMOTEPROC
> + tristate
> + select REMOTEPROC
> +
> endmenu
[..]
> diff --git a/drivers/remoteproc/st_slim_rproc.c b/drivers/remoteproc/st_slim_rproc.c
[..]
> +struct st_slim_rproc *st_slim_rproc_alloc(struct platform_device *pdev,
> + char *fw_name)
> +{
[..]
> + rproc = rproc_alloc(dev, np->name, &slim_rproc_ops,
> + fw_name, sizeof(*slim_rproc));
[..]
> + rproc_put(rproc);
As of v4.9 you need to rproc_free() rather than rproc_put() to undo
rproc_alloc().
Regards,
Bjorn
^ permalink raw reply
* [RFC 0/8] KVM PCIe/MSI passthrough on ARM/ARM64 (Alt II)
From: Eric Auger @ 2016-11-03 21:39 UTC (permalink / raw)
To: linux-arm-kernel
Following Will & Robin's suggestions, this series attempts to propose
an alternative to [1] where the host would arbitrarily decide the
location of the IOVA MSI window and would be able to report to the
userspace the list of reserved IOVA regions that cannot be used
along with VFIO_IOMMU_MAP_DMA. This would allow the userspace to react
in case of conflict.
Userspace can retrieve all the reserved regions through the VFIO_IOMMU_GET_INFO
IOCTL by querying the new RESV_IOVA_RANGE chained capability. Each reserved
IOVA range is put in a separate capability.
At IOMMU level, the reserved regions are stored in an iommu_domain list
which is populated on each device attachment. An IOMMU add_reserved_regions
callback specializes the registration of the reserved regions.
On x86, the [FEE0_0000h - FEF0_000h] MSI window is registered (NOT tested).
On ARM, the PCI host bridge windows (ACS check to be added?) + the MSI IOVA
reserved regions are populated by the arm-smmu driver. Currently the MSI
IOVA region is arbitrarily located at 0x8000000 and 1MB sized. An IOVA domain
is created in add_reserved_regions callback. Then MSIs are transparently
mapped using this IOVA domain.
This series currently does not address some features addressed in [1]:
- MSI IOVA size requirement computation
- IRQ safety assessment
This RFC was just tested on ARM Overdrive with QEMU and is sent to help
potential discussions at LPC. Additionnal development + testing is needed.
2 tentative fixes may be submitted separately:
- vfio: fix vfio_info_cap_add/shift
- iommu/iova: fix __alloc_and_insert_iova_range
Best Regards
Eric
[1] [PATCH v14 00/16] KVM PCIe/MSI passthrough on ARM/ARM64
https://lkml.org/lkml/2016/10/12/347
Git: complete series available at
https://github.com/eauger/linux/tree/v4.9-rc3-reserved-rfc
Eric Auger (7):
vfio: fix vfio_info_cap_add/shift
iommu/iova: fix __alloc_and_insert_iova_range
iommu: Add a list of iommu_reserved_region in iommu_domain
vfio/type1: Introduce RESV_IOVA_RANGE capability
iommu: Handle the list of reserved regions
iommu/vt-d: Implement add_reserved_regions callback
iommu/arm-smmu: implement add_reserved_regions callback
Robin Murphy (1):
iommu/dma: Allow MSI-only cookies
drivers/iommu/arm-smmu.c | 63 +++++++++++++++++++++++++++++++++++++++++
drivers/iommu/dma-iommu.c | 39 +++++++++++++++++++++++++
drivers/iommu/intel-iommu.c | 48 ++++++++++++++++++++++---------
drivers/iommu/iommu.c | 25 ++++++++++++++++
drivers/iommu/iova.c | 2 +-
drivers/vfio/vfio.c | 5 ++--
drivers/vfio/vfio_iommu_type1.c | 63 ++++++++++++++++++++++++++++++++++++++++-
include/linux/dma-iommu.h | 9 ++++++
include/linux/iommu.h | 23 +++++++++++++++
include/uapi/linux/vfio.h | 16 ++++++++++-
10 files changed, 275 insertions(+), 18 deletions(-)
--
1.9.1
^ permalink raw reply
* [PATCHv6] support for AD5820 camera auto-focus coil
From: Sakari Ailus @ 2016-11-03 21:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161103102727.GA10084@amd>
On Thu, Nov 03, 2016 at 11:27:27AM +0100, Pavel Machek wrote:
> Hi!
>
> > > > > > Yeah. I just compiled it but haven't tested it. I presume it'll work. :-)
> > > > >
> > > > > I'm testing it on n900. I guess simpler hardware with ad5820 would be better for the
> > > > > test...
> > > > >
> > > > > What hardware do you have?
> > > >
> > > > N900. What else could it be? :-) :-)
> > >
> > > Heh. Basically anything is easier to develop for than n900 :-(.
> >
> > Is it?
> >
> > I actually find the old Nokia devices very practical. It's easy to boot your
> > own kernel and things just work... until musb broke a bit recently. It
> > requires reconnecting the usb cable again to function.
> >
> > I have to admit I mostly use an N9.
>
> Well, if you compare that to development on PC, I prefer PC.
>
> Even arm development boards are usually easier, as they don't need too
> complex userspace, and do have working serial ports.
>
> But I do have a serial adapter for N900 now (thanks, sre), so my main
> problem now is that N900 takes a lot of time to boot into usable
> state.
Yeah... I just upgraded my Debian installation (armel over NFS) a few major
numbers and I find it a lot slower than it used to do. I presume that's
mostly because of systemd...
--
Sakari Ailus
e-mail: sakari.ailus at iki.fi XMPP: sailus at retiisi.org.uk
^ permalink raw reply
* [PATCH 1/3] ARM: dts: rename MSM8660/APQ8060 pmicintc to pm8058
From: Bjorn Andersson @ 2016-11-03 21:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478164390-21613-1-git-send-email-linus.walleij@linaro.org>
On Thu 03 Nov 02:13 PDT 2016, Linus Walleij wrote:
> The name "pmicintc" is ambiguous: there is a second power
> management IC named PM8901 on these systems, and it is also
> an interrupt controller. To make things clear, just name the
> node alias "pm8058", this in unambigous and has all information
> we need.
>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Regards,
Bjorn
> ---
> arch/arm/boot/dts/qcom-apq8060-dragonboard.dts | 2 +-
> arch/arm/boot/dts/qcom-msm8660-surf.dts | 2 +-
> arch/arm/boot/dts/qcom-msm8660.dtsi | 12 ++++++------
> 3 files changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm/boot/dts/qcom-apq8060-dragonboard.dts b/arch/arm/boot/dts/qcom-apq8060-dragonboard.dts
> index 4b8872cc8bf9..4a532ddab53a 100644
> --- a/arch/arm/boot/dts/qcom-apq8060-dragonboard.dts
> +++ b/arch/arm/boot/dts/qcom-apq8060-dragonboard.dts
> @@ -412,7 +412,7 @@
> * The second interrupt is the PME interrupt
> * for network wakeup, connected to the TLMM.
> */
> - interrupts-extended = <&pmicintc 198 IRQ_TYPE_EDGE_FALLING>,
> + interrupts-extended = <&pm8058 198 IRQ_TYPE_EDGE_FALLING>,
> <&tlmm 29 IRQ_TYPE_EDGE_RISING>;
> reset-gpios = <&tlmm 30 GPIO_ACTIVE_LOW>;
> vdd33a-supply = <&dragon_veth>;
> diff --git a/arch/arm/boot/dts/qcom-msm8660-surf.dts b/arch/arm/boot/dts/qcom-msm8660-surf.dts
> index 23de764558ab..1adc04978a47 100644
> --- a/arch/arm/boot/dts/qcom-msm8660-surf.dts
> +++ b/arch/arm/boot/dts/qcom-msm8660-surf.dts
> @@ -48,7 +48,7 @@
> };
> };
>
> -&pmicintc {
> +&pm8058 {
> keypad at 148 {
> linux,keymap = <
> MATRIX_KEY(0, 0, KEY_FN_F1)
> diff --git a/arch/arm/boot/dts/qcom-msm8660.dtsi b/arch/arm/boot/dts/qcom-msm8660.dtsi
> index 4d828f810746..91c9a62ae725 100644
> --- a/arch/arm/boot/dts/qcom-msm8660.dtsi
> +++ b/arch/arm/boot/dts/qcom-msm8660.dtsi
> @@ -163,7 +163,7 @@
> reg = <0x500000 0x1000>;
> qcom,controller-type = "pmic-arbiter";
>
> - pmicintc: pmic at 0 {
> + pm8058: pmic at 0 {
> compatible = "qcom,pm8058";
> interrupt-parent = <&tlmm>;
> interrupts = <88 8>;
> @@ -176,7 +176,7 @@
> compatible = "qcom,pm8058-gpio",
> "qcom,ssbi-gpio";
> reg = <0x150>;
> - interrupt-parent = <&pmicintc>;
> + interrupt-parent = <&pm8058>;
> interrupts = <192 IRQ_TYPE_NONE>,
> <193 IRQ_TYPE_NONE>,
> <194 IRQ_TYPE_NONE>,
> @@ -232,7 +232,7 @@
> reg = <0x50>;
> gpio-controller;
> #gpio-cells = <2>;
> - interrupt-parent = <&pmicintc>;
> + interrupt-parent = <&pm8058>;
> interrupts =
> <128 IRQ_TYPE_NONE>,
> <129 IRQ_TYPE_NONE>,
> @@ -251,7 +251,7 @@
> pwrkey at 1c {
> compatible = "qcom,pm8058-pwrkey";
> reg = <0x1c>;
> - interrupt-parent = <&pmicintc>;
> + interrupt-parent = <&pm8058>;
> interrupts = <50 1>, <51 1>;
> debounce = <15625>;
> pull-up;
> @@ -260,7 +260,7 @@
> keypad at 148 {
> compatible = "qcom,pm8058-keypad";
> reg = <0x148>;
> - interrupt-parent = <&pmicintc>;
> + interrupt-parent = <&pm8058>;
> interrupts = <74 1>, <75 1>;
> debounce = <15>;
> scan-delay = <32>;
> @@ -270,7 +270,7 @@
> rtc at 1e8 {
> compatible = "qcom,pm8058-rtc";
> reg = <0x1e8>;
> - interrupt-parent = <&pmicintc>;
> + interrupt-parent = <&pm8058>;
> interrupts = <39 1>;
> allow-set-time;
> };
> --
> 2.7.4
>
^ permalink raw reply
* [PATCH 2/3] ARM: dts: reference PM8058 as IRQ parent
From: Bjorn Andersson @ 2016-11-03 21:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478164390-21613-2-git-send-email-linus.walleij@linaro.org>
On Thu 03 Nov 02:13 PDT 2016, Linus Walleij wrote:
> Some nodes are referencing the pm8058_gpio as IRQ parent, but
> the HW IRQ offset they are supplying is actually that for the
> parent to that controller: the PM8058 itself. Since that is the
> proper parent, reference it directly.
>
> We can switch this to the pm8058_gpio and the proper offset
> once we have fixed the SSBI GPIO driver to properly deal with
> the hierarchical IRQ domain and get proper local offset
> translation.
>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Regards,
Bjorn
> ---
> arch/arm/boot/dts/qcom-apq8060-dragonboard.dts | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm/boot/dts/qcom-apq8060-dragonboard.dts b/arch/arm/boot/dts/qcom-apq8060-dragonboard.dts
> index 4a532ddab53a..ea660ffa03ea 100644
> --- a/arch/arm/boot/dts/qcom-apq8060-dragonboard.dts
> +++ b/arch/arm/boot/dts/qcom-apq8060-dragonboard.dts
> @@ -369,8 +369,8 @@
> ak8975 at 0c {
> compatible = "asahi-kasei,ak8975";
> reg = <0x0c>;
> - /* GPIO33 has interrupt 224 on the PM8058 */
> - interrupt-parent = <&pm8058_gpio>;
> + /* FIXME: GPIO33 has interrupt 224 on the PM8058 */
> + interrupt-parent = <&pm8058>;
> interrupts = <224 IRQ_TYPE_EDGE_RISING>;
> pinctrl-names = "default";
> pinctrl-0 = <&dragon_ak8975_gpios>;
> @@ -380,8 +380,8 @@
> bmp085 at 77 {
> compatible = "bosch,bmp085";
> reg = <0x77>;
> - /* GPIO16 has interrupt 207 on the PM8058 */
> - interrupt-parent = <&pm8058_gpio>;
> + /* FIXME: GPIO16 has interrupt 207 on the PM8058 */
> + interrupt-parent = <&pm8058>;
> interrupts = <207 IRQ_TYPE_EDGE_RISING>;
> reset-gpios = <&tlmm 86 GPIO_ACTIVE_LOW>;
> pinctrl-names = "default";
> --
> 2.7.4
>
^ permalink raw reply
* [RFC PATCH 1/3] ARM64: meson: Add Amlogic Meson GX PM Suspend
From: Sudeep Holla @ 2016-11-03 21:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478183365-23708-2-git-send-email-narmstrong@baylibre.com>
On Thu, Nov 03, 2016 at 03:29:23PM +0100, Neil Armstrong wrote:
> The Amlogic Meson GX SoCs uses a non-standard argument to the
> PSCI CPU_SUSPEND call to enter system suspend.
>
> Implement such call within platform_suspend_ops.
>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
> drivers/firmware/meson/Kconfig | 6 +++
> drivers/firmware/meson/Makefile | 1 +
> drivers/firmware/meson/meson_gx_pm.c | 86 ++++++++++++++++++++++++++++++++++++
> 3 files changed, 93 insertions(+)
> create mode 100644 drivers/firmware/meson/meson_gx_pm.c
>
> diff --git a/drivers/firmware/meson/Kconfig b/drivers/firmware/meson/Kconfig
> index 170d7e8..5b3fea3 100644
> --- a/drivers/firmware/meson/Kconfig
> +++ b/drivers/firmware/meson/Kconfig
> @@ -7,3 +7,9 @@ config MESON_SM
> depends on ARM64_4K_PAGES
> help
> Say y here to enable the Amlogic secure monitor driver
> +
> +config MESON_GX_PM
> + bool
> + default ARCH_MESON if ARM64
> + help
> + Say y here to enable the Amlogic GX SoC Power Management
> diff --git a/drivers/firmware/meson/Makefile b/drivers/firmware/meson/Makefile
> index 9ab3884..b6e285d 100644
> --- a/drivers/firmware/meson/Makefile
> +++ b/drivers/firmware/meson/Makefile
> @@ -1 +1,2 @@
> obj-$(CONFIG_MESON_SM) += meson_sm.o
> +obj-$(CONFIG_MESON_GX_PM) += meson_gx_pm.o
> diff --git a/drivers/firmware/meson/meson_gx_pm.c b/drivers/firmware/meson/meson_gx_pm.c
> new file mode 100644
> index 0000000..c104c2e
> --- /dev/null
> +++ b/drivers/firmware/meson/meson_gx_pm.c
> @@ -0,0 +1,86 @@
> +/*
> + * Amlogic Meson GX Power Management
> + *
> + * Copyright (c) 2016 Baylibre, SAS.
> + * Author: Neil Armstrong <narmstrong@baylibre.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of version 2 of the GNU General Public License as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> + * more details.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/suspend.h>
> +#include <linux/arm-smccc.h>
> +
> +#include <uapi/linux/psci.h>
> +
> +#include <asm/suspend.h>
> +
> +/*
> + * The Amlogic GX SoCs uses a special argument value to the
> + * PSCI CPU_SUSPEND method to enter SUSPEND_MEM.
> + */
> +
> +#define MESON_SUSPEND_PARAM 0x0010000
> +#define PSCI_FN_NATIVE(version, name) PSCI_##version##_FN64_##name
> +
> +static int meson_gx_suspend_finish(unsigned long arg)
> +{
> + struct arm_smccc_res res;
> +
> + arm_smccc_smc(PSCI_FN_NATIVE(0_2, CPU_SUSPEND), arg,
> + virt_to_phys(cpu_resume), 0, 0, 0, 0, 0, &res);
> +
> + return res.a0;
> +}
> +
> +static int meson_gx_suspend_enter(suspend_state_t state)
> +{
> + switch (state) {
> + case PM_SUSPEND_MEM:
> + return cpu_suspend(MESON_SUSPEND_PARAM,
> + meson_gx_suspend_finish);
Short response to this patch: NAK
To be constructive, since this system lacks PSCI system suspend, it just
can't support. Alternatively, this can be normal cpuidle state and you
can use suspend to idle to achieve the same and you need not hack/work
around using platform specific driver.
--
Regards,
Sudeep
^ permalink raw reply
* [PATCH] PM / Domains: Fix for domain idle state
From: Lina Iyer @ 2016-11-03 21:54 UTC (permalink / raw)
To: linux-arm-kernel
Hi Rafael,
This follows the discussions we had at LPC. The decision to use a different
compatible (different from that of the CPU's idle state) resulted in a new idle
state node definition that is specific to PM domains. The patch describes this
new binding.
You have already pulled in my earlier changes for domain idle states into your
linux-next. This patch is intended to be applied on top of that and fixes the
domain idle state and maps it to the new definition.
Thanks,
Lina
Lina Iyer (1):
PM / Domains: Fix compatible for domain idle state
.../bindings/power/domain-idle-state.txt | 33 ++++++++++++++++++++++
.../devicetree/bindings/power/power_domain.txt | 8 +++---
drivers/base/power/domain.c | 2 +-
3 files changed, 38 insertions(+), 5 deletions(-)
create mode 100644 Documentation/devicetree/bindings/power/domain-idle-state.txt
--
2.7.4
^ permalink raw reply
* [PATCH] PM / Domains: Fix compatible for domain idle state
From: Lina Iyer @ 2016-11-03 21:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478210075-92045-1-git-send-email-lina.iyer@linaro.org>
Re-using idle state definition provided by arm,idle-state for domain
idle states creates a lot of confusion and limits further evolution of
the domain idle definition. To keep things clear and simple, define a
idle states for domain using a new compatible "domain-idle-state".
Fix existing PM domains code to look for the newly defined compatible.
Cc: <devicetree@vger.kernel.org>
Cc: Rob Herring <robh@kernel.org>
Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
---
.../bindings/power/domain-idle-state.txt | 33 ++++++++++++++++++++++
.../devicetree/bindings/power/power_domain.txt | 8 +++---
drivers/base/power/domain.c | 2 +-
3 files changed, 38 insertions(+), 5 deletions(-)
create mode 100644 Documentation/devicetree/bindings/power/domain-idle-state.txt
diff --git a/Documentation/devicetree/bindings/power/domain-idle-state.txt b/Documentation/devicetree/bindings/power/domain-idle-state.txt
new file mode 100644
index 0000000..eefc7ed
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/domain-idle-state.txt
@@ -0,0 +1,33 @@
+PM Domain Idle State Node:
+
+A domain idle state node represents the state parameters that will be used to
+select the state when there are no active components in the domain.
+
+The state node has the following parameters -
+
+- compatible:
+ Usage: Required
+ Value type: <string>
+ Definition: Must be "domain-idle-state".
+
+- entry-latency-us
+ Usage: Required
+ Value type: <prop-encoded-array>
+ Definition: u32 value representing worst case latency in
+ microseconds required to enter the idle state.
+ The exit-latency-us duration may be guaranteed
+ only after entry-latency-us has passed.
+
+- exit-latency-us
+ Usage: Required
+ Value type: <prop-encoded-array>
+ Definition: u32 value representing worst case latency
+ in microseconds required to exit the idle state.
+
+- min-residency-us
+ Usage: Required
+ Value type: <prop-encoded-array>
+ Definition: u32 value representing minimum residency duration
+ in microseconds after which the idle state will yield
+ power benefits after overcoming the overhead in entering
+i the idle state.
diff --git a/Documentation/devicetree/bindings/power/power_domain.txt b/Documentation/devicetree/bindings/power/power_domain.txt
index e165036..723e1ad 100644
--- a/Documentation/devicetree/bindings/power/power_domain.txt
+++ b/Documentation/devicetree/bindings/power/power_domain.txt
@@ -31,7 +31,7 @@ Optional properties:
- domain-idle-states : A phandle of an idle-state that shall be soaked into a
generic domain power state. The idle state definitions are
- compatible with arm,idle-state specified in [1].
+ compatible with domain-idle-state specified in [1].
The domain-idle-state property reflects the idle state of this PM domain and
not the idle states of the devices or sub-domains in the PM domain. Devices
and sub-domains have their own idle-states independent of the parent
@@ -85,7 +85,7 @@ Example 3:
};
DOMAIN_RET: state at 0 {
- compatible = "arm,idle-state";
+ compatible = "domain-idle-state";
reg = <0x0>;
entry-latency-us = <1000>;
exit-latency-us = <2000>;
@@ -93,7 +93,7 @@ Example 3:
};
DOMAIN_PWR_DN: state at 1 {
- compatible = "arm,idle-state";
+ compatible = "domain-idle-state";
reg = <0x1>;
entry-latency-us = <5000>;
exit-latency-us = <8000>;
@@ -118,4 +118,4 @@ The node above defines a typical PM domain consumer device, which is located
inside a PM domain with index 0 of a power controller represented by a node
with the label "power".
-[1]. Documentation/devicetree/bindings/arm/idle-states.txt
+[1]. Documentation/devicetree/bindings/power/domain-idle-state.txt
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 661737c..f0bc672 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -2048,7 +2048,7 @@ int genpd_dev_pm_attach(struct device *dev)
EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
static const struct of_device_id idle_state_match[] = {
- { .compatible = "arm,idle-state", },
+ { .compatible = "domain-idle-state", },
{ }
};
--
2.7.4
^ permalink raw reply related
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