Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 8/9] X86: remove redundant cpuidle_idle_call()
From: Nicolas Pitre @ 2014-01-27  6:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390802904-28399-1-git-send-email-nicolas.pitre@linaro.org>

The core idle loop now takes care of it.

Signed-off-by: Nicolas Pitre <nico@linaro.org>
---
 arch/x86/kernel/process.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 3fb8d95ab8..4505e2a950 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -298,10 +298,7 @@ void arch_cpu_idle_dead(void)
  */
 void arch_cpu_idle(void)
 {
-	if (cpuidle_idle_call())
-		x86_idle();
-	else
-		local_irq_enable();
+	x86_idle();
 }
 
 /*
-- 
1.8.4.108.g55ea5f6

^ permalink raw reply related

* [PATCH 7/9] SH: remove redundant cpuidle_idle_call()
From: Nicolas Pitre @ 2014-01-27  6:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390802904-28399-1-git-send-email-nicolas.pitre@linaro.org>

The core idle loop now takes care of it.

Signed-off-by: Nicolas Pitre <nico@linaro.org>
---
 arch/sh/kernel/idle.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c
index 2ea4483fd7..be616ee0cf 100644
--- a/arch/sh/kernel/idle.c
+++ b/arch/sh/kernel/idle.c
@@ -16,7 +16,6 @@
 #include <linux/thread_info.h>
 #include <linux/irqflags.h>
 #include <linux/smp.h>
-#include <linux/cpuidle.h>
 #include <linux/atomic.h>
 #include <asm/pgalloc.h>
 #include <asm/smp.h>
@@ -40,8 +39,7 @@ void arch_cpu_idle_dead(void)
 
 void arch_cpu_idle(void)
 {
-	if (cpuidle_idle_call())
-		sh_idle();
+	sh_idle();
 }
 
 void __init select_idle_routine(void)
-- 
1.8.4.108.g55ea5f6

^ permalink raw reply related

* [PATCH 6/9] PPC: remove redundant cpuidle_idle_call()
From: Nicolas Pitre @ 2014-01-27  6:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390802904-28399-1-git-send-email-nicolas.pitre@linaro.org>

The core idle loop now takes care of it.  However a few things need
checking:

- Invocation of cpuidle_idle_call() in pseries_lpar_idle() happened
  through arch_cpu_idle() and was therefore always preceded by a call
  to ppc64_runlatch_off().  To preserve this property now that
  cpuidle_idle_call() is invoked directly from core code, a call to
  ppc64_runlatch_off() has been added to idle_loop_prolog() in
  platforms/pseries/processor_idle.c.

- Similarly, cpuidle_idle_call() was followed by ppc64_runlatch_off()
  so a call to the later has been added to idle_loop_epilog().

- And since arch_cpu_idle() always made sure to re-enable IRQs if they
  were not enabled, this is now
  done in idle_loop_epilog() as well.

The above was made in order to keep the execution flow close to the
original.  I don't know if that was strictly necessary. Someone well
aquainted with the platform details might find some room for possible
optimizations.

Signed-off-by: Nicolas Pitre <nico@linaro.org>
---
 arch/powerpc/platforms/pseries/processor_idle.c |  5 ++++
 arch/powerpc/platforms/pseries/setup.c          | 34 ++++++++++---------------
 2 files changed, 19 insertions(+), 20 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c
index a166e38bd6..72ddfe3d2f 100644
--- a/arch/powerpc/platforms/pseries/processor_idle.c
+++ b/arch/powerpc/platforms/pseries/processor_idle.c
@@ -33,6 +33,7 @@ static struct cpuidle_state *cpuidle_state_table;
 
 static inline void idle_loop_prolog(unsigned long *in_purr)
 {
+	ppc64_runlatch_off();
 	*in_purr = mfspr(SPRN_PURR);
 	/*
 	 * Indicate to the HV that we are idle. Now would be
@@ -49,6 +50,10 @@ static inline void idle_loop_epilog(unsigned long in_purr)
 	wait_cycles += mfspr(SPRN_PURR) - in_purr;
 	get_lppaca()->wait_state_cycles = cpu_to_be64(wait_cycles);
 	get_lppaca()->idle = 0;
+
+	if (irqs_disabled())
+		local_irq_enable();
+	ppc64_runlatch_on();
 }
 
 static int snooze_loop(struct cpuidle_device *dev,
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index c1f1908587..7604c19d54 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -39,7 +39,6 @@
 #include <linux/irq.h>
 #include <linux/seq_file.h>
 #include <linux/root_dev.h>
-#include <linux/cpuidle.h>
 #include <linux/of.h>
 #include <linux/kexec.h>
 
@@ -356,29 +355,24 @@ early_initcall(alloc_dispatch_log_kmem_cache);
 
 static void pseries_lpar_idle(void)
 {
-	/* This would call on the cpuidle framework, and the back-end pseries
-	 * driver to  go to idle states
+	/*
+	 * Default handler to go into low thread priority and possibly
+	 * low power mode by cedeing processor to hypervisor
 	 */
-	if (cpuidle_idle_call()) {
-		/* On error, execute default handler
-		 * to go into low thread priority and possibly
-		 * low power mode by cedeing processor to hypervisor
-		 */
 
-		/* Indicate to hypervisor that we are idle. */
-		get_lppaca()->idle = 1;
+	/* Indicate to hypervisor that we are idle. */
+	get_lppaca()->idle = 1;
 
-		/*
-		 * Yield the processor to the hypervisor.  We return if
-		 * an external interrupt occurs (which are driven prior
-		 * to returning here) or if a prod occurs from another
-		 * processor. When returning here, external interrupts
-		 * are enabled.
-		 */
-		cede_processor();
+	/*
+	 * Yield the processor to the hypervisor.  We return if
+	 * an external interrupt occurs (which are driven prior
+	 * to returning here) or if a prod occurs from another
+	 * processor. When returning here, external interrupts
+	 * are enabled.
+	 */
+	cede_processor();
 
-		get_lppaca()->idle = 0;
-	}
+	get_lppaca()->idle = 0;
 }
 
 /*
-- 
1.8.4.108.g55ea5f6

^ permalink raw reply related

* [PATCH 5/9] ARM: remove redundant cpuidle_idle_call()
From: Nicolas Pitre @ 2014-01-27  6:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390802904-28399-1-git-send-email-nicolas.pitre@linaro.org>

The core idle loop now takes care of it.

Signed-off-by: Nicolas Pitre <nico@linaro.org>
---
 arch/arm/kernel/process.c | 16 +++++-----------
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 725b8c95e0..34a59b7614 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -30,7 +30,6 @@
 #include <linux/uaccess.h>
 #include <linux/random.h>
 #include <linux/hw_breakpoint.h>
-#include <linux/cpuidle.h>
 #include <linux/leds.h>
 #include <linux/reboot.h>
 
@@ -133,7 +132,11 @@ EXPORT_SYMBOL_GPL(arm_pm_restart);
 
 void (*arm_pm_idle)(void);
 
-static void default_idle(void)
+/*
+ * Called from the core idle loop.
+ */
+
+void arch_cpu_idle(void)
 {
 	if (arm_pm_idle)
 		arm_pm_idle();
@@ -163,15 +166,6 @@ void arch_cpu_idle_dead(void)
 #endif
 
 /*
- * Called from the core idle loop.
- */
-void arch_cpu_idle(void)
-{
-	if (cpuidle_idle_call())
-		default_idle();
-}
-
-/*
  * Called by kexec, immediately prior to machine_kexec().
  *
  * This must completely disable all secondary CPUs; simply causing those CPUs
-- 
1.8.4.108.g55ea5f6

^ permalink raw reply related

* [PATCH 4/9] idle: move the cpuidle entry point to the generic idle loop
From: Nicolas Pitre @ 2014-01-27  6:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390802904-28399-1-git-send-email-nicolas.pitre@linaro.org>

In order to integrate cpuidle with the scheduler, we must have a better
proximity in the core code with what cpuidle is doing and not delegate
such interaction to arch code.

Architectures implementing arch_cpu_idle() should simply enter
a cheap idle mode in the absence of a proper cpuidle driver.

Signed-off-by: Nicolas Pitre <nico@linaro.org>
---
 kernel/cpu/idle.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/kernel/cpu/idle.c b/kernel/cpu/idle.c
index 4e327e211b..a6f40ad9f8 100644
--- a/kernel/cpu/idle.c
+++ b/kernel/cpu/idle.c
@@ -3,6 +3,7 @@
  */
 #include <linux/sched.h>
 #include <linux/cpu.h>
+#include <linux/cpuidle.h>
 #include <linux/tick.h>
 #include <linux/mm.h>
 #include <linux/stackprotector.h>
@@ -94,7 +95,8 @@ static void cpu_idle_loop(void)
 				if (!current_clr_polling_and_test()) {
 					stop_critical_timings();
 					rcu_idle_enter();
-					arch_cpu_idle();
+					if (cpuidle_idle_call())
+						arch_cpu_idle();
 					WARN_ON_ONCE(irqs_disabled());
 					rcu_idle_exit();
 					start_critical_timings();
-- 
1.8.4.108.g55ea5f6

^ permalink raw reply related

* [PATCH 3/9] idle: no more arch_cpu_idle_prepare() users
From: Nicolas Pitre @ 2014-01-27  6:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390802904-28399-1-git-send-email-nicolas.pitre@linaro.org>

... so we can get rid of it entirely.

Signed-off-by: Nicolas Pitre <nico@linaro.org>
---
 include/linux/cpu.h | 1 -
 kernel/cpu/idle.c   | 2 --
 2 files changed, 3 deletions(-)

diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 03e235ad1b..218fab7521 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -221,7 +221,6 @@ void cpu_idle(void);
 void cpu_idle_poll_ctrl(bool enable);
 
 void arch_cpu_idle(void);
-void arch_cpu_idle_prepare(void);
 void arch_cpu_idle_enter(void);
 void arch_cpu_idle_exit(void);
 void arch_cpu_idle_dead(void);
diff --git a/kernel/cpu/idle.c b/kernel/cpu/idle.c
index 988573a9a3..4e327e211b 100644
--- a/kernel/cpu/idle.c
+++ b/kernel/cpu/idle.c
@@ -52,7 +52,6 @@ static inline int cpu_idle_poll(void)
 }
 
 /* Weak implementations for optional arch specific functions */
-void __weak arch_cpu_idle_prepare(void) { }
 void __weak arch_cpu_idle_enter(void) { }
 void __weak arch_cpu_idle_exit(void) { }
 void __weak arch_cpu_idle_dead(void) { }
@@ -136,6 +135,5 @@ void cpu_startup_entry(enum cpuhp_state state)
 	boot_init_stack_canary();
 #endif
 	__current_set_polling();
-	arch_cpu_idle_prepare();
 	cpu_idle_loop();
 }
-- 
1.8.4.108.g55ea5f6

^ permalink raw reply related

* [PATCH 2/9] ARM64: get rid of arch_cpu_idle_prepare()
From: Nicolas Pitre @ 2014-01-27  6:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390802904-28399-1-git-send-email-nicolas.pitre@linaro.org>

ARM and ARM64 are the only two architectures implementing
arch_cpu_idle_prepare() simply to call local_fiq_enable().

We have secondary_start_kernel() already calling local_fiq_enable() and
this is done a second time in arch_cpu_idle_prepare() in that case. And
enabling FIQs has nothing to do with idling the CPU to start with.

So let's introduce init_fiq_boot_cpu() to take care of FIQs on the boot
CPU and remove arch_cpu_idle_prepare(). This is now done a bit earlier
at late_initcall time but this shouldn't make a difference in practice
given that FIQs are not currently used on ARM64.

Signed-off-by: Nicolas Pitre <nico@linaro.org>
---
 arch/arm64/kernel/process.c | 5 -----
 arch/arm64/kernel/setup.c   | 7 +++++++
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index de17c89985..f6c733da67 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -84,11 +84,6 @@ EXPORT_SYMBOL_GPL(pm_power_off);
 void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
 EXPORT_SYMBOL_GPL(arm_pm_restart);
 
-void arch_cpu_idle_prepare(void)
-{
-	local_fiq_enable();
-}
-
 /*
  * This is our default idle handler.
  */
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index bd9bbd0e44..259557983a 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -255,6 +255,13 @@ static int __init arm64_device_init(void)
 }
 arch_initcall(arm64_device_init);
 
+static int __init init_fiq_boot_cpu(void)
+{
+	local_fiq_enable();
+	return 0;
+}
+late_initcall(init_fiq_boot_cpu);
+
 static DEFINE_PER_CPU(struct cpu, cpu_data);
 
 static int __init topology_init(void)
-- 
1.8.4.108.g55ea5f6

^ permalink raw reply related

* [PATCH 1/9] ARM: get rid of arch_cpu_idle_prepare()
From: Nicolas Pitre @ 2014-01-27  6:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390802904-28399-1-git-send-email-nicolas.pitre@linaro.org>

ARM and ARM64 are the only two architectures implementing
arch_cpu_idle_prepare() simply to call local_fiq_enable().

We have secondary_start_kernel() already calling local_fiq_enable() and
this is done a second time in arch_cpu_idle_prepare() in that case. And
enabling FIQs has nothing to do with idling the CPU to start with.

So let's introduce init_fiq_boot_cpu() to take care of FIQs on the boot
CPU and remove arch_cpu_idle_prepare(). This is now done a bit earlier
at late_initcall time but this shouldn't make a difference in practice
i.e. when FIQs are actually used.

Signed-off-by: Nicolas Pitre <nico@linaro.org>
---
 arch/arm/kernel/process.c | 5 -----
 arch/arm/kernel/setup.c   | 7 +++++++
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 92f7b15dd2..725b8c95e0 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -142,11 +142,6 @@ static void default_idle(void)
 	local_irq_enable();
 }
 
-void arch_cpu_idle_prepare(void)
-{
-	local_fiq_enable();
-}
-
 void arch_cpu_idle_enter(void)
 {
 	ledtrig_cpu(CPU_LED_IDLE_START);
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 987a7f5bce..d027b1a6fe 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -789,6 +789,13 @@ static int __init init_machine_late(void)
 }
 late_initcall(init_machine_late);
 
+static int __init init_fiq_boot_cpu(void)
+{
+	local_fiq_enable();
+	return 0;
+}
+late_initcall(init_fiq_boot_cpu);
+
 #ifdef CONFIG_KEXEC
 static inline unsigned long long get_total_mem(void)
 {
-- 
1.8.4.108.g55ea5f6

^ permalink raw reply related

* [PATCH 0/9] setting the table for integration of cpuidle with the scheduler
From: Nicolas Pitre @ 2014-01-27  6:08 UTC (permalink / raw)
  To: linux-arm-kernel

As everyone should know by now, we want to integrate the cpuidle
governor with the scheduler for a more efficient idling of CPUs.
In order to help the transition, this small patch series moves the
existing interaction with cpuidle from architecture code to generic
core code.  No functional change should have occurred yet.

The ARM, PPC, SH and X86 architectures are concerned.  Small cleanups
to ARM and ARM64 are also included. I don't know yet the best path for
those patches to get into mainline, but it is probably best if they
stay together. So ACKs from architecture maintainers would be greatly
appreciated.


 arch/arm/kernel/process.c                       | 21 +++---------
 arch/arm/kernel/setup.c                         |  7 ++++
 arch/arm64/kernel/process.c                     |  5 ---
 arch/arm64/kernel/setup.c                       |  7 ++++
 arch/powerpc/platforms/pseries/processor_idle.c |  5 +++
 arch/powerpc/platforms/pseries/setup.c          | 34 ++++++++-----------
 arch/sh/kernel/idle.c                           |  4 +--
 arch/x86/kernel/process.c                       |  5 +--
 include/linux/cpu.h                             |  1 -
 kernel/Makefile                                 |  1 -
 kernel/cpu/Makefile                             |  1 -
 kernel/sched/Makefile                           |  2 +-
 kernel/{cpu => sched}/idle.c                    |  6 ++--
 13 files changed, 44 insertions(+), 55 deletions(-)


Nicolas

^ permalink raw reply

* [PATCH] pinctrl: sirf: correct the pin index of ac97_pins group
From: Barry Song @ 2014-01-27  6:01 UTC (permalink / raw)
  To: linux-arm-kernel

From: Qipan Li <Qipan.Li@csr.com>

according to datasheet and ac97_muxmask assignment, ac97_pins should be
corrected.

Signed-off-by: Qipan Li <Qipan.Li@csr.com>
Signed-off-by: Barry Song <Baohua.Song@csr.com>
---
 drivers/pinctrl/sirf/pinctrl-prima2.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/pinctrl/sirf/pinctrl-prima2.c b/drivers/pinctrl/sirf/pinctrl-prima2.c
index 37b4265..dde0285 100644
--- a/drivers/pinctrl/sirf/pinctrl-prima2.c
+++ b/drivers/pinctrl/sirf/pinctrl-prima2.c
@@ -413,7 +413,7 @@ static const struct sirfsoc_padmux ac97_padmux = {
 	.funcval = 0,
 };
 
-static const unsigned ac97_pins[] = { 33, 34, 35, 36 };
+static const unsigned ac97_pins[] = { 43, 44, 45, 46 };
 
 static const struct sirfsoc_muxmask spi1_muxmask[] = {
 	{
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH v3] audit: Add generic compat syscall support
From: AKASHI Takahiro @ 2014-01-27  5:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140123145119.GE27520@arm.com>

Catalin and audit maintainers,

On 01/23/2014 11:51 PM, Catalin Marinas wrote:
> On Fri, Jan 17, 2014 at 08:03:15AM +0000, AKASHI Takahiro wrote:
>> lib/audit.c provides a generic definition for auditing system calls.
>> This patch extends it for compat syscall support on bi-architectures
>> (32/64-bit) by adding lib/compat_audit.c when CONFIG_COMPAT enabled.
>>
>> Each architecture that wants to use this must define audit_is_compat()
>> in asm/audit.h.
>>
>> Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
>
> I'm not familiar with the audit subsystem but I have some (cosmetic)
> comments below.
>
>> diff --git a/include/linux/audit.h b/include/linux/audit.h
>> index bf1ef22..3d71949 100644
>> --- a/include/linux/audit.h
>> +++ b/include/linux/audit.h
>> @@ -78,6 +78,15 @@ extern int is_audit_feature_set(int which);
>>   extern int __init audit_register_class(int class, unsigned *list);
>>   extern int audit_classify_syscall(int abi, unsigned syscall);
>>   extern int audit_classify_arch(int arch);
>> +#if defined(CONFIG_AUDIT_GENERIC) && defined(CONFIG_COMPAT)
>> +extern unsigned compat_write_class[];
>> +extern unsigned compat_read_class[];
>> +extern unsigned compat_dir_class[];
>> +extern unsigned compat_chattr_class[];
>> +extern unsigned compat_signal_class[];
>> +
>> +extern int audit_classify_compat_syscall(int abi, unsigned syscall);
>> +#endif
>>
>>   /* audit_names->type values */
>>   #define	AUDIT_TYPE_UNKNOWN	0	/* we don't know yet */
>> diff --git a/lib/Makefile b/lib/Makefile
>> index a459c31..73ea908 100644
>> --- a/lib/Makefile
>> +++ b/lib/Makefile
>> @@ -93,6 +93,9 @@ obj-$(CONFIG_TEXTSEARCH_BM) += ts_bm.o
>>   obj-$(CONFIG_TEXTSEARCH_FSM) += ts_fsm.o
>>   obj-$(CONFIG_SMP) += percpu_counter.o
>>   obj-$(CONFIG_AUDIT_GENERIC) += audit.o
>> +ifeq ($(CONFIG_COMPAT),y)
>> +obj-$(CONFIG_AUDIT_GENERIC) += compat_audit.o
>> +endif
>
> You could use a CONFIG_AUDIT_COMPAT_GENERIC and simplify other #ifdefs
> as well.

I will add the following in lib/Kconfig:

   config AUDIT_COMPAT_GENERIC
     depends on AUDIT_GENERIC & COMPAT
     default y

>> --- a/lib/audit.c
>> +++ b/lib/audit.c
>> @@ -1,6 +1,7 @@
>>   #include <linux/init.h>
>>   #include <linux/types.h>
>>   #include <linux/audit.h>
>> +#include <asm/audit.h>
>>   #include <asm/unistd.h>
>>
>>   static unsigned dir_class[] = {
>> @@ -30,11 +31,20 @@ static unsigned signal_class[] = {
>>
>>   int audit_classify_arch(int arch)
>>   {
>> +#ifdef CONFIG_COMPAT
>> +	if (audit_is_compat(arch))
>> +		return 1;
>> +#endif
>>   	return 0;
>>   }
>
> Here and in other places, just define a default audit_is_compat()
> functions which returns false when !CONFIG_COMPAT to avoid the #ifdefs.

OK. With Richard's comment, the definition below will be added
to uapi/linux/audit.h:

   #ifdef CONFIG_COMPAT
   #define audit_is_compat(arch)  (!!((arch) & __AUDIT_ARCH_64BIT))
   #else
   #define audit_is_compat(arch)  false
   #endif

>> diff --git a/lib/compat_audit.c b/lib/compat_audit.c
>> new file mode 100644
>> index 0000000..94f6480
>> --- /dev/null
>> +++ b/lib/compat_audit.c
>> @@ -0,0 +1,51 @@
>> +#include <linux/init.h>
>> +#include <linux/types.h>
>> +/* FIXME: this might be architecture dependent */
>> +#include <asm/unistd_32.h>
>
> It most likely is architecture dependent.

I'm wondering what name is the most appropriate in this case.
Most archictures have __NR_xyz definitions in "unistd_32.h",
but arm64 doesn't have it, instead "unistd32." which contains
only __SYSCALL(xyz, NO). Confusing?

>> +int audit_classify_compat_syscall(int abi, unsigned syscall)
>> +{
>> +	switch (syscall) {
>> +#ifdef __NR_open
>> +	case __NR_open:
>> +		return 2;
>> +#endif
>> +#ifdef __NR_openat
>> +	case __NR_openat:
>> +		return 3;
>> +#endif
>> +#ifdef __NR_socketcall
>> +	case __NR_socketcall:
>> +		return 4;
>> +#endif
>> +	case __NR_execve:
>> +		return 5;
>> +	default:
>> +		return 1;
>> +	}
>> +}
>
> BTW, since they aren't many, you could get the arch code to define
> __NR_compat_open etc. explicitly and use these. On arm64 we have a few
> of these defined to avoid name collision in signal handling code.

Again, most architecture have their own unistd32.h for compat system calls,
and use __NR_open-like naming.
It's unlikely for these archs to migrate to "generic compat" auditing,
but I believe that '__NR_open'-like naming is better because we may be able to avoid
arch-specific changes even for future(?) syscall-related enhancements in audit.

But, anyway, it's up to audit maintainer's preference.

Thanks,
-Takahiro AKASHI

^ permalink raw reply

* [PATCHv11 2/2] dma: Add Freescale eDMA engine driver support
From: Jingchang Lu @ 2014-01-27  5:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390209831-15679-1-git-send-email-b35083@freescale.com>

Hi, Vinod,

  Let me give some more explanation on the eDMA engine pause and termination here:
The eDMA engine is a request-driven controller, it manage all channels in one engine
and schedule them to perform each one's transfer when one's dma request arrive.
When a dma request of a specific channel is received, the channel's appropriate TCD
Parameter contents are loaded into the eDMA engine, and the appropriate reads and writes
Perform until the minor byte transfer count has transferred, the number of bytes to transfer
per request is determined by the salve's characteristics, such as the FIFO size, 
and the dma request condition is also determined by specific slave, such as FIFO empty.
And to the transfer a bunch of data need many dma requests.
  So if the dma request enable bit of a channel is cleared, there will be no further dma
Request received by the eDMA engine, thus the channel will never be scheduled to run by
the eDMA engine, the channel is paused, halted, also as stopped. If the channel need to
transfer the remained data with the previous setting, just set the dma request enable bit,
the transfer will complete with slave's dma request.(resume)
If the parameters need be changed, corresponding register parameters can be reprogrammed,
after all is ok, the dma request enable bit can be set to enable a new dma transfer.(terminate)
  So is this ok and could it be merged, thanks!


Best Regards,
Jingchang
  

> -----Original Message-----
> From: Jingchang Lu [mailto:b35083 at freescale.com]
> Sent: Monday, January 20, 2014 5:24 PM
> To: vinod.koul at intel.com
> Cc: dan.j.williams at intel.com; arnd at arndb.de; shawn.guo at linaro.org;
> pawel.moll at arm.com; mark.rutland at arm.com; swarren at wwwdotorg.org; linux-
> kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> devicetree at vger.kernel.org; Lu Jingchang-B35083; Wang Huan-B18965
> Subject: [PATCHv11 2/2] dma: Add Freescale eDMA engine driver support
> 
> Add Freescale enhanced direct memory(eDMA) controller support.
> This module can be found on Vybrid and LS-1 SoCs.
> 
> Signed-off-by: Alison Wang <b18965@freescale.com>
> Signed-off-by: Jingchang Lu <b35083@freescale.com>
> Acked-by: Arnd Bergmann <arnd@arndb.de>
> ---
> changes in v11:
>  Add dma device_slave_caps definition.
> 
> changes in v10:
>  define fsl_edma_mutex in fsl_edma_engine instead of global.
>  minor changes of binding description.
> 
> changes in v9:
>  define endian's operating functions instead of macro definition.
>  remove the filter function, using dma_get_slave_channel instead.
> 
> changes in v8:
>  change the edma driver according eDMA dts change.
>  add big-endian and little-endian handling.
> 
>  no changes in v4 ~ v7.
> 
>  changes in v3:
>   add vf610 edma dt-bindings namespace with prefix VF610_*.
> 
>  changes in v2:
>   using generic dma-channels property instead of fsl,dma-channels.
> 
>  Documentation/devicetree/bindings/dma/fsl-edma.txt |  76 ++
>  drivers/dma/Kconfig                                |  10 +
>  drivers/dma/Makefile                               |   1 +
>  drivers/dma/fsl-edma.c                             | 975
> +++++++++++++++++++++
>  4 files changed, 1062 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/dma/fsl-edma.txt
>  create mode 100644 drivers/dma/fsl-edma.c
> 
> diff --git a/Documentation/devicetree/bindings/dma/fsl-edma.txt
> b/Documentation/devicetree/bindings/dma/fsl-edma.txt
> new file mode 100644
> index 0000000..191d7bd
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/dma/fsl-edma.txt
> @@ -0,0 +1,76 @@
> +* Freescale enhanced Direct Memory Access(eDMA) Controller
> +
> +  The eDMA channels have multiplex capability by programmble memory-
> mapped
> +registers. channels are split into two groups, called DMAMUX0 and
> DMAMUX1,
> +specific DMA request source can only be multiplexed by any channel of
> certain
> +group, DMAMUX0 or DMAMUX1, but not both.
> +
> +* eDMA Controller
> +Required properties:
> +- compatible :
> +	- "fsl,vf610-edma" for eDMA used similar to that on Vybrid vf610
> SoC
> +- reg : Specifies base physical address(s) and size of the eDMA
> registers.
> +	The 1st region is eDMA control register's address and size.
> +	The 2nd and the 3rd regions are programmable channel multiplexing
> +	control register's address and size.
> +- interrupts : A list of interrupt-specifiers, one for each entry in
> +	interrupt-names.
> +- interrupt-names : Should contain:
> +	"edma-tx" - the transmission interrupt
> +	"edma-err" - the error interrupt
> +- #dma-cells : Must be <2>.
> +	The 1st cell specifies the DMAMUX(0 for DMAMUX0 and 1 for DMAMUX1).
> +	Specific request source can only be multiplexed by specific
> channels
> +	group called DMAMUX.
> +	The 2nd cell specifies the request source(slot) ID.
> +	See the SoC's reference manual for all the supported request
> sources.
> +- dma-channels : Number of channels supported by the controller
> +- clock-names : A list of channel group clock names. Should contain:
> +	"dmamux0" - clock name of mux0 group
> +	"dmamux1" - clock name of mux1 group
> +- clocks : A list of phandle and clock-specifier pairs, one for each
> entry in
> +	clock-names.
> +
> +Optional properties:
> +- big-endian: If present registers and hardware scatter/gather
> descriptors
> +	of the eDMA are implemented in big endian mode, otherwise in little
> +	mode.
> +
> +
> +Examples:
> +
> +edma0: dma-controller at 40018000 {
> +	#dma-cells = <2>;
> +	compatible = "fsl,vf610-edma";
> +	reg = <0x40018000 0x2000>,
> +		<0x40024000 0x1000>,
> +		<0x40025000 0x1000>;
> +	interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>,
> +		<0 9 IRQ_TYPE_LEVEL_HIGH>;
> +	interrupt-names = "edma-tx", "edma-err";
> +	dma-channels = <32>;
> +	clock-names = "dmamux0", "dmamux1";
> +	clocks = <&clks VF610_CLK_DMAMUX0>,
> +		<&clks VF610_CLK_DMAMUX1>;
> +};
> +
> +
> +* DMA clients
> +DMA client drivers that uses the DMA function must use the format
> described
> +in the dma.txt file, using a two-cell specifier for each channel: the
> 1st
> +specifies the channel group(DMAMUX) in which this request can be
> multiplexed,
> +and the 2nd specifies the request source.
> +
> +Examples:
> +
> +sai2: sai at 40031000 {
> +	compatible = "fsl,vf610-sai";
> +	reg = <0x40031000 0x1000>;
> +	interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
> +	clock-names = "sai";
> +	clocks = <&clks VF610_CLK_SAI2>;
> +	dma-names = "tx", "rx";
> +	dmas = <&edma0 0 21>,
> +		<&edma0 0 20>;
> +	status = "disabled";
> +};
> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> index 9ae6f54..3d8a522 100644
> --- a/drivers/dma/Kconfig
> +++ b/drivers/dma/Kconfig
> @@ -342,6 +342,16 @@ config K3_DMA
>  	  Support the DMA engine for Hisilicon K3 platform
>  	  devices.
> 
> +config FSL_EDMA
> +	tristate "Freescale eDMA engine support"
> +	depends on OF
> +	select DMA_ENGINE
> +	select DMA_VIRTUAL_CHANNELS
> +	help
> +	  Support the Freescale eDMA engine with programmable channel
> +	  multiplexing capability for DMA request sources(slot).
> +	  This module can be found on Freescale Vybrid and LS-1 SoCs.
> +
>  config DMA_ENGINE
>  	bool
> 
> diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
> index 0a6f08e..e39c56b 100644
> --- a/drivers/dma/Makefile
> +++ b/drivers/dma/Makefile
> @@ -43,3 +43,4 @@ obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
>  obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o
>  obj-$(CONFIG_TI_CPPI41) += cppi41.o
>  obj-$(CONFIG_K3_DMA) += k3dma.o
> +obj-$(CONFIG_FSL_EDMA) += fsl-edma.o
> diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c
> new file mode 100644
> index 0000000..9025300
> --- /dev/null
> +++ b/drivers/dma/fsl-edma.c
> @@ -0,0 +1,975 @@
> +/*
> + * drivers/dma/fsl-edma.c
> + *
> + * Copyright 2013-2014 Freescale Semiconductor, Inc.
> + *
> + * Driver for the Freescale eDMA engine with flexible channel
> multiplexing
> + * capability for DMA request sources. The eDMA block can be found on
> some
> + * Vybrid and Layerscape SoCs.
> + *
> + * This program is free software; you can redistribute  it and/or modify
> it
> + * under  the terms of  the GNU General  Public License as published by
> the
> + * Free Software Foundation;  either version 2 of the  License, or (at
> your
> + * option) any later version.
> + */
> +
> +#include <linux/init.h>
> +#include <linux/module.h>
> +#include <linux/interrupt.h>
> +#include <linux/clk.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/dmapool.h>
> +#include <linux/slab.h>
> +#include <linux/spinlock.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_dma.h>
> +
> +#include "virt-dma.h"
> +
> +#define EDMA_CR			0x00
> +#define EDMA_ES			0x04
> +#define EDMA_ERQ		0x0C
> +#define EDMA_EEI		0x14
> +#define EDMA_SERQ		0x1B
> +#define EDMA_CERQ		0x1A
> +#define EDMA_SEEI		0x19
> +#define EDMA_CEEI		0x18
> +#define EDMA_CINT		0x1F
> +#define EDMA_CERR		0x1E
> +#define EDMA_SSRT		0x1D
> +#define EDMA_CDNE		0x1C
> +#define EDMA_INTR		0x24
> +#define EDMA_ERR		0x2C
> +
> +#define EDMA_TCD_SADDR(x)	(0x1000 + 32 * (x))
> +#define EDMA_TCD_SOFF(x)	(0x1004 + 32 * (x))
> +#define EDMA_TCD_ATTR(x)	(0x1006 + 32 * (x))
> +#define EDMA_TCD_NBYTES(x)	(0x1008 + 32 * (x))
> +#define EDMA_TCD_SLAST(x)	(0x100C + 32 * (x))
> +#define EDMA_TCD_DADDR(x)	(0x1010 + 32 * (x))
> +#define EDMA_TCD_DOFF(x)	(0x1014 + 32 * (x))
> +#define EDMA_TCD_CITER_ELINK(x)	(0x1016 + 32 * (x))
> +#define EDMA_TCD_CITER(x)	(0x1016 + 32 * (x))
> +#define EDMA_TCD_DLAST_SGA(x)	(0x1018 + 32 * (x))
> +#define EDMA_TCD_CSR(x)		(0x101C + 32 * (x))
> +#define EDMA_TCD_BITER_ELINK(x)	(0x101E + 32 * (x))
> +#define EDMA_TCD_BITER(x)	(0x101E + 32 * (x))
> +
> +#define EDMA_CR_EDBG		BIT(1)
> +#define EDMA_CR_ERCA		BIT(2)
> +#define EDMA_CR_ERGA		BIT(3)
> +#define EDMA_CR_HOE		BIT(4)
> +#define EDMA_CR_HALT		BIT(5)
> +#define EDMA_CR_CLM		BIT(6)
> +#define EDMA_CR_EMLM		BIT(7)
> +#define EDMA_CR_ECX		BIT(16)
> +#define EDMA_CR_CX		BIT(17)
> +
> +#define EDMA_SEEI_SEEI(x)	((x) & 0x1F)
> +#define EDMA_CEEI_CEEI(x)	((x) & 0x1F)
> +#define EDMA_CINT_CINT(x)	((x) & 0x1F)
> +#define EDMA_CERR_CERR(x)	((x) & 0x1F)
> +
> +#define EDMA_TCD_ATTR_DSIZE(x)		(((x) & 0x0007))
> +#define EDMA_TCD_ATTR_DMOD(x)		(((x) & 0x001F) << 3)
> +#define EDMA_TCD_ATTR_SSIZE(x)		(((x) & 0x0007) << 8)
> +#define EDMA_TCD_ATTR_SMOD(x)		(((x) & 0x001F) << 11)
> +#define EDMA_TCD_ATTR_SSIZE_8BIT	(0x0000)
> +#define EDMA_TCD_ATTR_SSIZE_16BIT	(0x0100)
> +#define EDMA_TCD_ATTR_SSIZE_32BIT	(0x0200)
> +#define EDMA_TCD_ATTR_SSIZE_64BIT	(0x0300)
> +#define EDMA_TCD_ATTR_SSIZE_32BYTE	(0x0500)
> +#define EDMA_TCD_ATTR_DSIZE_8BIT	(0x0000)
> +#define EDMA_TCD_ATTR_DSIZE_16BIT	(0x0001)
> +#define EDMA_TCD_ATTR_DSIZE_32BIT	(0x0002)
> +#define EDMA_TCD_ATTR_DSIZE_64BIT	(0x0003)
> +#define EDMA_TCD_ATTR_DSIZE_32BYTE	(0x0005)
> +
> +#define EDMA_TCD_SOFF_SOFF(x)		(x)
> +#define EDMA_TCD_NBYTES_NBYTES(x)	(x)
> +#define EDMA_TCD_SLAST_SLAST(x)		(x)
> +#define EDMA_TCD_DADDR_DADDR(x)		(x)
> +#define EDMA_TCD_CITER_CITER(x)		((x) & 0x7FFF)
> +#define EDMA_TCD_DOFF_DOFF(x)		(x)
> +#define EDMA_TCD_DLAST_SGA_DLAST_SGA(x)	(x)
> +#define EDMA_TCD_BITER_BITER(x)		((x) & 0x7FFF)
> +
> +#define EDMA_TCD_CSR_START		BIT(0)
> +#define EDMA_TCD_CSR_INT_MAJOR		BIT(1)
> +#define EDMA_TCD_CSR_INT_HALF		BIT(2)
> +#define EDMA_TCD_CSR_D_REQ		BIT(3)
> +#define EDMA_TCD_CSR_E_SG		BIT(4)
> +#define EDMA_TCD_CSR_E_LINK		BIT(5)
> +#define EDMA_TCD_CSR_ACTIVE		BIT(6)
> +#define EDMA_TCD_CSR_DONE		BIT(7)
> +
> +#define EDMAMUX_CHCFG_DIS		0x0
> +#define EDMAMUX_CHCFG_ENBL		0x80
> +#define EDMAMUX_CHCFG_SOURCE(n)		((n) & 0x3F)
> +
> +#define DMAMUX_NR	2
> +
> +#define FSL_EDMA_BUSWIDTHS	BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
> +				BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
> +				BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \
> +				BIT(DMA_SLAVE_BUSWIDTH_8_BYTES)
> +
> +struct fsl_edma_hw_tcd {
> +	u32	saddr;
> +	u16	soff;
> +	u16	attr;
> +	u32	nbytes;
> +	u32	slast;
> +	u32	daddr;
> +	u16	doff;
> +	u16	citer;
> +	u32	dlast_sga;
> +	u16	csr;
> +	u16	biter;
> +};
> +
> +struct fsl_edma_sw_tcd {
> +	dma_addr_t			ptcd;
> +	struct fsl_edma_hw_tcd		*vtcd;
> +};
> +
> +struct fsl_edma_slave_config {
> +	enum dma_transfer_direction	dir;
> +	enum dma_slave_buswidth		addr_width;
> +	u32				dev_addr;
> +	u32				burst;
> +	u32				attr;
> +};
> +
> +struct fsl_edma_chan {
> +	struct virt_dma_chan		vchan;
> +	enum dma_status			status;
> +	struct fsl_edma_engine		*edma;
> +	struct fsl_edma_desc		*edesc;
> +	struct fsl_edma_slave_config	fsc;
> +	struct dma_pool			*tcd_pool;
> +};
> +
> +struct fsl_edma_desc {
> +	struct virt_dma_desc		vdesc;
> +	struct fsl_edma_chan		*echan;
> +	bool				iscyclic;
> +	unsigned int			n_tcds;
> +	struct fsl_edma_sw_tcd		tcd[];
> +};
> +
> +struct fsl_edma_engine {
> +	struct dma_device	dma_dev;
> +	void __iomem		*membase;
> +	void __iomem		*muxbase[DMAMUX_NR];
> +	struct clk		*muxclk[DMAMUX_NR];
> +	struct mutex		fsl_edma_mutex;
> +	u32			n_chans;
> +	int			txirq;
> +	int			errirq;
> +	bool			big_endian;
> +	struct fsl_edma_chan	chans[];
> +};
> +
> +/*
> + * R/W functions for big- or little-endian registers
> + * the eDMA controller's endian is independent of the CPU core's endian.
> + */
> +
> +static u16 edma_readw(struct fsl_edma_engine *edma, void __iomem *addr)
> +{
> +	if (edma->big_endian)
> +		return ioread16be(addr);
> +	else
> +		return ioread16(addr);
> +}
> +
> +static u32 edma_readl(struct fsl_edma_engine *edma, void __iomem *addr)
> +{
> +	if (edma->big_endian)
> +		return ioread32be(addr);
> +	else
> +		return ioread32(addr);
> +}
> +
> +static void edma_writeb(struct fsl_edma_engine *edma, u8 val, void
> __iomem *addr)
> +{
> +	iowrite8(val, addr);
> +}
> +
> +static void edma_writew(struct fsl_edma_engine *edma, u16 val, void
> __iomem *addr)
> +{
> +	if (edma->big_endian)
> +		iowrite16be(val, addr);
> +	else
> +		iowrite16(val, addr);
> +}
> +
> +static void edma_writel(struct fsl_edma_engine *edma, u32 val, void
> __iomem *addr)
> +{
> +	if (edma->big_endian)
> +		iowrite32be(val, addr);
> +	else
> +		iowrite32(val, addr);
> +}
> +
> +static struct fsl_edma_chan *to_fsl_edma_chan(struct dma_chan *chan)
> +{
> +	return container_of(chan, struct fsl_edma_chan, vchan.chan);
> +}
> +
> +static struct fsl_edma_desc *to_fsl_edma_desc(struct virt_dma_desc *vd)
> +{
> +	return container_of(vd, struct fsl_edma_desc, vdesc);
> +}
> +
> +static void fsl_edma_enable_request(struct fsl_edma_chan *fsl_chan)
> +{
> +	void __iomem *addr = fsl_chan->edma->membase;
> +	u32 ch = fsl_chan->vchan.chan.chan_id;
> +
> +	edma_writeb(fsl_chan->edma, EDMA_SEEI_SEEI(ch), addr + EDMA_SEEI);
> +	edma_writeb(fsl_chan->edma, ch, addr + EDMA_SERQ);
> +}
> +
> +static void fsl_edma_disable_request(struct fsl_edma_chan *fsl_chan)
> +{
> +	void __iomem *addr = fsl_chan->edma->membase;
> +	u32 ch = fsl_chan->vchan.chan.chan_id;
> +
> +	edma_writeb(fsl_chan->edma, ch, addr + EDMA_CERQ);
> +	edma_writeb(fsl_chan->edma, EDMA_CEEI_CEEI(ch), addr + EDMA_CEEI);
> +}
> +
> +static void fsl_edma_chan_mux(struct fsl_edma_chan *fsl_chan,
> +			unsigned int slot, bool enable)
> +{
> +	u32 ch = fsl_chan->vchan.chan.chan_id;
> +	void __iomem *muxaddr = fsl_chan->edma->muxbase[ch / DMAMUX_NR];
> +	unsigned chans_per_mux, ch_off;
> +
> +	chans_per_mux = fsl_chan->edma->n_chans / DMAMUX_NR;
> +	ch_off = fsl_chan->vchan.chan.chan_id % chans_per_mux;
> +
> +	if (enable)
> +		edma_writeb(fsl_chan->edma,
> +				EDMAMUX_CHCFG_ENBL | EDMAMUX_CHCFG_SOURCE(slot),
> +				muxaddr + ch_off);
> +	else
> +		edma_writeb(fsl_chan->edma, EDMAMUX_CHCFG_DIS, muxaddr +
> ch_off);
> +}
> +
> +static unsigned int fsl_edma_get_tcd_attr(enum dma_slave_buswidth
> addr_width)
> +{
> +	switch (addr_width) {
> +	case 1:
> +		return EDMA_TCD_ATTR_SSIZE_8BIT | EDMA_TCD_ATTR_DSIZE_8BIT;
> +	case 2:
> +		return EDMA_TCD_ATTR_SSIZE_16BIT | EDMA_TCD_ATTR_DSIZE_16BIT;
> +	case 4:
> +		return EDMA_TCD_ATTR_SSIZE_32BIT | EDMA_TCD_ATTR_DSIZE_32BIT;
> +	case 8:
> +		return EDMA_TCD_ATTR_SSIZE_64BIT | EDMA_TCD_ATTR_DSIZE_64BIT;
> +	default:
> +		return EDMA_TCD_ATTR_SSIZE_32BIT | EDMA_TCD_ATTR_DSIZE_32BIT;
> +	}
> +}
> +
> +static void fsl_edma_free_desc(struct virt_dma_desc *vdesc)
> +{
> +	struct fsl_edma_desc *fsl_desc;
> +	int i;
> +
> +	fsl_desc = to_fsl_edma_desc(vdesc);
> +	for (i = 0; i < fsl_desc->n_tcds; i++)
> +			dma_pool_free(fsl_desc->echan->tcd_pool,
> +					fsl_desc->tcd[i].vtcd,
> +					fsl_desc->tcd[i].ptcd);
> +	kfree(fsl_desc);
> +}
> +
> +static int fsl_edma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
> +		unsigned long arg)
> +{
> +	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
> +	struct dma_slave_config *cfg = (void *)arg;
> +	unsigned long flags;
> +	LIST_HEAD(head);
> +
> +	switch (cmd) {
> +	case DMA_TERMINATE_ALL:
> +		spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
> +		fsl_edma_disable_request(fsl_chan);
> +		fsl_chan->edesc = NULL;
> +		vchan_get_all_descriptors(&fsl_chan->vchan, &head);
> +		spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
> +		vchan_dma_desc_free_list(&fsl_chan->vchan, &head);
> +		return 0;
> +
> +	case DMA_SLAVE_CONFIG:
> +		fsl_chan->fsc.dir = cfg->direction;
> +		if (cfg->direction == DMA_DEV_TO_MEM) {
> +			fsl_chan->fsc.dev_addr = cfg->src_addr;
> +			fsl_chan->fsc.addr_width = cfg->src_addr_width;
> +			fsl_chan->fsc.burst = cfg->src_maxburst;
> +			fsl_chan->fsc.attr = fsl_edma_get_tcd_attr(cfg-
> >src_addr_width);
> +		} else if (cfg->direction == DMA_MEM_TO_DEV) {
> +			fsl_chan->fsc.dev_addr = cfg->dst_addr;
> +			fsl_chan->fsc.addr_width = cfg->dst_addr_width;
> +			fsl_chan->fsc.burst = cfg->dst_maxburst;
> +			fsl_chan->fsc.attr = fsl_edma_get_tcd_attr(cfg-
> >dst_addr_width);
> +		} else {
> +			return -EINVAL;
> +		}
> +		return 0;
> +
> +	case DMA_PAUSE:
> +		spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
> +		if (fsl_chan->edesc) {
> +			fsl_edma_disable_request(fsl_chan);
> +			fsl_chan->status = DMA_PAUSED;
> +		}
> +		spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
> +		return 0;
> +
> +	case DMA_RESUME:
> +		spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
> +		if (fsl_chan->edesc) {
> +			fsl_edma_enable_request(fsl_chan);
> +			fsl_chan->status = DMA_IN_PROGRESS;
> +		}
> +		spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
> +		return 0;
> +
> +	default:
> +		return -ENXIO;
> +	}
> +}
> +
> +static size_t fsl_edma_desc_residue(struct fsl_edma_chan *fsl_chan,
> +		struct virt_dma_desc *vdesc, bool in_progress)
> +{
> +	struct fsl_edma_desc *edesc = fsl_chan->edesc;
> +	void __iomem *addr = fsl_chan->edma->membase;
> +	u32 ch = fsl_chan->vchan.chan.chan_id;
> +	enum dma_transfer_direction dir = fsl_chan->fsc.dir;
> +	dma_addr_t cur_addr, dma_addr;
> +	size_t len, size;
> +	int i;
> +
> +	/* calculate the total size in this desc */
> +	for (len = i = 0; i < fsl_chan->edesc->n_tcds; i++)
> +		len += edma_readl(fsl_chan->edma, &(edesc->tcd[i].vtcd-
> >nbytes))
> +			* edma_readw(fsl_chan->edma, &(edesc->tcd[i].vtcd-
> >biter));
> +
> +	if (!in_progress)
> +		return len;
> +
> +	if (dir == DMA_MEM_TO_DEV)
> +		cur_addr = edma_readl(fsl_chan->edma, addr +
> EDMA_TCD_SADDR(ch));
> +	else
> +		cur_addr = edma_readl(fsl_chan->edma, addr +
> EDMA_TCD_DADDR(ch));
> +
> +	/* figure out the finished and calculate the residue */
> +	for (i = 0; i < fsl_chan->edesc->n_tcds; i++) {
> +		size = edma_readl(fsl_chan->edma, &(edesc->tcd[i].vtcd-
> >nbytes))
> +			* edma_readw(fsl_chan->edma, &(edesc->tcd[i].vtcd-
> >biter));
> +		if (dir == DMA_MEM_TO_DEV)
> +			dma_addr = edma_readl(fsl_chan->edma,
> +					&(edesc->tcd[i].vtcd->saddr));
> +		else
> +			dma_addr = edma_readl(fsl_chan->edma,
> +					&(edesc->tcd[i].vtcd->daddr));
> +
> +		len -= size;
> +		if (cur_addr > dma_addr && cur_addr < dma_addr + size) {
> +			len += dma_addr + size - cur_addr;
> +			break;
> +		}
> +	}
> +
> +	return len;
> +}
> +
> +static enum dma_status fsl_edma_tx_status(struct dma_chan *chan,
> +		dma_cookie_t cookie, struct dma_tx_state *txstate)
> +{
> +	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
> +	struct virt_dma_desc *vdesc;
> +	enum dma_status status;
> +	unsigned long flags;
> +
> +	status = dma_cookie_status(chan, cookie, txstate);
> +	if (status == DMA_COMPLETE)
> +		return status;
> +
> +	if (!txstate)
> +		return fsl_chan->status;
> +
> +	spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
> +	vdesc = vchan_find_desc(&fsl_chan->vchan, cookie);
> +	if (fsl_chan->edesc && cookie == fsl_chan->edesc->vdesc.tx.cookie)
> +		txstate->residue = fsl_edma_desc_residue(fsl_chan, vdesc,
> true);
> +	else if (vdesc)
> +		txstate->residue = fsl_edma_desc_residue(fsl_chan, vdesc,
> false);
> +	else
> +		txstate->residue = 0;
> +
> +	spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
> +
> +	return fsl_chan->status;
> +}
> +
> +static void fsl_edma_set_tcd_params(struct fsl_edma_chan *fsl_chan,
> +		u32 src, u32 dst, u16 attr, u16 soff, u32 nbytes,
> +		u32 slast, u16 citer, u16 biter, u32 doff, u32 dlast_sga,
> +		u16 csr)
> +{
> +	void __iomem *addr = fsl_chan->edma->membase;
> +	u32 ch = fsl_chan->vchan.chan.chan_id;
> +
> +	/*
> +	 * TCD parameters have been swapped in fill_tcd_params(),
> +	 * so just write them to registers in the cpu endian here
> +	 */
> +	writew(0, addr + EDMA_TCD_CSR(ch));
> +	writel(src, addr + EDMA_TCD_SADDR(ch));
> +	writel(dst, addr + EDMA_TCD_DADDR(ch));
> +	writew(attr, addr + EDMA_TCD_ATTR(ch));
> +	writew(soff, addr + EDMA_TCD_SOFF(ch));
> +	writel(nbytes, addr + EDMA_TCD_NBYTES(ch));
> +	writel(slast, addr + EDMA_TCD_SLAST(ch));
> +	writew(citer, addr + EDMA_TCD_CITER(ch));
> +	writew(biter, addr + EDMA_TCD_BITER(ch));
> +	writew(doff, addr + EDMA_TCD_DOFF(ch));
> +	writel(dlast_sga, addr + EDMA_TCD_DLAST_SGA(ch));
> +	writew(csr, addr + EDMA_TCD_CSR(ch));
> +}
> +
> +static void fill_tcd_params(struct fsl_edma_engine *edma,
> +		struct fsl_edma_hw_tcd *tcd, u32 src, u32 dst,
> +		u16 attr, u16 soff, u32 nbytes, u32 slast, u16 citer,
> +		u16 biter, u16 doff, u32 dlast_sga, bool major_int,
> +		bool disable_req, bool enable_sg)
> +{
> +	u16 csr = 0;
> +
> +	/*
> +	 * eDMA hardware SGs require the TCD parameters stored in memory
> +	 * the same endian as the eDMA module so that they can be loaded
> +	 * automatically by the engine
> +	 */
> +	edma_writel(edma, src, &(tcd->saddr));
> +	edma_writel(edma, dst, &(tcd->daddr));
> +	edma_writew(edma, attr, &(tcd->attr));
> +	edma_writew(edma, EDMA_TCD_SOFF_SOFF(soff), &(tcd->soff));
> +	edma_writel(edma, EDMA_TCD_NBYTES_NBYTES(nbytes), &(tcd->nbytes));
> +	edma_writel(edma, EDMA_TCD_SLAST_SLAST(slast), &(tcd->slast));
> +	edma_writew(edma, EDMA_TCD_CITER_CITER(citer), &(tcd->citer));
> +	edma_writew(edma, EDMA_TCD_DOFF_DOFF(doff), &(tcd->doff));
> +	edma_writel(edma, EDMA_TCD_DLAST_SGA_DLAST_SGA(dlast_sga), &(tcd-
> >dlast_sga));
> +	edma_writew(edma, EDMA_TCD_BITER_BITER(biter), &(tcd->biter));
> +	if (major_int)
> +		csr |= EDMA_TCD_CSR_INT_MAJOR;
> +
> +	if (disable_req)
> +		csr |= EDMA_TCD_CSR_D_REQ;
> +
> +	if (enable_sg)
> +		csr |= EDMA_TCD_CSR_E_SG;
> +
> +	edma_writew(edma, csr, &(tcd->csr));
> +}
> +
> +static struct fsl_edma_desc *fsl_edma_alloc_desc(struct fsl_edma_chan
> *fsl_chan,
> +		int sg_len)
> +{
> +	struct fsl_edma_desc *fsl_desc;
> +	int i;
> +
> +	fsl_desc = kzalloc(sizeof(*fsl_desc) + sizeof(struct
> fsl_edma_sw_tcd) * sg_len,
> +				GFP_NOWAIT);
> +	if (!fsl_desc)
> +		return NULL;
> +
> +	fsl_desc->echan = fsl_chan;
> +	fsl_desc->n_tcds = sg_len;
> +	for (i = 0; i < sg_len; i++) {
> +		fsl_desc->tcd[i].vtcd = dma_pool_alloc(fsl_chan->tcd_pool,
> +					GFP_NOWAIT, &fsl_desc->tcd[i].ptcd);
> +		if (!fsl_desc->tcd[i].vtcd)
> +			goto err;
> +	}
> +	return fsl_desc;
> +
> +err:
> +	while (--i >= 0)
> +		dma_pool_free(fsl_chan->tcd_pool, fsl_desc->tcd[i].vtcd,
> +				fsl_desc->tcd[i].ptcd);
> +	kfree(fsl_desc);
> +	return NULL;
> +}
> +
> +static struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic(
> +		struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len,
> +		size_t period_len, enum dma_transfer_direction direction,
> +		unsigned long flags, void *context)
> +{
> +	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
> +	struct fsl_edma_desc *fsl_desc;
> +	dma_addr_t dma_buf_next;
> +	int sg_len, i;
> +	u32 src_addr, dst_addr, last_sg, nbytes;
> +	u16 soff, doff, iter;
> +
> +	if (!is_slave_direction(fsl_chan->fsc.dir))
> +		return NULL;
> +
> +	sg_len = buf_len / period_len;
> +	fsl_desc = fsl_edma_alloc_desc(fsl_chan, sg_len);
> +	if (!fsl_desc)
> +		return NULL;
> +	fsl_desc->iscyclic = true;
> +
> +	dma_buf_next = dma_addr;
> +	nbytes = fsl_chan->fsc.addr_width * fsl_chan->fsc.burst;
> +	iter = period_len / nbytes;
> +
> +	for (i = 0; i < sg_len; i++) {
> +		if (dma_buf_next >= dma_addr + buf_len)
> +			dma_buf_next = dma_addr;
> +
> +		/* get next sg's physical address */
> +		last_sg = fsl_desc->tcd[(i + 1) % sg_len].ptcd;
> +
> +		if (fsl_chan->fsc.dir == DMA_MEM_TO_DEV) {
> +			src_addr = dma_buf_next;
> +			dst_addr = fsl_chan->fsc.dev_addr;
> +			soff = fsl_chan->fsc.addr_width;
> +			doff = 0;
> +		} else {
> +			src_addr = fsl_chan->fsc.dev_addr;
> +			dst_addr = dma_buf_next;
> +			soff = 0;
> +			doff = fsl_chan->fsc.addr_width;
> +		}
> +
> +		fill_tcd_params(fsl_chan->edma, fsl_desc->tcd[i].vtcd,
> src_addr,
> +				dst_addr, fsl_chan->fsc.attr, soff, nbytes, 0,
> +				iter, iter, doff, last_sg, true, false, true);
> +		dma_buf_next += period_len;
> +	}
> +
> +	return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags);
> +}
> +
> +static struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg(
> +		struct dma_chan *chan, struct scatterlist *sgl,
> +		unsigned int sg_len, enum dma_transfer_direction direction,
> +		unsigned long flags, void *context)
> +{
> +	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
> +	struct fsl_edma_desc *fsl_desc;
> +	struct scatterlist *sg;
> +	u32 src_addr, dst_addr, last_sg, nbytes;
> +	u16 soff, doff, iter;
> +	int i;
> +
> +	if (!is_slave_direction(fsl_chan->fsc.dir))
> +		return NULL;
> +
> +	fsl_desc = fsl_edma_alloc_desc(fsl_chan, sg_len);
> +	if (!fsl_desc)
> +		return NULL;
> +	fsl_desc->iscyclic = false;
> +
> +	nbytes = fsl_chan->fsc.addr_width * fsl_chan->fsc.burst;
> +	for_each_sg(sgl, sg, sg_len, i) {
> +		/* get next sg's physical address */
> +		last_sg = fsl_desc->tcd[(i + 1) % sg_len].ptcd;
> +
> +		if (fsl_chan->fsc.dir == DMA_MEM_TO_DEV) {
> +			src_addr = sg_dma_address(sg);
> +			dst_addr = fsl_chan->fsc.dev_addr;
> +			soff = fsl_chan->fsc.addr_width;
> +			doff = 0;
> +		} else {
> +			src_addr = fsl_chan->fsc.dev_addr;
> +			dst_addr = sg_dma_address(sg);
> +			soff = 0;
> +			doff = fsl_chan->fsc.addr_width;
> +		}
> +
> +		iter = sg_dma_len(sg) / nbytes;
> +		if (i < sg_len - 1) {
> +			last_sg = fsl_desc->tcd[(i + 1)].ptcd;
> +			fill_tcd_params(fsl_chan->edma, fsl_desc->tcd[i].vtcd,
> +					src_addr, dst_addr, fsl_chan->fsc.attr,
> +					soff, nbytes, 0, iter, iter, doff, last_sg,
> +					false, false, true);
> +		} else {
> +			last_sg = 0;
> +			fill_tcd_params(fsl_chan->edma, fsl_desc->tcd[i].vtcd,
> +					src_addr, dst_addr, fsl_chan->fsc.attr,
> +					soff, nbytes, 0, iter, iter, doff, last_sg,
> +					true, true, false);
> +		}
> +	}
> +
> +	return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags);
> +}
> +
> +static void fsl_edma_xfer_desc(struct fsl_edma_chan *fsl_chan)
> +{
> +	struct fsl_edma_hw_tcd *tcd;
> +	struct virt_dma_desc *vdesc;
> +
> +	vdesc = vchan_next_desc(&fsl_chan->vchan);
> +	if (!vdesc)
> +		return;
> +	fsl_chan->edesc = to_fsl_edma_desc(vdesc);
> +	tcd = fsl_chan->edesc->tcd[0].vtcd;
> +	fsl_edma_set_tcd_params(fsl_chan, tcd->saddr, tcd->daddr, tcd->attr,
> +			tcd->soff, tcd->nbytes, tcd->slast, tcd->citer,
> +			tcd->biter, tcd->doff, tcd->dlast_sga, tcd->csr);
> +	fsl_edma_enable_request(fsl_chan);
> +	fsl_chan->status = DMA_IN_PROGRESS;
> +}
> +
> +static irqreturn_t fsl_edma_tx_handler(int irq, void *dev_id)
> +{
> +	struct fsl_edma_engine *fsl_edma = dev_id;
> +	unsigned int intr, ch;
> +	void __iomem *base_addr;
> +	struct fsl_edma_chan *fsl_chan;
> +
> +	base_addr = fsl_edma->membase;
> +
> +	intr = edma_readl(fsl_edma, base_addr + EDMA_INTR);
> +	if (!intr)
> +		return IRQ_NONE;
> +
> +	for (ch = 0; ch < fsl_edma->n_chans; ch++) {
> +		if (intr & (0x1 << ch)) {
> +			edma_writeb(fsl_edma, EDMA_CINT_CINT(ch),
> +				base_addr + EDMA_CINT);
> +
> +			fsl_chan = &fsl_edma->chans[ch];
> +
> +			spin_lock(&fsl_chan->vchan.lock);
> +			if (!fsl_chan->edesc->iscyclic) {
> +				list_del(&fsl_chan->edesc->vdesc.node);
> +				vchan_cookie_complete(&fsl_chan->edesc->vdesc);
> +				fsl_chan->edesc = NULL;
> +				fsl_chan->status = DMA_COMPLETE;
> +			} else {
> +				vchan_cyclic_callback(&fsl_chan->edesc->vdesc);
> +			}
> +
> +			if (!fsl_chan->edesc)
> +				fsl_edma_xfer_desc(fsl_chan);
> +
> +			spin_unlock(&fsl_chan->vchan.lock);
> +		}
> +	}
> +	return IRQ_HANDLED;
> +}
> +
> +static irqreturn_t fsl_edma_err_handler(int irq, void *dev_id)
> +{
> +	struct fsl_edma_engine *fsl_edma = dev_id;
> +	unsigned int err, ch;
> +
> +	err = edma_readl(fsl_edma, fsl_edma->membase + EDMA_ERR);
> +	if (!err)
> +		return IRQ_NONE;
> +
> +	for (ch = 0; ch < fsl_edma->n_chans; ch++) {
> +		if (err & (0x1 << ch)) {
> +			fsl_edma_disable_request(&fsl_edma->chans[ch]);
> +			edma_writeb(fsl_edma, EDMA_CERR_CERR(ch),
> +				fsl_edma->membase + EDMA_CERR);
> +			fsl_edma->chans[ch].status = DMA_ERROR;
> +		}
> +	}
> +	return IRQ_HANDLED;
> +}
> +
> +static irqreturn_t fsl_edma_irq_handler(int irq, void *dev_id)
> +{
> +	if (fsl_edma_tx_handler(irq, dev_id) == IRQ_HANDLED)
> +		return IRQ_HANDLED;
> +
> +	return fsl_edma_err_handler(irq, dev_id);
> +}
> +
> +static void fsl_edma_issue_pending(struct dma_chan *chan)
> +{
> +	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
> +
> +	if (vchan_issue_pending(&fsl_chan->vchan) && !fsl_chan->edesc)
> +		fsl_edma_xfer_desc(fsl_chan);
> +
> +	spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
> +}
> +
> +static struct dma_chan *fsl_edma_xlate(struct of_phandle_args *dma_spec,
> +		struct of_dma *ofdma)
> +{
> +	struct fsl_edma_engine *fsl_edma = ofdma->of_dma_data;
> +	struct dma_chan *chan;
> +
> +	if (dma_spec->args_count != 2)
> +		return NULL;
> +
> +	mutex_lock(&fsl_edma->fsl_edma_mutex);
> +	list_for_each_entry(chan, &fsl_edma->dma_dev.channels, device_node)
> {
> +		if (chan->client_count)
> +			continue;
> +		if ((chan->chan_id / DMAMUX_NR) == dma_spec->args[0]) {
> +			chan = dma_get_slave_channel(chan);
> +			if (chan) {
> +				chan->device->privatecnt++;
> +				fsl_edma_chan_mux(to_fsl_edma_chan(chan),
> +					dma_spec->args[1], true);
> +				mutex_unlock(&fsl_edma->fsl_edma_mutex);
> +				return chan;
> +			}
> +		}
> +	}
> +	mutex_unlock(&fsl_edma->fsl_edma_mutex);
> +	return NULL;
> +}
> +
> +static int fsl_edma_alloc_chan_resources(struct dma_chan *chan)
> +{
> +	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
> +
> +	fsl_chan->tcd_pool = dma_pool_create("tcd_pool", chan->device->dev,
> +				sizeof(struct fsl_edma_hw_tcd),
> +				32, 0);
> +	return 0;
> +}
> +
> +static void fsl_edma_free_chan_resources(struct dma_chan *chan)
> +{
> +	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
> +	unsigned long flags;
> +	LIST_HEAD(head);
> +
> +	spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
> +	fsl_edma_disable_request(fsl_chan);
> +	fsl_edma_chan_mux(fsl_chan, 0, false);
> +	fsl_chan->edesc = NULL;
> +	vchan_get_all_descriptors(&fsl_chan->vchan, &head);
> +	spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
> +
> +	vchan_dma_desc_free_list(&fsl_chan->vchan, &head);
> +	dma_pool_destroy(fsl_chan->tcd_pool);
> +	fsl_chan->tcd_pool = NULL;
> +}
> +
> +static int fsl_dma_device_slave_caps(struct dma_chan *dchan,
> +		struct dma_slave_caps *caps)
> +{
> +	caps->src_addr_widths = FSL_EDMA_BUSWIDTHS;
> +	caps->dstn_addr_widths = FSL_EDMA_BUSWIDTHS;
> +	caps->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
> +	caps->cmd_pause = true;
> +	caps->cmd_terminate = true;
> +
> +	return 0;
> +}
> +
> +static int
> +fsl_edma_irq_init(struct platform_device *pdev, struct fsl_edma_engine
> *fsl_edma)
> +{
> +	int ret;
> +
> +	fsl_edma->txirq = platform_get_irq_byname(pdev, "edma-tx");
> +	if (fsl_edma->txirq < 0) {
> +		dev_err(&pdev->dev, "Can't get edma-tx irq.\n");
> +		return fsl_edma->txirq;
> +	}
> +
> +	fsl_edma->errirq = platform_get_irq_byname(pdev, "edma-err");
> +	if (fsl_edma->errirq < 0) {
> +		dev_err(&pdev->dev, "Can't get edma-err irq.\n");
> +		return fsl_edma->errirq;
> +	}
> +
> +	if (fsl_edma->txirq == fsl_edma->errirq) {
> +		ret = devm_request_irq(&pdev->dev, fsl_edma->txirq,
> +				fsl_edma_irq_handler, 0, "eDMA", fsl_edma);
> +		if (ret) {
> +			dev_err(&pdev->dev, "Can't register eDMA IRQ.\n");
> +			 return  ret;
> +		}
> +	} else {
> +		ret = devm_request_irq(&pdev->dev, fsl_edma->txirq,
> +				fsl_edma_tx_handler, 0, "eDMA tx", fsl_edma);
> +		if (ret) {
> +			dev_err(&pdev->dev, "Can't register eDMA tx IRQ.\n");
> +			return  ret;
> +		}
> +
> +		ret = devm_request_irq(&pdev->dev, fsl_edma->errirq,
> +				fsl_edma_err_handler, 0, "eDMA err", fsl_edma);
> +		if (ret) {
> +			dev_err(&pdev->dev, "Can't register eDMA err IRQ.\n");
> +			return  ret;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static int fsl_edma_probe(struct platform_device *pdev)
> +{
> +	struct device_node *np = pdev->dev.of_node;
> +	struct fsl_edma_engine *fsl_edma;
> +	struct fsl_edma_chan *fsl_chan;
> +	struct resource *res;
> +	int len, chans;
> +	int ret, i;
> +
> +	ret = of_property_read_u32(np, "dma-channels", &chans);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Can't get dma-channels.\n");
> +		return ret;
> +	}
> +
> +	len = sizeof(*fsl_edma) + sizeof(*fsl_chan) * chans;
> +	fsl_edma = devm_kzalloc(&pdev->dev, len, GFP_KERNEL);
> +	if (!fsl_edma)
> +		return -ENOMEM;
> +
> +	fsl_edma->n_chans = chans;
> +	mutex_init(&fsl_edma->fsl_edma_mutex);
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	fsl_edma->membase = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(fsl_edma->membase))
> +		return PTR_ERR(fsl_edma->membase);
> +
> +	for (i = 0; i < DMAMUX_NR; i++) {
> +		char clkname[32];
> +
> +		res = platform_get_resource(pdev, IORESOURCE_MEM, 1 + i);
> +		fsl_edma->muxbase[i] = devm_ioremap_resource(&pdev->dev, res);
> +		if (IS_ERR(fsl_edma->muxbase[i]))
> +			return PTR_ERR(fsl_edma->muxbase[i]);
> +
> +		sprintf(clkname, "dmamux%d", i);
> +		fsl_edma->muxclk[i] = devm_clk_get(&pdev->dev, clkname);
> +		if (IS_ERR(fsl_edma->muxclk[i])) {
> +			dev_err(&pdev->dev, "Missing DMAMUX block clock.\n");
> +			return PTR_ERR(fsl_edma->muxclk[i]);
> +		}
> +
> +		ret = clk_prepare_enable(fsl_edma->muxclk[i]);
> +		if (ret) {
> +			dev_err(&pdev->dev, "DMAMUX clk block failed.\n");
> +			return ret;
> +		}
> +
> +	}
> +
> +	ret = fsl_edma_irq_init(pdev, fsl_edma);
> +	if (ret)
> +		return ret;
> +
> +	fsl_edma->big_endian = of_property_read_bool(np, "big-endian");
> +
> +	INIT_LIST_HEAD(&fsl_edma->dma_dev.channels);
> +	for (i = 0; i < fsl_edma->n_chans; i++) {
> +		struct fsl_edma_chan *fsl_chan = &fsl_edma->chans[i];
> +
> +		fsl_chan->edma = fsl_edma;
> +
> +		fsl_chan->vchan.desc_free = fsl_edma_free_desc;
> +		vchan_init(&fsl_chan->vchan, &fsl_edma->dma_dev);
> +
> +		edma_writew(fsl_edma, 0x0, fsl_edma->membase +
> EDMA_TCD_CSR(i));
> +		fsl_edma_chan_mux(fsl_chan, 0, false);
> +	}
> +
> +	dma_cap_set(DMA_PRIVATE, fsl_edma->dma_dev.cap_mask);
> +	dma_cap_set(DMA_SLAVE, fsl_edma->dma_dev.cap_mask);
> +	dma_cap_set(DMA_CYCLIC, fsl_edma->dma_dev.cap_mask);
> +
> +	fsl_edma->dma_dev.dev = &pdev->dev;
> +	fsl_edma->dma_dev.device_alloc_chan_resources
> +		= fsl_edma_alloc_chan_resources;
> +	fsl_edma->dma_dev.device_free_chan_resources
> +		= fsl_edma_free_chan_resources;
> +	fsl_edma->dma_dev.device_tx_status = fsl_edma_tx_status;
> +	fsl_edma->dma_dev.device_prep_slave_sg = fsl_edma_prep_slave_sg;
> +	fsl_edma->dma_dev.device_prep_dma_cyclic = fsl_edma_prep_dma_cyclic;
> +	fsl_edma->dma_dev.device_control = fsl_edma_control;
> +	fsl_edma->dma_dev.device_issue_pending = fsl_edma_issue_pending;
> +	fsl_edma->dma_dev.device_slave_caps = fsl_dma_device_slave_caps;
> +
> +	platform_set_drvdata(pdev, fsl_edma);
> +
> +	ret = dma_async_device_register(&fsl_edma->dma_dev);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Can't register Freescale eDMA
> engine.\n");
> +		return ret;
> +	}
> +
> +	ret = of_dma_controller_register(np, fsl_edma_xlate, fsl_edma);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Can't register Freescale eDMA
> of_dma.\n");
> +		dma_async_device_unregister(&fsl_edma->dma_dev);
> +		return ret;
> +	}
> +
> +	/* enable round robin arbitration */
> +	edma_writel(fsl_edma, EDMA_CR_ERGA | EDMA_CR_ERCA, fsl_edma-
> >membase + EDMA_CR);
> +
> +	return 0;
> +}
> +
> +static int fsl_edma_remove(struct platform_device *pdev)
> +{
> +	struct device_node *np = pdev->dev.of_node;
> +	struct fsl_edma_engine *fsl_edma = platform_get_drvdata(pdev);
> +	int i;
> +
> +	of_dma_controller_free(np);
> +	dma_async_device_unregister(&fsl_edma->dma_dev);
> +
> +	for (i = 0; i < DMAMUX_NR; i++)
> +		clk_disable_unprepare(fsl_edma->muxclk[i]);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id fsl_edma_dt_ids[] = {
> +	{ .compatible = "fsl,vf610-edma", },
> +	{ /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, fsl_edma_dt_ids);
> +
> +static struct platform_driver fsl_edma_driver = {
> +	.driver		= {
> +		.name	= "fsl-edma",
> +		.owner  = THIS_MODULE,
> +		.of_match_table = fsl_edma_dt_ids,
> +	},
> +	.probe          = fsl_edma_probe,
> +	.remove		= fsl_edma_remove,
> +};
> +
> +module_platform_driver(fsl_edma_driver);
> +
> +MODULE_ALIAS("platform:fsl-edma");
> +MODULE_DESCRIPTION("Freescale eDMA engine driver");
> +MODULE_LICENSE("GPL v2");
> --
> 1.8.0
> 

^ permalink raw reply

* [PATCH v2 1/6] audit: Enable arm64 support
From: AKASHI Takahiro @ 2014-01-27  5:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140123141808.GD27520@arm.com>

[To audit maintainers]

On 01/23/2014 11:18 PM, Catalin Marinas wrote:
> On Fri, Jan 17, 2014 at 08:13:14AM +0000, AKASHI Takahiro wrote:
>> --- a/include/uapi/linux/audit.h
>> +++ b/include/uapi/linux/audit.h
>> @@ -327,6 +327,8 @@ enum {
>>   /* distinguish syscall tables */
>>   #define __AUDIT_ARCH_64BIT 0x80000000
>>   #define __AUDIT_ARCH_LE	   0x40000000
>> +#define AUDIT_ARCH_AARCH64	(EM_AARCH64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
>> +#define AUDIT_ARCH_AARCH64EB	(EM_AARCH64|__AUDIT_ARCH_64BIT)
>>   #define AUDIT_ARCH_ALPHA	(EM_ALPHA|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
>>   #define AUDIT_ARCH_ARM		(EM_ARM|__AUDIT_ARCH_LE)
>>   #define AUDIT_ARCH_ARMEB	(EM_ARM)
>> diff --git a/init/Kconfig b/init/Kconfig
>> index 79383d3..3aae602 100644
>> --- a/init/Kconfig
>> +++ b/init/Kconfig
>> @@ -284,7 +284,7 @@ config AUDIT
>>
>>   config AUDITSYSCALL
>>   	bool "Enable system-call auditing support"
>> -	depends on AUDIT && (X86 || PARISC || PPC || S390 || IA64 || UML || SPARC64 || SUPERH || (ARM && AEABI && !OABI_COMPAT))
>> +	depends on AUDIT && (X86 || PARISC || PPC || S390 || IA64 || UML || SPARC64 || SUPERH || (ARM && AEABI && !OABI_COMPAT) || ARM64)
>
> The usual comment for such changes: could you please clean this up and
> just use something like "depends on HAVE_ARCH_AUDITSYSCALL"?

Do you agree to this change?

If so, I can create a patch, but have some concerns:
1) I can't verify it on other architectures than (arm &) arm64.
2) Some architectures (microblaze, mips, openrisc) are not listed here, but
    their ptrace.c have a call to audit_syscall_entry/exit().
    (audit_syscall_entry/exit are null if !AUDITSYSCALL, though)
So I'm afraid that the change might break someone's assumption.

Thanks,
-Takahiro AKASHI

^ permalink raw reply

* [PATCH] input: pxa27x-keypad: bug fix of getting scan code
From: Chao Xie @ 2014-01-27  4:41 UTC (permalink / raw)
  To: linux-arm-kernel

From: Chao Xie <chao.xie@marvell.com>

The rows of pxa27x-keypad used by each boards are not fixed.
So in the driver, it will get the rows from DT and register
the keymap as:
matrix_keypad_build_keymap(keymap_data, NULL,
                           pdata->matrix_key_rows,
                           pdata->matrix_key_cols,
                           keypad->keycodes, input_dev);

But the scan code is gotten as
MATRIX_SCAN_CODE(row, col, MATRIX_ROW_SHIFT);
It is not correct. Fix it as
MATRIX_SCAN_CODE(row, col, keypad->row_shift);

row_shift is calculated from pdata->matrix_key_rows.

Signed-off-by: Chao Xie <chao.xie@marvell.com>
---
 drivers/input/keyboard/pxa27x_keypad.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c
index d8241ba..8da3eb0 100644
--- a/drivers/input/keyboard/pxa27x_keypad.c
+++ b/drivers/input/keyboard/pxa27x_keypad.c
@@ -113,6 +113,7 @@ struct pxa27x_keypad {
 
 	/* state row bits of each column scan */
 	uint32_t matrix_key_state[MAX_MATRIX_KEY_COLS];
+	uint32_t row_shift;
 	uint32_t direct_key_state;
 
 	unsigned int direct_key_mask;
@@ -139,6 +140,7 @@ static int pxa27x_keypad_matrix_key_parse_dt(struct pxa27x_keypad *keypad,
 	pdata->matrix_key_rows = rows;
 	pdata->matrix_key_cols = cols;
 
+	keypad->row_shift = get_count_order(pdata->matrix_key_cols);
 	error = matrix_keypad_build_keymap(NULL, NULL,
 					   pdata->matrix_key_rows,
 					   pdata->matrix_key_cols,
@@ -359,6 +361,7 @@ static int pxa27x_keypad_build_keycode(struct pxa27x_keypad *keypad)
 	if (error)
 		return error;
 
+	keypad->row_shift = get_count_order(pdata->matrix_key_cols);
 	/*
 	 * The keycodes may not only include matrix keys but also the direct
 	 * or rotary keys.
@@ -467,7 +470,8 @@ scan:
 			if ((bits_changed & (1 << row)) == 0)
 				continue;
 
-			code = MATRIX_SCAN_CODE(row, col, MATRIX_ROW_SHIFT);
+			code = MATRIX_SCAN_CODE(row, col, keypad->row_shift);
+
 			input_event(input_dev, EV_MSC, MSC_SCAN, code);
 			input_report_key(input_dev, keypad->keycodes[code],
 					 new_state[col] & (1 << row));
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH] dma: mmp_pdma: add IRQF_SHARED when request irq
From: Chao Xie @ 2014-01-27  1:44 UTC (permalink / raw)
  To: linux-arm-kernel

From: Chao Xie <chao.xie@marvell.com>

For some SOCes use mmp_pdma, they have several dma controllers
sharing same irq.
So add IRQF_SHARED to flag when request irq. It can make multiple
controllers share the same irq.

Signed-off-by: Chao Xie <chao.xie@marvell.com>
---
 drivers/dma/mmp_pdma.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c
index 32e58ee..b86415b 100644
--- a/drivers/dma/mmp_pdma.c
+++ b/drivers/dma/mmp_pdma.c
@@ -866,8 +866,8 @@ static int mmp_pdma_chan_init(struct mmp_pdma_device *pdev, int idx, int irq)
 	phy->base = pdev->base;
 
 	if (irq) {
-		ret = devm_request_irq(pdev->dev, irq, mmp_pdma_chan_handler, 0,
-				       "pdma", phy);
+		ret = devm_request_irq(pdev->dev, irq, mmp_pdma_chan_handler,
+				       IRQF_SHARED, "pdma", phy);
 		if (ret) {
 			dev_err(pdev->dev, "channel request irq fail!\n");
 			return ret;
@@ -964,8 +964,8 @@ static int mmp_pdma_probe(struct platform_device *op)
 	if (irq_num != dma_channels) {
 		/* all chan share one irq, demux inside */
 		irq = platform_get_irq(op, 0);
-		ret = devm_request_irq(pdev->dev, irq, mmp_pdma_int_handler, 0,
-				       "pdma", pdev);
+		ret = devm_request_irq(pdev->dev, irq, mmp_pdma_int_handler,
+				       IRQF_SHARED, "pdma", pdev);
 		if (ret)
 			return ret;
 	}
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH 4/4] ARM: OMAP2+: Add pdata quirk for sys_clkout2 for omap3 DBB056
From: Christoph Fritz @ 2014-01-27  0:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390782797-24105-1-git-send-email-chf.fritz@googlemail.com>

Full device tree support for clock control, especially to set frequencies,
is not yet accomplished. Until then, configure the 24Mhz of sys_clkout2 to
feed an USB-Hub here.

Signed-off-by: Christoph Fritz <chf.fritz@googlemail.com>
---
 arch/arm/mach-omap2/pdata-quirks.c |   37 ++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
index 435a823..e36ac3f 100644
--- a/arch/arm/mach-omap2/pdata-quirks.c
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -172,6 +172,43 @@ static void __init am3517_evm_legacy_init(void)
 
 static void __init omap3_dbb056_legacy_init(void)
 {
+	struct clk *clkout2;
+	struct clk *cm96fck;
+
+	/* Reparent clkout2 to 96M_FCK */
+	pr_info("%s: Late Reparent clkout2 to 96M_FCK\n", __func__);
+	clkout2 = clk_get(NULL, "clkout2_src_ck");
+	if (clkout2 < 0) {
+		pr_err("a83x-quirk: couldn't get clkout2_src_ck\n");
+		return;
+	}
+	cm96fck = clk_get(NULL, "cm_96m_fck");
+	if (cm96fck < 0) {
+		pr_err("a83x-quirk: couldn't get cm_96m_fck\n");
+		return;
+	}
+	if (clk_set_parent(clkout2, cm96fck) < 0) {
+		pr_err("a83x-quirk: couldn't reparent clkout2_src_ck\n");
+		return;
+	}
+
+	/* Set clkout2 to 24MHz for internal usb hub*/
+	pr_info("%s: Set clkout2 to 24MHz for internal usb hub\n", __func__);
+	clkout2 = clk_get(NULL, "sys_clkout2");
+	if (clkout2 < 0) {
+		pr_err("%s: couldn't get sys_clkout2\n", __func__);
+		return;
+	}
+	if (clk_set_rate(clkout2, 24000000) < 0) {
+		pr_err("%s: couldn't set sys_clkout2 rate\n", __func__);
+		return;
+	}
+	if (clk_prepare_enable(clkout2) < 0) {
+		pr_err("%s: couldn't enable sys_clkout2\n", __func__);
+		return;
+	}
+
+	/* Initialize display */
 	omap3_dbb056_display_init_of();
 }
 #endif /* CONFIG_ARCH_OMAP3 */
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 3/4] ARM: OMAP2+: add legacy display for omap3 DBB056
From: Christoph Fritz @ 2014-01-27  0:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390782797-24105-1-git-send-email-chf.fritz@googlemail.com>

Full device tree support for omapdss is not yet accomplished. Until
then, init display by legacy platform code.

Signed-off-by: Christoph Fritz <chf.fritz@googlemail.com>
---
 arch/arm/mach-omap2/dss-common.c   |   49 ++++++++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/dss-common.h   |    1 +
 arch/arm/mach-omap2/pdata-quirks.c |    8 +++++-
 3 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/dss-common.c b/arch/arm/mach-omap2/dss-common.c
index dadccc9..b8b4e39 100644
--- a/arch/arm/mach-omap2/dss-common.c
+++ b/arch/arm/mach-omap2/dss-common.c
@@ -257,3 +257,52 @@ void __init omap3_igep2_display_init_of(void)
 	platform_device_register(&omap3_igep2_tfp410_device);
 	platform_device_register(&omap3_igep2_dvi_connector_device);
 }
+
+/* OMAP3 dbb056 data */
+
+#define DBB056_DISPLAY_ENABLE_GPIO 156
+
+static const struct display_timing dbb056_lcd_videomode = {
+	.pixelclock = { 0, 19200000, 0 },
+
+	.hactive = { 0, 640, 0 },
+	.hfront_porch = { 0, 104, 0 },
+	.hback_porch = { 0, 8, 0 },
+	.hsync_len = { 0, 8, 0 },
+
+	.vactive = { 0, 480, 0 },
+	.vfront_porch = { 0, 104, 0 },
+	.vback_porch = { 0, 8, 0 },
+	.vsync_len = { 0, 8, 0 },
+
+	.flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW |
+		DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_NEGEDGE,
+};
+
+static struct panel_dpi_platform_data dbb056_lcd_pdata = {
+	.name                   = "lcd",
+	.source                 = "dpi.0",
+
+	.data_lines             = 18,
+
+	.display_timing         = &dbb056_lcd_videomode,
+
+	.enable_gpio            = DBB056_DISPLAY_ENABLE_GPIO,
+	.backlight_gpio         = -1,
+};
+
+static struct platform_device dbb056_lcd_device = {
+	.name                   = "panel-dpi",
+	.id                     = 0,
+	.dev.platform_data      = &dbb056_lcd_pdata,
+};
+
+static struct omap_dss_board_info omap_dbb056_dss_data = {
+	.default_display_name = "lcd",
+};
+
+void __init omap3_dbb056_display_init_of(void)
+{
+	platform_device_register(&dbb056_lcd_device);
+	omap_display_init(&omap_dbb056_dss_data);
+}
diff --git a/arch/arm/mach-omap2/dss-common.h b/arch/arm/mach-omap2/dss-common.h
index a9becf0..a125b55 100644
--- a/arch/arm/mach-omap2/dss-common.h
+++ b/arch/arm/mach-omap2/dss-common.h
@@ -9,5 +9,6 @@
 void __init omap4_panda_display_init_of(void);
 void __init omap_4430sdp_display_init_of(void);
 void __init omap3_igep2_display_init_of(void);
+void __init omap3_dbb056_display_init_of(void);
 
 #endif
diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
index 3d5b24d..435a823 100644
--- a/arch/arm/mach-omap2/pdata-quirks.c
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -169,6 +169,11 @@ static void __init am3517_evm_legacy_init(void)
 	omap_ctrl_writel(v, AM35XX_CONTROL_IP_SW_RESET);
 	omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); /* OCP barrier */
 }
+
+static void __init omap3_dbb056_legacy_init(void)
+{
+	omap3_dbb056_display_init_of();
+}
 #endif /* CONFIG_ARCH_OMAP3 */
 
 #ifdef CONFIG_ARCH_OMAP4
@@ -259,10 +264,11 @@ struct of_dev_auxdata omap_auxdata_lookup[] __initdata = {
 static struct pdata_init pdata_quirks[] __initdata = {
 #ifdef CONFIG_ARCH_OMAP3
 	{ "compulab,omap3-sbc-t3730", omap3_sbc_t3730_legacy_init, },
+	{ "incostartec,omap3-lilly-dbb056", omap3_dbb056_legacy_init, },
+	{ "isee,omap3-igep0020", omap3_igep0020_legacy_init, },
 	{ "nokia,omap3-n900", hsmmc2_internal_input_clk, },
 	{ "nokia,omap3-n9", hsmmc2_internal_input_clk, },
 	{ "nokia,omap3-n950", hsmmc2_internal_input_clk, },
-	{ "isee,omap3-igep0020", omap3_igep0020_legacy_init, },
 	{ "ti,omap3-evm-37xx", omap3_evm_legacy_init, },
 	{ "ti,omap3-zoom3", omap3_zoom_legacy_init, },
 	{ "ti,am3517-evm", am3517_evm_legacy_init, },
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 2/4] ARM: dts: omap3: Add support for INCOstartec DBB056 baseboard
From: Christoph Fritz @ 2014-01-27  0:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390782797-24105-1-git-send-email-chf.fritz@googlemail.com>

INCOstartec LILLY-DBB056 is a carrier board (baseboard) for
computer-on-module LILLY-A83X.

This patch adds device-tree support for most of its features.

Signed-off-by: Christoph Fritz <chf.fritz@googlemail.com>
---
 arch/arm/boot/dts/Makefile               |    1 +
 arch/arm/boot/dts/omap3-lilly-dbb056.dts |  165 ++++++++++++++++++++++++++++++
 2 files changed, 166 insertions(+)
 create mode 100644 arch/arm/boot/dts/omap3-lilly-dbb056.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index cfd364d..b449161 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -215,6 +215,7 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \
 	omap3-gta04.dtb \
 	omap3-igep0020.dtb \
 	omap3-igep0030.dtb \
+	omap3-lilly-dbb056.dtb \
 	omap3-zoom3.dtb \
 	omap4-panda.dtb \
 	omap4-panda-a4.dtb \
diff --git a/arch/arm/boot/dts/omap3-lilly-dbb056.dts b/arch/arm/boot/dts/omap3-lilly-dbb056.dts
new file mode 100644
index 0000000..89e2b68
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-lilly-dbb056.dts
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2014 Christoph Fritz <chf.fritzc@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+/dts-v1/;
+
+#include "omap3-lilly-a83x.dtsi"
+
+/ {
+	model = "INCOstartec LILLY-DBB056 (DM3730)";
+	compatible = "incostartec,omap3-lilly-dbb056", "incostartec,omap3-lilly-a83x", "ti,omap36xx", "ti,omap3";
+};
+
+&twl {
+	vaux2: regulator-vaux2 {
+		compatible = "ti,twl4030-vaux2";
+		regulator-min-microvolt = <2800000>;
+		regulator-max-microvolt = <2800000>;
+		regulator-always-on;
+	};
+};
+
+&vpll2 {
+        /* Needed for DSS */
+        regulator-name = "vdds_dsi";
+};
+
+&omap3_pmx_core {
+	pinctrl-names = "default";
+	pinctrl-0 = <&lcd_pins>;
+
+	lan9117_pins: pinmux_lan9117_pins {
+		pinctrl-single,pins = <
+			OMAP3_CORE1_IOPAD(0x2114, PIN_INPUT | MUX_MODE4)   /* cam_fld.gpio_98 */
+		>;
+	};
+
+	gpio4_pins: pinmux_gpio4_pins {
+		pinctrl-single,pins = <
+			OMAP3_CORE1_IOPAD(0x212e, PIN_INPUT | MUX_MODE4)   /* cam_xclkb.gpio_111 -> sja1000 IRQ */
+		>;
+	};
+
+	lcd_pins: pinmux_lcd_pins {
+		pinctrl-single,pins = <
+			OMAP3_CORE1_IOPAD(0x20d4, PIN_OUTPUT | MUX_MODE0)   /* dss_pclk.dss_pclk */
+			OMAP3_CORE1_IOPAD(0x20d6, PIN_OUTPUT | MUX_MODE0)   /* dss_hsync.dss_hsync */
+			OMAP3_CORE1_IOPAD(0x20d8, PIN_OUTPUT | MUX_MODE0)   /* dss_vsync.dss_vsync */
+			OMAP3_CORE1_IOPAD(0x20da, PIN_OUTPUT | MUX_MODE0)   /* dss_acbias.dss_acbias */
+			OMAP3_CORE1_IOPAD(0x20dc, PIN_OUTPUT | MUX_MODE0)   /* dss_data0.dss_data0 */
+			OMAP3_CORE1_IOPAD(0x20de, PIN_OUTPUT | MUX_MODE0)   /* dss_data1.dss_data1 */
+			OMAP3_CORE1_IOPAD(0x20e0, PIN_OUTPUT | MUX_MODE0)   /* dss_data2.dss_data2 */
+			OMAP3_CORE1_IOPAD(0x20e2, PIN_OUTPUT | MUX_MODE0)   /* dss_data3.dss_data3 */
+			OMAP3_CORE1_IOPAD(0x20e4, PIN_OUTPUT | MUX_MODE0)   /* dss_data4.dss_data4 */
+			OMAP3_CORE1_IOPAD(0x20e6, PIN_OUTPUT | MUX_MODE0)   /* dss_data5.dss_data5 */
+			OMAP3_CORE1_IOPAD(0x20e8, PIN_OUTPUT | MUX_MODE0)   /* dss_data6.dss_data6 */
+			OMAP3_CORE1_IOPAD(0x20ea, PIN_OUTPUT | MUX_MODE0)   /* dss_data7.dss_data7 */
+			OMAP3_CORE1_IOPAD(0x20ec, PIN_OUTPUT | MUX_MODE0)   /* dss_data8.dss_data8 */
+			OMAP3_CORE1_IOPAD(0x20ee, PIN_OUTPUT | MUX_MODE0)   /* dss_data9.dss_data9 */
+			OMAP3_CORE1_IOPAD(0x20f0, PIN_OUTPUT | MUX_MODE0)   /* dss_data10.dss_data10 */
+			OMAP3_CORE1_IOPAD(0x20f2, PIN_OUTPUT | MUX_MODE0)   /* dss_data11.dss_data11 */
+			OMAP3_CORE1_IOPAD(0x20f4, PIN_OUTPUT | MUX_MODE0)   /* dss_data12.dss_data12 */
+			OMAP3_CORE1_IOPAD(0x20f6, PIN_OUTPUT | MUX_MODE0)   /* dss_data13.dss_data13 */
+			OMAP3_CORE1_IOPAD(0x20f8, PIN_OUTPUT | MUX_MODE0)   /* dss_data14.dss_data14 */
+			OMAP3_CORE1_IOPAD(0x20fa, PIN_OUTPUT | MUX_MODE0)   /* dss_data15.dss_data15 */
+			OMAP3_CORE1_IOPAD(0x20fc, PIN_OUTPUT | MUX_MODE0)   /* dss_data16.dss_data16 */
+			OMAP3_CORE1_IOPAD(0x20fe, PIN_OUTPUT | MUX_MODE0)   /* dss_data17.dss_data17 */
+			OMAP3_CORE1_IOPAD(0x218c, PIN_OUTPUT | MUX_MODE4)   /* mcbsp1_clk.gpio_156 -> enable DSS */
+		>;
+	};
+
+	mmc2_pins: pinmux_mmc2_pins {
+		pinctrl-single,pins = <
+			OMAP3_CORE1_IOPAD(0x2158, PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc2_clk.sdmmc2_clk */
+			OMAP3_CORE1_IOPAD(0x215a, PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc2_cmd.sdmmc2_cmd */
+			OMAP3_CORE1_IOPAD(0x215c, PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc2_dat0.sdmmc2_dat0 */
+			OMAP3_CORE1_IOPAD(0x215e, PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc2_dat1.sdmmc2_dat1 */
+			OMAP3_CORE1_IOPAD(0x2160, PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc2_dat2.sdmmc2_dat2 */
+			OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc2_dat3.sdmmc2_dat3 */
+			OMAP3_CORE1_IOPAD(0x2164, PIN_OUTPUT | MUX_MODE1)   /* sdmmc2_dat4.sdmmc2_dir_dat0 */
+			OMAP3_CORE1_IOPAD(0x2166, PIN_OUTPUT | MUX_MODE1)   /* sdmmc2_dat5.sdmmc2_dir_dat1 */
+			OMAP3_CORE1_IOPAD(0x2168, PIN_OUTPUT | MUX_MODE1)   /* sdmmc2_dat6.sdmmc2_dir_cmd */
+			OMAP3_CORE1_IOPAD(0x216a, PIN_INPUT | MUX_MODE1)    /* sdmmc2_dat7.sdmmc2_clkin */
+			OMAP3_CORE1_IOPAD(0x219a, PIN_INPUT_PULLUP | MUX_MODE4)   /* uart3_cts_rctx.gpio_163 -> wp */
+			OMAP3_CORE1_IOPAD(0x219c, PIN_INPUT_PULLUP | MUX_MODE4)   /* uart3_rts_sd.gpio_164 -> cd */
+		>;
+	};
+
+	spi1_pins: pinmux_spi1_pins {
+		pinctrl-single,pins = <
+			OMAP3_CORE1_IOPAD(0x21c8, PIN_INPUT | MUX_MODE0)   /* mcspi1_clk.mcspi1_clk */
+			OMAP3_CORE1_IOPAD(0x21ca, PIN_INPUT | MUX_MODE0)   /* mcspi1_simo.mcspi1_simo */
+			OMAP3_CORE1_IOPAD(0x21cc, PIN_INPUT | MUX_MODE0)   /* mcspi1_somi.mcspi1_somi */
+			OMAP3_CORE1_IOPAD(0x21ce, PIN_INPUT_PULLDOWN | MUX_MODE0)   /* mcspi1_cs0.mcspi1_cs0 */
+		>;
+	};
+};
+
+&gpio4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&gpio4_pins>;
+};
+
+&mmc2 {
+	status = "okay";
+	bus-width = <4>;
+	vmmc-supply = <&vmmc1>;
+	cd-gpios = <&gpio6 4 0>;   /* gpio_164 */
+	wp-gpios = <&gpio6 3 0>;   /* gpio_163 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc2_pins>;
+	ti,dual-volt;
+};
+
+&mcspi1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi1_pins>;
+};
+
+&gpmc {
+	ranges = <0 0 0x30000000 0x1000000>,   /* nand assigned by COM a83x */
+		<4 0 0x20000000 0x01000000>,
+		<7 0 0x15000000 0x01000000>;   /* eth assigend by COM a83x */
+
+	ethernet at 4,0 {
+		compatible = "smsc,lan9117", "smsc,lan9115";
+		bank-width = <2>;
+		gpmc,mux-add-data = <2>;
+		gpmc,cs-on-ns = <10>;
+		gpmc,cs-rd-off-ns = <65>;
+		gpmc,cs-wr-off-ns = <65>;
+		gpmc,adv-on-ns = <0>;
+		gpmc,adv-rd-off-ns = <10>;
+		gpmc,adv-wr-off-ns = <10>;
+		gpmc,oe-on-ns = <10>;
+		gpmc,oe-off-ns = <65>;
+		gpmc,we-on-ns = <10>;
+		gpmc,we-off-ns = <65>;
+		gpmc,rd-cycle-ns = <100>;
+		gpmc,wr-cycle-ns = <100>;
+		gpmc,access-ns = <60>;
+		gpmc,page-burst-access-ns = <5>;
+		gpmc,bus-turnaround-ns = <0>;
+		gpmc,cycle2cycle-delay-ns = <75>;
+		gpmc,wr-data-mux-bus-ns = <15>;
+		gpmc,wr-access-ns = <75>;
+		gpmc,cycle2cycle-samecsen;
+		gpmc,cycle2cycle-diffcsen;
+		vddvario-supply = <&reg_vcc3>;
+		vdd33a-supply = <&reg_vcc3>;
+		reg-io-width = <4>;
+		interrupt-parent = <&gpio4>;
+		interrupts = <2 0x2>;
+		reg = <4 0 0xff>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&lan9117_pins>;
+		phy-mode = "mii";
+		smsc,force-internal-phy;
+	};
+};
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 1/4] ARM: dts: omap3: Add support for INCOstartec a83x module
From: Christoph Fritz @ 2014-01-27  0:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390782797-24105-1-git-send-email-chf.fritz@googlemail.com>

INCOstartec LILLY-A83X module is a TI DM3730xx100 (OMAP3) SoC
computer-on-module.

This patch adds device tree support for most of its features.

Signed-off-by: Christoph Fritz <chf.fritz@googlemail.com>
---
 arch/arm/boot/dts/omap3-lilly-a83x.dtsi |  459 +++++++++++++++++++++++++++++++
 1 file changed, 459 insertions(+)
 create mode 100644 arch/arm/boot/dts/omap3-lilly-a83x.dtsi

diff --git a/arch/arm/boot/dts/omap3-lilly-a83x.dtsi b/arch/arm/boot/dts/omap3-lilly-a83x.dtsi
new file mode 100644
index 0000000..6369d9f
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-lilly-a83x.dtsi
@@ -0,0 +1,459 @@
+/*
+ * Copyright (C) 2014 Christoph Fritz <chf.fritzc@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include "omap36xx.dtsi"
+
+/ {
+	model = "INCOstartec LILLY-A83X module (DM3730)";
+	compatible = "incostartec,omap3-lilly-a83x", "ti,omap36xx", "ti,omap3";
+
+	chosen {
+			bootargs = "console=ttyO0,115200n8 vt.global_cursor_default=0 consoleblank=0";
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x80000000 0x8000000>;   /* 128 MB */
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led1 {
+			label = "lilly-a83x::led1";
+			gpios = <&gpio1 29 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "default-on";
+		};
+
+	};
+
+	sound {
+		compatible = "ti,omap-twl4030";
+		ti,model = "lilly-a83x";
+
+		ti,mcbsp = <&mcbsp2>;
+		ti,codec = <&twl_audio>;
+	};
+
+	reg_vcc3: vcc3 {
+		compatible = "regulator-fixed";
+		regulator-name = "VCC3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+	};
+
+	hsusb1_phy: hsusb1_phy {
+		compatible = "usb-nop-xceiv";
+		vcc-supply = <&reg_vcc3>;
+	};
+};
+
+&omap3_pmx_wkup {
+	pinctrl-names = "default";
+
+	lan9221_pins: pinmux_lan9221_pins {
+		pinctrl-single,pins = <
+			OMAP3_WKUP_IOPAD(0x2a5a, PIN_INPUT | MUX_MODE4)   /* reserved.gpio_129 */
+		>;
+	};
+
+	tsc2048_pins: pinmux_tsc2048_pins {
+		pinctrl-single,pins = <
+			OMAP3_WKUP_IOPAD(0x2a16, PIN_INPUT_PULLUP | MUX_MODE4)   /* sys_boot6.gpio_8 */
+		>;
+	};
+
+	mmc1cd_pins: pinmux_mmc1cd_pins {
+		pinctrl-single,pins = <
+			OMAP3_WKUP_IOPAD(0x2a56, PIN_INPUT | MUX_MODE4)   /* reserved.gpio_126 */
+		>;
+	};
+};
+
+&omap3_pmx_core {
+	pinctrl-names = "default";
+
+	uart1_pins: pinmux_uart1_pins {
+		pinctrl-single,pins = <
+			OMAP3_CORE1_IOPAD(0x217c, PIN_OUTPUT | MUX_MODE0)   /* uart1_tx.uart1_tx */
+			OMAP3_CORE1_IOPAD(0x217e, PIN_OUTPUT | MUX_MODE0)   /* uart1_rts.uart1_rts */
+			OMAP3_CORE1_IOPAD(0x2180, PIN_INPUT | MUX_MODE0)    /* uart1_cts.uart1_cts */
+			OMAP3_CORE1_IOPAD(0x2182, PIN_INPUT | MUX_MODE0)    /* uart1_rx.uart1_rx */
+		>;
+	};
+
+	uart2_pins: pinmux_uart2_pins {
+		pinctrl-single,pins = <
+			OMAP3_CORE1_IOPAD(0x2170, PIN_OUTPUT | MUX_MODE1)   /* mcbsp3_clkx.uart2_tx */
+			OMAP3_CORE1_IOPAD(0x2172, PIN_INPUT | MUX_MODE1)    /* mcbsp3_fsx.uart2_rx */
+		>;
+	};
+
+	uart3_pins: pinmux_uart3_pins {
+		pinctrl-single,pins = <
+			OMAP3_CORE1_IOPAD(0x219e, PIN_INPUT | MUX_MODE0)    /* uart3_rx_irrx.uart3_rx_irrx */
+			OMAP3_CORE1_IOPAD(0x21a0, PIN_OUTPUT | MUX_MODE0)   /* uart3_tx_irtx.uart3_tx_irtx */
+		>;
+	};
+
+	i2c1_pins: pinmux_i2c1_pins {
+		pinctrl-single,pins = <
+			OMAP3_CORE1_IOPAD(0x21ba ,PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c1_scl.i2c1_scl */
+			OMAP3_CORE1_IOPAD(0x21bc ,PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c1_sda.i2c1_sda */
+		>;
+	};
+
+	i2c2_pins: pinmux_i2c2_pins {
+		pinctrl-single,pins = <
+			OMAP3_CORE1_IOPAD(0x21be, PIN_INPUT | MUX_MODE0)   /* i2c2_scl.i2c2_scl */
+			OMAP3_CORE1_IOPAD(0x21c0, PIN_INPUT | MUX_MODE0)   /* i2c2_sda.i2c2_sda */
+		>;
+	};
+
+	i2c3_pins: pinmux_i2c3_pins {
+		pinctrl-single,pins = <
+			OMAP3_CORE1_IOPAD(0x21c2, PIN_INPUT | MUX_MODE0)   /* i2c3_scl.i2c3_scl */
+			OMAP3_CORE1_IOPAD(0x21c4, PIN_INPUT | MUX_MODE0)   /* i2c3_sda.i2c3_sda */
+		>;
+	};
+
+	hsusb1_pins: pinmux_hsusb1_pins {
+		pinctrl-single,pins = <
+
+			/* GPIO 182 controls USB-Hub reset. But USB-Phy its
+			 * reset can't be controlled. So we clamp this GPIO to
+			 * high (PIN_OFF_OUTPUT_HIGH) to always enable USB-Hub.
+			 */
+
+			OMAP3_CORE1_IOPAD(0x21de, PIN_OUTPUT_PULLUP | PIN_OFF_OUTPUT_HIGH | MUX_MODE4)   /* mcspi2_cs1.gpio_182 */
+		>;
+	};
+
+	hsusb_otg_pins: pinmux_hsusb_otg_pins {
+		pinctrl-single,pins = <
+			OMAP3_CORE1_IOPAD(0x21a2, PIN_INPUT | MUX_MODE0)   /* hsusb0_clk.hsusb0_clk */
+			OMAP3_CORE1_IOPAD(0x21a4, PIN_OUTPUT | MUX_MODE0)  /* hsusb0_stp.hsusb0_stp */
+			OMAP3_CORE1_IOPAD(0x21a6, PIN_INPUT | MUX_MODE0)   /* hsusb0_dir.hsusb0_dir */
+			OMAP3_CORE1_IOPAD(0x21a8, PIN_INPUT | MUX_MODE0)   /* hsusb0_nxt.hsusb0_nxt */
+			OMAP3_CORE1_IOPAD(0x21aa, PIN_INPUT | MUX_MODE0)   /* hsusb0_data0.hsusb0_data0 */
+			OMAP3_CORE1_IOPAD(0x21ac, PIN_INPUT | MUX_MODE0)   /* hsusb0_data1.hsusb0_data1 */
+			OMAP3_CORE1_IOPAD(0x21ae, PIN_INPUT | MUX_MODE0)   /* hsusb0_data2.hsusb0_data2 */
+			OMAP3_CORE1_IOPAD(0x21b0, PIN_INPUT | MUX_MODE0)   /* hsusb0_data3.hsusb0_data3 */
+			OMAP3_CORE1_IOPAD(0x21b2, PIN_INPUT | MUX_MODE0)   /* hsusb0_data4.hsusb0_data4 */
+			OMAP3_CORE1_IOPAD(0x21b4, PIN_INPUT | MUX_MODE0)   /* hsusb0_data5.hsusb0_data5 */
+			OMAP3_CORE1_IOPAD(0x21b6, PIN_INPUT | MUX_MODE0)   /* hsusb0_data6.hsusb0_data6 */
+			OMAP3_CORE1_IOPAD(0x21b8, PIN_INPUT | MUX_MODE0)   /* hsusb0_data7.hsusb0_data7 */
+		>;
+	};
+
+	mmc1_pins: pinmux_mmc1_pins {
+		pinctrl-single,pins = <
+			OMAP3_CORE1_IOPAD(0x2144, PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc1_clk.sdmmc1_clk */
+			OMAP3_CORE1_IOPAD(0x2146, PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc1_cmd.sdmmc1_cmd */
+			OMAP3_CORE1_IOPAD(0x2148, PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc1_dat0.sdmmc1_dat0 */
+			OMAP3_CORE1_IOPAD(0x214a, PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc1_dat1.sdmmc1_dat1 */
+			OMAP3_CORE1_IOPAD(0x214c, PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc1_dat2.sdmmc1_dat2 */
+			OMAP3_CORE1_IOPAD(0x214e, PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc1_dat3.sdmmc1_dat3 */
+		>;
+	};
+
+	spi2_pins: pinmux_spi2_pins {
+		pinctrl-single,pins = <
+			OMAP3_CORE1_IOPAD(0x21d6, PIN_INPUT_PULLDOWN | MUX_MODE0)   /* mcspi2_clk.mcspi2_clk */
+			OMAP3_CORE1_IOPAD(0x21d8, PIN_INPUT_PULLDOWN | MUX_MODE0)   /* mcspi2_simo.mcspi2_simo */
+			OMAP3_CORE1_IOPAD(0x21da, PIN_INPUT_PULLDOWN | MUX_MODE0)   /* mcspi2_somi.mcspi2_somi */
+			OMAP3_CORE1_IOPAD(0x21dc, PIN_OUTPUT | MUX_MODE0)   /* mcspi2_cs0.mcspi2_cs0 */
+		>;
+	};
+};
+
+&omap3_pmx_core2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <
+			&hsusb1_2_pins
+	>;
+
+	hsusb1_2_pins: pinmux_hsusb1_2_pins {
+		pinctrl-single,pins = <
+			OMAP3630_CORE2_IOPAD(0x25d8, PIN_OUTPUT | MUX_MODE3)  /* etk_clk.hsusb1_stp */
+			OMAP3630_CORE2_IOPAD(0x25da, PIN_INPUT | MUX_MODE3)   /* etk_ctl.hsusb1_clk */
+			OMAP3630_CORE2_IOPAD(0x25dc, PIN_INPUT | MUX_MODE3)   /* etk_d0.hsusb1_data0 */
+			OMAP3630_CORE2_IOPAD(0x25de, PIN_INPUT | MUX_MODE3)   /* etk_d1.hsusb1_data1 */
+			OMAP3630_CORE2_IOPAD(0x25e0, PIN_INPUT | MUX_MODE3)   /* etk_d2.hsusb1_data2 */
+			OMAP3630_CORE2_IOPAD(0x25e2, PIN_INPUT | MUX_MODE3)   /* etk_d3.hsusb1_data7 */
+			OMAP3630_CORE2_IOPAD(0x25e4, PIN_INPUT | MUX_MODE3)   /* etk_d4.hsusb1_data4 */
+			OMAP3630_CORE2_IOPAD(0x25e6, PIN_INPUT | MUX_MODE3)   /* etk_d5.hsusb1_data5 */
+			OMAP3630_CORE2_IOPAD(0x25e8, PIN_INPUT | MUX_MODE3)   /* etk_d6.hsusb1_data6 */
+			OMAP3630_CORE2_IOPAD(0x25ea, PIN_INPUT | MUX_MODE3)   /* etk_d7.hsusb1_data3 */
+			OMAP3630_CORE2_IOPAD(0x25ec, PIN_INPUT | MUX_MODE3)   /* etk_d8.hsusb1_dir */
+			OMAP3630_CORE2_IOPAD(0x25ee, PIN_INPUT | MUX_MODE3)   /* etk_d9.hsusb1_nxt */
+		>;
+	};
+
+	gpio1_pins: pinmux_gpio1_pins {
+		pinctrl-single,pins = <
+			OMAP3630_CORE2_IOPAD(0x25fa, PIN_OUTPUT_PULLDOWN | MUX_MODE4)   /* etk_d15.gpio_29 */
+		>;
+	};
+
+};
+
+&gpio1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&gpio1_pins>;
+};
+
+&gpio6 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&hsusb1_pins>;
+};
+
+&i2c1 {
+	clock-frequency = <2600000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins>;
+
+	twl: twl at 48 {
+		reg = <0x48>;
+		interrupts = <7>;   /* SYS_NIRQ cascaded to intc */
+		interrupt-parent = <&intc>;
+
+		twl_audio: audio {
+			compatible = "ti,twl4030-audio";
+			codec {
+			};
+		};
+	};
+};
+
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
+
+&twl {
+	vmmc1: regulator-vmmc1 {
+		regulator-always-on;
+	};
+
+	vdd1: regulator-vdd1 {
+		regulator-always-on;
+	};
+
+	vdd2: regulator-vdd2 {
+		regulator-always-on;
+	};
+};
+
+&i2c2 {
+	clock-frequency = <2600000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c2_pins>;
+};
+
+&i2c3 {
+	clock-frequency = <2600000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c3_pins>;
+		gpiom1: gpio at 20 {
+			compatible = "mcp,mcp23017";
+			gpio-controller;
+			#gpio-cells = <2>;
+			reg = <0x20>;
+		};
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>;
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart2_pins>;
+};
+
+&uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart3_pins>;
+};
+
+&uart4 {
+	status = "disabled";
+};
+
+&mmc1 {
+	cd-gpios = <&gpio4 30 IRQ_TYPE_LEVEL_LOW>;
+	cd-inverted;
+	vmmc-supply = <&vmmc1>;
+	bus-width = <4>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc1_pins &mmc1cd_pins>;
+	cap-sdio-irq;
+	cap-sd-highspeed;
+	cap-mmc-highspeed;
+};
+
+&mmc2 {
+	status = "disabled";
+};
+
+&mmc3 {
+	status = "disabled";
+};
+
+&mcspi2 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi2_pins>;
+
+	tsc2046 at 0 {
+		reg = <0>;   /* CS0 */
+		compatible = "ti,tsc2046";
+		interrupt-parent = <&gpio1>;
+		interrupts = <8 0>;   /* boot6 / gpio_8 */
+		spi-max-frequency = <1000000>;
+		pendown-gpio = <&gpio1 8 0>;
+		vcc-supply = <&reg_vcc3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&tsc2048_pins>;
+
+		ti,x-min = <300>;
+		ti,x-max = <3000>;
+		ti,y-min = <600>;
+		ti,y-max = <3600>;
+		ti,x-plate-ohms = <80>;
+		ti,pressure-max = <255>;
+		ti,swap-xy;
+
+		linux,wakeup;
+	};
+};
+
+&usbhsehci {
+	phys = <&hsusb1_phy>;
+};
+
+&usbhshost {
+	pinctrl-names = "default";
+	pinctrl-0 = <&hsusb1_2_pins>;
+	num-ports = <2>;
+	port1-mode = "ehci-phy";
+};
+
+&usb_otg_hs {
+	pinctrl-names = "default";
+	pinctrl-0 = <&hsusb_otg_pins>;
+	interface-type = <0>;
+	usb-phy = <&usb2_phy>;
+	phys = <&usb2_phy>;
+	phy-names = "usb2-phy";
+	mode = <3>;
+	power = <50>;
+};
+
+&gpmc {
+	ranges = <0 0 0x30000000 0x1000000>,
+		<7 0 0x15000000 0x01000000>;
+
+	nand at 0,0 {
+		reg = <0 0 0x1000000>;
+		nand-bus-width = <16>;
+		ti,nand-ecc-opt = "bch8";
+		/* no elm on omap3 */
+
+		gpmc,mux-add-data = <0>;
+		gpmc,device-nand;
+		gpmc,device-width = <2>;
+		gpmc,wait-pin = <0>;
+		gpmc,wait-monitoring-ns = <0>;
+		gpmc,burst-length= <4>;
+		gpmc,cs-on-ns = <0>;
+		gpmc,cs-rd-off-ns = <100>;
+		gpmc,cs-wr-off-ns = <100>;
+		gpmc,adv-on-ns = <0>;
+		gpmc,adv-rd-off-ns = <100>;
+		gpmc,adv-wr-off-ns = <100>;
+		gpmc,oe-on-ns = <5>;
+		gpmc,oe-off-ns = <75>;
+		gpmc,we-on-ns = <5>;
+		gpmc,we-off-ns = <75>;
+		gpmc,rd-cycle-ns = <100>;
+		gpmc,wr-cycle-ns = <100>;
+		gpmc,access-ns = <60>;
+		gpmc,page-burst-access-ns = <5>;
+		gpmc,bus-turnaround-ns = <0>;
+		gpmc,cycle2cycle-samecsen;
+		gpmc,cycle2cycle-delay-ns = <50>;
+		gpmc,wr-data-mux-bus-ns = <75>;
+		gpmc,wr-access-ns = <155>;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition at 0 {
+			label = "MLO";
+			reg = <0 0x80000>;
+		};
+
+		partition at 0x80000 {
+			label = "u-boot";
+			reg = <0x80000 0x1e0000>;
+		};
+
+		partition at 0x260000 {
+			label = "u-boot-environment";
+			reg = <0x260000 0x20000>;
+		};
+
+		partition at 0x280000 {
+			label = "kernel";
+			reg = <0x280000 0x500000>;
+		};
+
+		partition at 0x780000 {
+			label = "filesystem";
+			reg = <0x780000 0xf880000>;
+		};
+	};
+
+	ethernet at 7,0 {
+		compatible = "smsc,lan9221", "smsc,lan9115";
+		bank-width = <2>;
+		gpmc,mux-add-data = <2>;
+		gpmc,cs-on-ns = <10>;
+		gpmc,cs-rd-off-ns = <60>;
+		gpmc,cs-wr-off-ns = <60>;
+		gpmc,adv-on-ns = <0>;
+		gpmc,adv-rd-off-ns = <10>;
+		gpmc,adv-wr-off-ns = <10>;
+		gpmc,oe-on-ns = <10>;
+		gpmc,oe-off-ns = <60>;
+		gpmc,we-on-ns = <10>;
+		gpmc,we-off-ns = <60>;
+		gpmc,rd-cycle-ns = <100>;
+		gpmc,wr-cycle-ns = <100>;
+		gpmc,access-ns = <50>;
+		gpmc,page-burst-access-ns = <5>;
+		gpmc,bus-turnaround-ns = <0>;
+		gpmc,cycle2cycle-delay-ns = <75>;
+		gpmc,wr-data-mux-bus-ns = <15>;
+		gpmc,wr-access-ns = <75>;
+		gpmc,cycle2cycle-samecsen;
+		gpmc,cycle2cycle-diffcsen;
+		vddvario-supply = <&reg_vcc3>;
+		vdd33a-supply = <&reg_vcc3>;
+		reg-io-width = <4>;
+		interrupt-parent = <&gpio5>;
+		interrupts = <1 0x2>;
+		reg = <7 0 0xff>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&lan9221_pins>;
+		phy-mode = "mii";
+	};
+};
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH v3 0/4] ARM: add omap3 INCOstartec board support
From: Christoph Fritz @ 2014-01-27  0:33 UTC (permalink / raw)
  To: linux-arm-kernel

This set of patches adds board support for an omap3 system from INCOstartec.
It's based on next-20140124.

Due to a regression since next-20140115 the following errors are present:

 - pin sys_clkout2, which gets configured to 24 Mhz by the fourth patch
   in this set, erroneously outputs only 12 Mhz.
   Just out of curiosity, configuring it to 48 Mhz puts out desired 24 Mhz.

 - omap_dss, which gets configured by the third patch in this set, fails
   to do 'dss_set_fck_rate(fck);' in
   drivers/video/omap2/dss/dss.c:dss_setup_default_clock() which leads to:

    | omapdss_dss: probe of omapdss_dss failed with error -22
    | omapdss CORE error: Failed to initialize DSS platform driver
    | panel-dpi panel-dpi.0: failed to find video source 'dpi.0

  Both regressions seem to have something to do with the clock framework. 
  Could this be related to the DT clock conversion patches?

Changes compared to previous version (v3):
 - rebased on next-20140124
 - use pinctrl macros OMAP3_WKUP_IOPAD, OMAP3_CORE1_IOPAD
   and OMAP3630_CORE2_IOPAD
 - use same convention for all comments
 - dss-quirk: name twl4030 VPLL2 regulator as vdds_dsi
 - fix style
Changes compared to previous version (v2):
 - rebased on next-20140122 from next-20140115
 - using omap36xx.dtsi instead of unsupported 1ghz omap37xx100
Initial version (v1):
 - based on next-20140115

Christoph Fritz (4):
  ARM: dts: omap3: Add support for INCOstartec a83x module
  ARM: dts: omap3: Add support for INCOstartec DBB056 baseboard
  ARM: OMAP2+: add legacy display for omap3 DBB056
  ARM: OMAP2+: Add pdata quirk for sys_clkout2 for omap3 DBB056

 arch/arm/boot/dts/Makefile               |    1 +
 arch/arm/boot/dts/omap3-lilly-a83x.dtsi  |  459 ++++++++++++++++++++++++++++++
 arch/arm/boot/dts/omap3-lilly-dbb056.dts |  165 +++++++++++
 arch/arm/mach-omap2/dss-common.c         |   49 ++++
 arch/arm/mach-omap2/dss-common.h         |    1 +
 arch/arm/mach-omap2/pdata-quirks.c       |   45 ++-
 6 files changed, 719 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/omap3-lilly-a83x.dtsi
 create mode 100644 arch/arm/boot/dts/omap3-lilly-dbb056.dts

-- 
1.7.10.4

^ permalink raw reply

* [PATCH v2 1/5] ARM: dts: omap3: Add support for INCOstartec a83x module
From: Christoph Fritz @ 2014-01-27  0:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52E0207E.3050900@ti.com>

Hi Nishanth,

 thanks for reviewing this patch. Please see my comments below.

On Wed, Jan 22, 2014 at 01:48:14PM -0600, Nishanth Menon wrote:
> On 01/22/2014 01:04 PM, Christoph Fritz wrote:

> > +	regulators {
> > +		compatible = "simple-bus";
> Shrug, just moving the fixed regulator to root also will do the job,
> not sure simple-bus much sense here :(
> 

will get fixed

> > +		reg_vcc3: vcc3 {
> > +                        compatible = "regulator-fixed";
> > +                        regulator-name = "VCC3";
> > +                        regulator-min-microvolt = <3300000>;
> > +                        regulator-max-microvolt = <3300000>;
> > +                        regulator-always-on;
> > +		};
> > +	};
> > +
> > +	hsusb1_phy: hsusb1_phy {
> > +		compatible = "usb-nop-xceiv";
> > +		vcc-supply = <&reg_vcc3>;
> > +	};
> > +};
> > +
> > +&omap3_pmx_wkup {
> > +	pinctrl-names = "default";
> > +
> > +	lan9221_pins: pinmux_lan9221_pins {
> > +		pinctrl-single,pins = <
> > +			0x5A (PIN_INPUT | MUX_MODE4)   /* gpio_129 */
> umm.. you might want to follow the convention as you followed later in
> comments.

My convention was: If pin can be described unique with one name,
don't use two. But I'll change that to be uniform with all comments.

> > +		>;
> > +	};
> > +
> > +	tsc2048_pins: pinmux_tsc2048_pins {
> > +		pinctrl-single,pins = <
> > +			0x16 (PIN_INPUT_PULLUP | MUX_MODE4)   /* gpio_8 */
> umm.. you might want to follow the convention as you followed later in
> comments.

will get fixed

> > +		>;
> > +	};
> > +
> > +	mmc1cd_pins: pinmux_mmc1cd_pins {
> > +		pinctrl-single,pins = <
> > +			0x56 (PIN_INPUT | MUX_MODE4)   /* gpio_126 */
> umm.. you might want to follow the convention as you followed later in
> comments.

will get fixed

> > +		>;
> > +	};
> > +};
> > +
> > +&omap3_pmx_core {
> > +	pinctrl-names = "default";
> > +
> > +	gpio1_pins: pinmux_gpio1_pins {
> > +		pinctrl-single,pins = <
> > +			0x5ca (PIN_OUTPUT_PULLDOWN | MUX_MODE4)   /* gpio_29 */
> umm.. you might want to follow the convention as you followed later in
> comments.

will get fixed

> > +		>;
> > +	};
> > +
> > +	uart1_pins: pinmux_uart1_pins {
> > +		pinctrl-single,pins = <
> > +			0x14c (PIN_OUTPUT | MUX_MODE0)   /* uart1_tx.uart1_tx */
> > +			0x14e (PIN_OUTPUT | MUX_MODE0)   /* uart1_rts.uart1_rts */
> > +			0x150 (PIN_INPUT | MUX_MODE0)    /* uart1_cts.uart1_cts */
> > +			0x152 (PIN_INPUT | MUX_MODE0)    /* uart1_rx.uart1_rx */
> > +		>;
> you may be interested in include/dt-bindings/pinctrl/omap.h
> OMAP3_CORE1_IOPAD, OMAP3_CORE2_IOPAD as needed here.

will get fixed

> > +	};
> > +
> > +	uart2_pins: pinmux_uart2_pins {
> > +		pinctrl-single,pins = <
> > +			0x140 (PIN_OUTPUT | MUX_MODE1)   /* mcbsp3_clkx.uart2_tx */
> > +			0x142 (PIN_INPUT | MUX_MODE1)    /* mcbsp3_fsx.uart2_rx */
> > +		>;
> > +	};
> > +
> > +	uart3_pins: pinmux_uart3_pins {
> > +		pinctrl-single,pins = <
> > +			0x16e (PIN_INPUT | MUX_MODE0)    /* uart3_rx_irrx.uart3_rx_irrx */
> > +			0x170 (PIN_OUTPUT | MUX_MODE0)   /* uart3_tx_irtx.uart3_tx_irtx */
> > +		>;
> > +	};
> > +
> > +	i2c1_pins: pinmux_i2c1_pins {
> > +		pinctrl-single,pins = <
> > +			0x18a (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c1_scl */
> > +			0x18c (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c1_sda */
> umm.. you might want to follow the convention as you followed
> elsewhere in comments.

will get fixed

> > +		>;
> > +	};
> > +
> > +	i2c2_pins: pinmux_i2c2_pins {
> > +		pinctrl-single,pins = <
> > +			0x18e (PIN_INPUT | MUX_MODE0)   /* i2c2_scl.i2c2_scl */
> > +			0x190 (PIN_INPUT | MUX_MODE0)   /* i2c2_sda.i2c2_sda */
> > +		>;
> > +	};
> > +
> > +	i2c3_pins: pinmux_i2c3_pins {
> > +		pinctrl-single,pins = <
> > +			0x192 (PIN_INPUT | MUX_MODE0)   /* i2c3_scl.i2c3_scl */
> > +			0x194 (PIN_INPUT | MUX_MODE0)   /* i2c3_sda.i2c3_sda */
> > +		>;
> > +	};
> > +
> > +	hsusb1_pins: pinmux_hsusb1_pins {
> > +		pinctrl-single,pins = <
> > +			0x5a8 (PIN_OUTPUT | MUX_MODE3)  /* etk_clk.hsusb1_stp */
> &omap3_pmx_core2 and OMAP3_CORE2_IOPAD probably here. and probably see
> similar usage in other board dtsi.

will get fixed

> > +
> > +#include "twl4030.dtsi"
> > +#include "twl4030_omap3.dtsi"
> > +
> > +&twl {
> > +	vmmc1: regulator-vmmc1 {
> > +		regulator-always-on;
> > +	};
> > +
> > +	vdd1: regulator-vdd1 {
> > +		regulator-always-on;
> > +	};
> > +
> > +	vdd2: regulator-vdd2 {
> > +		regulator-always-on;
> > +	};
> I hope you have covered all required regulators here including the
> ones you might need for IO.1P8 perhaps?

Yes, I rechecked all and it's fine now. IO.1P8 was low due to a
hardware error which is now fixed.

> > +
> > +&mmc1 {
> > +	reg = <0x4809c000 0x400>;
> little curious as to why this. is that to override length 0x200 to
> 0x400? that belongs to soc.dtsi then.

This is a remnant from last year and will get purged.

Let me reroll this patch in a new v3 set.

Thanks
  -- Christoph

^ permalink raw reply

* [PATCH v2 4/5] ARM: OMAP2+: Add pdata quirk for sys_clkout2 for omap3 DBB056
From: Christoph Fritz @ 2014-01-27  0:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52E01D01.2010709@ti.com>

Hi Nishanth,

 thanks for reviewing this patch. Please see my comments below.

On Wed, Jan 22, 2014 at 01:33:21PM -0600, Nishanth Menon wrote:
> On 01/22/2014 01:04 PM, Christoph Fritz wrote:
> > Full device tree support for clock control is not yet accomplished. Until
> > then, configure the 24Mhz of sys_clkout2 to feed an USB-Hub here.
> > 
> > Signed-off-by: Christoph Fritz <chf.fritz@googlemail.com>
> > ---
> >  arch/arm/mach-omap2/pdata-quirks.c |   37 ++++++++++++++++++++++++++++++++++++
> >  1 file changed, 37 insertions(+)
> > 
> > diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
> > index a58590f..9ef7ca8 100644
> > --- a/arch/arm/mach-omap2/pdata-quirks.c
> > +++ b/arch/arm/mach-omap2/pdata-quirks.c
> > @@ -171,6 +171,43 @@ static void __init am3517_evm_legacy_init(void)
> >  }
> >  static void __init omap3_dbb056_legacy_init(void)
> >  {
> > +	struct clk *clkout2;
> > +	struct clk *cm96fck;
> > +
> > +	/* Reparent clkout2 to 96M_FCK */
> > +	pr_info("a83x-quirk: Late Reparent clkout2 to 96M_FCK\n");
> what'd be a83x?

It's the computer-on-module name. Will get changed to __func__.

> > +	clkout2 = clk_get(NULL, "clkout2_src_ck");
> > +	if(clkout2 < 0) {
> > +		pr_err("a83x-quirk: couldn't get clkout2_src_ck\n");
> > +		return;
> > +	}
> > +	cm96fck = clk_get(NULL, "cm_96m_fck");
> > +	if(cm96fck < 0) {
> > +		pr_err("a83x-quirk: couldn't get cm_96m_fck\n");
> > +		return;
> > +	}
> > +	if(clk_set_parent(clkout2, cm96fck) < 0) {
> > +		pr_err("a83x-quirk: couldn't reparent clkout2_src_ck\n");
> > +		return;
> > +	}
> yep - we have bunch of similar code in drivers/clk/ti -> but we'd need
> a generic property to handle this.

This whole quirk of configuring sys_clkout2 in a platform file will
go away. Tero is planning to post some RFC patches to configure this
by DT.

> > +
> > +	/* Set clkout2 to 24MHz for internal usb hub*/
> > +	pr_info("a83x-quirk: Set clkout2 to 24MHz for internal usb hub\n");
> > +	clkout2 = clk_get(NULL, "sys_clkout2");
> > +	if(clkout2 < 0) {
> > +		pr_err("a83x-quirk: couldn't get sys_clkout2\n");
> > +		return;
> > +	}
> > +	if(clk_set_rate(clkout2, 24000000) < 0) {
> same here.
> > +		printk(KERN_ERR "board-omap3evm: couldn't set sys_clkout2 rate\n");
> "board-omap3evm:" copy paste?
> any reason why not pr_err?

will get fixed

> > +		return;
> > +	}
> > +	if(clk_prepare_enable(clkout2) < 0) {
> > +		pr_err("a83x-quirk: couldn't enable sys_clkout2\n");
> > +		return;
> > +	}
> > +
> > +	/* Initialize display */
> >  	omap3_dbb056_display_init_of();
> >  }
> >  #endif /* CONFIG_ARCH_OMAP3 */
> > 
> 
> looking at the coding style, I assume we'd missed running
> checkpatch.pl --strict?

Let me reroll this patch in a new v3 set.

Thanks
  -- Christoph

^ permalink raw reply

* [PATCHv3 00/41] OMAPDSS: DT support v3
From: Javier Martinez Canillas @ 2014-01-26 23:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390301833-24944-1-git-send-email-tomi.valkeinen@ti.com>

Hi Tomi,

On Tue, Jan 21, 2014 at 7:56 AM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> Hi,
>
> Here's version 3 of the DSS DT series.
>
> The previous version can be found from:
>
> v1: http://permalink.gmane.org/gmane.linux.ports.arm.omap/108249
> v2: http://permalink.gmane.org/gmane.linux.ports.arm.omap/108866
>
> The main changes to v2 are:
>
> - DT Binding documentation
> - OMAP2 DSS support
> - Split DSI register space
> - DSS nodes disabled by default
> - Hack to have generic DT bindings but OMAP specific drivers (for now)
>
> This series can also be found from:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux.git work/dss-dt-review-3
>

I tested this branch on my DM3730 IGEPv2 and output display is working
correctly.

Tested-by: Javier Martinez Canillas <javier@dowhile0.org>

>  Tomi
>
> Javier Martinez Canillas (1):
>   ARM: omap3-igep0020.dts: add display information
>
> Sebastian Reichel (1):
>   OMAPDSS: acx565akm: Add DT support
>
> Tomi Valkeinen (39):
>   ARM: OMAP2+: add omapdss_init_of()
>   ARM: OMAP2+: DT 'compatible' tweak for displays
>   OMAPDSS: add 'label' support for DT
>   OMAPDSS: get dssdev->alias from DT alias
>   OMAPFB: clean up default display search
>   OMAPFB: search for default display with DT alias
>   OMAPDSS: add of helpers
>   OMAPDSS: Improve regulator names for DT
>   OMAPDSS: Add DT support to DSS
>   OMAPDSS: Add DT support to DISPC
>   OMAPDSS: Add DT support to HDMI
>   OMAPDSS: Add DT support to VENC
>   OMAPDSS: Add DT support to DSI
>   OMAPDSS: panel-dsi-cm: Add DT support
>   OMAPDSS: encoder-tfp410: Add DT support
>   OMAPDSS: connector-dvi: Add DT support
>   OMAPDSS: encoder-tpd12s015: Add DT support
>   OMAPDSS: hdmi-connector: Add DT support
>   OMAPDSS: panel-dpi: Add DT support
>   OMAPDSS: connector-analog-tv: Add DT support
>   ARM: omap2.dtsi: add omapdss information
>   ARM: omap3.dtsi: add omapdss information
>   ARM: omap4.dtsi: add omapdss information
>   ARM: omap4-panda.dts: add display information
>   ARM: omap4-sdp.dts: add display information
>   ARM: omap3-beagle.dts: add display information
>   ARM: omap3-beagle-xm.dts: add display information
>   ARM: omap3-n900.dts: add display information
>   OMAPDSS: remove DT hacks for regulators
>   ARM: OMAP2+: remove pdata quirks for displays
>   Doc/DT: Add OMAP DSS DT Bindings
>   Doc/DT: Add DT binding documentation for Analog TV Connector
>   Doc/DT: Add DT binding documentation for DVI Connector
>   Doc/DT: Add DT binding documentation for HDMI Connector
>   Doc/DT: Add DT binding documentation for MIPI DPI Panel
>   Doc/DT: Add DT binding documentation for MIPI DSI CM Panel
>   Doc/DT: Add DT binding documentation for Sony acx565akm panel
>   Doc/DT: Add DT binding documentation for TFP410 encoder
>   Doc/DT: Add DT binding documentation for tpd12s015 encoder
>
>  .../bindings/video/analog-tv-connector.txt         |  23 +++
>  .../devicetree/bindings/video/dvi-connector.txt    |  26 +++
>  .../devicetree/bindings/video/hdmi-connector.txt   |  23 +++
>  .../devicetree/bindings/video/panel-dpi.txt        |  43 ++++
>  .../devicetree/bindings/video/panel-dsi-cm.txt     |  26 +++
>  .../devicetree/bindings/video/sony,acx565akm.txt   |  28 +++
>  .../devicetree/bindings/video/ti,omap-dss.txt      | 197 ++++++++++++++++++
>  .../devicetree/bindings/video/ti,omap2-dss.txt     |  54 +++++
>  .../devicetree/bindings/video/ti,omap3-dss.txt     |  73 +++++++
>  .../devicetree/bindings/video/ti,omap4-dss.txt     |  99 +++++++++
>  .../devicetree/bindings/video/ti,tfp410.txt        |  41 ++++
>  .../devicetree/bindings/video/ti,tpd12s015.txt     |  44 ++++
>  .../devicetree/bindings/video/video-ports.txt      |  22 ++
>  arch/arm/boot/dts/omap2.dtsi                       |  31 +++
>  arch/arm/boot/dts/omap3-beagle-xm.dts              | 119 +++++++++++
>  arch/arm/boot/dts/omap3-beagle.dts                 | 116 +++++++++++
>  arch/arm/boot/dts/omap3-igep0020.dts               |  59 +++++-
>  arch/arm/boot/dts/omap3-n900.dts                   |  70 ++++++-
>  arch/arm/boot/dts/omap3.dtsi                       |  42 ++++
>  arch/arm/boot/dts/omap4-panda-common.dtsi          | 119 ++++++++++-
>  arch/arm/boot/dts/omap4-sdp.dts                    | 107 +++++++++-
>  arch/arm/boot/dts/omap4.dtsi                       |  65 ++++++
>  arch/arm/mach-omap2/board-generic.c                |   4 +
>  arch/arm/mach-omap2/common.h                       |   3 +
>  arch/arm/mach-omap2/display.c                      | 132 ++++++++++++
>  arch/arm/mach-omap2/dss-common.c                   | 224 ---------------------
>  arch/arm/mach-omap2/pdata-quirks.c                 |   3 -
>  .../video/omap2/displays-new/connector-analog-tv.c |  43 +++-
>  drivers/video/omap2/displays-new/connector-dvi.c   |  43 ++++
>  drivers/video/omap2/displays-new/connector-hdmi.c  |  30 +++
>  drivers/video/omap2/displays-new/encoder-tfp410.c  |  43 +++-
>  .../video/omap2/displays-new/encoder-tpd12s015.c   |  56 ++++++
>  drivers/video/omap2/displays-new/panel-dpi.c       |  64 +++++-
>  drivers/video/omap2/displays-new/panel-dsi-cm.c    |  65 +++++-
>  .../omap2/displays-new/panel-sony-acx565akm.c      |  33 ++-
>  drivers/video/omap2/dss/Makefile                   |   2 +-
>  drivers/video/omap2/dss/dispc.c                    |   8 +
>  drivers/video/omap2/dss/display.c                  |  28 ++-
>  drivers/video/omap2/dss/dpi.c                      |  47 +++++
>  drivers/video/omap2/dss/dsi.c                      | 147 +++++++++++++-
>  drivers/video/omap2/dss/dss-of.c                   | 159 +++++++++++++++
>  drivers/video/omap2/dss/dss.c                      |  64 ++++++
>  drivers/video/omap2/dss/dss.h                      |   6 +
>  drivers/video/omap2/dss/hdmi4.c                    |  14 +-
>  drivers/video/omap2/dss/sdi.c                      |  45 +++++
>  drivers/video/omap2/dss/venc.c                     |  66 +++++-
>  drivers/video/omap2/omapfb/omapfb-main.c           |  67 ++++--
>  include/video/omapdss.h                            |  14 ++
>  48 files changed, 2550 insertions(+), 287 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/video/analog-tv-connector.txt
>  create mode 100644 Documentation/devicetree/bindings/video/dvi-connector.txt
>  create mode 100644 Documentation/devicetree/bindings/video/hdmi-connector.txt
>  create mode 100644 Documentation/devicetree/bindings/video/panel-dpi.txt
>  create mode 100644 Documentation/devicetree/bindings/video/panel-dsi-cm.txt
>  create mode 100644 Documentation/devicetree/bindings/video/sony,acx565akm.txt
>  create mode 100644 Documentation/devicetree/bindings/video/ti,omap-dss.txt
>  create mode 100644 Documentation/devicetree/bindings/video/ti,omap2-dss.txt
>  create mode 100644 Documentation/devicetree/bindings/video/ti,omap3-dss.txt
>  create mode 100644 Documentation/devicetree/bindings/video/ti,omap4-dss.txt
>  create mode 100644 Documentation/devicetree/bindings/video/ti,tfp410.txt
>  create mode 100644 Documentation/devicetree/bindings/video/ti,tpd12s015.txt
>  create mode 100644 Documentation/devicetree/bindings/video/video-ports.txt
>  create mode 100644 drivers/video/omap2/dss/dss-of.c
>
> --
> 1.8.3.2
>

Thanks a lot and best regards,
Javier

^ permalink raw reply

* Freescale FEC packet loss
From: Ben Hutchings @ 2014-01-26 21:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201401262012.13051.marex@denx.de>

On Sun, 2014-01-26 at 20:12 +0100, Marek Vasut wrote:
> On Sunday, January 26, 2014 at 07:56:30 PM, Ben Hutchings wrote:
> > On Wed, 2014-01-22 at 22:55 +0100, Marek Vasut wrote:
> > > Hi guys,
> > > 
> > > I am running stock Linux 3.13 on i.MX6Q SabreLite board. The CPU is
> > > i.MX6Q TO 1.0 .
> > > 
> > > I am hitting a WARNING when I use the FEC ethernet to transfer data, thus
> > > I started investigating this problem. TL;DR I am not able to figure this
> > > problem out, so I am not attaching a patch :-(
> > > 
> > > Steps to reproduce:
> > > -------------------
> > > 1) Boot stock Linux 3.13 on i.MX6Q SabreLite board
> > > 2) Plug in an SD card into one of the SD slots (I use the full-size one)
> > > 3) Plug in an USB stick into one of the USB ports (I use the upper one)
> > > 4) Plug in an ethernet cable into the board
> > > 
> > >    -> Connect the other side into a gigabit-capable PC
> > 
> > [...]
> > 
> > I think there are known problems with 1000BASE-T on the Sabre Lite
> > board.
> 
> This is MX6-wide thing, not sabrelite specific actually.
> 
> > Two possible workarounds are to limit the PHY to 100BASE-TX
> > (should be doable with ethtool) or force it to be clock master for
> > 1000BASE-T (requires a driver patch).
> 
> Can you please elaborate on the later ? I don't quite understand that.

1000BASE-T uses all 4 pairs in both directions at the same time, which
requires that both ends transmit symbols synchronously.  As part of the
autonegotiation protocol, they decide which is the clock master (using a
local clock generator) and which is the clock slave (generating a clock
from the received signal).  A PHY can be configured to support only one
of these roles.

> > The vendor kernel apparently does both!
> 
> More like the vendor kernel papers over this bug.
> 
> > Matthew Garrett has been trying to implement a workaround in a
> > clean way.
> 
> Do you have any pointers about this please ?

http://thread.gmane.org/gmane.linux.drivers.devicetree/58570

Ben.

-- 
Ben Hutchings
If the facts do not conform to your theory, they must be disposed of.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 828 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140126/3121cd37/attachment.sig>

^ permalink raw reply

* linux-next: manual merge of the clk tree with the arm-soc tree
From: Tomasz Figa @ 2014-01-26 21:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52E57744.5030807@gmail.com>

On 26.01.2014 21:59, Tomasz Figa wrote:
> Hi Stephen,
>
> On 13.01.2014 06:06, Stephen Rothwell wrote:
>> Hi Mike,
>>
>> Today's linux-next merge of the clk tree got a conflict in
>> drivers/clk/samsung/clk-exynos4.c between commit 86576fbe201b ("clk:
>> samsung: exynos4: Fix definition of div_mmc_pre4 divider") from the
>> arm-soc tree and commit 2d7382375054 ("clk: exynos4: replace clock ID
>> private enums with IDs from DT header") from the clk tree.
>>
>> I fixed it up (see below) and can carry the fix as necessary (no action
>> is required).
>
> It seems like somehow this fix-up has been lost in action and the
> conflict ended up being merged incorrectly in linux-next. Could you take
> a look?

Ehh, it's a false alarm fortunately. I've been looking at wrong ref, 
silly me. Sorry for the noise.

Best regards,
Tomasz

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox