LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: clk: mpc85xx: Update the driver to align to new clock bindings
From: Scott Wood @ 2014-03-19 21:52 UTC (permalink / raw)
  To: tang yuantian; +Cc: linuxppc-dev, mturquette
In-Reply-To: <1390267965-22408-1-git-send-email-Yuantian.Tang@freescale.com>

On Tue, Jan 21, 2014 at 09:32:45AM +0800, tang yuantian wrote:
> From: Tang Yuantian <yuantian.tang@freescale.com>
> 
> The clock bindings for Freescale CoreNet platform are updated.
> So, the driver needs to be updated accordingly.
> The main changes include:
> 	- Added a new node to present the input system clock
> 	- Changed PLL and MUX's compatible string
> 
> Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
> 
> ---
> drivers/clk/clk-ppc-corenet.c | 70 +++++++++++++++++++++++++++++--------------
>  1 file changed, 48 insertions(+), 22 deletions(-)

Acked-by: Scott Wood <scottwood@freescale.com>

Mike, does this need to go to linux-arm-kernel@lists.infradead.org as per
MAINTAINERS for drivers/clk?

> diff --git a/drivers/clk/clk-ppc-corenet.c b/drivers/clk/clk-ppc-corenet.c
> index c4f76ed..8b284be 100644
> --- a/drivers/clk/clk-ppc-corenet.c
> +++ b/drivers/clk/clk-ppc-corenet.c
> @@ -27,7 +27,6 @@ struct cmux_clk {
>  #define CLKSEL_ADJUST		BIT(0)
>  #define to_cmux_clk(p)		container_of(p, struct cmux_clk, hw)
>  
> -static void __iomem *base;
>  static unsigned int clocks_per_pll;
>  
>  static int cmux_set_parent(struct clk_hw *hw, u8 idx)
> @@ -100,7 +99,11 @@ static void __init core_mux_init(struct device_node *np)
>  		pr_err("%s: could not allocate cmux_clk\n", __func__);
>  		goto err_name;
>  	}
> -	cmux_clk->reg = base + offset;
> +	cmux_clk->reg = of_iomap(np, 0);
> +	if (!cmux_clk->reg) {
> +		pr_err("%s: could not map register\n", __func__);
> +		goto err_clk;
> +	}

dev_err?  Though it looks like of_clk_init() makes it hard to pass a
reference to the parent device (or anything else but a function pointer
and device tree node) to the init function -- why?

>  	node = of_find_compatible_node(NULL, NULL, "fsl,p4080-clockgen");
>  	if (node && (offset >= 0x80))
> @@ -143,38 +146,39 @@ err_name:
>  
>  static void __init core_pll_init(struct device_node *np)
>  {
> -	u32 offset, mult;
> +	u32 mult;
>  	int i, rc, count;
>  	const char *clk_name, *parent_name;
>  	struct clk_onecell_data *onecell_data;
>  	struct clk      **subclks;
> +	void __iomem *base;
>  
> -	rc = of_property_read_u32(np, "reg", &offset);
> -	if (rc) {
> -		pr_err("%s: could not get reg property\n", np->name);
> +	base = of_iomap(np, 0);
> +	if (!base) {
> +		pr_err("clk-ppc: iomap error\n");
>  		return;
>  	}
>  
>  	/* get the multiple of PLL */
> -	mult = ioread32be(base + offset);
> +	mult = ioread32be(base);
>  
>  	/* check if this PLL is disabled */
>  	if (mult & PLL_KILL) {
>  		pr_debug("PLL:%s is disabled\n", np->name);
> -		return;
> +		goto err_map;
>  	}
>  	mult = (mult >> 1) & 0x3f;
>  
>  	parent_name = of_clk_get_parent_name(np, 0);
>  	if (!parent_name) {
>  		pr_err("PLL: %s must have a parent\n", np->name);
> -		return;
> +		goto err_map;
>  	}
>  
>  	count = of_property_count_strings(np, "clock-output-names");
>  	if (count < 0 || count > 4) {
>  		pr_err("%s: clock is not supported\n", np->name);
> -		return;
> +		goto err_map;
>  	}
>  
>  	/* output clock number per PLL */
> @@ -183,7 +187,7 @@ static void __init core_pll_init(struct device_node *np)
>  	subclks = kzalloc(sizeof(struct clk *) * count, GFP_KERNEL);
>  	if (!subclks) {
>  		pr_err("%s: could not allocate subclks\n", __func__);
> -		return;
> +		goto err_map;
>  	}
>  
>  	onecell_data = kzalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
> @@ -230,30 +234,52 @@ static void __init core_pll_init(struct device_node *np)
>  		goto err_cell;
>  	}
>  
> +	iounmap(base);
>  	return;
>  err_cell:
>  	kfree(onecell_data);
>  err_clks:
>  	kfree(subclks);
> +err_map:
> +	iounmap(base);
> +}

Consider devres -- is there a devres version of of_iomap()?

-Scott

^ permalink raw reply

* [PATCH 3/4] ARCH: AUDIT: implement syscall_get_arch for all arches
From: Eric Paris @ 2014-03-19 22:04 UTC (permalink / raw)
  To: linux-audit
  Cc: linux-mips, linux-ia64, linux-parisc, microblaze-uclinux, linux,
	Eric Paris, sparclinux, linuxppc-dev
In-Reply-To: <1395266643-3139-1-git-send-email-eparis@redhat.com>

For all arches which support audit implement syscall_get_arch()
They are all pretty easy and straight forward, stolen from how the call
to audit_syscall_entry() determines the arch.

Signed-off-by: Eric Paris <eparis@redhat.com>
Cc: linux-ia64@vger.kernel.org
Cc: microblaze-uclinux@itee.uq.edu.au
Cc: linux-mips@linux-mips.org
Cc: linux@lists.openrisc.net
Cc: linux-parisc@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: sparclinux@vger.kernel.org
---
 arch/ia64/include/asm/syscall.h       |  6 ++++++
 arch/microblaze/include/asm/syscall.h |  5 +++++
 arch/mips/include/asm/syscall.h       |  2 +-
 arch/openrisc/include/asm/syscall.h   |  5 +++++
 arch/parisc/include/asm/syscall.h     | 11 +++++++++++
 arch/powerpc/include/asm/syscall.h    | 12 ++++++++++++
 arch/sparc/include/asm/syscall.h      |  8 ++++++++
 include/uapi/linux/audit.h            |  1 +
 8 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/arch/ia64/include/asm/syscall.h b/arch/ia64/include/asm/syscall.h
index a7ff1c6..1d0b875 100644
--- a/arch/ia64/include/asm/syscall.h
+++ b/arch/ia64/include/asm/syscall.h
@@ -13,6 +13,7 @@
 #ifndef _ASM_SYSCALL_H
 #define _ASM_SYSCALL_H	1
 
+#include <uapi/linux/audit.h>
 #include <linux/sched.h>
 #include <linux/err.h>
 
@@ -79,4 +80,9 @@ static inline void syscall_set_arguments(struct task_struct *task,
 
 	ia64_syscall_get_set_arguments(task, regs, i, n, args, 1);
 }
+
+static inline int syscall_get_arch(void)
+{
+	return AUDIT_ARCH_IA64;
+}
 #endif	/* _ASM_SYSCALL_H */
diff --git a/arch/microblaze/include/asm/syscall.h b/arch/microblaze/include/asm/syscall.h
index 9bc4317..53cfaf3 100644
--- a/arch/microblaze/include/asm/syscall.h
+++ b/arch/microblaze/include/asm/syscall.h
@@ -1,6 +1,7 @@
 #ifndef __ASM_MICROBLAZE_SYSCALL_H
 #define __ASM_MICROBLAZE_SYSCALL_H
 
+#include <uapi/linux/audit.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <asm/ptrace.h>
@@ -99,4 +100,8 @@ static inline void syscall_set_arguments(struct task_struct *task,
 asmlinkage long do_syscall_trace_enter(struct pt_regs *regs);
 asmlinkage void do_syscall_trace_leave(struct pt_regs *regs);
 
+static inline int syscall_get_arch(void)
+{
+	return AUDIT_ARCH_MICROBLAZE;
+}
 #endif /* __ASM_MICROBLAZE_SYSCALL_H */
diff --git a/arch/mips/include/asm/syscall.h b/arch/mips/include/asm/syscall.h
index fc556d8..992b6ab 100644
--- a/arch/mips/include/asm/syscall.h
+++ b/arch/mips/include/asm/syscall.h
@@ -103,7 +103,7 @@ extern const unsigned long sysn32_call_table[];
 
 static inline int syscall_get_arch(void)
 {
-	int arch = EM_MIPS;
+	int arch = AUDIT_ARCH_MIPS;
 #ifdef CONFIG_64BIT
 	arch |=  __AUDIT_ARCH_64BIT;
 #endif
diff --git a/arch/openrisc/include/asm/syscall.h b/arch/openrisc/include/asm/syscall.h
index b752bb6..2db9f1c 100644
--- a/arch/openrisc/include/asm/syscall.h
+++ b/arch/openrisc/include/asm/syscall.h
@@ -19,6 +19,7 @@
 #ifndef __ASM_OPENRISC_SYSCALL_H__
 #define __ASM_OPENRISC_SYSCALL_H__
 
+#include <uapi/linux/audit.h>
 #include <linux/err.h>
 #include <linux/sched.h>
 
@@ -71,4 +72,8 @@ syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
 	memcpy(&regs->gpr[3 + i], args, n * sizeof(args[0]));
 }
 
+static inline int syscall_get_arch(void)
+{
+	return AUDIT_ARCH_OPENRISC;
+}
 #endif
diff --git a/arch/parisc/include/asm/syscall.h b/arch/parisc/include/asm/syscall.h
index 8bdfd2c..a5eba95 100644
--- a/arch/parisc/include/asm/syscall.h
+++ b/arch/parisc/include/asm/syscall.h
@@ -3,6 +3,8 @@
 #ifndef _ASM_PARISC_SYSCALL_H_
 #define _ASM_PARISC_SYSCALL_H_
 
+#include <uapi/linux/audit.h>
+#include <linux/compat.h>
 #include <linux/err.h>
 #include <asm/ptrace.h>
 
@@ -37,4 +39,13 @@ static inline void syscall_get_arguments(struct task_struct *tsk,
 	}
 }
 
+static inline int syscall_get_arch(void)
+{
+	int arch = AUDIT_ARCH_PARISC;
+#ifdef CONFIG_64BIT
+	if (!is_compat_task())
+		arch = AUDIT_ARCH_PARISC64;
+#endif
+	return arch;
+}
 #endif /*_ASM_PARISC_SYSCALL_H_*/
diff --git a/arch/powerpc/include/asm/syscall.h b/arch/powerpc/include/asm/syscall.h
index b54b2ad..4271544 100644
--- a/arch/powerpc/include/asm/syscall.h
+++ b/arch/powerpc/include/asm/syscall.h
@@ -13,6 +13,8 @@
 #ifndef _ASM_SYSCALL_H
 #define _ASM_SYSCALL_H	1
 
+#include <uapi/linux/audit.h>
+#include <linux/compat.h>
 #include <linux/sched.h>
 
 /* ftrace syscalls requires exporting the sys_call_table */
@@ -86,4 +88,14 @@ static inline void syscall_set_arguments(struct task_struct *task,
 	memcpy(&regs->gpr[3 + i], args, n * sizeof(args[0]));
 }
 
+static inline int syscall_get_arch(void)
+{
+	int arch = AUDIT_ARCH_PPC;
+
+#ifdef CONFIG_PPC64
+	if (!is_32bit_task())
+		arch = AUDIT_ARCH_PPC64;
+#endif
+	return arch;
+}
 #endif	/* _ASM_SYSCALL_H */
diff --git a/arch/sparc/include/asm/syscall.h b/arch/sparc/include/asm/syscall.h
index 025a02a..fed3d51 100644
--- a/arch/sparc/include/asm/syscall.h
+++ b/arch/sparc/include/asm/syscall.h
@@ -1,9 +1,11 @@
 #ifndef __ASM_SPARC_SYSCALL_H
 #define __ASM_SPARC_SYSCALL_H
 
+#include <uapi/linux/audit.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <asm/ptrace.h>
+#include <asm/thread_info.h>
 
 /*
  * The syscall table always contains 32 bit pointers since we know that the
@@ -124,4 +126,10 @@ static inline void syscall_set_arguments(struct task_struct *task,
 		regs->u_regs[UREG_I0 + i + j] = args[j];
 }
 
+static inline int syscall_get_arch(void)
+{
+	return test_thread_flag(TIF_32BIT) ? AUDIT_ARCH_SPARC
+					   : AUDIT_ARCH_SPARC64;
+}
+
 #endif /* __ASM_SPARC_SYSCALL_H */
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 9af01d7..8496cfa 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -343,6 +343,7 @@ enum {
 #define AUDIT_ARCH_IA64		(EM_IA_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
 #define AUDIT_ARCH_M32R		(EM_M32R)
 #define AUDIT_ARCH_M68K		(EM_68K)
+#define AUDIT_ARCH_MICROBLAZE	(EM_MICROBLAZE)
 #define AUDIT_ARCH_MIPS		(EM_MIPS)
 #define AUDIT_ARCH_MIPSEL	(EM_MIPS|__AUDIT_ARCH_LE)
 #define AUDIT_ARCH_MIPS64	(EM_MIPS|__AUDIT_ARCH_64BIT)
-- 
1.8.5.3

^ permalink raw reply related

* Re: [PATCH] powerpc 32: Provides VIRT_CPU_ACCOUNTING
From: Scott Wood @ 2014-03-19 22:05 UTC (permalink / raw)
  To: Christophe Leroy; +Cc: linuxppc-dev, Paul Mackerras, linux-kernel
In-Reply-To: <20140319215241.236B21A4BDE@localhost.localdomain>

On Wed, 2014-03-19 at 22:52 +0100, Christophe Leroy wrote:
> This patch provides VIRT_CPU_ACCOUTING to PPC32 architecture.
> Unlike PPC64, PPC32 doesn't provide the PACA register. Therefore the
> implementation is similar to the one done in the IA64 architecture.
> It is based on additional information added to the Task Info structure.

PACA isn't a register -- just a convention for how Linux uses a GPR.
Maybe it's time to use it on PPC32 as well?

> Index: b/arch/powerpc/kernel/asm-offsets.c
> ===================================================================
> --- b/arch/powerpc/kernel/asm-offsets.c	(revision 5607)
> +++ b/arch/powerpc/kernel/asm-offsets.c	(revision 5608)
> @@ -167,6 +167,10 @@
>  	DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
>  	DEFINE(TI_TASK, offsetof(struct thread_info, task));
>  	DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
> +	DEFINE(TI_AC_STAMP, offsetof(struct thread_info, ac_stamp));
> +	DEFINE(TI_AC_LEAVE, offsetof(struct thread_info, ac_leave));
> +	DEFINE(TI_AC_STIME, offsetof(struct thread_info, ac_stime));
> +	DEFINE(TI_AC_UTIME, offsetof(struct thread_info, ac_utime));

Doesn't this need to be protected by #ifdef
CONFIG_VIRT_CPU_ACCOUNTING_NATIVE?

>  
>  #ifdef CONFIG_PPC64
>  	DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size));
> Index: b/arch/powerpc/include/asm/thread_info.h
> ===================================================================
> --- b/arch/powerpc/include/asm/thread_info.h	(revision 5607)
> +++ b/arch/powerpc/include/asm/thread_info.h	(revision 5608)
> @@ -43,6 +43,12 @@
>  	int		cpu;			/* cpu we're on */
>  	int		preempt_count;		/* 0 => preemptable,
>  						   <0 => BUG */
> +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
> +	__u32 ac_stamp;
> +	__u32 ac_leave;
> +	__u32 ac_stime;
> +	__u32 ac_utime;
> +#endif

This isn't uapi; why not use "u32"?

Plus, it should be made clear that this is only used on 32-bit.

>  	struct restart_block restart_block;
>  	unsigned long	local_flags;		/* private flags for thread */
>  
> @@ -58,6 +64,8 @@
>  	.task =		&tsk,			\
>  	.exec_domain =	&default_exec_domain,	\
>  	.cpu =		0,			\
> +	.ac_stime =	0,			\
> +	.ac_utime =	0,			\

Also needs to be ifdeffed -- which isn't going to work in a macro, so
maybe remove the ifdef from the variable declarations, or just let the
fields be initialized to zero by default.  Or add PACA to 32-bit. :-)

-Scott

^ permalink raw reply

* Re: [PATCH 3/4] ARCH: AUDIT: implement syscall_get_arch for all arches
From: Matt Turner @ 2014-03-19 22:19 UTC (permalink / raw)
  To: Eric Paris
  Cc: linux-mips@linux-mips.org, linux-ia64,
	linux-parisc@vger.kernel.org, microblaze-uclinux, linux,
	linux-audit, sparclinux, linuxppc-dev
In-Reply-To: <1395266643-3139-3-git-send-email-eparis@redhat.com>

On Wed, Mar 19, 2014 at 3:04 PM, Eric Paris <eparis@redhat.com> wrote:
> For all arches which support audit implement syscall_get_arch()

support audit -- is that AUDIT_ARCH? If so, alpha gained support
recently, so I think this patch needs to handle alpha too?

^ permalink raw reply

* [PATCH] powerpc 32: Provides VIRT_CPU_ACCOUNTING
From: Christophe Leroy @ 2014-03-19 21:52 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, scottwood
  Cc: linuxppc-dev, linux-kernel

This patch provides VIRT_CPU_ACCOUTING to PPC32 architecture.
Unlike PPC64, PPC32 doesn't provide the PACA register. Therefore the
implementation is similar to the one done in the IA64 architecture.
It is based on additional information added to the Task Info structure.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>

Index: b/arch/powerpc/Kconfig
===================================================================
--- b/arch/powerpc/Kconfig	(revision 5607)
+++ b/arch/powerpc/Kconfig	(revision 5608)
@@ -138,6 +138,7 @@
 	select OLD_SIGSUSPEND
 	select OLD_SIGACTION if PPC32
 	select HAVE_DEBUG_STACKOVERFLOW
+	select HAVE_VIRT_CPU_ACCOUNTING
 
 config EARLY_PRINTK
 	bool
Index: b/arch/powerpc/kernel/time.c
===================================================================
--- b/arch/powerpc/kernel/time.c	(revision 5607)
+++ b/arch/powerpc/kernel/time.c	(revision 5608)
@@ -162,7 +162,9 @@
 
 cputime_t cputime_one_jiffy;
 
+#ifdef CONFIG_PPC_SPLPAR
 void (*dtl_consumer)(struct dtl_entry *, u64);
+#endif
 
 static void calc_cputime_factors(void)
 {
@@ -178,6 +180,7 @@
 	__cputime_clockt_factor = res.result_low;
 }
 
+#ifdef CONFIG_PPC64
 /*
  * Read the SPURR on systems that have it, otherwise the PURR,
  * or if that doesn't exist return the timebase value passed in.
@@ -190,6 +193,7 @@
 		return mfspr(SPRN_PURR);
 	return tb;
 }
+#endif
 
 #ifdef CONFIG_PPC_SPLPAR
 
@@ -291,6 +295,7 @@
  * Account time for a transition between system, hard irq
  * or soft irq state.
  */
+#ifdef CONFIG_PPC64
 static u64 vtime_delta(struct task_struct *tsk,
 			u64 *sys_scaled, u64 *stolen)
 {
@@ -377,7 +382,70 @@
 	get_paca()->utime_sspurr = 0;
 	account_user_time(tsk, utime, utimescaled);
 }
+#else
 
+void vtime_account_user(struct task_struct *tsk)
+{
+	cputime_t delta_utime;
+	struct thread_info *ti = task_thread_info(tsk);
+
+	if (ti->ac_utime) {
+		delta_utime = ti->ac_utime;
+		account_user_time(tsk, delta_utime, delta_utime);
+		ti->ac_utime = 0;
+	}
+}
+
+/*
+ * Called from the context switch with interrupts disabled, to charge all
+ * accumulated times to the current process, and to prepare accounting on
+ * the next process.
+ */
+void arch_vtime_task_switch(struct task_struct *prev)
+{
+	struct thread_info *pi = task_thread_info(prev);
+	struct thread_info *ni = task_thread_info(current);
+
+	ni->ac_stamp = pi->ac_stamp;
+	ni->ac_stime = ni->ac_utime = 0;
+}
+
+/*
+ * Account time for a transition between system, hard irq or soft irq state.
+ * Note that this function is called with interrupts enabled.
+ */
+static cputime_t vtime_delta(struct task_struct *tsk)
+{
+	struct thread_info *ti = task_thread_info(tsk);
+	__u32 delta_stime;
+	__u32 now;
+
+	WARN_ON_ONCE(!irqs_disabled());
+
+	now = mftbl();
+
+	delta_stime = ti->ac_stime + (now - ti->ac_stamp);
+	ti->ac_stime = 0;
+	ti->ac_stamp = now;
+
+	return (cputime_t)delta_stime;
+}
+
+void vtime_account_system(struct task_struct *tsk)
+{
+	cputime_t delta = vtime_delta(tsk);
+
+	account_system_time(tsk, 0, delta, delta);
+}
+EXPORT_SYMBOL_GPL(vtime_account_system);
+
+void vtime_account_idle(struct task_struct *tsk)
+{
+	account_idle_time(vtime_delta(tsk));
+}
+
+#endif
+
 #else /* ! CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
 #define calc_cputime_factors()
 #endif
@@ -871,6 +939,8 @@
 		       ppc_proc_freq / 1000000, ppc_proc_freq % 1000000);
 	}
 
+	mttbl(0);
+	mttbu(0);
 	tb_ticks_per_jiffy = ppc_tb_freq / HZ;
 	tb_ticks_per_sec = ppc_tb_freq;
 	tb_ticks_per_usec = ppc_tb_freq / 1000000;
Index: b/arch/powerpc/kernel/entry_32.S
===================================================================
--- b/arch/powerpc/kernel/entry_32.S	(revision 5607)
+++ b/arch/powerpc/kernel/entry_32.S	(revision 5608)
@@ -177,6 +177,12 @@
 	addi	r12,r12,-1
 	stw	r12,4(r11)
 #endif
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
+	CURRENT_THREAD_INFO(r9, r1)
+	tophys(r9, r9)
+	ACCOUNT_CPU_USER_ENTRY(r9, r11, r12)
+#endif
+
 	b	3f
 
 2:	/* if from kernel, check interrupted DOZE/NAP mode and
@@ -406,6 +412,13 @@
 	lwarx	r7,0,r1
 END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
 	stwcx.	r0,0,r1			/* to clear the reservation */
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
+	andi.	r4,r8,MSR_PR
+	beq	3f
+	CURRENT_THREAD_INFO(r4, r1)
+	ACCOUNT_CPU_USER_EXIT(r4, r5, r7)
+3:
+#endif
 	lwz	r4,_LINK(r1)
 	lwz	r5,_CCR(r1)
 	mtlr	r4
@@ -841,6 +854,10 @@
 	andis.	r10,r0,DBCR0_IDM@h
 	bnel-	load_dbcr0
 #endif
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
+	CURRENT_THREAD_INFO(r9, r1)
+	ACCOUNT_CPU_USER_EXIT(r9, r10, r11)
+#endif
 
 	b	restore
 
Index: b/arch/powerpc/kernel/asm-offsets.c
===================================================================
--- b/arch/powerpc/kernel/asm-offsets.c	(revision 5607)
+++ b/arch/powerpc/kernel/asm-offsets.c	(revision 5608)
@@ -167,6 +167,10 @@
 	DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
 	DEFINE(TI_TASK, offsetof(struct thread_info, task));
 	DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
+	DEFINE(TI_AC_STAMP, offsetof(struct thread_info, ac_stamp));
+	DEFINE(TI_AC_LEAVE, offsetof(struct thread_info, ac_leave));
+	DEFINE(TI_AC_STIME, offsetof(struct thread_info, ac_stime));
+	DEFINE(TI_AC_UTIME, offsetof(struct thread_info, ac_utime));
 
 #ifdef CONFIG_PPC64
 	DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size));
Index: b/arch/powerpc/include/asm/thread_info.h
===================================================================
--- b/arch/powerpc/include/asm/thread_info.h	(revision 5607)
+++ b/arch/powerpc/include/asm/thread_info.h	(revision 5608)
@@ -43,6 +43,12 @@
 	int		cpu;			/* cpu we're on */
 	int		preempt_count;		/* 0 => preemptable,
 						   <0 => BUG */
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
+	__u32 ac_stamp;
+	__u32 ac_leave;
+	__u32 ac_stime;
+	__u32 ac_utime;
+#endif
 	struct restart_block restart_block;
 	unsigned long	local_flags;		/* private flags for thread */
 
@@ -58,6 +64,8 @@
 	.task =		&tsk,			\
 	.exec_domain =	&default_exec_domain,	\
 	.cpu =		0,			\
+	.ac_stime =	0,			\
+	.ac_utime =	0,			\
 	.preempt_count = INIT_PREEMPT_COUNT,	\
 	.restart_block = {			\
 		.fn = do_no_restart_syscall,	\
Index: b/arch/powerpc/include/asm/cputime.h
===================================================================
--- b/arch/powerpc/include/asm/cputime.h	(revision 5607)
+++ b/arch/powerpc/include/asm/cputime.h	(revision 5608)
@@ -228,7 +228,11 @@
 
 #define cputime64_to_clock_t(ct)	cputime_to_clock_t((cputime_t)(ct))
 
+#ifdef CONFIG_PPC64
 static inline void arch_vtime_task_switch(struct task_struct *tsk) { }
+#else
+extern void arch_vtime_task_switch(struct task_struct *tsk);
+#endif
 
 #endif /* __KERNEL__ */
 #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
Index: b/arch/powerpc/include/asm/ppc_asm.h
===================================================================
--- b/arch/powerpc/include/asm/ppc_asm.h	(revision 5607)
+++ b/arch/powerpc/include/asm/ppc_asm.h	(revision 5608)
@@ -25,10 +25,16 @@
  */
 
 #ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
+#ifdef CONFIG_PPC64
 #define ACCOUNT_CPU_USER_ENTRY(ra, rb)
 #define ACCOUNT_CPU_USER_EXIT(ra, rb)
+#else /* CONFIG_PPC64 */
+#define ACCOUNT_CPU_USER_ENTRY(ti, ra, rb)
+#define ACCOUNT_CPU_USER_EXIT(ti, ra, rb)
+#endif
 #define ACCOUNT_STOLEN_TIME
-#else
+#else /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
+#ifdef CONFIG_PPC64
 #define ACCOUNT_CPU_USER_ENTRY(ra, rb)					\
 	MFTB(ra);			/* get timebase */		\
 	ld	rb,PACA_STARTTIME_USER(r13);				\
@@ -68,7 +74,27 @@
 #define ACCOUNT_STOLEN_TIME
 
 #endif /* CONFIG_PPC_SPLPAR */
+#else /* CONFIG_PPC64 */
+#define ACCOUNT_CPU_USER_ENTRY(ti, ra, rb)				\
+	MFTB(ra);							\
+	lwz rb, TI_AC_LEAVE(ti);					\
+	stw ra, TI_AC_STAMP(ti);	/* AC_STAMP = NOW */		\
+	subf rb, rb, ra;		/* R = NOW - AC_LEAVE */	\
+	lwz ra, TI_AC_UTIME(ti);					\
+	add ra, rb, ra;			/* AC_UTIME += R */		\
+	stw ra, TI_AC_UTIME(ti);					\
 
+#define ACCOUNT_CPU_USER_EXIT(ti, ra, rb)				\
+	MFTB(ra);							\
+	lwz rb, TI_AC_STAMP(ti);					\
+	stw ra, TI_AC_LEAVE(ti);					\
+	subf rb, rb, ra;		/* R = NOW - AC_STAMP */	\
+	lwz ra, TI_AC_STIME(ti);					\
+	add ra, rb, ra;			/* AC_STIME += R */		\
+	stw ra, TI_AC_STIME(ti);					\
+
+#endif
+
 #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
 
 /*

^ permalink raw reply

* Re: [1/2, v9] powerpc/mpc85xx:Add initial device tree support of T104x
From: Scott Wood @ 2014-03-19 22:33 UTC (permalink / raw)
  To: Prabhakar Kushwaha
  Cc: Varun Sethi, Poonam Aggrwal, linuxppc-dev, Priyanka Jain
In-Reply-To: <1390650059-19437-1-git-send-email-prabhakar@freescale.com>

On Sat, Jan 25, 2014 at 05:10:59PM +0530, Prabhakar Kushwaha wrote:
> +	corenet-cf@18000 {
> +		compatible = "fsl,corenet-cf";
> +		reg = <0x18000 0x1000>;
> +		interrupts = <16 2 1 31>;
> +		fsl,ccf-num-csdids = <32>;
> +		fsl,ccf-num-snoopids = <32>;
> +	};

I know this isn't a new problem, but this needs a binding -- and a
different compatible from p4080-era CCF.  AFAICT it's a completely
different programming model, and even the block version registers weren't
present in the original version.

> +/include/ "qoriq-mpic.dtsi"
> +
> +	guts: global-utilities@e0000 {
> +		compatible = "fsl,t1040-device-config", "fsl,qoriq-device-config-2.0";
> +		reg = <0xe0000 0xe00>;
> +		fsl,has-rstcr;
> +		fsl,liodn-bits = <12>;
> +	};
> +
> +	clockgen: global-utilities@e1000 {
> +		compatible = "fsl,t1040-clockgen", "fsl,qoriq-clockgen-2.0",
> +				   "fixed-clock";
> +		ranges = <0x0 0xe1000 0x1000>;
> +		clock-frequency = <100000000>;

Why is clock-frequency hardcoded here rather than supplied by U-Boot? 
Especially since this is an SoC file, not a board file.

> +		reg = <0xe1000 0x1000>;
> +		clock-output-names = "sysclk";
> +		#address-cells = <1>;
> +		#size-cells = <1>;

clock-output-names and fixed-clock doesn't belong on this node.

> +
> +		sysclk: sysclk {
> +			#clock-cells = <0>;
> +			compatible = "fsl,qoriq-sysclk-2.0";
> +			clock-output-names = "sysclk";
> +		};
> +
> +
> +		pll0: pll0@800 {
> +			#clock-cells = <1>;
> +			reg = <0x800 4>;
> +			compatible = "fsl,qoriq-core-pll-2.0";
> +			clocks = <&clockgen>;
> +			clock-output-names = "pll0", "pll0-div2", "pll0-div4";
> +		};
> +
> +		pll1: pll1@820 {
> +			#clock-cells = <1>;
> +			reg = <0x820 4>;
> +			compatible = "fsl,qoriq-core-pll-2.0";
> +			clocks = <&clockgen>;
> +			clock-output-names = "pll1", "pll1-div2", "pll1-div4";
> +		};

clocks should point to sysclk.

> +	display@180000 {
> +		compatible = "fsl,t1040-diu", "fsl,diu";
> +		reg = <0x180000 1000>;
> +		interrupts = <74 2 0 0>;
> +	};
> +
> +/include/ "qoriq-sata2-0.dtsi"
> +sata@220000 {
> +			fsl,iommu-parent = <&pamu0>;
> +			fsl,liodn-reg = <&guts 0x550>; /* SATA1LIODNR */
> +};
> +/include/ "qoriq-sata2-1.dtsi"
> +sata@221000 {
> +			fsl,iommu-parent = <&pamu0>;
> +			fsl,liodn-reg = <&guts 0x554>; /* SATA2LIODNR */
> +};
> +/include/ "qoriq-sec5.0-0.dtsi"
> +};

Whitespace

-Scott

^ permalink raw reply

* Re: powerpc/config: Remove unnecssary CONFIG_FSL_IFC
From: Scott Wood @ 2014-03-19 22:42 UTC (permalink / raw)
  To: Prabhakar Kushwaha; +Cc: linuxppc-dev
In-Reply-To: <1390652612-3553-1-git-send-email-prabhakar@freescale.com>

On Sat, Jan 25, 2014 at 05:53:32PM +0530, Prabhakar Kushwaha wrote:
> CONFIG_FSL_IFC gets enabled by Kconfig dependancies.
> So remove unnecssary define from the defconfigs
> 
> Signed-off-by: Prabhakar Kushwaha <prabhakar@freescale.com>
> 
> ---
> arch/powerpc/configs/corenet64_smp_defconfig |    1 -
>  arch/powerpc/configs/mpc85xx_defconfig       |    1 -
>  arch/powerpc/configs/mpc85xx_smp_defconfig   |    1 -
>  3 files changed, 3 deletions(-)

I'll apply this, but FSL_IFC really should be made user-selectable
without needing to enable NAND support, since it also provides error
reporting for NOR and GPCM.

Also, when submitting patches like this, it's best to mention that it's
the output of running savedefconfig (and if that isn't how the patch was
generated, do it that way instead).

-Scott

^ permalink raw reply

* 3.16.6 build error: swsusp_booke.S:85: Error: invalid sprg number
From: John Donnelly @ 2014-03-19 22:58 UTC (permalink / raw)
  To: linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 1276 bytes --]

Platform: Freescale  p4080--e500mc  ,

Suggestions welcome .

 /bin/sh arch/powerpc/kernel/systbl_chk.sh arch/powerpc/kernel/systbl_chk.i
make -f scripts/Makefile.build obj=arch/powerpc/kernel/vdso32
  gcc -mbig-endian -m32 -Wp,-MD,arch/powerpc/kernel/.swsusp_booke.o.d
 -nostdinc -isystem /usr/lib/gcc/ppc64-redhat-linux/4.8.2/include
-I/root/linux-3.13.6/arch/powerpc/include -Iarch/powerpc/include/generated
 -Iinclude -I/root/linux-3.13.6/arch/powerpc/include/uapi
-Iarch/powerpc/include/generated/uapi -I/root/linux-3.13.6/include/uapi
-Iinclude/generated/uapi -include
/root/linux-3.13.6/include/linux/kconfig.h -D__KERNEL__ -Iarch/powerpc
 -D__ASSEMBLY__ -Iarch/powerpc  -gdwarf-2          -c -o
arch/powerpc/kernel/swsusp_booke.o arch/powerpc/kernel/swsusp_booke.S
arch/powerpc/kernel/swsusp_booke.S: Assembler messages:
arch/powerpc/kernel/swsusp_booke.S:85: Error: invalid sprg number
arch/powerpc/kernel/swsusp_booke.S:87: Error: invalid sprg number


-- 

*Regards,*
* John.*

*--*

*o* Energy-efficiency is #1 reason data centers look to expand.  -- Digital
Realty Trust
*o* Green Data Centers spending to increase 300% worldwide by 2016.  --
Pike Research
*o *Data Centers have become as vital to the functioni
ng of society as power stations.  -- The Economist

[-- Attachment #2: Type: text/html, Size: 3186 bytes --]

^ permalink raw reply

* [PATCH 4/4] ARCH: AUDIT: audit_syscall_entry() should not require the arch
From: Eric Paris @ 2014-03-19 22:04 UTC (permalink / raw)
  To: linux-audit
  Cc: linux-mips, x86, linux-ia64, user-mode-linux-devel, linux-parisc,
	linux-s390, linux-xtensa, microblaze-uclinux, linux, linux-sh,
	Eric Paris, linux-alpha, sparclinux, linuxppc-dev,
	linux-arm-kernel
In-Reply-To: <1395266643-3139-1-git-send-email-eparis@redhat.com>

We have a function where the arch can be queried, syscall_get_arch().
So rather than have every single piece of arch specific code use and/or
duplicate syscall_get_arch(), just have the audit code use the
syscall_get_arch() code.

Signed-off-by: Eric Paris <eparis@redhat.com>
Cc: linux-alpha@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-ia64@vger.kernel.org
Cc: microblaze-uclinux@itee.uq.edu.au
Cc: linux-mips@linux-mips.org
Cc: linux@lists.openrisc.net
Cc: linux-parisc@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-s390@vger.kernel.org
Cc: linux-sh@vger.kernel.org
Cc: sparclinux@vger.kernel.org
Cc: user-mode-linux-devel@lists.sourceforge.net
Cc: linux-xtensa@linux-xtensa.org
Cc: x86@kernel.org
---
 arch/alpha/kernel/ptrace.c      |  2 +-
 arch/arm/kernel/ptrace.c        |  4 ++--
 arch/ia64/kernel/ptrace.c       |  2 +-
 arch/microblaze/kernel/ptrace.c |  3 +--
 arch/mips/kernel/ptrace.c       |  4 +---
 arch/openrisc/kernel/ptrace.c   |  3 +--
 arch/parisc/kernel/ptrace.c     |  9 +++------
 arch/powerpc/kernel/ptrace.c    |  7 ++-----
 arch/s390/kernel/ptrace.c       |  4 +---
 arch/sh/kernel/ptrace_32.c      | 14 +-------------
 arch/sh/kernel/ptrace_64.c      | 17 +----------------
 arch/sparc/kernel/ptrace_64.c   |  9 ++-------
 arch/um/kernel/ptrace.c         |  3 +--
 arch/x86/kernel/ptrace.c        |  8 ++------
 arch/x86/um/asm/ptrace.h        |  4 ----
 arch/xtensa/kernel/ptrace.c     |  2 +-
 include/linux/audit.h           |  7 ++++---
 17 files changed, 25 insertions(+), 77 deletions(-)

diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c
index 86d8351..d9ee817 100644
--- a/arch/alpha/kernel/ptrace.c
+++ b/arch/alpha/kernel/ptrace.c
@@ -321,7 +321,7 @@ asmlinkage unsigned long syscall_trace_enter(void)
 	if (test_thread_flag(TIF_SYSCALL_TRACE) &&
 	    tracehook_report_syscall_entry(current_pt_regs()))
 		ret = -1UL;
-	audit_syscall_entry(AUDIT_ARCH_ALPHA, regs->r0, regs->r16, regs->r17, regs->r18, regs->r19);
+	audit_syscall_entry(regs->r0, regs->r16, regs->r17, regs->r18, regs->r19);
 	return ret ?: current_pt_regs()->r0;
 }
 
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 0dd3b79..c9d2b34 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -943,8 +943,8 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
 	if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
 		trace_sys_enter(regs, scno);
 
-	audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, regs->ARM_r1,
-			    regs->ARM_r2, regs->ARM_r3);
+	audit_syscall_entry(scno, regs->ARM_r0, regs->ARM_r1, regs->ARM_r2,
+			    regs->ARM_r3);
 
 	return scno;
 }
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index b7a5fff..6f54d51 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -1219,7 +1219,7 @@ syscall_trace_enter (long arg0, long arg1, long arg2, long arg3,
 		ia64_sync_krbs();
 
 
-	audit_syscall_entry(AUDIT_ARCH_IA64, regs.r15, arg0, arg1, arg2, arg3);
+	audit_syscall_entry(regs.r15, arg0, arg1, arg2, arg3);
 
 	return 0;
 }
diff --git a/arch/microblaze/kernel/ptrace.c b/arch/microblaze/kernel/ptrace.c
index 39cf508..bb10637 100644
--- a/arch/microblaze/kernel/ptrace.c
+++ b/arch/microblaze/kernel/ptrace.c
@@ -147,8 +147,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
 		 */
 		ret = -1L;
 
-	audit_syscall_entry(EM_MICROBLAZE, regs->r12, regs->r5, regs->r6,
-			    regs->r7, regs->r8);
+	audit_syscall_entry(regs->r12, regs->r5, regs->r6, regs->r7, regs->r8);
 
 	return ret ?: regs->r12;
 }
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 65ba622..c06bb82 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -671,9 +671,7 @@ asmlinkage void syscall_trace_enter(struct pt_regs *regs)
 	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
 		trace_sys_enter(regs, regs->regs[2]);
 
-	audit_syscall_entry(syscall_get_arch(),
-			    regs->regs[2],
-			    regs->regs[4], regs->regs[5],
+	audit_syscall_entry(regs->regs[2], regs->regs[4], regs->regs[5],
 			    regs->regs[6], regs->regs[7]);
 }
 
diff --git a/arch/openrisc/kernel/ptrace.c b/arch/openrisc/kernel/ptrace.c
index 71a2a0c..4f59fa4 100644
--- a/arch/openrisc/kernel/ptrace.c
+++ b/arch/openrisc/kernel/ptrace.c
@@ -187,8 +187,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
 		 */
 		ret = -1L;
 
-	audit_syscall_entry(AUDIT_ARCH_OPENRISC, regs->gpr[11],
-			    regs->gpr[3], regs->gpr[4],
+	audit_syscall_entry(regs->gpr[11], regs->gpr[3], regs->gpr[4],
 			    regs->gpr[5], regs->gpr[6]);
 
 	return ret ? : regs->gpr[11];
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index e842ee2..7481457 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -276,14 +276,11 @@ long do_syscall_trace_enter(struct pt_regs *regs)
 
 #ifdef CONFIG_64BIT
 	if (!is_compat_task())
-		audit_syscall_entry(AUDIT_ARCH_PARISC64,
-			regs->gr[20],
-			regs->gr[26], regs->gr[25],
-			regs->gr[24], regs->gr[23]);
+		audit_syscall_entry(regs->gr[20], regs->gr[26], regs->gr[25],
+				    regs->gr[24], regs->gr[23]);
 	else
 #endif
-		audit_syscall_entry(AUDIT_ARCH_PARISC,
-			regs->gr[20] & 0xffffffff,
+		audit_syscall_entry(regs->gr[20] & 0xffffffff,
 			regs->gr[26] & 0xffffffff,
 			regs->gr[25] & 0xffffffff,
 			regs->gr[24] & 0xffffffff,
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 2e3d2bf..524a943 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1788,14 +1788,11 @@ long do_syscall_trace_enter(struct pt_regs *regs)
 
 #ifdef CONFIG_PPC64
 	if (!is_32bit_task())
-		audit_syscall_entry(AUDIT_ARCH_PPC64,
-				    regs->gpr[0],
-				    regs->gpr[3], regs->gpr[4],
+		audit_syscall_entry(regs->gpr[0], regs->gpr[3], regs->gpr[4],
 				    regs->gpr[5], regs->gpr[6]);
 	else
 #endif
-		audit_syscall_entry(AUDIT_ARCH_PPC,
-				    regs->gpr[0],
+		audit_syscall_entry(regs->gpr[0],
 				    regs->gpr[3] & 0xffffffff,
 				    regs->gpr[4] & 0xffffffff,
 				    regs->gpr[5] & 0xffffffff,
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index e65c91c..2e2e7bb5 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -812,9 +812,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
 	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
 		trace_sys_enter(regs, regs->gprs[2]);
 
-	audit_syscall_entry(is_compat_task() ?
-				AUDIT_ARCH_S390 : AUDIT_ARCH_S390X,
-			    regs->gprs[2], regs->orig_gpr2,
+	audit_syscall_entry(regs->gprs[2], regs->orig_gpr2,
 			    regs->gprs[3], regs->gprs[4],
 			    regs->gprs[5]);
 out:
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c
index 668c816..c1a6b89 100644
--- a/arch/sh/kernel/ptrace_32.c
+++ b/arch/sh/kernel/ptrace_32.c
@@ -484,17 +484,6 @@ long arch_ptrace(struct task_struct *child, long request,
 	return ret;
 }
 
-static inline int audit_arch(void)
-{
-	int arch = EM_SH;
-
-#ifdef CONFIG_CPU_LITTLE_ENDIAN
-	arch |= __AUDIT_ARCH_LE;
-#endif
-
-	return arch;
-}
-
 asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
 {
 	long ret = 0;
@@ -513,8 +502,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
 	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
 		trace_sys_enter(regs, regs->regs[0]);
 
-	audit_syscall_entry(audit_arch(), regs->regs[3],
-			    regs->regs[4], regs->regs[5],
+	audit_syscall_entry(regs->regs[3], regs->regs[4], regs->regs[5],
 			    regs->regs[6], regs->regs[7]);
 
 	return ret ?: regs->regs[0];
diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c
index af90339..5cea973 100644
--- a/arch/sh/kernel/ptrace_64.c
+++ b/arch/sh/kernel/ptrace_64.c
@@ -504,20 +504,6 @@ asmlinkage int sh64_ptrace(long request, long pid,
 	return sys_ptrace(request, pid, addr, data);
 }
 
-static inline int audit_arch(void)
-{
-	int arch = EM_SH;
-
-#ifdef CONFIG_64BIT
-	arch |= __AUDIT_ARCH_64BIT;
-#endif
-#ifdef CONFIG_CPU_LITTLE_ENDIAN
-	arch |= __AUDIT_ARCH_LE;
-#endif
-
-	return arch;
-}
-
 asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs)
 {
 	long long ret = 0;
@@ -536,8 +522,7 @@ asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs)
 	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
 		trace_sys_enter(regs, regs->regs[9]);
 
-	audit_syscall_entry(audit_arch(), regs->regs[1],
-			    regs->regs[2], regs->regs[3],
+	audit_syscall_entry(regs->regs[1], regs->regs[2], regs->regs[3],
 			    regs->regs[4], regs->regs[5]);
 
 	return ret ?: regs->regs[9];
diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c
index c13c9f2..9ddc492 100644
--- a/arch/sparc/kernel/ptrace_64.c
+++ b/arch/sparc/kernel/ptrace_64.c
@@ -1076,13 +1076,8 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs)
 	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
 		trace_sys_enter(regs, regs->u_regs[UREG_G1]);
 
-	audit_syscall_entry((test_thread_flag(TIF_32BIT) ?
-			     AUDIT_ARCH_SPARC :
-			     AUDIT_ARCH_SPARC64),
-			    regs->u_regs[UREG_G1],
-			    regs->u_regs[UREG_I0],
-			    regs->u_regs[UREG_I1],
-			    regs->u_regs[UREG_I2],
+	audit_syscall_entry(regs->u_regs[UREG_G1], regs->u_regs[UREG_I0],
+			    regs->u_regs[UREG_I1], regs->u_regs[UREG_I2],
 			    regs->u_regs[UREG_I3]);
 
 	return ret;
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index 694d551..62435ef 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -165,8 +165,7 @@ static void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs,
  */
 void syscall_trace_enter(struct pt_regs *regs)
 {
-	audit_syscall_entry(HOST_AUDIT_ARCH,
-			    UPT_SYSCALL_NR(&regs->regs),
+	audit_syscall_entry(UPT_SYSCALL_NR(&regs->regs),
 			    UPT_SYSCALL_ARG1(&regs->regs),
 			    UPT_SYSCALL_ARG2(&regs->regs),
 			    UPT_SYSCALL_ARG3(&regs->regs),
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 7461f50..46dfba6 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -1488,15 +1488,11 @@ long syscall_trace_enter(struct pt_regs *regs)
 		trace_sys_enter(regs, regs->orig_ax);
 
 	if (IS_IA32)
-		audit_syscall_entry(AUDIT_ARCH_I386,
-				    regs->orig_ax,
-				    regs->bx, regs->cx,
+		audit_syscall_entry(regs->orig_ax, regs->bx, regs->cx,
 				    regs->dx, regs->si);
 #ifdef CONFIG_X86_64
 	else
-		audit_syscall_entry(AUDIT_ARCH_X86_64,
-				    regs->orig_ax,
-				    regs->di, regs->si,
+		audit_syscall_entry(regs->orig_ax, regs->di, regs->si,
 				    regs->dx, regs->r10);
 #endif
 
diff --git a/arch/x86/um/asm/ptrace.h b/arch/x86/um/asm/ptrace.h
index 54f8102..e59eef2 100644
--- a/arch/x86/um/asm/ptrace.h
+++ b/arch/x86/um/asm/ptrace.h
@@ -47,8 +47,6 @@ struct user_desc;
 
 #ifdef CONFIG_X86_32
 
-#define HOST_AUDIT_ARCH AUDIT_ARCH_I386
-
 extern int ptrace_get_thread_area(struct task_struct *child, int idx,
                                   struct user_desc __user *user_desc);
 
@@ -57,8 +55,6 @@ extern int ptrace_set_thread_area(struct task_struct *child, int idx,
 
 #else
 
-#define HOST_AUDIT_ARCH AUDIT_ARCH_X86_64
-
 #define PT_REGS_R8(r) UPT_R8(&(r)->regs)
 #define PT_REGS_R9(r) UPT_R9(&(r)->regs)
 #define PT_REGS_R10(r) UPT_R10(&(r)->regs)
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c
index 562fac6..4d54b48 100644
--- a/arch/xtensa/kernel/ptrace.c
+++ b/arch/xtensa/kernel/ptrace.c
@@ -342,7 +342,7 @@ void do_syscall_trace_enter(struct pt_regs *regs)
 		do_syscall_trace();
 
 #if 0
-	audit_syscall_entry(current, AUDIT_ARCH_XTENSA..);
+	audit_syscall_entry(...);
 #endif
 }
 
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 4b2983e..62c9d98 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -26,6 +26,7 @@
 #include <linux/sched.h>
 #include <linux/ptrace.h>
 #include <uapi/linux/audit.h>
+#include <asm/syscall.h>
 
 struct audit_sig_info {
 	uid_t		uid;
@@ -135,12 +136,12 @@ static inline void audit_free(struct task_struct *task)
 	if (unlikely(task->audit_context))
 		__audit_free(task);
 }
-static inline void audit_syscall_entry(int arch, int major, unsigned long a0,
+static inline void audit_syscall_entry(int major, unsigned long a0,
 				       unsigned long a1, unsigned long a2,
 				       unsigned long a3)
 {
 	if (unlikely(current->audit_context))
-		__audit_syscall_entry(arch, major, a0, a1, a2, a3);
+		__audit_syscall_entry(syscall_get_arch(), major, a0, a1, a2, a3);
 }
 static inline void audit_syscall_exit(void *pt_regs)
 {
@@ -316,7 +317,7 @@ static inline int audit_alloc(struct task_struct *task)
 }
 static inline void audit_free(struct task_struct *task)
 { }
-static inline void audit_syscall_entry(int arch, int major, unsigned long a0,
+static inline void audit_syscall_entry(int major, unsigned long a0,
 				       unsigned long a1, unsigned long a2,
 				       unsigned long a3)
 { }
-- 
1.8.5.3

^ permalink raw reply related

* Re: [PATCH 3/4] ARCH: AUDIT: implement syscall_get_arch for all arches
From: Eric Paris @ 2014-03-19 23:02 UTC (permalink / raw)
  To: Matt Turner
  Cc: linux-mips@linux-mips.org, linux-ia64,
	linux-parisc@vger.kernel.org, microblaze-uclinux, linux,
	linux-audit, sparclinux, linuxppc-dev
In-Reply-To: <CAEdQ38Ex47GxhN1ZZMu+RETpWs-ENbfCr8v=6iFg9p_QWaa9zw@mail.gmail.com>

On Wed, 2014-03-19 at 15:19 -0700, Matt Turner wrote:
> On Wed, Mar 19, 2014 at 3:04 PM, Eric Paris <eparis@redhat.com> wrote:
> > For all arches which support audit implement syscall_get_arch()
> 
> support audit -- is that AUDIT_ARCH? If so, alpha gained support
> recently, so I think this patch needs to handle alpha too?

Absolutely right.  I broke Alpha (in the next patch).  Will fix.

-Eric

^ permalink raw reply

* Re: [v2, 2/2] powerpc/mpc85xx: add support for Keymile's kmcoge4 board
From: Scott Wood @ 2014-03-19 23:08 UTC (permalink / raw)
  To: Valentin Longchamp; +Cc: linuxppc-dev
In-Reply-To: <1392119407-29490-3-git-send-email-valentin.longchamp@keymile.com>

On Tue, Feb 11, 2014 at 12:50:07PM +0100, Valentin Longchamp wrote:
> +		reset_cpld@1,0 {
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +			reg = <1 0 0x80>;
> +			interrupt-parent = <&mpic>;
> +			interrupts = <
> +				4 1 0 0
> +				5 1 0 0>;
> +		};
> +
> +		chassis_mgmt@3,0 {
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +			reg = <3 0 0x100>;
> +			interrupt-parent = <&mpic>;
> +			interrupts = <6 1 0 0>;
> +		};

Dashes are preferred to underscores in device trees.

More importantly, these nodes need proper compatibles and bindings.  Once
that's done, the name for the nodes should probably be
"board_control@whatever" for both.

-Scott

^ permalink raw reply

* Re: clk: mpc85xx: Update the driver to align to new clock bindings
From: Mike Turquette @ 2014-03-20  0:06 UTC (permalink / raw)
  To: Scott Wood, tang yuantian; +Cc: linuxppc-dev
In-Reply-To: <20140319215223.GA28070@home.buserror.net>

Quoting Scott Wood (2014-03-19 14:52:23)
> On Tue, Jan 21, 2014 at 09:32:45AM +0800, tang yuantian wrote:
> > From: Tang Yuantian <yuantian.tang@freescale.com>
> > =

> > The clock bindings for Freescale CoreNet platform are updated.
> > So, the driver needs to be updated accordingly.
> > The main changes include:
> >       - Added a new node to present the input system clock
> >       - Changed PLL and MUX's compatible string
> > =

> > Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
> > =

> > ---
> > drivers/clk/clk-ppc-corenet.c | 70 +++++++++++++++++++++++++++++-------=
-------
> >  1 file changed, 48 insertions(+), 22 deletions(-)
> =

> Acked-by: Scott Wood <scottwood@freescale.com>
> =

> Mike, does this need to go to linux-arm-kernel@lists.infradead.org as per
> MAINTAINERS for drivers/clk?

Nope, I should probably change that to LKML just be politically correct.
The important thing is to Cc me (which the original poster did) and ping
me if I don't review your patch after a week or two (which you did).

This patch looks great and I've taken it into clk-next.

Thanks,
Mike

> =

> > diff --git a/drivers/clk/clk-ppc-corenet.c b/drivers/clk/clk-ppc-corene=
t.c
> > index c4f76ed..8b284be 100644
> > --- a/drivers/clk/clk-ppc-corenet.c
> > +++ b/drivers/clk/clk-ppc-corenet.c
> > @@ -27,7 +27,6 @@ struct cmux_clk {
> >  #define CLKSEL_ADJUST                BIT(0)
> >  #define to_cmux_clk(p)               container_of(p, struct cmux_clk, =
hw)
> >  =

> > -static void __iomem *base;
> >  static unsigned int clocks_per_pll;
> >  =

> >  static int cmux_set_parent(struct clk_hw *hw, u8 idx)
> > @@ -100,7 +99,11 @@ static void __init core_mux_init(struct device_node=
 *np)
> >               pr_err("%s: could not allocate cmux_clk\n", __func__);
> >               goto err_name;
> >       }
> > -     cmux_clk->reg =3D base + offset;
> > +     cmux_clk->reg =3D of_iomap(np, 0);
> > +     if (!cmux_clk->reg) {
> > +             pr_err("%s: could not map register\n", __func__);
> > +             goto err_clk;
> > +     }
> =

> dev_err?  Though it looks like of_clk_init() makes it hard to pass a
> reference to the parent device (or anything else but a function pointer
> and device tree node) to the init function -- why?
> =

> >       node =3D of_find_compatible_node(NULL, NULL, "fsl,p4080-clockgen"=
);
> >       if (node && (offset >=3D 0x80))
> > @@ -143,38 +146,39 @@ err_name:
> >  =

> >  static void __init core_pll_init(struct device_node *np)
> >  {
> > -     u32 offset, mult;
> > +     u32 mult;
> >       int i, rc, count;
> >       const char *clk_name, *parent_name;
> >       struct clk_onecell_data *onecell_data;
> >       struct clk      **subclks;
> > +     void __iomem *base;
> >  =

> > -     rc =3D of_property_read_u32(np, "reg", &offset);
> > -     if (rc) {
> > -             pr_err("%s: could not get reg property\n", np->name);
> > +     base =3D of_iomap(np, 0);
> > +     if (!base) {
> > +             pr_err("clk-ppc: iomap error\n");
> >               return;
> >       }
> >  =

> >       /* get the multiple of PLL */
> > -     mult =3D ioread32be(base + offset);
> > +     mult =3D ioread32be(base);
> >  =

> >       /* check if this PLL is disabled */
> >       if (mult & PLL_KILL) {
> >               pr_debug("PLL:%s is disabled\n", np->name);
> > -             return;
> > +             goto err_map;
> >       }
> >       mult =3D (mult >> 1) & 0x3f;
> >  =

> >       parent_name =3D of_clk_get_parent_name(np, 0);
> >       if (!parent_name) {
> >               pr_err("PLL: %s must have a parent\n", np->name);
> > -             return;
> > +             goto err_map;
> >       }
> >  =

> >       count =3D of_property_count_strings(np, "clock-output-names");
> >       if (count < 0 || count > 4) {
> >               pr_err("%s: clock is not supported\n", np->name);
> > -             return;
> > +             goto err_map;
> >       }
> >  =

> >       /* output clock number per PLL */
> > @@ -183,7 +187,7 @@ static void __init core_pll_init(struct device_node=
 *np)
> >       subclks =3D kzalloc(sizeof(struct clk *) * count, GFP_KERNEL);
> >       if (!subclks) {
> >               pr_err("%s: could not allocate subclks\n", __func__);
> > -             return;
> > +             goto err_map;
> >       }
> >  =

> >       onecell_data =3D kzalloc(sizeof(struct clk_onecell_data), GFP_KER=
NEL);
> > @@ -230,30 +234,52 @@ static void __init core_pll_init(struct device_no=
de *np)
> >               goto err_cell;
> >       }
> >  =

> > +     iounmap(base);
> >       return;
> >  err_cell:
> >       kfree(onecell_data);
> >  err_clks:
> >       kfree(subclks);
> > +err_map:
> > +     iounmap(base);
> > +}
> =

> Consider devres -- is there a devres version of of_iomap()?
> =

> -Scott

^ permalink raw reply

* Re: [1/3] powerpc/fsl-booke: Add support for T2080/T2081 SoC
From: Scott Wood @ 2014-03-20  0:29 UTC (permalink / raw)
  To: Shengzhou Liu; +Cc: linuxppc-dev, prabhakar
In-Reply-To: <1393840220-31086-1-git-send-email-Shengzhou.Liu@freescale.com>

On Mon, Mar 03, 2014 at 05:50:18PM +0800, Shengzhou Liu wrote:
> +	corenet-cf@18000 {
> +		compatible = "fsl,corenet-cf";
> +		reg = <0x18000 0x1000>;
> +		interrupts = <16 2 1 31>;
> +		fsl,ccf-num-csdids = <32>;
> +		fsl,ccf-num-snoopids = <32>;
> +	};

As I told Prabhakar in 
https://lists.ozlabs.org/pipermail/linuxppc-dev/2014-March/116093.html
this needs a binding and a new compatible property.

> +	clockgen: global-utilities@e1000 {
> +		compatible = "fsl,t2080-clockgen", "fsl,qoriq-clockgen-2.0";
> +		reg = <0xe1000 0x1000>;
> +	};

See Documentation/devicetree/bindings/clock/corenet-clock.txt

-Scott

^ permalink raw reply

* Re: [PATCH] T1040RDB: add qe node for T1040RDB dts
From: Scott Wood @ 2014-03-20  0:51 UTC (permalink / raw)
  To: Zhao Qiang-B45475; +Cc: linuxppc-dev@lists.ozlabs.org, Xie Xiaobo-R63061
In-Reply-To: <f07545053329444e9022bd43dc7d66c4@BLUPR03MB341.namprd03.prod.outlook.com>

On Wed, 2014-03-12 at 20:56 -0500, Zhao Qiang-B45475 wrote:
> On Wed, 2014-03-13 at 2:46 AM, Scott wrote:
> 
> > -----Original Message-----
> > From: Wood Scott-B07421
> > Sent: Thursday, March 13, 2014 2:46 AM
> > To: Zhao Qiang-B45475
> > Cc: linuxppc-dev@lists.ozlabs.org; Wood Scott-B07421; Xie Xiaobo-R63061
> > Subject: Re: [PATCH] T1040RDB: add qe node for T1040RDB dts
> > 
> > On Wed, 2014-03-12 at 16:26 +0800, Zhao Qiang wrote:
> > > Signed-off-by: Zhao Qiang <B45475@freescale.com>
> > > ---
> > >  arch/powerpc/boot/dts/t1040rdb.dts | 43
> > > ++++++++++++++++++++++++++++++++++++++
> > >  1 file changed, 43 insertions(+)
> > 
> > Presumably this is on top of this patch:
> > http://patchwork.ozlabs.org/patch/314138/
> > 
> > ...since there's no existing t1040 device tree support.  Always mention
> > when your patch is on top of a patch that hasn't yet been merged and
> > isn't in the same patch set.
> > 
> > At least some of this stuff seems like it should be in t1040si-post.dts
> > (or a file included by it), rather than the board dts.
> 
> Every board can use ucc differently, It is not correct to put this node into t1040si-post.dtsi.
> For example t1040qds can use ucc1 to tdm while maybe t1040rdb use ucc1 to uart.

That's why I said "some". :-)

Anything that is specific to the board should be in the board file, but
it's not clear that everything in this patch is board-specific.
si/siram?  Reg/ranges on the qe node?  Etc.

-Scott

^ permalink raw reply

* RE: [2/2] fsl/pci: The new pci suspend/resume implementation
From: Dongsheng.Wang @ 2014-03-20  2:25 UTC (permalink / raw)
  To: Scott Wood
  Cc: roy.zang@freescale.com, galak@codeaurora.org, rjw@rjwysocki.net,
	linux-pci@vger.kernel.org, bhelgaas@google.com,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <20140319210041.GA14019@home.buserror.net>

Hi Scott,

I will send v2 patch to fix your comment. Thanks for your review. :)

> -----Original Message-----
> From: Wood Scott-B07421
> Sent: Thursday, March 20, 2014 5:01 AM
> To: Wang Dongsheng-B40534
> Cc: bhelgaas@google.com; rjw@rjwysocki.net; roy.zang@freescale.com;
> galak@codeaurora.org; linux-pci@vger.kernel.org; linuxppc-dev@lists.ozlab=
s.org
> Subject: Re: [2/2] fsl/pci: The new pci suspend/resume implementation
>=20
> On Tue, Jan 07, 2014 at 04:04:08PM +0800, Dongsheng Wang wrote:
> > From: Wang Dongsheng <dongsheng.wang@freescale.com>
> >
> > The new suspend/resume implementation, send pme turnoff message in
> > suspend, and send pme exit message in resume.
> >
> > Add a PME handler, to response PME & message interrupt.
> >
> > Change platform_driver->suspend/resume to syscore->suspend/resume.
> > pci-driver will call back EP device, to save EP state in
> > pci_pm_suspend_noirq, so we need to keep the link, until
> > pci_pm_suspend_noirq finish.
> >
> > Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>
>=20
> Is this patch OK to go in without patch 1/2?  It's not clear whether that=
 was
> deemed incorrect (as in new patch coming) or unnecessary.
>=20

Yes, I will abandon 1/2. And send this as a independent patch.

> It would also be good if you submit with the explanation from
> http://www.spinics.net/lists/linux-pci/msg27844.html in the commit messag=
e.
>=20

Thanks.

> > -static int fsl_pci_probe(struct platform_device *pdev)
> > +#ifdef CONFIG_PM
> > +static irqreturn_t fsl_pci_pme_handle(int irq, void *dev_id)
> >  {
> > -	int ret;
> > -	struct device_node *node;
> > +	struct pci_controller *hose =3D dev_id;
> > +	struct ccsr_pci __iomem *pci =3D hose->private_data;
> > +	u32 dr;
> >
> > -	node =3D pdev->dev.of_node;
> > -	ret =3D fsl_add_bridge(pdev, fsl_pci_primary =3D=3D node);
> > +	dr =3D in_be32(&pci->pex_pme_mes_dr);
> > +	if (dr)
> > +		out_be32(&pci->pex_pme_mes_dr, dr);
> > +	else
> > +		return IRQ_NONE;
> >
> > -	mpc85xx_pci_err_probe(pdev);
> > +	return IRQ_HANDLED;
> > +}
>=20
> Why do you put some of the HANDLED path in the if statement, and some out=
side?
>=20
> Just do:
>=20
> if (!dr)
> 	return IRQ_NONE;
>=20
> out_be32(...);
> return IRQ_HANDLED;
>=20

Right. :)

> > +static int fsl_pci_pme_probe(struct pci_controller *hose) {
> > +	struct ccsr_pci __iomem *pci;
> > +	struct pci_dev *dev =3D hose->bus->self;
> > +	u16 pms;
> > +	int pme_irq;
> > +	int res;
> > +
> > +	/* PME Disable */
> > +	pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pms);
> > +	pms &=3D ~PCI_PM_CTRL_PME_ENABLE;
> > +	pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pms);
> > +
> > +	pme_irq =3D irq_of_parse_and_map(hose->dn, 0);
> > +	if (!pme_irq) {
> > +		pr_warn("Failed to map PME interrupt.\n");
>=20
> dev_err()
>=20
> > +
> > +		return -ENXIO;
> > +	}
> > +
> > +	res =3D devm_request_irq(hose->parent, pme_irq,
> > +			fsl_pci_pme_handle,
> > +			IRQF_DISABLED | IRQF_SHARED,
> > +			"[PCI] PME", hose);
>=20
> IRQF_DISABLED is a deprecated no-op.
>=20
> > +	if (res < 0) {
> > +		pr_warn("Unable to requiest irq %d for PME\n", pme_irq);
>=20
> dev_err() etc.
>=20

Ok, I will use it.

Regards,
-Dongsheng

> -Scott

^ permalink raw reply

* [PATCH v2] fsl/pci: The new pci suspend/resume implementation
From: Dongsheng Wang @ 2014-03-20  3:19 UTC (permalink / raw)
  To: scottwood; +Cc: linuxppc-dev, galak, rjw, Wang Dongsheng, linux-pci, bhelgaas

From: Wang Dongsheng <dongsheng.wang@freescale.com>

If we do nothing in suspend/resume, some platform PCIe ip-block
can't guarantee the link back to L0 state from sleep, then, when
we read the EP device will hang. Only we send pme turnoff message
in pci controller suspend, and send pme exit message in resume, the
link state will be normal.

When we send pme turnoff message in pci controller suspend, the
links will into l2/l3 ready, then, host cannot communicate with
ep device, but pci-driver will call back EP device to save them
state. So we need to change platform_driver->suspend/resume to
syscore->suspend/resume.

So the new suspend/resume implementation, send pme turnoff message
in suspend, and send pme exit message in resume. And add a PME handler,
to response PME & message interrupt.

Change platform_driver->suspend/resume to syscore->suspend/resume.
pci-driver will call back EP device, to save EP state in
pci_pm_suspend_noirq, so we need to keep the link, until
pci_pm_suspend_noirq finish.

Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>
---
*V2*
- Abandon patch 1/2. And send this as a independent patch.
  The original patch links:
  patch 1/2, http://patchwork.ozlabs.org/patch/307553/ (Abandon)
  patch 2/2, http://patchwork.ozlabs.org/patch/307554/
- Change pr_warn to dev_err().
- Fix code style that to deal with if statement.

diff --git a/arch/powerpc/platforms/85xx/c293pcie.c b/arch/powerpc/platforms/85xx/c293pcie.c
index 213d5b8..84476b6 100644
--- a/arch/powerpc/platforms/85xx/c293pcie.c
+++ b/arch/powerpc/platforms/85xx/c293pcie.c
@@ -68,6 +68,7 @@ define_machine(c293_pcie) {
 	.init_IRQ		= c293_pcie_pic_init,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 	.get_irq		= mpic_get_irq,
 	.restart		= fsl_rstcr_restart,
diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c b/arch/powerpc/platforms/85xx/corenet_generic.c
index fbd871e..aa8b9a3 100644
--- a/arch/powerpc/platforms/85xx/corenet_generic.c
+++ b/arch/powerpc/platforms/85xx/corenet_generic.c
@@ -163,6 +163,7 @@ define_machine(corenet_generic) {
 	.init_IRQ		= corenet_gen_pic_init,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 	.get_irq		= mpic_get_coreint_irq,
 	.restart		= fsl_rstcr_restart,
diff --git a/arch/powerpc/platforms/85xx/ge_imp3a.c b/arch/powerpc/platforms/85xx/ge_imp3a.c
index e6285ae..11790e0 100644
--- a/arch/powerpc/platforms/85xx/ge_imp3a.c
+++ b/arch/powerpc/platforms/85xx/ge_imp3a.c
@@ -215,6 +215,7 @@ define_machine(ge_imp3a) {
 	.show_cpuinfo		= ge_imp3a_show_cpuinfo,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 	.get_irq		= mpic_get_irq,
 	.restart		= fsl_rstcr_restart,
diff --git a/arch/powerpc/platforms/85xx/mpc8536_ds.c b/arch/powerpc/platforms/85xx/mpc8536_ds.c
index 15ce4b5..a378ba3 100644
--- a/arch/powerpc/platforms/85xx/mpc8536_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc8536_ds.c
@@ -76,6 +76,7 @@ define_machine(mpc8536_ds) {
 	.init_IRQ		= mpc8536_ds_pic_init,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 	.get_irq		= mpic_get_irq,
 	.restart		= fsl_rstcr_restart,
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
index 7a31a0e..b0753e2 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
@@ -385,6 +385,7 @@ define_machine(mpc85xx_cds) {
 #ifdef CONFIG_PCI
 	.restart	= mpc85xx_cds_restart,
 	.pcibios_fixup_bus	= mpc85xx_cds_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #else
 	.restart	= fsl_rstcr_restart,
 #endif
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
index 9ebb91e..ffdf021 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
@@ -209,6 +209,7 @@ define_machine(mpc8544_ds) {
 	.init_IRQ		= mpc85xx_ds_pic_init,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 	.get_irq		= mpic_get_irq,
 	.restart		= fsl_rstcr_restart,
@@ -223,6 +224,7 @@ define_machine(mpc8572_ds) {
 	.init_IRQ		= mpc85xx_ds_pic_init,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 	.get_irq		= mpic_get_irq,
 	.restart		= fsl_rstcr_restart,
@@ -237,6 +239,7 @@ define_machine(p2020_ds) {
 	.init_IRQ		= mpc85xx_ds_pic_init,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 	.get_irq		= mpic_get_irq,
 	.restart		= fsl_rstcr_restart,
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index a7b3621..6cd3b8a 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -416,6 +416,7 @@ define_machine(mpc8568_mds) {
 	.progress	= udbg_progress,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 };
 
@@ -437,6 +438,7 @@ define_machine(mpc8569_mds) {
 	.progress	= udbg_progress,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 };
 
@@ -459,6 +461,7 @@ define_machine(p1021_mds) {
 	.progress	= udbg_progress,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 };
 
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
index 53b6fb0..3e2bc3d 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
@@ -254,6 +254,7 @@ define_machine(p2020_rdb) {
 	.init_IRQ		= mpc85xx_rdb_pic_init,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 	.get_irq		= mpic_get_irq,
 	.restart		= fsl_rstcr_restart,
@@ -268,6 +269,7 @@ define_machine(p1020_rdb) {
 	.init_IRQ		= mpc85xx_rdb_pic_init,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 	.get_irq		= mpic_get_irq,
 	.restart		= fsl_rstcr_restart,
@@ -282,6 +284,7 @@ define_machine(p1021_rdb_pc) {
 	.init_IRQ		= mpc85xx_rdb_pic_init,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 	.get_irq		= mpic_get_irq,
 	.restart		= fsl_rstcr_restart,
@@ -296,6 +299,7 @@ define_machine(p2020_rdb_pc) {
 	.init_IRQ		= mpc85xx_rdb_pic_init,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 	.get_irq		= mpic_get_irq,
 	.restart		= fsl_rstcr_restart,
@@ -310,6 +314,7 @@ define_machine(p1025_rdb) {
 	.init_IRQ		= mpc85xx_rdb_pic_init,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 	.get_irq		= mpic_get_irq,
 	.restart		= fsl_rstcr_restart,
@@ -324,6 +329,7 @@ define_machine(p1020_mbg_pc) {
 	.init_IRQ		= mpc85xx_rdb_pic_init,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 	.get_irq		= mpic_get_irq,
 	.restart		= fsl_rstcr_restart,
@@ -338,6 +344,7 @@ define_machine(p1020_utm_pc) {
 	.init_IRQ		= mpc85xx_rdb_pic_init,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 	.get_irq		= mpic_get_irq,
 	.restart		= fsl_rstcr_restart,
@@ -352,6 +359,7 @@ define_machine(p1020_rdb_pc) {
 	.init_IRQ		= mpc85xx_rdb_pic_init,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 	.get_irq		= mpic_get_irq,
 	.restart		= fsl_rstcr_restart,
@@ -366,6 +374,7 @@ define_machine(p1020_rdb_pd) {
 	.init_IRQ		= mpc85xx_rdb_pic_init,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 	.get_irq		= mpic_get_irq,
 	.restart		= fsl_rstcr_restart,
@@ -380,6 +389,7 @@ define_machine(p1024_rdb) {
 	.init_IRQ		= mpc85xx_rdb_pic_init,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 	.get_irq		= mpic_get_irq,
 	.restart		= fsl_rstcr_restart,
diff --git a/arch/powerpc/platforms/85xx/p1010rdb.c b/arch/powerpc/platforms/85xx/p1010rdb.c
index d6a3dd3..ad1a3d4 100644
--- a/arch/powerpc/platforms/85xx/p1010rdb.c
+++ b/arch/powerpc/platforms/85xx/p1010rdb.c
@@ -78,6 +78,7 @@ define_machine(p1010_rdb) {
 	.init_IRQ		= p1010_rdb_pic_init,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 	.get_irq		= mpic_get_irq,
 	.restart		= fsl_rstcr_restart,
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c
index e611e79..6ac986d 100644
--- a/arch/powerpc/platforms/85xx/p1022_ds.c
+++ b/arch/powerpc/platforms/85xx/p1022_ds.c
@@ -567,6 +567,7 @@ define_machine(p1022_ds) {
 	.init_IRQ		= p1022_ds_pic_init,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb	= fsl_pcibios_fixup_phb,
 #endif
 	.get_irq		= mpic_get_irq,
 	.restart		= fsl_rstcr_restart,
diff --git a/arch/powerpc/platforms/85xx/p1022_rdk.c b/arch/powerpc/platforms/85xx/p1022_rdk.c
index 8c92971..7a180f0 100644
--- a/arch/powerpc/platforms/85xx/p1022_rdk.c
+++ b/arch/powerpc/platforms/85xx/p1022_rdk.c
@@ -147,6 +147,7 @@ define_machine(p1022_rdk) {
 	.init_IRQ		= p1022_rdk_pic_init,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 	.get_irq		= mpic_get_irq,
 	.restart		= fsl_rstcr_restart,
diff --git a/arch/powerpc/platforms/85xx/p1023_rds.c b/arch/powerpc/platforms/85xx/p1023_rds.c
index 2ae9d49..0e61400 100644
--- a/arch/powerpc/platforms/85xx/p1023_rds.c
+++ b/arch/powerpc/platforms/85xx/p1023_rds.c
@@ -126,6 +126,7 @@ define_machine(p1023_rds) {
 	.progress		= udbg_progress,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 };
 
@@ -140,5 +141,6 @@ define_machine(p1023_rdb) {
 	.progress		= udbg_progress,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 };
diff --git a/arch/powerpc/platforms/85xx/qemu_e500.c b/arch/powerpc/platforms/85xx/qemu_e500.c
index 5cefc5a..7f26732 100644
--- a/arch/powerpc/platforms/85xx/qemu_e500.c
+++ b/arch/powerpc/platforms/85xx/qemu_e500.c
@@ -66,6 +66,7 @@ define_machine(qemu_e500) {
 	.init_IRQ		= qemu_e500_pic_init,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 	.get_irq		= mpic_get_coreint_irq,
 	.restart		= fsl_rstcr_restart,
diff --git a/arch/powerpc/platforms/85xx/sbc8548.c b/arch/powerpc/platforms/85xx/sbc8548.c
index f621218..b072146 100644
--- a/arch/powerpc/platforms/85xx/sbc8548.c
+++ b/arch/powerpc/platforms/85xx/sbc8548.c
@@ -135,6 +135,7 @@ define_machine(sbc8548) {
 	.restart	= fsl_rstcr_restart,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 	.calibrate_decr = generic_calibrate_decr,
 	.progress	= udbg_progress,
diff --git a/arch/powerpc/platforms/85xx/xes_mpc85xx.c b/arch/powerpc/platforms/85xx/xes_mpc85xx.c
index dcbf7e4..1a9c108 100644
--- a/arch/powerpc/platforms/85xx/xes_mpc85xx.c
+++ b/arch/powerpc/platforms/85xx/xes_mpc85xx.c
@@ -170,6 +170,7 @@ define_machine(xes_mpc8572) {
 	.init_IRQ		= xes_mpc85xx_pic_init,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 	.get_irq		= mpic_get_irq,
 	.restart		= fsl_rstcr_restart,
@@ -184,6 +185,7 @@ define_machine(xes_mpc8548) {
 	.init_IRQ		= xes_mpc85xx_pic_init,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 	.get_irq		= mpic_get_irq,
 	.restart		= fsl_rstcr_restart,
@@ -198,6 +200,7 @@ define_machine(xes_mpc8540) {
 	.init_IRQ		= xes_mpc85xx_pic_init,
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 	.get_irq		= mpic_get_irq,
 	.restart		= fsl_rstcr_restart,
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 4dfd61d..ccb3cb8 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -22,10 +22,13 @@
 #include <linux/delay.h>
 #include <linux/string.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/log2.h>
 #include <linux/slab.h>
+#include <linux/suspend.h>
+#include <linux/syscore_ops.h>
 #include <linux/uaccess.h>
 
 #include <asm/io.h>
@@ -1085,55 +1088,171 @@ void fsl_pci_assign_primary(void)
 	}
 }
 
-static int fsl_pci_probe(struct platform_device *pdev)
+#ifdef CONFIG_PM_SLEEP
+static irqreturn_t fsl_pci_pme_handle(int irq, void *dev_id)
 {
-	int ret;
-	struct device_node *node;
+	struct pci_controller *hose = dev_id;
+	struct ccsr_pci __iomem *pci = hose->private_data;
+	u32 dr;
 
-	node = pdev->dev.of_node;
-	ret = fsl_add_bridge(pdev, fsl_pci_primary == node);
+	dr = in_be32(&pci->pex_pme_mes_dr);
+	if (!dr)
+		return IRQ_NONE;
 
-	mpc85xx_pci_err_probe(pdev);
+	out_be32(&pci->pex_pme_mes_dr, dr);
 
-	return 0;
+	return IRQ_HANDLED;
 }
 
-#ifdef CONFIG_PM
-static int fsl_pci_resume(struct device *dev)
+static int fsl_pci_pme_probe(struct pci_controller *hose)
 {
-	struct pci_controller *hose;
-	struct resource pci_rsrc;
+	struct ccsr_pci __iomem *pci;
+	struct pci_dev *dev;
+	int pme_irq;
+	int res;
+	u16 pms;
 
-	hose = pci_find_hose_for_OF_device(dev->of_node);
-	if (!hose)
-		return -ENODEV;
+	/* Get hose's pci_dev */
+	dev = list_first_entry(&hose->bus->devices, typeof(*dev), bus_list);
+
+	/* PME Disable */
+	pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pms);
+	pms &= ~PCI_PM_CTRL_PME_ENABLE;
+	pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pms);
+
+	pme_irq = irq_of_parse_and_map(hose->dn, 0);
+	if (!pme_irq) {
+		dev_err(&dev->dev, "Failed to map PME interrupt.\n");
+
+		return -ENXIO;
+	}
+
+	res = devm_request_irq(hose->parent, pme_irq,
+			fsl_pci_pme_handle,
+			IRQF_SHARED,
+			"[PCI] PME", hose);
+	if (res < 0) {
+		dev_err(&dev->dev, "Unable to requiest irq %d for PME\n", pme_irq);
+		irq_dispose_mapping(pme_irq);
 
-	if (of_address_to_resource(dev->of_node, 0, &pci_rsrc)) {
-		dev_err(dev, "Get pci register base failed.");
 		return -ENODEV;
 	}
 
-	setup_pci_atmu(hose);
+	pci = hose->private_data;
+
+	/* Enable PTOD, ENL23D & EXL23D */
+	out_be32(&pci->pex_pme_mes_disr, 0);
+	setbits32(&pci->pex_pme_mes_disr,
+		  PME_DISR_EN_PTOD | PME_DISR_EN_ENL23D | PME_DISR_EN_EXL23D);
+
+	out_be32(&pci->pex_pme_mes_ier, 0);
+	setbits32(&pci->pex_pme_mes_ier,
+		  PME_DISR_EN_PTOD | PME_DISR_EN_ENL23D | PME_DISR_EN_EXL23D);
+
+	/* PME Enable */
+	pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pms);
+	pms |= PCI_PM_CTRL_PME_ENABLE;
+	pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pms);
 
 	return 0;
 }
 
-static const struct dev_pm_ops pci_pm_ops = {
-	.resume = fsl_pci_resume,
-};
+static void send_pme_turnoff_message(struct pci_controller *hose)
+{
+	struct ccsr_pci __iomem *pci = hose->private_data;
+	u32 dr;
+	int i;
 
-#define PCI_PM_OPS (&pci_pm_ops)
+	/* Send PME_Turn_Off Message Request */
+	setbits32(&pci->pex_pmcr, PEX_PMCR_PTOMR);
 
-#else
+	/* Wait trun off done */
+	for (i = 0; i < 150; i++) {
+		dr = in_be32(&pci->pex_pme_mes_dr);
+		if (dr) {
+			out_be32(&pci->pex_pme_mes_dr, dr);
+			break;
+		}
 
-#define PCI_PM_OPS NULL
+		udelay(1000);
+	}
+}
 
+static void fsl_pci_syscore_do_suspend(struct pci_controller *hose)
+{
+	send_pme_turnoff_message(hose);
+}
+
+static int fsl_pci_syscore_suspend(void)
+{
+	struct pci_controller *hose, *tmp;
+
+	list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
+		fsl_pci_syscore_do_suspend(hose);
+
+	return 0;
+}
+
+static void fsl_pci_syscore_do_resume(struct pci_controller *hose)
+{
+	struct ccsr_pci __iomem *pci = hose->private_data;
+	u32 dr;
+	int i;
+
+	/* Send Exit L2 State Message */
+	setbits32(&pci->pex_pmcr, PEX_PMCR_EXL2S);
+
+	/* Wait exit done */
+	for (i = 0; i < 150; i++) {
+		dr = in_be32(&pci->pex_pme_mes_dr);
+		if (dr) {
+			out_be32(&pci->pex_pme_mes_dr, dr);
+			break;
+		}
+
+		udelay(1000);
+	}
+
+	setup_pci_atmu(hose);
+}
+
+static void fsl_pci_syscore_resume(void)
+{
+	struct pci_controller *hose, *tmp;
+
+	list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
+		fsl_pci_syscore_do_resume(hose);
+}
+
+static struct syscore_ops pci_syscore_pm_ops = {
+	.suspend = fsl_pci_syscore_suspend,
+	.resume = fsl_pci_syscore_resume,
+};
 #endif
 
+void fsl_pcibios_fixup_phb(struct pci_controller *phb)
+{
+#ifdef CONFIG_PM_SLEEP
+	fsl_pci_pme_probe(phb);
+#endif
+}
+
+static int fsl_pci_probe(struct platform_device *pdev)
+{
+	struct device_node *node;
+	int ret;
+
+	node = pdev->dev.of_node;
+	ret = fsl_add_bridge(pdev, fsl_pci_primary == node);
+
+	mpc85xx_pci_err_probe(pdev);
+
+	return 0;
+}
+
 static struct platform_driver fsl_pci_driver = {
 	.driver = {
 		.name = "fsl-pci",
-		.pm = PCI_PM_OPS,
 		.of_match_table = pci_ids,
 	},
 	.probe = fsl_pci_probe,
@@ -1141,6 +1260,9 @@ static struct platform_driver fsl_pci_driver = {
 
 static int __init fsl_pci_init(void)
 {
+#ifdef CONFIG_PM_SLEEP
+	register_syscore_ops(&pci_syscore_pm_ops);
+#endif
 	return platform_driver_register(&fsl_pci_driver);
 }
 arch_initcall(fsl_pci_init);
diff --git a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h
index 8d455df..c1cec77 100644
--- a/arch/powerpc/sysdev/fsl_pci.h
+++ b/arch/powerpc/sysdev/fsl_pci.h
@@ -32,6 +32,13 @@ struct platform_device;
 #define PIWAR_WRITE_SNOOP	0x00005000
 #define PIWAR_SZ_MASK          0x0000003f
 
+#define PEX_PMCR_PTOMR		0x1
+#define PEX_PMCR_EXL2S		0x2
+
+#define PME_DISR_EN_PTOD	0x00008000
+#define PME_DISR_EN_ENL23D	0x00002000
+#define PME_DISR_EN_EXL23D	0x00001000
+
 /* PCI/PCI Express outbound window reg */
 struct pci_outbound_window_regs {
 	__be32	potar;	/* 0x.0 - Outbound translation address register */
@@ -111,6 +118,7 @@ struct ccsr_pci {
 
 extern int fsl_add_bridge(struct platform_device *pdev, int is_primary);
 extern void fsl_pcibios_fixup_bus(struct pci_bus *bus);
+extern void fsl_pcibios_fixup_phb(struct pci_controller *phb);
 extern int mpc83xx_add_bridge(struct device_node *dev);
 u64 fsl_pci_immrbar_base(struct pci_controller *hose);
 
-- 
1.8.5

^ permalink raw reply related

* Pull request: scottwood/linux.git next
From: Scott Wood @ 2014-03-20  4:25 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev

The following changes since commit c7e64b9ce04aa2e3fad7396d92b5cb92056d16ac:

  powerpc/powernv Platform dump interface (2014-03-07 16:19:10 +1100)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/scottwood/linux.git next

for you to fetch changes up to 48b16180d0d91324e5d2423c6d53d97bbe3dcc14:

  fsl/pci: The new pci suspend/resume implementation (2014-03-19 22:37:44 -0500)

----------------------------------------------------------------
Luis Henriques (1):
      powerpc/kconfig: Remove TSI108_BRIDGE duplicates

Minghuan Lian (1):
      powerpc/pci: Fix IMMRBAR address

Prabhakar Kushwaha (1):
      powerpc/config: Remove unnecssary CONFIG_FSL_IFC

Scott Wood (8):
      powerpc/booke64: Fix exception numbers
      powerpc/e6500: Make TLB lock recursive
      powerpc/booke64: Use SPRG7 for VDSO
      powerpc/booke64: Use SPRG_TLB_EXFRAME on bolted handlers
      powerpc/booke64: Remove ints from EXCEPTION_COMMON
      powerpc/booke64: Add crit/mc/debug support to EXCEPTION_COMMON
      powerpc/booke64: Critical and machine check exception support
      Revert "powerpc/watchdog: Don't enable interrupt on PPC64 BookE"

Sebastian Siewior (1):
      powerpc: 85xx rdb: move np pointer to avoid builderror

Tang Yuantian (2):
      powerpc/mpc85xx: Update clock nodes in device tree
      powerpc: T4240: Add ina220 node in dts

Tiejun Chen (2):
      powerpc/book3e: initialize crit/mc/dbg kernel stack pointers
      powerpc/book3e: store crit/mc/dbg exception thread info

Wang Dongsheng (2):
      powerpc/fsl: add PVR definition for E500MC and E5500
      fsl/pci: The new pci suspend/resume implementation

Zhao Qiang (2):
      QE: split function mpc85xx_qe_init() into two functions.
      Corenet: Add QE platform support for Corenet

harninder rai (1):
      powerpc/fsl: Add/update miscellaneous missing binding

 .../devicetree/bindings/powerpc/fsl/l2cache.txt    |  23 ++
 .../devicetree/bindings/powerpc/fsl/mem-ctrlr.txt  |  27 ++
 Documentation/devicetree/bindings/usb/fsl-usb.txt  |   4 +-
 arch/powerpc/boot/dts/fsl/b4420si-post.dtsi        |  36 ++
 arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi         |   2 +
 arch/powerpc/boot/dts/fsl/b4860si-post.dtsi        |  36 ++
 arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi         |   4 +
 arch/powerpc/boot/dts/fsl/p2041si-post.dtsi        |  60 +++
 arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi         |   4 +
 arch/powerpc/boot/dts/fsl/p3041si-post.dtsi        |  61 +++
 arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi         |   4 +
 arch/powerpc/boot/dts/fsl/p4080si-post.dtsi        | 113 ++++++
 arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi         |   8 +
 arch/powerpc/boot/dts/fsl/p5020si-post.dtsi        |  43 ++
 arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi         |   2 +
 arch/powerpc/boot/dts/fsl/p5040si-post.dtsi        |  61 +++
 arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi         |   4 +
 arch/powerpc/boot/dts/fsl/t4240si-post.dtsi        |  86 ++++
 arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi         |  12 +
 arch/powerpc/boot/dts/t4240qds.dts                 |  42 ++
 arch/powerpc/configs/corenet64_smp_defconfig       |   1 -
 arch/powerpc/configs/mpc85xx_defconfig             |   1 -
 arch/powerpc/configs/mpc85xx_smp_defconfig         |   1 -
 arch/powerpc/include/asm/exception-64e.h           |  15 +-
 arch/powerpc/include/asm/kvm_booke_hv_asm.h        |  17 +-
 arch/powerpc/include/asm/mmu-book3e.h              |   9 +-
 arch/powerpc/include/asm/paca.h                    |   9 +-
 arch/powerpc/include/asm/reg.h                     |  15 +-
 arch/powerpc/kernel/asm-offsets.c                  |   2 +-
 arch/powerpc/kernel/exceptions-64e.S               | 435 ++++++++++++++++-----
 arch/powerpc/kernel/setup_64.c                     |  20 +-
 arch/powerpc/kernel/vdso.c                         |   8 +-
 arch/powerpc/kernel/vdso32/getcpu.S                |   2 +-
 arch/powerpc/kernel/vdso64/getcpu.S                |   2 +-
 arch/powerpc/kvm/book3s_hv_rmhandlers.S            |   4 +-
 arch/powerpc/kvm/book3s_interrupts.S               |   4 +-
 arch/powerpc/kvm/bookehv_interrupts.S              |  21 +-
 arch/powerpc/mm/tlb_low_64e.S                      |  63 +--
 arch/powerpc/mm/tlb_nohash.c                       |  11 +
 arch/powerpc/platforms/85xx/c293pcie.c             |   1 +
 arch/powerpc/platforms/85xx/common.c               |   6 +
 arch/powerpc/platforms/85xx/corenet_generic.c      |  17 +
 arch/powerpc/platforms/85xx/ge_imp3a.c             |   1 +
 arch/powerpc/platforms/85xx/mpc8536_ds.c           |   1 +
 arch/powerpc/platforms/85xx/mpc85xx.h              |   2 +
 arch/powerpc/platforms/85xx/mpc85xx_cds.c          |   1 +
 arch/powerpc/platforms/85xx/mpc85xx_ds.c           |   3 +
 arch/powerpc/platforms/85xx/mpc85xx_mds.c          |   4 +
 arch/powerpc/platforms/85xx/mpc85xx_rdb.c          |  16 +-
 arch/powerpc/platforms/85xx/p1010rdb.c             |   1 +
 arch/powerpc/platforms/85xx/p1022_ds.c             |   1 +
 arch/powerpc/platforms/85xx/p1022_rdk.c            |   1 +
 arch/powerpc/platforms/85xx/p1023_rds.c            |   2 +
 arch/powerpc/platforms/85xx/qemu_e500.c            |   1 +
 arch/powerpc/platforms/85xx/sbc8548.c              |   1 +
 arch/powerpc/platforms/85xx/twr_p102x.c            |   1 +
 arch/powerpc/platforms/85xx/xes_mpc85xx.c          |   3 +
 arch/powerpc/platforms/embedded6xx/Kconfig         |   2 -
 arch/powerpc/sysdev/fsl_pci.c                      | 178 +++++++--
 arch/powerpc/sysdev/fsl_pci.h                      |   8 +
 drivers/watchdog/booke_wdt.c                       |   8 -
 61 files changed, 1312 insertions(+), 219 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/powerpc/fsl/l2cache.txt
 create mode 100644 Documentation/devicetree/bindings/powerpc/fsl/mem-ctrlr.txt

^ permalink raw reply

* Re: 3.16.6 build error: swsusp_booke.S:85: Error: invalid sprg number
From: Scott Wood @ 2014-03-20  4:52 UTC (permalink / raw)
  To: John Donnelly; +Cc: linuxppc-dev
In-Reply-To: <CAGtOQbTgXnxEHfuqtQ-BwpsnY=J2WktMFTNXysfYw9-cYprstQ@mail.gmail.com>

On Wed, 2014-03-19 at 17:58 -0500, John Donnelly wrote:
> Platform: Freescale  p4080--e500mc  ,
> 
> 
> Suggestions welcome . 
> 
> 
>  /bin/sh arch/powerpc/kernel/systbl_chk.sh
> arch/powerpc/kernel/systbl_chk.i
> make -f scripts/Makefile.build obj=arch/powerpc/kernel/vdso32
>   gcc -mbig-endian -m32 -Wp,-MD,arch/powerpc/kernel/.swsusp_booke.o.d
>  -nostdinc -isystem /usr/lib/gcc/ppc64-redhat-linux/4.8.2/include
> -I/root/linux-3.13.6/arch/powerpc/include
> -Iarch/powerpc/include/generated  -Iinclude
> -I/root/linux-3.13.6/arch/powerpc/include/uapi
> -Iarch/powerpc/include/generated/uapi
> -I/root/linux-3.13.6/include/uapi -Iinclude/generated/uapi
> -include /root/linux-3.13.6/include/linux/kconfig.h -D__KERNEL__
> -Iarch/powerpc  -D__ASSEMBLY__ -Iarch/powerpc  -gdwarf-2          -c
> -o arch/powerpc/kernel/swsusp_booke.o
> arch/powerpc/kernel/swsusp_booke.S
> arch/powerpc/kernel/swsusp_booke.S: Assembler messages:
> arch/powerpc/kernel/swsusp_booke.S:85: Error: invalid sprg number
> arch/powerpc/kernel/swsusp_booke.S:87: Error: invalid sprg number
> 
You need commit b58a7bd6df7b61446b833a7c72f8a1f11066e0b0.

-Scott

^ permalink raw reply

* Re: Tasks stuck in futex code (in 3.14-rc6)
From: Srikar Dronamraju @ 2014-03-20  5:33 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: linuxppc-dev, LKML, davidlohr, paulus, tglx, Paul McKenney,
	torvalds, mingo
In-Reply-To: <20140319170829.GD8557@laptop.programming.kicks-ass.net>

> > Joy,.. let me look at that with ppc in mind.
> 
> OK; so while pretty much all the comments from that patch are utter
> nonsense (what was I thinking), I cannot actually find a real bug.
> 
> But could you try the below which replaces a control dependency with a
> full barrier. The control flow is plenty convoluted that I think the
> control barrier isn't actually valid anymore and that might indeed
> explain the fail.
> 

Unfortunately the patch didnt help. Still seeing tasks stuck

# ps -Ao pid,tt,user,fname,tmout,f,wchan | grep futex
14680 pts/0    root     java         - 0 futex_wait_queue_me
14797 pts/0    root     java         - 0 futex_wait_queue_me
# :> /var/log/messages
# echo t > /proc/sysrq-trigger 
# grep futex_wait_queue_me /var/log/messages | wc -l 
334
#

[ 6904.211478] Call Trace:
[ 6904.211481] [c000000fa1f1b4d0] [0000000000000020] 0x20 (unreliable)
[ 6904.211486] [c000000fa1f1b6a0] [c000000000015208] .__switch_to+0x1e8/0x330
[ 6904.211491] [c000000fa1f1b750] [c000000000702f00] .__schedule+0x360/0x8b0
[ 6904.211495] [c000000fa1f1b9d0] [c000000000147348] .futex_wait_queue_me+0xf8/0x1a0
[ 6904.211500] [c000000fa1f1ba60] [c0000000001486dc] .futex_wait+0x17c/0x2a0
[ 6904.211505] [c000000fa1f1bc10] [c00000000014a614] .do_futex+0x254/0xd80
[ 6904.211510] [c000000fa1f1bd60] [c00000000014b25c] .SyS_futex+0x11c/0x1d0
[ 6904.238874] [c000000fa1f1be30] [c00000000000a0fc] syscall_exit+0x0/0x7c
[ 6904.238879] java            S 00003fff825f6044     0 14682  14076 0x00000080

Is there any other information that I provide that can help?

-- 
Thanks and Regards
Srikar Dronamraju

^ permalink raw reply

* Re: Tasks stuck in futex code (in 3.14-rc6)
From: Davidlohr Bueso @ 2014-03-20  5:56 UTC (permalink / raw)
  To: Srikar Dronamraju
  Cc: Peter Zijlstra, torvalds, LKML, paulus, tglx, Paul McKenney,
	linuxppc-dev, mingo
In-Reply-To: <20140320053350.GB30295@linux.vnet.ibm.com>

On Thu, 2014-03-20 at 11:03 +0530, Srikar Dronamraju wrote:
> > > Joy,.. let me look at that with ppc in mind.
> > 
> > OK; so while pretty much all the comments from that patch are utter
> > nonsense (what was I thinking), I cannot actually find a real bug.
> > 
> > But could you try the below which replaces a control dependency with a
> > full barrier. The control flow is plenty convoluted that I think the
> > control barrier isn't actually valid anymore and that might indeed
> > explain the fail.
> > 
> 
> Unfortunately the patch didnt help. Still seeing tasks stuck
> 
> # ps -Ao pid,tt,user,fname,tmout,f,wchan | grep futex
> 14680 pts/0    root     java         - 0 futex_wait_queue_me
> 14797 pts/0    root     java         - 0 futex_wait_queue_me
> # :> /var/log/messages
> # echo t > /proc/sysrq-trigger 
> # grep futex_wait_queue_me /var/log/messages | wc -l 
> 334
> #
> 
> [ 6904.211478] Call Trace:
> [ 6904.211481] [c000000fa1f1b4d0] [0000000000000020] 0x20 (unreliable)
> [ 6904.211486] [c000000fa1f1b6a0] [c000000000015208] .__switch_to+0x1e8/0x330
> [ 6904.211491] [c000000fa1f1b750] [c000000000702f00] .__schedule+0x360/0x8b0
> [ 6904.211495] [c000000fa1f1b9d0] [c000000000147348] .futex_wait_queue_me+0xf8/0x1a0
> [ 6904.211500] [c000000fa1f1ba60] [c0000000001486dc] .futex_wait+0x17c/0x2a0
> [ 6904.211505] [c000000fa1f1bc10] [c00000000014a614] .do_futex+0x254/0xd80
> [ 6904.211510] [c000000fa1f1bd60] [c00000000014b25c] .SyS_futex+0x11c/0x1d0
> [ 6904.238874] [c000000fa1f1be30] [c00000000000a0fc] syscall_exit+0x0/0x7c
> [ 6904.238879] java            S 00003fff825f6044     0 14682  14076 0x00000080
> 
> Is there any other information that I provide that can help?

This problem suggests that we missed a wakeup for a task that was adding
itself to the queue in a wait path. And the only place that can happen
is with the hb spinlock check for any pending waiters. Just in case we
missed some assumption about checking the hash bucket spinlock as a way
of detecting any waiters (powerpc?), could you revert this commit and
try the original atomic operations variant:

https://lkml.org/lkml/2013/12/19/630

^ permalink raw reply

* RE: [PATCH] fix dmaengine_unmap failure.
From: Xuelin Shi @ 2014-03-20  6:34 UTC (permalink / raw)
  To: Dan Williams; +Cc: Vinod Koul, dmaengine@vger.kernel.org, linuxppc-dev
In-Reply-To: <CAPcyv4imH14PuiZJwMw1B+UnxBgHzPAS22p4b171MrmKDBJM+Q@mail.gmail.com>

SGkgRGFuLA0KDQpJJ20gT0sgdG8gc2F2ZSBtZW1vcnkgaGVyZS4gSSdkIGxpa2UgdG8gc2VuZCB2
Mi4NCg0KVGhhbmtzLA0KWHVlbGluIFNoaQ0KDQotLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0K
RnJvbTogRGFuIFdpbGxpYW1zIFttYWlsdG86ZGFuLmoud2lsbGlhbXNAaW50ZWwuY29tXSANClNl
bnQ6IDIwMTTE6jPUwjE5yNUgMjM6NDQNClRvOiBTaGkgWHVlbGluLUIyOTIzNw0KQ2M6IFZpbm9k
IEtvdWw7IGxpbnV4cHBjLWRldjsgZG1hZW5naW5lQHZnZXIua2VybmVsLm9yZw0KU3ViamVjdDog
UmU6IFtQQVRDSF0gZml4IGRtYWVuZ2luZV91bm1hcCBmYWlsdXJlLg0KDQpPbiBUdWUsIE1hciAx
OCwgMjAxNCBhdCAxMTozOSBQTSwgWHVlbGluIFNoaSA8eHVlbGluLnNoaUBmcmVlc2NhbGUuY29t
PiB3cm90ZToNCj4gSGkgRGFuLA0KPg0KPiBJbiBhc3luY19tdWx0KC4uLikgb2YgYXN5bmNfcmFp
ZDZfcmVjb3YuYywgdGhlIGNvdW50IDMgaXMgdXNlZCB0byByZXF1ZXN0IGFuIHVubWFwLg0KPiBI
b3dldmVyIHRoZSB0b19jbnQgYW5kIGJpZGlfY250IGFyZSBib3RoIHNldCB0byAxIGFuZCBmcm9t
X2NudCB0byAwLg0KPiBUaGVuIHdoaWxlIHRyeWluZyB0byBkbyB1bm1hcCwgd2UgYXJlIGdldHRp
bmcgdGhlIHdyb25nICJ1bm1hcCIgZnJvbSBhIGRpZmZlcmVudCBtZW1wb29sLg0KPg0KPiBJbiB0
aGlzIHBhdGNoLCB0aGUgbWVtcG9vbCBpcyBhc3NvY2lhdGVkIHdpdGggdGhlIHVubWFwIHN0cnVj
dHVyZSBpbnN0ZWFkIG9mIGNvbXB1dGluZyBpdCBhZ2Fpbi4NCj4gQnkgdGhpcyB3YXksIGl0IGlz
IGd1YXJhbnRlZWQgdGhhdCB0aGUgdW5tYXAgaXMgdGhlIHNhbWUgd2hlbiB3ZSBnZXQgYW5kIHB1
dCB0aGUgdW5tYXAgZGF0YS4NCj4NCj4gQlRXOiB0aGUgbWVtcG9vbCBpcyBqdXN0IHVzZWQgdG8g
bWFuYWdlIHRoZSBzdHJ1Y3QgdW5tYXAsIG5vdCB0aGUgcGFnZXMuDQo+DQoNCkkgc2VlLCB3aGF0
IGFib3V0IGp1c3Qgc3RvcmluZyB0aGUgbWFwX2NudCBhdCBhbGxvY2F0aW9uIHRpbWU/ICBJdCBj
b3VsZCBiZSBhbm90aGVyIGJ5dGUgaW4gc3RydWN0IGRtYWVuZ2luZV91bm1hcF9kYXRhIHJhdGhl
ciB0aGFuIGFuIDggYnl0ZSBwb2ludGVyLg0KDQoNCg==

^ permalink raw reply

* [PATCH v2] fix dmaengine_unmap failure
From: xuelin.shi @ 2014-03-20  6:33 UTC (permalink / raw)
  To: vinod.koul, dan.j.williams; +Cc: dmaengine, Xuelin Shi, linuxppc-dev

From: Xuelin Shi <xuelin.shi@freescale.com>

The count which is used to get_unmap_data maybe not the same as the
count computed in dmaengine_unmap which causes to free data in a
wrong pool.

This patch fixes this issue by keeping the map count with unmap_data
structure and use this count to get the pool.

Signed-off-by: Xuelin Shi <xuelin.shi@freescale.com>
---
change history:
	v1: keep mempool pointer with unmap struct
	v2: keep u8 map_cnt instead of mempool pointer to save mem.

 drivers/dma/dmaengine.c   | 2 ++
 include/linux/dmaengine.h | 1 +
 2 files changed, 3 insertions(+)

diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index ed610b4..a4068e2 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -1014,6 +1014,7 @@ static void dmaengine_unmap(struct kref *kref)
 		dma_unmap_page(dev, unmap->addr[i], unmap->len,
 			       DMA_BIDIRECTIONAL);
 	}
+	cnt = unmap->map_cnt;
 	mempool_free(unmap, __get_unmap_pool(cnt)->pool);
 }
 
@@ -1079,6 +1080,7 @@ dmaengine_get_unmap_data(struct device *dev, int nr, gfp_t flags)
 	memset(unmap, 0, sizeof(*unmap));
 	kref_init(&unmap->kref);
 	unmap->dev = dev;
+	unmap->map_cnt = nr;
 
 	return unmap;
 }
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index c5c92d5..0a5f552 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -433,6 +433,7 @@ typedef bool (*dma_filter_fn)(struct dma_chan *chan, void *filter_param);
 typedef void (*dma_async_tx_callback)(void *dma_async_param);
 
 struct dmaengine_unmap_data {
+	u8 map_cnt;
 	u8 to_cnt;
 	u8 from_cnt;
 	u8 bidi_cnt;
-- 
1.8.3.2

^ permalink raw reply related

* Re: Tasks stuck in futex code (in 3.14-rc6)
From: Peter Zijlstra @ 2014-03-20  7:23 UTC (permalink / raw)
  To: Srikar Dronamraju
  Cc: linuxppc-dev, LKML, davidlohr, paulus, tglx, Paul McKenney,
	torvalds, mingo
In-Reply-To: <20140320053350.GB30295@linux.vnet.ibm.com>

On Thu, Mar 20, 2014 at 11:03:50AM +0530, Srikar Dronamraju wrote:
> > > Joy,.. let me look at that with ppc in mind.
> > 
> > OK; so while pretty much all the comments from that patch are utter
> > nonsense (what was I thinking), I cannot actually find a real bug.
> > 
> > But could you try the below which replaces a control dependency with a
> > full barrier. The control flow is plenty convoluted that I think the
> > control barrier isn't actually valid anymore and that might indeed
> > explain the fail.
> > 
> 
> Unfortunately the patch didnt help. Still seeing tasks stuck

Aww bugger. I'll be traveling tomorrow and today is wasted getting
ready. So unless Davidlohr has anything we'll need to scrap this change.

^ permalink raw reply

* Re: [v2, 2/2] powerpc/mpc85xx: add support for Keymile's kmcoge4 board
From: Valentin Longchamp @ 2014-03-20  8:42 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev@lists.ozlabs.org
In-Reply-To: <20140319230813.GA30481@home.buserror.net>

On 03/20/2014 12:08 AM, Scott Wood wrote:
> On Tue, Feb 11, 2014 at 12:50:07PM +0100, Valentin Longchamp wrote:
>> +		reset_cpld@1,0 {
>> +			interrupt-controller;
>> +			#interrupt-cells = <2>;
>> +			reg = <1 0 0x80>;
>> +			interrupt-parent = <&mpic>;
>> +			interrupts = <
>> +				4 1 0 0
>> +				5 1 0 0>;
>> +		};
>> +
>> +		chassis_mgmt@3,0 {
>> +			interrupt-controller;
>> +			#interrupt-cells = <2>;
>> +			reg = <3 0 0x100>;
>> +			interrupt-parent = <&mpic>;
>> +			interrupts = <6 1 0 0>;
>> +		};
> 
> Dashes are preferred to underscores in device trees.

OK.

> 
> More importantly, these nodes need proper compatibles and bindings.  Once
> that's done, the name for the nodes should probably be
> "board_control@whatever" for both.
> 

The first one can be board-ctrl. The second however manages things that are
beyond this board and important for other boards in the chassis, so I think
chassis-mgmt is correct.

For the binding/compatbiles issues: in the first discussion I had omitted these
nodes because these are not available (and honestly for such FPGAs I doubt they
will ever be mainlined). We discussed it and concluded that the DTS should
describe the HW and not the drivers available in the kernel so I have now added
them. Do you want me to add the compatible strings we use in our tree even
though there are no bindings ? Leave them as is ? Or drop them ?

Valentin

^ permalink raw reply

* [PATCH v2] fix wrong usage of dmaengine_unmap_put in async_xxx
From: xuelin.shi @ 2014-03-20  8:16 UTC (permalink / raw)
  To: vinod.koul, dan.j.williams; +Cc: dmaengine, Xuelin Shi, linuxppc-dev

From: Xuelin Shi <xuelin.shi@freescale.com>

dmaengine_unmap_put does below two things:
a) unmap pages for srcs and dests
b) free unmap struct

The unmap struct data is generated but only initialized while
other some dma contions are met, like dma alignment etc.
If the unmap data is not initialized, call dmaengine_unmap_put
will unmap some random data in unmap->addr[...]

Also call dmaengine_get_unmap_data immediatally after generating tx
is not correct. Maybe the tx has not been finished by DMA hardware
yet but the srcs and dests are dma unmapped.

This patch fixed above two issues by:
a) only generates unmap struct data when other dma conditions are met.
b) eliminates dmaengine_unmap_put when tx is generated because tx knowes
the best time to unmap it (in interrupt processing).

Signed-off-by: Xuelin Shi <xuelin.shi@freescale.com>
---
change log:
	v1: include change in async_memcpy, async_xor, async_pq
 	v2: add change in async_raid6_recov.c and fix some style issue

 crypto/async_tx/async_memcpy.c      |  80 ++++++++-------
 crypto/async_tx/async_pq.c          | 189 +++++++++++++++++++-----------------
 crypto/async_tx/async_raid6_recov.c | 108 +++++++++++----------
 crypto/async_tx/async_xor.c         | 164 ++++++++++++++++---------------
 4 files changed, 286 insertions(+), 255 deletions(-)

diff --git a/crypto/async_tx/async_memcpy.c b/crypto/async_tx/async_memcpy.c
index f8c0b8d..6546e87 100644
--- a/crypto/async_tx/async_memcpy.c
+++ b/crypto/async_tx/async_memcpy.c
@@ -51,11 +51,10 @@ async_memcpy(struct page *dest, struct page *src, unsigned int dest_offset,
 	struct dma_device *device = chan ? chan->device : NULL;
 	struct dma_async_tx_descriptor *tx = NULL;
 	struct dmaengine_unmap_data *unmap = NULL;
+	void *dest_buf, *src_buf;
 
-	if (device)
-		unmap = dmaengine_get_unmap_data(device->dev, 2, GFP_NOIO);
-
-	if (unmap && is_dma_copy_aligned(device, src_offset, dest_offset, len)) {
+	if (device &&
+	    is_dma_copy_aligned(device, src_offset, dest_offset, len)) {
 		unsigned long dma_prep_flags = 0;
 
 		if (submit->cb_fn)
@@ -63,45 +62,56 @@ async_memcpy(struct page *dest, struct page *src, unsigned int dest_offset,
 		if (submit->flags & ASYNC_TX_FENCE)
 			dma_prep_flags |= DMA_PREP_FENCE;
 
-		unmap->to_cnt = 1;
-		unmap->addr[0] = dma_map_page(device->dev, src, src_offset, len,
-					      DMA_TO_DEVICE);
-		unmap->from_cnt = 1;
-		unmap->addr[1] = dma_map_page(device->dev, dest, dest_offset, len,
-					      DMA_FROM_DEVICE);
-		unmap->len = len;
-
-		tx = device->device_prep_dma_memcpy(chan, unmap->addr[1],
-						    unmap->addr[0], len,
-						    dma_prep_flags);
+		unmap = dmaengine_get_unmap_data(device->dev, 2, GFP_NOIO);
+		if (unmap) {
+			unmap->to_cnt = 1;
+			unmap->addr[0] = dma_map_page(device->dev, src,
+						      src_offset, len,
+						      DMA_TO_DEVICE);
+			unmap->from_cnt = 1;
+			unmap->addr[1] = dma_map_page(device->dev, dest,
+						      dest_offset, len,
+						      DMA_FROM_DEVICE);
+			unmap->len = len;
+
+			tx = device->device_prep_dma_memcpy(chan,
+							    unmap->addr[1],
+							    unmap->addr[0],
+							    len,
+							    dma_prep_flags);
+			if (tx) {
+				pr_debug("%s: (async) len: %zu\n", __func__,
+					 len);
+
+				dma_set_unmap(tx, unmap);
+				async_tx_submit(chan, tx, submit);
+				return tx;
+			}
+
+			/* could not get a descriptor, unmap and fall through to
+			 * the synchronous path
+			 */
+			dmaengine_unmap_put(unmap);
+		}
 	}
 
-	if (tx) {
-		pr_debug("%s: (async) len: %zu\n", __func__, len);
+	/* run the operation synchronously */
+	pr_debug("%s: (sync) len: %zu\n", __func__, len);
 
-		dma_set_unmap(tx, unmap);
-		async_tx_submit(chan, tx, submit);
-	} else {
-		void *dest_buf, *src_buf;
-		pr_debug("%s: (sync) len: %zu\n", __func__, len);
+	/* wait for any prerequisite operations */
+	async_tx_quiesce(&submit->depend_tx);
 
-		/* wait for any prerequisite operations */
-		async_tx_quiesce(&submit->depend_tx);
+	dest_buf = kmap_atomic(dest) + dest_offset;
+	src_buf = kmap_atomic(src) + src_offset;
 
-		dest_buf = kmap_atomic(dest) + dest_offset;
-		src_buf = kmap_atomic(src) + src_offset;
+	memcpy(dest_buf, src_buf, len);
 
-		memcpy(dest_buf, src_buf, len);
-
-		kunmap_atomic(src_buf);
-		kunmap_atomic(dest_buf);
-
-		async_tx_sync_epilog(submit);
-	}
+	kunmap_atomic(src_buf);
+	kunmap_atomic(dest_buf);
 
-	dmaengine_unmap_put(unmap);
+	async_tx_sync_epilog(submit);
 
-	return tx;
+	return NULL;
 }
 EXPORT_SYMBOL_GPL(async_memcpy);
 
diff --git a/crypto/async_tx/async_pq.c b/crypto/async_tx/async_pq.c
index d05327c..f446cda 100644
--- a/crypto/async_tx/async_pq.c
+++ b/crypto/async_tx/async_pq.c
@@ -175,10 +175,7 @@ async_gen_syndrome(struct page **blocks, unsigned int offset, int disks,
 
 	BUG_ON(disks > 255 || !(P(blocks, disks) || Q(blocks, disks)));
 
-	if (device)
-		unmap = dmaengine_get_unmap_data(device->dev, disks, GFP_NOIO);
-
-	if (unmap &&
+	if (device &&
 	    (src_cnt <= dma_maxpq(device, 0) ||
 	     dma_maxpq(device, DMA_PREP_CONTINUE) > 0) &&
 	    is_dma_pq_aligned(device, offset, 0, len)) {
@@ -194,46 +191,54 @@ async_gen_syndrome(struct page **blocks, unsigned int offset, int disks,
 		/* convert source addresses being careful to collapse 'empty'
 		 * sources and update the coefficients accordingly
 		 */
-		unmap->len = len;
-		for (i = 0, j = 0; i < src_cnt; i++) {
-			if (blocks[i] == NULL)
-				continue;
-			unmap->addr[j] = dma_map_page(device->dev, blocks[i], offset,
-						      len, DMA_TO_DEVICE);
-			coefs[j] = raid6_gfexp[i];
-			unmap->to_cnt++;
-			j++;
-		}
+		unmap = dmaengine_get_unmap_data(device->dev, disks, GFP_NOIO);
+		if (unmap) {
+			unmap->len = len;
+			for (i = 0, j = 0; i < src_cnt; i++) {
+				if (blocks[i] == NULL)
+					continue;
+				unmap->addr[j] = dma_map_page(device->dev,
+							      blocks[i],
+							      offset,
+							      len,
+							      DMA_TO_DEVICE);
+				coefs[j] = raid6_gfexp[i];
+				unmap->to_cnt++;
+				j++;
+			}
 
-		/*
-		 * DMAs use destinations as sources,
-		 * so use BIDIRECTIONAL mapping
-		 */
-		unmap->bidi_cnt++;
-		if (P(blocks, disks))
-			unmap->addr[j++] = dma_map_page(device->dev, P(blocks, disks),
-							offset, len, DMA_BIDIRECTIONAL);
-		else {
-			unmap->addr[j++] = 0;
-			dma_flags |= DMA_PREP_PQ_DISABLE_P;
-		}
+			/*
+			 * DMAs use destinations as sources,
+			 * so use BIDIRECTIONAL mapping
+			 */
+			unmap->bidi_cnt++;
+			if (P(blocks, disks))
+				unmap->addr[j++] = dma_map_page(device->dev,
+							P(blocks, disks),
+							offset, len,
+							DMA_BIDIRECTIONAL);
+			else {
+				unmap->addr[j++] = 0;
+				dma_flags |= DMA_PREP_PQ_DISABLE_P;
+			}
 
-		unmap->bidi_cnt++;
-		if (Q(blocks, disks))
-			unmap->addr[j++] = dma_map_page(device->dev, Q(blocks, disks),
-						       offset, len, DMA_BIDIRECTIONAL);
-		else {
-			unmap->addr[j++] = 0;
-			dma_flags |= DMA_PREP_PQ_DISABLE_Q;
-		}
+			unmap->bidi_cnt++;
+			if (Q(blocks, disks))
+				unmap->addr[j++] = dma_map_page(device->dev,
+							Q(blocks, disks),
+							offset, len,
+							DMA_BIDIRECTIONAL);
+			else {
+				unmap->addr[j++] = 0;
+				dma_flags |= DMA_PREP_PQ_DISABLE_Q;
+			}
 
-		tx = do_async_gen_syndrome(chan, coefs, j, unmap, dma_flags, submit);
-		dmaengine_unmap_put(unmap);
-		return tx;
+			tx = do_async_gen_syndrome(chan, coefs, j, unmap,
+						   dma_flags, submit);
+			return tx;
+		}
 	}
 
-	dmaengine_unmap_put(unmap);
-
 	/* run the pq synchronously */
 	pr_debug("%s: (sync) disks: %d len: %zu\n", __func__, disks, len);
 
@@ -293,10 +298,7 @@ async_syndrome_val(struct page **blocks, unsigned int offset, int disks,
 
 	BUG_ON(disks < 4);
 
-	if (device)
-		unmap = dmaengine_get_unmap_data(device->dev, disks, GFP_NOIO);
-
-	if (unmap && disks <= dma_maxpq(device, 0) &&
+	if (device && disks <= dma_maxpq(device, 0) &&
 	    is_dma_pq_aligned(device, offset, 0, len)) {
 		struct device *dev = device->dev;
 		dma_addr_t pq[2];
@@ -305,58 +307,63 @@ async_syndrome_val(struct page **blocks, unsigned int offset, int disks,
 		pr_debug("%s: (async) disks: %d len: %zu\n",
 			 __func__, disks, len);
 
-		unmap->len = len;
-		for (i = 0; i < disks-2; i++)
-			if (likely(blocks[i])) {
-				unmap->addr[j] = dma_map_page(dev, blocks[i],
-							      offset, len,
+		unmap = dmaengine_get_unmap_data(device->dev, disks, GFP_NOIO);
+		if (unmap) {
+			unmap->len = len;
+			for (i = 0; i < disks-2; i++)
+				if (likely(blocks[i])) {
+					unmap->addr[j] = dma_map_page(dev,
+							      blocks[i],
+							      offset,
+							      len,
 							      DMA_TO_DEVICE);
-				coefs[j] = raid6_gfexp[i];
+					coefs[j] = raid6_gfexp[i];
+					unmap->to_cnt++;
+					src_cnt++;
+					j++;
+				}
+
+			if (!P(blocks, disks)) {
+				pq[0] = 0;
+				dma_flags |= DMA_PREP_PQ_DISABLE_P;
+			} else {
+				pq[0] = dma_map_page(dev, P(blocks, disks),
+						     offset, len,
+						     DMA_TO_DEVICE);
+				unmap->addr[j++] = pq[0];
+				unmap->to_cnt++;
+			}
+			if (!Q(blocks, disks)) {
+				pq[1] = 0;
+				dma_flags |= DMA_PREP_PQ_DISABLE_Q;
+			} else {
+				pq[1] = dma_map_page(dev, Q(blocks, disks),
+						     offset, len,
+						     DMA_TO_DEVICE);
+				unmap->addr[j++] = pq[1];
 				unmap->to_cnt++;
-				src_cnt++;
-				j++;
 			}
 
-		if (!P(blocks, disks)) {
-			pq[0] = 0;
-			dma_flags |= DMA_PREP_PQ_DISABLE_P;
-		} else {
-			pq[0] = dma_map_page(dev, P(blocks, disks),
-					     offset, len,
-					     DMA_TO_DEVICE);
-			unmap->addr[j++] = pq[0];
-			unmap->to_cnt++;
-		}
-		if (!Q(blocks, disks)) {
-			pq[1] = 0;
-			dma_flags |= DMA_PREP_PQ_DISABLE_Q;
-		} else {
-			pq[1] = dma_map_page(dev, Q(blocks, disks),
-					     offset, len,
-					     DMA_TO_DEVICE);
-			unmap->addr[j++] = pq[1];
-			unmap->to_cnt++;
-		}
-
-		if (submit->flags & ASYNC_TX_FENCE)
-			dma_flags |= DMA_PREP_FENCE;
-		for (;;) {
-			tx = device->device_prep_dma_pq_val(chan, pq,
-							    unmap->addr,
-							    src_cnt,
-							    coefs,
-							    len, pqres,
-							    dma_flags);
-			if (likely(tx))
-				break;
-			async_tx_quiesce(&submit->depend_tx);
-			dma_async_issue_pending(chan);
-		}
+			if (submit->flags & ASYNC_TX_FENCE)
+				dma_flags |= DMA_PREP_FENCE;
+			for (;;) {
+				tx = device->device_prep_dma_pq_val(chan, pq,
+								    unmap->addr,
+								    src_cnt,
+								    coefs,
+								    len, pqres,
+								    dma_flags);
+				if (likely(tx))
+					break;
+				async_tx_quiesce(&submit->depend_tx);
+				dma_async_issue_pending(chan);
+			}
 
-		dma_set_unmap(tx, unmap);
-		async_tx_submit(chan, tx, submit);
+			dma_set_unmap(tx, unmap);
+			async_tx_submit(chan, tx, submit);
 
-		return tx;
+			return tx;
+		}
 	} else {
 		struct page *p_src = P(blocks, disks);
 		struct page *q_src = Q(blocks, disks);
@@ -411,9 +418,9 @@ async_syndrome_val(struct page **blocks, unsigned int offset, int disks,
 		submit->cb_param = cb_param_orig;
 		submit->flags = flags_orig;
 		async_tx_sync_epilog(submit);
-
-		return NULL;
 	}
+
+	return NULL;
 }
 EXPORT_SYMBOL_GPL(async_syndrome_val);
 
diff --git a/crypto/async_tx/async_raid6_recov.c b/crypto/async_tx/async_raid6_recov.c
index 934a849..c55d8f1 100644
--- a/crypto/async_tx/async_raid6_recov.c
+++ b/crypto/async_tx/async_raid6_recov.c
@@ -40,10 +40,7 @@ async_sum_product(struct page *dest, struct page **srcs, unsigned char *coef,
 	u8 ax, bx;
 	u8 *a, *b, *c;
 
-	if (dma)
-		unmap = dmaengine_get_unmap_data(dma->dev, 3, GFP_NOIO);
-
-	if (unmap) {
+	if (dma) {
 		struct device *dev = dma->dev;
 		dma_addr_t pq[2];
 		struct dma_async_tx_descriptor *tx;
@@ -51,29 +48,35 @@ async_sum_product(struct page *dest, struct page **srcs, unsigned char *coef,
 
 		if (submit->flags & ASYNC_TX_FENCE)
 			dma_flags |= DMA_PREP_FENCE;
-		unmap->addr[0] = dma_map_page(dev, srcs[0], 0, len, DMA_TO_DEVICE);
-		unmap->addr[1] = dma_map_page(dev, srcs[1], 0, len, DMA_TO_DEVICE);
-		unmap->to_cnt = 2;
-
-		unmap->addr[2] = dma_map_page(dev, dest, 0, len, DMA_BIDIRECTIONAL);
-		unmap->bidi_cnt = 1;
-		/* engine only looks at Q, but expects it to follow P */
-		pq[1] = unmap->addr[2];
-
-		unmap->len = len;
-		tx = dma->device_prep_dma_pq(chan, pq, unmap->addr, 2, coef,
-					     len, dma_flags);
-		if (tx) {
-			dma_set_unmap(tx, unmap);
-			async_tx_submit(chan, tx, submit);
+
+		unmap = dmaengine_get_unmap_data(dma->dev, 3, GFP_NOIO);
+		if (unmap) {
+			unmap->addr[0] = dma_map_page(dev, srcs[0], 0, len,
+						      DMA_TO_DEVICE);
+			unmap->addr[1] = dma_map_page(dev, srcs[1], 0, len,
+						      DMA_TO_DEVICE);
+			unmap->to_cnt = 2;
+
+			unmap->addr[2] = dma_map_page(dev, dest, 0, len,
+						      DMA_BIDIRECTIONAL);
+			unmap->bidi_cnt = 1;
+			/* engine only looks at Q, but expects it to follow P */
+			pq[1] = unmap->addr[2];
+
+			unmap->len = len;
+			tx = dma->device_prep_dma_pq(chan, pq, unmap->addr, 2,
+						     coef, len, dma_flags);
+			if (tx) {
+				dma_set_unmap(tx, unmap);
+				async_tx_submit(chan, tx, submit);
+				return tx;
+			}
+
+			/* could not get a descriptor, unmap and fall through to
+			 * the synchronous path
+			 */
 			dmaengine_unmap_put(unmap);
-			return tx;
 		}
-
-		/* could not get a descriptor, unmap and fall through to
-		 * the synchronous path
-		 */
-		dmaengine_unmap_put(unmap);
 	}
 
 	/* run the operation synchronously */
@@ -104,10 +107,7 @@ async_mult(struct page *dest, struct page *src, u8 coef, size_t len,
 	const u8 *qmul; /* Q multiplier table */
 	u8 *d, *s;
 
-	if (dma)
-		unmap = dmaengine_get_unmap_data(dma->dev, 3, GFP_NOIO);
-
-	if (unmap) {
+	if (dma) {
 		dma_addr_t dma_dest[2];
 		struct device *dev = dma->dev;
 		struct dma_async_tx_descriptor *tx;
@@ -115,31 +115,37 @@ async_mult(struct page *dest, struct page *src, u8 coef, size_t len,
 
 		if (submit->flags & ASYNC_TX_FENCE)
 			dma_flags |= DMA_PREP_FENCE;
-		unmap->addr[0] = dma_map_page(dev, src, 0, len, DMA_TO_DEVICE);
-		unmap->to_cnt++;
-		unmap->addr[1] = dma_map_page(dev, dest, 0, len, DMA_BIDIRECTIONAL);
-		dma_dest[1] = unmap->addr[1];
-		unmap->bidi_cnt++;
-		unmap->len = len;
-
-		/* this looks funny, but the engine looks for Q at
-		 * dma_dest[1] and ignores dma_dest[0] as a dest
-		 * due to DMA_PREP_PQ_DISABLE_P
-		 */
-		tx = dma->device_prep_dma_pq(chan, dma_dest, unmap->addr,
-					     1, &coef, len, dma_flags);
 
-		if (tx) {
-			dma_set_unmap(tx, unmap);
+		unmap = dmaengine_get_unmap_data(dma->dev, 3, GFP_NOIO);
+		if (unmap) {
+			unmap->addr[0] = dma_map_page(dev, src, 0, len,
+						      DMA_TO_DEVICE);
+			unmap->to_cnt++;
+			unmap->addr[1] = dma_map_page(dev, dest, 0, len,
+						      DMA_BIDIRECTIONAL);
+			dma_dest[1] = unmap->addr[1];
+			unmap->bidi_cnt++;
+			unmap->len = len;
+
+			/* this looks funny, but the engine looks for Q at
+			 * dma_dest[1] and ignores dma_dest[0] as a dest
+			 * due to DMA_PREP_PQ_DISABLE_P
+			 */
+			tx = dma->device_prep_dma_pq(chan, dma_dest,
+						     unmap->addr, 1, &coef,
+						     len, dma_flags);
+
+			if (tx) {
+				dma_set_unmap(tx, unmap);
+				async_tx_submit(chan, tx, submit);
+				return tx;
+			}
+
+			/* could not get a descriptor, unmap and fall through to
+			 * the synchronous path
+			 */
 			dmaengine_unmap_put(unmap);
-			async_tx_submit(chan, tx, submit);
-			return tx;
 		}
-
-		/* could not get a descriptor, unmap and fall through to
-		 * the synchronous path
-		 */
-		dmaengine_unmap_put(unmap);
 	}
 
 	/* no channel available, or failed to allocate a descriptor, so
diff --git a/crypto/async_tx/async_xor.c b/crypto/async_tx/async_xor.c
index 3c562f5..019e469 100644
--- a/crypto/async_tx/async_xor.c
+++ b/crypto/async_tx/async_xor.c
@@ -182,55 +182,57 @@ async_xor(struct page *dest, struct page **src_list, unsigned int offset,
 
 	BUG_ON(src_cnt <= 1);
 
-	if (device)
-		unmap = dmaengine_get_unmap_data(device->dev, src_cnt+1, GFP_NOIO);
-
-	if (unmap && is_dma_xor_aligned(device, offset, 0, len)) {
+	if (device && is_dma_xor_aligned(device, offset, 0, len)) {
 		struct dma_async_tx_descriptor *tx;
 		int i, j;
 
 		/* run the xor asynchronously */
 		pr_debug("%s (async): len: %zu\n", __func__, len);
 
-		unmap->len = len;
-		for (i = 0, j = 0; i < src_cnt; i++) {
-			if (!src_list[i])
-				continue;
-			unmap->to_cnt++;
-			unmap->addr[j++] = dma_map_page(device->dev, src_list[i],
-							offset, len, DMA_TO_DEVICE);
-		}
+		unmap = dmaengine_get_unmap_data(device->dev, src_cnt + 1,
+						 GFP_NOIO);
+		if (unmap) {
+			unmap->len = len;
+			for (i = 0, j = 0; i < src_cnt; i++) {
+				if (!src_list[i])
+					continue;
+				unmap->to_cnt++;
+				unmap->addr[j++] = dma_map_page(device->dev,
+								src_list[i],
+								offset, len,
+								DMA_TO_DEVICE);
+			}
 
-		/* map it bidirectional as it may be re-used as a source */
-		unmap->addr[j] = dma_map_page(device->dev, dest, offset, len,
-					      DMA_BIDIRECTIONAL);
-		unmap->bidi_cnt = 1;
-
-		tx = do_async_xor(chan, unmap, submit);
-		dmaengine_unmap_put(unmap);
-		return tx;
-	} else {
-		dmaengine_unmap_put(unmap);
-		/* run the xor synchronously */
-		pr_debug("%s (sync): len: %zu\n", __func__, len);
-		WARN_ONCE(chan, "%s: no space for dma address conversion\n",
-			  __func__);
-
-		/* in the sync case the dest is an implied source
-		 * (assumes the dest is the first source)
-		 */
-		if (submit->flags & ASYNC_TX_XOR_DROP_DST) {
-			src_cnt--;
-			src_list++;
+			/* map it bidirectional as it may be re-used
+			   as a source */
+			unmap->addr[j] = dma_map_page(device->dev, dest, offset,
+						      len, DMA_BIDIRECTIONAL);
+			unmap->bidi_cnt = 1;
+
+			tx = do_async_xor(chan, unmap, submit);
+			return tx;
 		}
+	}
 
-		/* wait for any prerequisite operations */
-		async_tx_quiesce(&submit->depend_tx);
+	/* run the xor synchronously */
+	pr_debug("%s (sync): len: %zu\n", __func__, len);
+	WARN_ONCE(chan, "%s: no space for dma address conversion\n",
+		  __func__);
+
+	/* in the sync case the dest is an implied source
+	 * (assumes the dest is the first source)
+	 */
+	if (submit->flags & ASYNC_TX_XOR_DROP_DST) {
+		src_cnt--;
+		src_list++;
+	}
 
-		do_sync_xor(dest, src_list, offset, src_cnt, len, submit);
+	/* wait for any prerequisite operations */
+	async_tx_quiesce(&submit->depend_tx);
 
-		return NULL;
-	}
+	do_sync_xor(dest, src_list, offset, src_cnt, len, submit);
+
+	return NULL;
 }
 EXPORT_SYMBOL_GPL(async_xor);
 
@@ -275,13 +277,11 @@ async_xor_val(struct page *dest, struct page **src_list, unsigned int offset,
 	struct dma_device *device = chan ? chan->device : NULL;
 	struct dma_async_tx_descriptor *tx = NULL;
 	struct dmaengine_unmap_data *unmap = NULL;
+	enum async_tx_flags flags_orig = submit->flags;
 
 	BUG_ON(src_cnt <= 1);
 
-	if (device)
-		unmap = dmaengine_get_unmap_data(device->dev, src_cnt, GFP_NOIO);
-
-	if (unmap && src_cnt <= device->max_xor &&
+	if (device && src_cnt <= device->max_xor &&
 	    is_dma_xor_aligned(device, offset, 0, len)) {
 		unsigned long dma_prep_flags = 0;
 		int i;
@@ -293,51 +293,59 @@ async_xor_val(struct page *dest, struct page **src_list, unsigned int offset,
 		if (submit->flags & ASYNC_TX_FENCE)
 			dma_prep_flags |= DMA_PREP_FENCE;
 
-		for (i = 0; i < src_cnt; i++) {
-			unmap->addr[i] = dma_map_page(device->dev, src_list[i],
-						      offset, len, DMA_TO_DEVICE);
-			unmap->to_cnt++;
-		}
-		unmap->len = len;
-
-		tx = device->device_prep_dma_xor_val(chan, unmap->addr, src_cnt,
-						     len, result,
-						     dma_prep_flags);
-		if (unlikely(!tx)) {
-			async_tx_quiesce(&submit->depend_tx);
-
-			while (!tx) {
-				dma_async_issue_pending(chan);
-				tx = device->device_prep_dma_xor_val(chan,
-					unmap->addr, src_cnt, len, result,
-					dma_prep_flags);
+		unmap = dmaengine_get_unmap_data(device->dev, src_cnt,
+						 GFP_NOIO);
+		if (unmap) {
+			for (i = 0; i < src_cnt; i++) {
+				unmap->addr[i] = dma_map_page(device->dev,
+							      src_list[i],
+							      offset, len,
+							      DMA_TO_DEVICE);
+				unmap->to_cnt++;
+			}
+			unmap->len = len;
+
+			tx = device->device_prep_dma_xor_val(chan, unmap->addr,
+							     src_cnt,
+							     len, result,
+							     dma_prep_flags);
+			if (unlikely(!tx)) {
+				async_tx_quiesce(&submit->depend_tx);
+
+				while (!tx) {
+					dma_async_issue_pending(chan);
+					tx = device->device_prep_dma_xor_val(
+							chan, unmap->addr,
+							src_cnt, len,
+							result, dma_prep_flags);
+				}
 			}
+			dma_set_unmap(tx, unmap);
+			async_tx_submit(chan, tx, submit);
+
+			return tx;
 		}
-		dma_set_unmap(tx, unmap);
-		async_tx_submit(chan, tx, submit);
-	} else {
-		enum async_tx_flags flags_orig = submit->flags;
+	}
 
-		pr_debug("%s: (sync) len: %zu\n", __func__, len);
-		WARN_ONCE(device && src_cnt <= device->max_xor,
-			  "%s: no space for dma address conversion\n",
-			  __func__);
+	/* run the xor_val synchronously */
+	pr_debug("%s: (sync) len: %zu\n", __func__, len);
+	WARN_ONCE(device && src_cnt <= device->max_xor,
+		  "%s: no space for dma address conversion\n",
+		  __func__);
 
-		submit->flags |= ASYNC_TX_XOR_DROP_DST;
-		submit->flags &= ~ASYNC_TX_ACK;
+	submit->flags |= ASYNC_TX_XOR_DROP_DST;
+	submit->flags &= ~ASYNC_TX_ACK;
 
-		tx = async_xor(dest, src_list, offset, src_cnt, len, submit);
+	tx = async_xor(dest, src_list, offset, src_cnt, len, submit);
 
-		async_tx_quiesce(&tx);
+	async_tx_quiesce(&tx);
 
-		*result = !page_is_zero(dest, offset, len) << SUM_CHECK_P;
+	*result = !page_is_zero(dest, offset, len) << SUM_CHECK_P;
 
-		async_tx_sync_epilog(submit);
-		submit->flags = flags_orig;
-	}
-	dmaengine_unmap_put(unmap);
+	async_tx_sync_epilog(submit);
+	submit->flags = flags_orig;
 
-	return tx;
+	return NULL;
 }
 EXPORT_SYMBOL_GPL(async_xor_val);
 
-- 
1.8.3.2

^ permalink raw reply related


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