LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 net-next] af_unix: fix a fatal race with bit fields
From: Eric Dumazet @ 2013-05-01 15:24 UTC (permalink / raw)
  To: David Miller; +Cc: linuxppc-dev, paulus, ambrose, netdev
In-Reply-To: <20130501.033650.703182794549888825.davem@davemloft.net>

On Wed, 2013-05-01 at 03:36 -0400, David Miller wrote:
> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Date: Wed, 01 May 2013 11:39:53 +1000
> 
> > I'm not even completely certain bytes are safe to be honest, though
> > probably more than bitfields. I'll poke our compiler people.
> 
> Older Alpha only has 32-bit and 64-bit loads and stores, so byte sized
> accesses are not atomic, and therefore use racey read-modify-write
> sequences.

Right, so what about the following more general fix ?

Thanks !

[PATCH v2] af_unix: fix a fatal race with bit fields

Using bit fields is dangerous on ppc64/sparc64, as the compiler [1]
uses 64bit instructions to manipulate them.
If the 64bit word includes any atomic_t or spinlock_t, we can lose
critical concurrent changes.

This is happening in af_unix, where unix_sk(sk)->gc_candidate/
gc_maybe_cycle/lock share the same 64bit word.

This leads to fatal deadlock, as one/several cpus spin forever
on a spinlock that will never be available again.

A safer way would be to use a long to store flags.
This way we are sure compiler/arch wont do bad things.

As we own unix_gc_lock spinlock when clearing or setting bits,
we can use the non atomic __set_bit()/__clear_bit().

recursion_level can share the same 64bit location with the spinlock,
as it is set only with this spinlock held.

[1] bug fixed in gcc-4.8.0 :
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52080

Reported-by: Ambrose Feinstein <ambrose@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
---
 include/net/af_unix.h |    5 +++--
 net/unix/garbage.c    |   12 ++++++------
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index a8836e8..dbdfd2b 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -57,9 +57,10 @@ struct unix_sock {
 	struct list_head	link;
 	atomic_long_t		inflight;
 	spinlock_t		lock;
-	unsigned int		gc_candidate : 1;
-	unsigned int		gc_maybe_cycle : 1;
 	unsigned char		recursion_level;
+	unsigned long		gc_flags;
+#define UNIX_GC_CANDIDATE	0
+#define UNIX_GC_MAYBE_CYCLE	1
 	struct socket_wq	peer_wq;
 };
 #define unix_sk(__sk) ((struct unix_sock *)__sk)
diff --git a/net/unix/garbage.c b/net/unix/garbage.c
index d0f6545..9c6cc08 100644
--- a/net/unix/garbage.c
+++ b/net/unix/garbage.c
@@ -185,7 +185,7 @@ static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *),
 					 * have been added to the queues after
 					 * starting the garbage collection
 					 */
-					if (u->gc_candidate) {
+					if (test_bit(UNIX_GC_CANDIDATE, &u->gc_flags)) {
 						hit = true;
 						func(u);
 					}
@@ -254,7 +254,7 @@ static void inc_inflight_move_tail(struct unix_sock *u)
 	 * of the list, so that it's checked even if it was already
 	 * passed over
 	 */
-	if (u->gc_maybe_cycle)
+	if (test_bit(UNIX_GC_MAYBE_CYCLE, &u->gc_flags))
 		list_move_tail(&u->link, &gc_candidates);
 }
 
@@ -315,8 +315,8 @@ void unix_gc(void)
 		BUG_ON(total_refs < inflight_refs);
 		if (total_refs == inflight_refs) {
 			list_move_tail(&u->link, &gc_candidates);
-			u->gc_candidate = 1;
-			u->gc_maybe_cycle = 1;
+			__set_bit(UNIX_GC_CANDIDATE, &u->gc_flags);
+			__set_bit(UNIX_GC_MAYBE_CYCLE, &u->gc_flags);
 		}
 	}
 
@@ -344,7 +344,7 @@ void unix_gc(void)
 
 		if (atomic_long_read(&u->inflight) > 0) {
 			list_move_tail(&u->link, &not_cycle_list);
-			u->gc_maybe_cycle = 0;
+			__clear_bit(UNIX_GC_MAYBE_CYCLE, &u->gc_flags);
 			scan_children(&u->sk, inc_inflight_move_tail, NULL);
 		}
 	}
@@ -356,7 +356,7 @@ void unix_gc(void)
 	 */
 	while (!list_empty(&not_cycle_list)) {
 		u = list_entry(not_cycle_list.next, struct unix_sock, link);
-		u->gc_candidate = 0;
+		__clear_bit(UNIX_GC_CANDIDATE, &u->gc_flags);
 		list_move_tail(&u->link, &gc_inflight_list);
 	}
 

^ permalink raw reply related

* Re: [PATCH] powerpc: Bring all threads online prior to migration/hibernation
From: Nathan Fontenot @ 2013-05-01 15:25 UTC (permalink / raw)
  To: Robert Jennings, linuxppc-dev, Ben Herrenschmidt, stable
In-Reply-To: <20130426213203.GC3698@linux.vnet.ibm.com>

On 04/26/2013 04:32 PM, Robert Jennings wrote:
> With this patch before a migration/hibernation all threads present but
> not online will be brought online.  After migration/hibernation those
> threads are taken back offline.
> 
> During migration/hibernation all online CPUs must call H_JOIN, this is
> required by the hypervisor.  Without this patch, threads that are offline
> (H_CEDE'd) will not be woken to make the H_JOIN call and the OS will be
> deadlocked (all threads either JOIN'd or CEDE'd).
> 

This fixes a long standing bug in partition migration.

Acked-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>

> Cc: <stable@kernel.org>
> Signed-off-by: Robert Jennings <rcj@linux.vnet.ibm.com>
> ---
>  arch/powerpc/include/asm/rtas.h          |    2 +
>  arch/powerpc/kernel/rtas.c               |   95 ++++++++++++++++++++++++++++++
>  arch/powerpc/platforms/pseries/suspend.c |   22 +++++++
>  3 files changed, 119 insertions(+)
> 
> diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
> index aef00c6..ee38f29 100644
> --- a/arch/powerpc/include/asm/rtas.h
> +++ b/arch/powerpc/include/asm/rtas.h
> @@ -262,6 +262,8 @@ extern void rtas_progress(char *s, unsigned short hex);
>  extern void rtas_initialize(void);
>  extern int rtas_suspend_cpu(struct rtas_suspend_me_data *data);
>  extern int rtas_suspend_last_cpu(struct rtas_suspend_me_data *data);
> +extern int rtas_online_cpus_mask(cpumask_var_t cpus);
> +extern int rtas_offline_cpus_mask(cpumask_var_t cpus);
>  extern int rtas_ibm_suspend_me(struct rtas_args *);
>  
>  struct rtc_time;
> diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
> index 1fd6e7b..855ee98 100644
> --- a/arch/powerpc/kernel/rtas.c
> +++ b/arch/powerpc/kernel/rtas.c
> @@ -19,6 +19,7 @@
>  #include <linux/init.h>
>  #include <linux/capability.h>
>  #include <linux/delay.h>
> +#include <linux/cpu.h>
>  #include <linux/smp.h>
>  #include <linux/completion.h>
>  #include <linux/cpumask.h>
> @@ -807,6 +808,77 @@ static void rtas_percpu_suspend_me(void *info)
>  	__rtas_suspend_cpu((struct rtas_suspend_me_data *)info, 1);
>  }
>  
> +enum rtas_cpu_state {
> +	DOWN,
> +	UP,
> +};
> +
> +/* On return cpumask will be altered to indicate CPUs changed */
> +static int rtas_cpu_state_change_mask(enum rtas_cpu_state state,
> +				cpumask_var_t cpus)
> +{
> +	int cpu;
> +	int cpuret = 0;
> +	int ret = 0;
> +
> +	if (cpumask_empty(cpus))
> +		return 0;
> +
> +	for_each_cpu(cpu, cpus) {
> +		switch (state) {
> +		case DOWN:
> +			cpuret = cpu_down(cpu);
> +			break;
> +		case UP:
> +			cpuret = cpu_up(cpu);
> +			break;
> +		}
> +		if (cpuret) {
> +			pr_debug("%s: cpu_%s for cpu#%d returned %d.\n",
> +					__func__,
> +					((state == UP) ? "up" : "down"),
> +					cpu, cpuret);
> +			if (!ret)
> +				ret = cpuret;
> +			if (state == UP) {
> +				cpumask_shift_right(cpus, cpus, cpu);
> +				cpumask_shift_left(cpus, cpus, cpu);
> +				break;
> +			} else
> +				cpumask_clear_cpu(cpu, cpus);
> +		}
> +	}
> +
> +	return ret;
> +}
> +
> +int rtas_online_cpus_mask(cpumask_var_t cpus)
> +{
> +	int ret;
> +
> +	ret = rtas_cpu_state_change_mask(UP, cpus);
> +
> +	if (ret) {
> +		cpumask_var_t tmp_mask;
> +
> +		if (!alloc_cpumask_var(&tmp_mask, GFP_TEMPORARY))
> +			return ret;
> +
> +		cpumask_copy(tmp_mask, cpus);
> +		rtas_offline_cpus_mask(tmp_mask);
> +		free_cpumask_var(tmp_mask);
> +	}
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL(rtas_online_cpus_mask);
> +
> +int rtas_offline_cpus_mask(cpumask_var_t cpus)
> +{
> +	return rtas_cpu_state_change_mask(DOWN, cpus);
> +}
> +EXPORT_SYMBOL(rtas_offline_cpus_mask);
> +
>  int rtas_ibm_suspend_me(struct rtas_args *args)
>  {
>  	long state;
> @@ -814,6 +886,8 @@ int rtas_ibm_suspend_me(struct rtas_args *args)
>  	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
>  	struct rtas_suspend_me_data data;
>  	DECLARE_COMPLETION_ONSTACK(done);
> +	cpumask_var_t offline_mask;
> +	int cpuret;
>  
>  	if (!rtas_service_present("ibm,suspend-me"))
>  		return -ENOSYS;
> @@ -837,11 +911,24 @@ int rtas_ibm_suspend_me(struct rtas_args *args)
>  		return 0;
>  	}
>  
> +	if (!alloc_cpumask_var(&offline_mask, GFP_TEMPORARY))
> +		return -ENOMEM;
> +
>  	atomic_set(&data.working, 0);
>  	atomic_set(&data.done, 0);
>  	atomic_set(&data.error, 0);
>  	data.token = rtas_token("ibm,suspend-me");
>  	data.complete = &done;
> +
> +	/* All present CPUs must be online */
> +	cpumask_andnot(offline_mask, cpu_present_mask, cpu_online_mask);
> +	cpuret = rtas_online_cpus_mask(offline_mask);
> +	if (cpuret) {
> +		pr_err("%s: Could not bring present CPUs online.\n", __func__);
> +		atomic_set(&data.error, cpuret);
> +		goto out;
> +	}
> +
>  	stop_topology_update();
>  
>  	/* Call function on all CPUs.  One of us will make the
> @@ -857,6 +944,14 @@ int rtas_ibm_suspend_me(struct rtas_args *args)
>  
>  	start_topology_update();
>  
> +	/* Take down CPUs not online prior to suspend */
> +	cpuret = rtas_offline_cpus_mask(offline_mask);
> +	if (cpuret)
> +		pr_warn("%s: Could not restore CPUs to offline state.\n",
> +				__func__);
> +
> +out:
> +	free_cpumask_var(offline_mask);
>  	return atomic_read(&data.error);
>  }
>  #else /* CONFIG_PPC_PSERIES */
> diff --git a/arch/powerpc/platforms/pseries/suspend.c b/arch/powerpc/platforms/pseries/suspend.c
> index 47226e0..5f997e7 100644
> --- a/arch/powerpc/platforms/pseries/suspend.c
> +++ b/arch/powerpc/platforms/pseries/suspend.c
> @@ -16,6 +16,7 @@
>    * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
>    */
>  
> +#include <linux/cpu.h>
>  #include <linux/delay.h>
>  #include <linux/suspend.h>
>  #include <linux/stat.h>
> @@ -126,11 +127,15 @@ static ssize_t store_hibernate(struct device *dev,
>  			       struct device_attribute *attr,
>  			       const char *buf, size_t count)
>  {
> +	cpumask_var_t offline_mask;
>  	int rc;
>  
>  	if (!capable(CAP_SYS_ADMIN))
>  		return -EPERM;
>  
> +	if (!alloc_cpumask_var(&offline_mask, GFP_TEMPORARY))
> +		return -ENOMEM;
> +
>  	stream_id = simple_strtoul(buf, NULL, 16);
>  
>  	do {
> @@ -140,15 +145,32 @@ static ssize_t store_hibernate(struct device *dev,
>  	} while (rc == -EAGAIN);
>  
>  	if (!rc) {
> +		/* All present CPUs must be online */
> +		cpumask_andnot(offline_mask, cpu_present_mask,
> +				cpu_online_mask);
> +		rc = rtas_online_cpus_mask(offline_mask);
> +		if (rc) {
> +			pr_err("%s: Could not bring present CPUs online.\n",
> +					__func__);
> +			goto out;
> +		}
> +
>  		stop_topology_update();
>  		rc = pm_suspend(PM_SUSPEND_MEM);
>  		start_topology_update();
> +
> +		/* Take down CPUs not online prior to suspend */
> +		if (!rtas_offline_cpus_mask(offline_mask))
> +			pr_warn("%s: Could not restore CPUs to offline "
> +					"state.\n", __func__);
>  	}
>  
>  	stream_id = 0;
>  
>  	if (!rc)
>  		rc = count;
> +out:
> +	free_cpumask_var(offline_mask);
>  	return rc;
>  }
>  


-- 
-Nathan

^ permalink raw reply

* RE: [PATCH v2 net-next] af_unix: fix a fatal race with bit fields
From: Eric Dumazet @ 2013-05-01 16:00 UTC (permalink / raw)
  To: David Laight; +Cc: ambrose, paulus, netdev, linuxppc-dev, David Miller
In-Reply-To: <AE90C24D6B3A694183C094C60CF0A2F6026B721C@saturn3.aculab.com>

On Wed, 2013-05-01 at 16:53 +0100, David Laight wrote:
> Why not just change gc_candidate and gc_maybe_cycle to
> unsigned char?
> It might reduce the number of pad bytes somewhat.

You didn't quite follow the discussion.

I used bytes on V1, and we are not 100% sure its safe on all arches.

unsigned long is guaranteed to be safe. We absolutely rely on this.

Better use more bytes on a socket (with no impact on real memory use),
than spending hours to debug some strange issues.

^ permalink raw reply

* RE: [PATCH v2 net-next] af_unix: fix a fatal race with bit fields
From: David Laight @ 2013-05-01 15:53 UTC (permalink / raw)
  To: Eric Dumazet, David Miller; +Cc: linuxppc-dev, paulus, ambrose, netdev
In-Reply-To: <1367421843.11020.43.camel@edumazet-glaptop>

PiBkaWZmIC0tZ2l0IGEvaW5jbHVkZS9uZXQvYWZfdW5peC5oIGIvaW5jbHVkZS9uZXQvYWZfdW5p
eC5oDQo+IGluZGV4IGE4ODM2ZTguLmRiZGZkMmIgMTAwNjQ0DQo+IC0tLSBhL2luY2x1ZGUvbmV0
L2FmX3VuaXguaA0KPiArKysgYi9pbmNsdWRlL25ldC9hZl91bml4LmgNCj4gQEAgLTU3LDkgKzU3
LDEwIEBAIHN0cnVjdCB1bml4X3NvY2sgew0KPiAgCXN0cnVjdCBsaXN0X2hlYWQJbGluazsNCj4g
IAlhdG9taWNfbG9uZ190CQlpbmZsaWdodDsNCj4gIAlzcGlubG9ja190CQlsb2NrOw0KPiAtCXVu
c2lnbmVkIGludAkJZ2NfY2FuZGlkYXRlIDogMTsNCj4gLQl1bnNpZ25lZCBpbnQJCWdjX21heWJl
X2N5Y2xlIDogMTsNCj4gIAl1bnNpZ25lZCBjaGFyCQlyZWN1cnNpb25fbGV2ZWw7DQo+ICsJdW5z
aWduZWQgbG9uZwkJZ2NfZmxhZ3M7DQo+ICsjZGVmaW5lIFVOSVhfR0NfQ0FORElEQVRFCTANCj4g
KyNkZWZpbmUgVU5JWF9HQ19NQVlCRV9DWUNMRQkxDQo+ICAJc3RydWN0IHNvY2tldF93cQlwZWVy
X3dxOw0KPiAgfTsNCg0KV2h5IG5vdCBqdXN0IGNoYW5nZSBnY19jYW5kaWRhdGUgYW5kIGdjX21h
eWJlX2N5Y2xlIHRvDQp1bnNpZ25lZCBjaGFyPw0KSXQgbWlnaHQgcmVkdWNlIHRoZSBudW1iZXIg
b2YgcGFkIGJ5dGVzIHNvbWV3aGF0Lg0KDQoJRGF2aWQNCg0K

^ permalink raw reply

* Re: ppc/sata-fsl: orphan config value: CONFIG_MPC8315_DS
From: Scott Wood @ 2013-05-01 18:05 UTC (permalink / raw)
  To: Anthony Foiani
  Cc: Robert P.J.Day, linuxppc-dev@lists.ozlabs.org, Li Yang-R58472,
	Jeff Garzik, Adrian Bunk
In-Reply-To: <518078C0.7070805@scrye.com>

On 04/30/2013 09:06:56 PM, Anthony Foiani wrote:
> Scott --
>=20
> On 04/30/2013 06:42 PM, Scott Wood wrote:
>> I just meant that, for whatever boards you would have put this in =20
>> the device tree, put it in platform code instead (if the platform =20
>> file supports more than one board type, then check the compatible at =20
>> the top of the device tree).
>=20
> I think I understand what you're suggesting.
>=20
> Instead of a new property name, I would instead check for my specific =20
> board type (let's call it a foo-8315) in the top-level compatible =20
> list?  So I'd change my devtree to have this top-level compatible:
>=20
> / {
>     compatible =3D "example,foo-8315", "fsl,mpc8315erdb";

It should really only have compatible =3D "example,foo-8315", since it's =20
not 100% compatible with fsl,mpc8315erdb (at least due to this bug, but =20
probably there are other differences as well).

> If I saw that, I would then twiddle the bits as needed?

Yes.

> MIght work, although having it in the sata block of the device tree =20
> has the advantage of providing me exactly the OF node that I need (in =20
> ofdev->dev.of_node).  I'd have to figure out how to traverse to the =20
> dev tree root and then back down one to the root compat entry.  =20
> Probably not impossible, but I was aiming for a fairly minimal patch.

Well, if this is only seen on your board so far (or rather, your =20
vendor's board which isn't upstream), and you're OK with updating the =20
device tree, then I have no objection.

> It would also be nice if we could unravel exactly why that =20
> CONFIG_8315_DS ever showed up in the first place.

It would be nice, but I doubt that particular information is ever going =20
to surface...  IIRC I asked internally back when this first came up, =20
and didn't get an answer.

>> Or do you mean that you would not set this on any board's device =20
>> tree by default, and instead have users set it if they encounter =20
>> problems?
>=20
> No, I would expect to set it on all the boards, so using the =20
> compatibility hack above would work.

You mean all the boards that have the bug, which doesn't include any =20
upstream device tree, right?

-Scott=

^ permalink raw reply

* Re: [PATCH v2 net-next] af_unix: fix a fatal race with bit fields
From: David Miller @ 2013-05-01 19:14 UTC (permalink / raw)
  To: eric.dumazet; +Cc: linuxppc-dev, paulus, ambrose, netdev
In-Reply-To: <1367421843.11020.43.camel@edumazet-glaptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 01 May 2013 08:24:03 -0700

> [PATCH v2] af_unix: fix a fatal race with bit fields
> 
> Using bit fields is dangerous on ppc64/sparc64, as the compiler [1]
> uses 64bit instructions to manipulate them.
> If the 64bit word includes any atomic_t or spinlock_t, we can lose
> critical concurrent changes.
> 
> This is happening in af_unix, where unix_sk(sk)->gc_candidate/
> gc_maybe_cycle/lock share the same 64bit word.
> 
> This leads to fatal deadlock, as one/several cpus spin forever
> on a spinlock that will never be available again.
> 
> A safer way would be to use a long to store flags.
> This way we are sure compiler/arch wont do bad things.
> 
> As we own unix_gc_lock spinlock when clearing or setting bits,
> we can use the non atomic __set_bit()/__clear_bit().
> 
> recursion_level can share the same 64bit location with the spinlock,
> as it is set only with this spinlock held.
> 
> [1] bug fixed in gcc-4.8.0 :
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52080
> 
> Reported-by: Ambrose Feinstein <ambrose@google.com>
> Signed-off-by: Eric Dumazet <edumazet@google.com>

Applied and queued up for -stable, thanks Eric.

^ permalink raw reply

* Re: [PATCH] powerpc: Bring all threads online prior to migration/hibernation
From: Srivatsa S. Bhat @ 2013-05-01 19:43 UTC (permalink / raw)
  To: Robert Jennings, linuxppc-dev, Ben Herrenschmidt, stable
In-Reply-To: <20130426213203.GC3698@linux.vnet.ibm.com>

On 04/27/2013 03:02 AM, Robert Jennings wrote:
> With this patch before a migration/hibernation all threads present but
> not online will be brought online.  After migration/hibernation those
> threads are taken back offline.
> 
> During migration/hibernation all online CPUs must call H_JOIN, this is
> required by the hypervisor.  Without this patch, threads that are offline
> (H_CEDE'd) will not be woken to make the H_JOIN call and the OS will be
> deadlocked (all threads either JOIN'd or CEDE'd).
> 
> Cc: <stable@kernel.org>
> Signed-off-by: Robert Jennings <rcj@linux.vnet.ibm.com>
> ---

Reviewed-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>

Regards,
Srivatsa S. Bhat

>  arch/powerpc/include/asm/rtas.h          |    2 +
>  arch/powerpc/kernel/rtas.c               |   95 ++++++++++++++++++++++++++++++
>  arch/powerpc/platforms/pseries/suspend.c |   22 +++++++
>  3 files changed, 119 insertions(+)
> 
> diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
> index aef00c6..ee38f29 100644
> --- a/arch/powerpc/include/asm/rtas.h
> +++ b/arch/powerpc/include/asm/rtas.h
> @@ -262,6 +262,8 @@ extern void rtas_progress(char *s, unsigned short hex);
>  extern void rtas_initialize(void);
>  extern int rtas_suspend_cpu(struct rtas_suspend_me_data *data);
>  extern int rtas_suspend_last_cpu(struct rtas_suspend_me_data *data);
> +extern int rtas_online_cpus_mask(cpumask_var_t cpus);
> +extern int rtas_offline_cpus_mask(cpumask_var_t cpus);
>  extern int rtas_ibm_suspend_me(struct rtas_args *);
> 
>  struct rtc_time;
> diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
> index 1fd6e7b..855ee98 100644
> --- a/arch/powerpc/kernel/rtas.c
> +++ b/arch/powerpc/kernel/rtas.c
> @@ -19,6 +19,7 @@
>  #include <linux/init.h>
>  #include <linux/capability.h>
>  #include <linux/delay.h>
> +#include <linux/cpu.h>
>  #include <linux/smp.h>
>  #include <linux/completion.h>
>  #include <linux/cpumask.h>
> @@ -807,6 +808,77 @@ static void rtas_percpu_suspend_me(void *info)
>  	__rtas_suspend_cpu((struct rtas_suspend_me_data *)info, 1);
>  }
> 
> +enum rtas_cpu_state {
> +	DOWN,
> +	UP,
> +};
> +
> +/* On return cpumask will be altered to indicate CPUs changed */
> +static int rtas_cpu_state_change_mask(enum rtas_cpu_state state,
> +				cpumask_var_t cpus)
> +{
> +	int cpu;
> +	int cpuret = 0;
> +	int ret = 0;
> +
> +	if (cpumask_empty(cpus))
> +		return 0;
> +
> +	for_each_cpu(cpu, cpus) {
> +		switch (state) {
> +		case DOWN:
> +			cpuret = cpu_down(cpu);
> +			break;
> +		case UP:
> +			cpuret = cpu_up(cpu);
> +			break;
> +		}
> +		if (cpuret) {
> +			pr_debug("%s: cpu_%s for cpu#%d returned %d.\n",
> +					__func__,
> +					((state == UP) ? "up" : "down"),
> +					cpu, cpuret);
> +			if (!ret)
> +				ret = cpuret;
> +			if (state == UP) {
> +				cpumask_shift_right(cpus, cpus, cpu);
> +				cpumask_shift_left(cpus, cpus, cpu);
> +				break;
> +			} else
> +				cpumask_clear_cpu(cpu, cpus);
> +		}
> +	}
> +
> +	return ret;
> +}
> +
> +int rtas_online_cpus_mask(cpumask_var_t cpus)
> +{
> +	int ret;
> +
> +	ret = rtas_cpu_state_change_mask(UP, cpus);
> +
> +	if (ret) {
> +		cpumask_var_t tmp_mask;
> +
> +		if (!alloc_cpumask_var(&tmp_mask, GFP_TEMPORARY))
> +			return ret;
> +
> +		cpumask_copy(tmp_mask, cpus);
> +		rtas_offline_cpus_mask(tmp_mask);
> +		free_cpumask_var(tmp_mask);
> +	}
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL(rtas_online_cpus_mask);
> +
> +int rtas_offline_cpus_mask(cpumask_var_t cpus)
> +{
> +	return rtas_cpu_state_change_mask(DOWN, cpus);
> +}
> +EXPORT_SYMBOL(rtas_offline_cpus_mask);
> +
>  int rtas_ibm_suspend_me(struct rtas_args *args)
>  {
>  	long state;
> @@ -814,6 +886,8 @@ int rtas_ibm_suspend_me(struct rtas_args *args)
>  	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
>  	struct rtas_suspend_me_data data;
>  	DECLARE_COMPLETION_ONSTACK(done);
> +	cpumask_var_t offline_mask;
> +	int cpuret;
> 
>  	if (!rtas_service_present("ibm,suspend-me"))
>  		return -ENOSYS;
> @@ -837,11 +911,24 @@ int rtas_ibm_suspend_me(struct rtas_args *args)
>  		return 0;
>  	}
> 
> +	if (!alloc_cpumask_var(&offline_mask, GFP_TEMPORARY))
> +		return -ENOMEM;
> +
>  	atomic_set(&data.working, 0);
>  	atomic_set(&data.done, 0);
>  	atomic_set(&data.error, 0);
>  	data.token = rtas_token("ibm,suspend-me");
>  	data.complete = &done;
> +
> +	/* All present CPUs must be online */
> +	cpumask_andnot(offline_mask, cpu_present_mask, cpu_online_mask);
> +	cpuret = rtas_online_cpus_mask(offline_mask);
> +	if (cpuret) {
> +		pr_err("%s: Could not bring present CPUs online.\n", __func__);
> +		atomic_set(&data.error, cpuret);
> +		goto out;
> +	}
> +
>  	stop_topology_update();
> 
>  	/* Call function on all CPUs.  One of us will make the
> @@ -857,6 +944,14 @@ int rtas_ibm_suspend_me(struct rtas_args *args)
> 
>  	start_topology_update();
> 
> +	/* Take down CPUs not online prior to suspend */
> +	cpuret = rtas_offline_cpus_mask(offline_mask);
> +	if (cpuret)
> +		pr_warn("%s: Could not restore CPUs to offline state.\n",
> +				__func__);
> +
> +out:
> +	free_cpumask_var(offline_mask);
>  	return atomic_read(&data.error);
>  }
>  #else /* CONFIG_PPC_PSERIES */
> diff --git a/arch/powerpc/platforms/pseries/suspend.c b/arch/powerpc/platforms/pseries/suspend.c
> index 47226e0..5f997e7 100644
> --- a/arch/powerpc/platforms/pseries/suspend.c
> +++ b/arch/powerpc/platforms/pseries/suspend.c
> @@ -16,6 +16,7 @@
>    * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
>    */
> 
> +#include <linux/cpu.h>
>  #include <linux/delay.h>
>  #include <linux/suspend.h>
>  #include <linux/stat.h>
> @@ -126,11 +127,15 @@ static ssize_t store_hibernate(struct device *dev,
>  			       struct device_attribute *attr,
>  			       const char *buf, size_t count)
>  {
> +	cpumask_var_t offline_mask;
>  	int rc;
> 
>  	if (!capable(CAP_SYS_ADMIN))
>  		return -EPERM;
> 
> +	if (!alloc_cpumask_var(&offline_mask, GFP_TEMPORARY))
> +		return -ENOMEM;
> +
>  	stream_id = simple_strtoul(buf, NULL, 16);
> 
>  	do {
> @@ -140,15 +145,32 @@ static ssize_t store_hibernate(struct device *dev,
>  	} while (rc == -EAGAIN);
> 
>  	if (!rc) {
> +		/* All present CPUs must be online */
> +		cpumask_andnot(offline_mask, cpu_present_mask,
> +				cpu_online_mask);
> +		rc = rtas_online_cpus_mask(offline_mask);
> +		if (rc) {
> +			pr_err("%s: Could not bring present CPUs online.\n",
> +					__func__);
> +			goto out;
> +		}
> +
>  		stop_topology_update();
>  		rc = pm_suspend(PM_SUSPEND_MEM);
>  		start_topology_update();
> +
> +		/* Take down CPUs not online prior to suspend */
> +		if (!rtas_offline_cpus_mask(offline_mask))
> +			pr_warn("%s: Could not restore CPUs to offline "
> +					"state.\n", __func__);
>  	}
> 
>  	stream_id = 0;
> 
>  	if (!rc)
>  		rc = count;
> +out:
> +	free_cpumask_var(offline_mask);
>  	return rc;
>  }
> 

^ permalink raw reply

* Re: flush_icache_range on AMCC 44x targets
From: Josh Boyer @ 2013-05-01 19:53 UTC (permalink / raw)
  To: Mike; +Cc: linuxppc-dev
In-Reply-To: <CANtoAtNsjMdgdpj31myTDUBy_sbMk4nvgBzir_2ZHnSgsgZ=JQ@mail.gmail.com>

On Tue, Apr 30, 2013 at 02:17:59PM +0200, Mike wrote:
>Hi,
>
>i was reading trough arch/powerpc/kernel/misc32.S looking at the icbi and
>iccci instructions, from whats on print in
>http://s.eeweb.com/members/kvks_kumar/answers/1356585717-PPC440_UM2013.pdf(page
>272) iccci should be used once in the power-on / reset routine, and
>as far as flush_icache_range goes presumably before icbi is called?

I'm not understanding your question.

>So should not flush_icache_range go
>#ifdef CONFIG_44x
>iccci    0, r0
>#endif
>icbi    0,r6

The icbi isn't ever executed on 44x at all.

>arch/powerpc/kernel/misc32.S:
>/*
> * Write any modified data cache blocks out to memory
> * and invalidate the corresponding instruction cache blocks.
> * This is a no-op on the 601.
> *
> * flush_icache_range(unsigned long start, unsigned long stop)
> */
>_KPROBE(__flush_icache_range)
>BEGIN_FTR_SECTION
>    blr                /* for 601, do nothing */
>END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
>    li    r5,L1_CACHE_BYTES-1
>    andc    r3,r3,r5
>    subf    r4,r3,r4
>    add    r4,r4,r5
>    srwi.    r4,r4,L1_CACHE_SHIFT
>    beqlr
>    mtctr    r4
>    mr    r6,r3
>1:    dcbst    0,r3
>    addi    r3,r3,L1_CACHE_BYTES
>    bdnz    1b
>    sync                /* wait for dcbst's to get to ram */
>#ifndef CONFIG_44x

This part above is "if not defined CONFIG_44X", which means execute
everything below here until you hit #else if you are running on a
processor that isn't 4xx.

>    mtctr    r4
>2:    icbi    0,r6
>    addi    r6,r6,L1_CACHE_BYTES
>    bdnz    2b
>#else

Otherwise, use iccci.  Which is what you're sort of suggesting be done.

>    /* Flash invalidate on 44x because we are passed kmapped addresses and
>       this doesn't work for userspace pages due to the virtually tagged
>       icache.  Sigh. */
>    iccci    0, r0
>#endif

So.  I think the code is already doing what you think it should?

josh

^ permalink raw reply

* Re: PowerPC, P2020RDB, application debug when the application is in tight loop, Sysrq
From: Scott Wood @ 2013-05-01 19:54 UTC (permalink / raw)
  To: saikrishna gajula; +Cc: linuxppc-dev
In-Reply-To: <CAGstqXHrHWdiE=RvZ=1sV+=mPd9LiUZHL0gHPa89AVZRSND2Tg@mail.gmail.com>

On 04/17/2013 12:04:10 AM, saikrishna gajula wrote:
> HI All,
>=20
>              I am new to this group. I am working on Freescale P2020
> platform running linux 2.6.21.   I am looking for debug =20
> mechanism/utility,
> when a multi threaded application running on linux , appears to be =20
> hung (
> running in a tight loop,deadlock)  while not able to access the board
> through serial/SSH/Telnet.
>=20
>    I was looking at Magic sysrq option in linux to generate the stack,
> register dump when the application is hung. I am able to dump the call
> trace in normal working conditions. But i can't use  echo  t >
> /proc/sysrq-trigger and debug when the application hung.
>=20
>  I am using below piece of code(drivers/serial/8250.c) on P2020RDB to =20
> debug
> the application where in , in hung situation, when i press 'y'  =20
> followed by
> 't'  on serial console it should go to sysrq handler, and dump the =20
> call
> trace, but it is not happening.(simply board hung)
>=20
> {
>            if(sysrq_enable_flag)
>                   handle_sysrq(ch, up->port.info->tty);
>=20
>         sysrq_enable_flag =3D 0;
>=20
>         if(ch =3D=3D 'y')
>             sysrq_enable_flag =3D 1;
> }
>=20
> It would be helpful if you provide any hint on the issue, or any =20
> other way
> to debug the application in hang situations.

There's an erratum regarding breaks in Freescale's serial port =20
implementation that has been worked around in more recent kernels.  =20
2.6.21 is six years old.  If you update to a kernel that has the =20
workaround, or backport the workaround yourself to your old kernel, you =20
should be able to use a break instead of hacking in a check for 'y'.

Other than that, either the kernel is hung too badly to respond to =20
serial input at all (in which case use JTAG to debug) or there's =20
something wrong with your 'y' hack (sysrq_enable_flag doesn't even =20
appear in current kernels so I can't see if this is the case without =20
digging through old code).

In any case, upgrade to a newer kernel -- maybe you're hitting a bug =20
that has been fixed since then.

-Scott=

^ permalink raw reply

* Re: [PATCH] powerpc: Bring all threads online prior to migration/hibernation
From: Benjamin Herrenschmidt @ 2013-05-01 21:04 UTC (permalink / raw)
  To: Nathan Fontenot; +Cc: Robert Jennings, linuxppc-dev, stable
In-Reply-To: <51813403.50508@linux.vnet.ibm.com>

On Wed, 2013-05-01 at 10:25 -0500, Nathan Fontenot wrote:
> On 04/26/2013 04:32 PM, Robert Jennings wrote:
> > With this patch before a migration/hibernation all threads present but
> > not online will be brought online.  After migration/hibernation those
> > threads are taken back offline.
> > 
> > During migration/hibernation all online CPUs must call H_JOIN, this is
> > required by the hypervisor.  Without this patch, threads that are offline
> > (H_CEDE'd) will not be woken to make the H_JOIN call and the OS will be
> > deadlocked (all threads either JOIN'd or CEDE'd).
> > 
> 
> This fixes a long standing bug in partition migration.
> 
> Acked-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>

I was about to apply this one but had to take it out of my branch as it
breaks the UP build. Can you send a new revision of the patch ? It's a
bug fix, I'll put it in at -rc1.

Cheers,
Ben.

> > Cc: <stable@kernel.org>
> > Signed-off-by: Robert Jennings <rcj@linux.vnet.ibm.com>
> > ---
> >  arch/powerpc/include/asm/rtas.h          |    2 +
> >  arch/powerpc/kernel/rtas.c               |   95 ++++++++++++++++++++++++++++++
> >  arch/powerpc/platforms/pseries/suspend.c |   22 +++++++
> >  3 files changed, 119 insertions(+)
> > 
> > diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
> > index aef00c6..ee38f29 100644
> > --- a/arch/powerpc/include/asm/rtas.h
> > +++ b/arch/powerpc/include/asm/rtas.h
> > @@ -262,6 +262,8 @@ extern void rtas_progress(char *s, unsigned short hex);
> >  extern void rtas_initialize(void);
> >  extern int rtas_suspend_cpu(struct rtas_suspend_me_data *data);
> >  extern int rtas_suspend_last_cpu(struct rtas_suspend_me_data *data);
> > +extern int rtas_online_cpus_mask(cpumask_var_t cpus);
> > +extern int rtas_offline_cpus_mask(cpumask_var_t cpus);
> >  extern int rtas_ibm_suspend_me(struct rtas_args *);
> >  
> >  struct rtc_time;
> > diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
> > index 1fd6e7b..855ee98 100644
> > --- a/arch/powerpc/kernel/rtas.c
> > +++ b/arch/powerpc/kernel/rtas.c
> > @@ -19,6 +19,7 @@
> >  #include <linux/init.h>
> >  #include <linux/capability.h>
> >  #include <linux/delay.h>
> > +#include <linux/cpu.h>
> >  #include <linux/smp.h>
> >  #include <linux/completion.h>
> >  #include <linux/cpumask.h>
> > @@ -807,6 +808,77 @@ static void rtas_percpu_suspend_me(void *info)
> >  	__rtas_suspend_cpu((struct rtas_suspend_me_data *)info, 1);
> >  }
> >  
> > +enum rtas_cpu_state {
> > +	DOWN,
> > +	UP,
> > +};
> > +
> > +/* On return cpumask will be altered to indicate CPUs changed */
> > +static int rtas_cpu_state_change_mask(enum rtas_cpu_state state,
> > +				cpumask_var_t cpus)
> > +{
> > +	int cpu;
> > +	int cpuret = 0;
> > +	int ret = 0;
> > +
> > +	if (cpumask_empty(cpus))
> > +		return 0;
> > +
> > +	for_each_cpu(cpu, cpus) {
> > +		switch (state) {
> > +		case DOWN:
> > +			cpuret = cpu_down(cpu);
> > +			break;
> > +		case UP:
> > +			cpuret = cpu_up(cpu);
> > +			break;
> > +		}
> > +		if (cpuret) {
> > +			pr_debug("%s: cpu_%s for cpu#%d returned %d.\n",
> > +					__func__,
> > +					((state == UP) ? "up" : "down"),
> > +					cpu, cpuret);
> > +			if (!ret)
> > +				ret = cpuret;
> > +			if (state == UP) {
> > +				cpumask_shift_right(cpus, cpus, cpu);
> > +				cpumask_shift_left(cpus, cpus, cpu);
> > +				break;
> > +			} else
> > +				cpumask_clear_cpu(cpu, cpus);
> > +		}
> > +	}
> > +
> > +	return ret;
> > +}
> > +
> > +int rtas_online_cpus_mask(cpumask_var_t cpus)
> > +{
> > +	int ret;
> > +
> > +	ret = rtas_cpu_state_change_mask(UP, cpus);
> > +
> > +	if (ret) {
> > +		cpumask_var_t tmp_mask;
> > +
> > +		if (!alloc_cpumask_var(&tmp_mask, GFP_TEMPORARY))
> > +			return ret;
> > +
> > +		cpumask_copy(tmp_mask, cpus);
> > +		rtas_offline_cpus_mask(tmp_mask);
> > +		free_cpumask_var(tmp_mask);
> > +	}
> > +
> > +	return ret;
> > +}
> > +EXPORT_SYMBOL(rtas_online_cpus_mask);
> > +
> > +int rtas_offline_cpus_mask(cpumask_var_t cpus)
> > +{
> > +	return rtas_cpu_state_change_mask(DOWN, cpus);
> > +}
> > +EXPORT_SYMBOL(rtas_offline_cpus_mask);
> > +
> >  int rtas_ibm_suspend_me(struct rtas_args *args)
> >  {
> >  	long state;
> > @@ -814,6 +886,8 @@ int rtas_ibm_suspend_me(struct rtas_args *args)
> >  	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
> >  	struct rtas_suspend_me_data data;
> >  	DECLARE_COMPLETION_ONSTACK(done);
> > +	cpumask_var_t offline_mask;
> > +	int cpuret;
> >  
> >  	if (!rtas_service_present("ibm,suspend-me"))
> >  		return -ENOSYS;
> > @@ -837,11 +911,24 @@ int rtas_ibm_suspend_me(struct rtas_args *args)
> >  		return 0;
> >  	}
> >  
> > +	if (!alloc_cpumask_var(&offline_mask, GFP_TEMPORARY))
> > +		return -ENOMEM;
> > +
> >  	atomic_set(&data.working, 0);
> >  	atomic_set(&data.done, 0);
> >  	atomic_set(&data.error, 0);
> >  	data.token = rtas_token("ibm,suspend-me");
> >  	data.complete = &done;
> > +
> > +	/* All present CPUs must be online */
> > +	cpumask_andnot(offline_mask, cpu_present_mask, cpu_online_mask);
> > +	cpuret = rtas_online_cpus_mask(offline_mask);
> > +	if (cpuret) {
> > +		pr_err("%s: Could not bring present CPUs online.\n", __func__);
> > +		atomic_set(&data.error, cpuret);
> > +		goto out;
> > +	}
> > +
> >  	stop_topology_update();
> >  
> >  	/* Call function on all CPUs.  One of us will make the
> > @@ -857,6 +944,14 @@ int rtas_ibm_suspend_me(struct rtas_args *args)
> >  
> >  	start_topology_update();
> >  
> > +	/* Take down CPUs not online prior to suspend */
> > +	cpuret = rtas_offline_cpus_mask(offline_mask);
> > +	if (cpuret)
> > +		pr_warn("%s: Could not restore CPUs to offline state.\n",
> > +				__func__);
> > +
> > +out:
> > +	free_cpumask_var(offline_mask);
> >  	return atomic_read(&data.error);
> >  }
> >  #else /* CONFIG_PPC_PSERIES */
> > diff --git a/arch/powerpc/platforms/pseries/suspend.c b/arch/powerpc/platforms/pseries/suspend.c
> > index 47226e0..5f997e7 100644
> > --- a/arch/powerpc/platforms/pseries/suspend.c
> > +++ b/arch/powerpc/platforms/pseries/suspend.c
> > @@ -16,6 +16,7 @@
> >    * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
> >    */
> >  
> > +#include <linux/cpu.h>
> >  #include <linux/delay.h>
> >  #include <linux/suspend.h>
> >  #include <linux/stat.h>
> > @@ -126,11 +127,15 @@ static ssize_t store_hibernate(struct device *dev,
> >  			       struct device_attribute *attr,
> >  			       const char *buf, size_t count)
> >  {
> > +	cpumask_var_t offline_mask;
> >  	int rc;
> >  
> >  	if (!capable(CAP_SYS_ADMIN))
> >  		return -EPERM;
> >  
> > +	if (!alloc_cpumask_var(&offline_mask, GFP_TEMPORARY))
> > +		return -ENOMEM;
> > +
> >  	stream_id = simple_strtoul(buf, NULL, 16);
> >  
> >  	do {
> > @@ -140,15 +145,32 @@ static ssize_t store_hibernate(struct device *dev,
> >  	} while (rc == -EAGAIN);
> >  
> >  	if (!rc) {
> > +		/* All present CPUs must be online */
> > +		cpumask_andnot(offline_mask, cpu_present_mask,
> > +				cpu_online_mask);
> > +		rc = rtas_online_cpus_mask(offline_mask);
> > +		if (rc) {
> > +			pr_err("%s: Could not bring present CPUs online.\n",
> > +					__func__);
> > +			goto out;
> > +		}
> > +
> >  		stop_topology_update();
> >  		rc = pm_suspend(PM_SUSPEND_MEM);
> >  		start_topology_update();
> > +
> > +		/* Take down CPUs not online prior to suspend */
> > +		if (!rtas_offline_cpus_mask(offline_mask))
> > +			pr_warn("%s: Could not restore CPUs to offline "
> > +					"state.\n", __func__);
> >  	}
> >  
> >  	stream_id = 0;
> >  
> >  	if (!rc)
> >  		rc = count;
> > +out:
> > +	free_cpumask_var(offline_mask);
> >  	return rc;
> >  }
> >  
> 
> 

^ permalink raw reply

* Re: ppc/sata-fsl: orphan config value: CONFIG_MPC8315_DS
From: Anthony Foiani @ 2013-05-01 23:35 UTC (permalink / raw)
  To: Scott Wood
  Cc: Robert P.J.Day, linuxppc-dev@lists.ozlabs.org, Li Yang-R58472,
	Jeff Garzik, Adrian Bunk
In-Reply-To: <1367431525.29231.6@snotra>

Scott --

Thanks again for the quick reply.

On 05/01/2013 12:05 PM, Scott Wood wrote:
> On 04/30/2013 09:06:56 PM, Anthony Foiani wrote:
>> Instead of a new property name, I would instead check for my specific 
>> board type (let's call it a foo-8315) in the top-level compatible 
>> list?  So I'd change my devtree to have this top-level compatible:
>>
>> / {
>>     compatible = "example,foo-8315", "fsl,mpc8315erdb";
>
> It should really only have compatible = "example,foo-8315", since it's 
> not 100% compatible with fsl,mpc8315erdb (at least due to this bug, 
> but probably there are other differences as well).

Then I guess I don't understand the proper use of "compatible" (or is 
the root node special?)

E.g., the DTS for the "parent" board (MPC8315ERDB) has multiple entries 
for the crypto "compatible" value:

https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/powerpc/boot/dts/mpc8315erdb.dts?id=refs/tags/v3.9#n286
(or: *http://preview.tinyurl.com/btlqxgo* )

|		crypto@30000 {
			compatible = "fsl,sec3.3", "fsl,sec3.1", "fsl,sec3.0",
				     "fsl,sec2.4", "fsl,sec2.2", "fsl,sec2.1",
				     "fsl,sec2.0";
			reg = <0x30000 0x10000>;|

I read this as meaning: "if you have to ask if a certain feature is 
compatible with some 'foo', then this board provides that 
compatibility".  Not as "if a value is in the compatibility flag, then 
it is 100% compatible with that value".  (Although maybe that's true in 
the case of the SEC, so perhaps that a bad example.)

For what it's worth, the upstream vendor did have a separate root-node 
"compatible" value -- which called a board-specific function in a 
board-specific C file, both of which were direct cut & paste copies from 
the MPC8315ERDB function / file.  My gut instinct is that this degree of 
duplication is unhealthy and incorrect, but if my solution is considered 
abuse of the device tree, then I can try to do it a different way next 
time.

To clarify what I mean by "cut and paste", here are the differences 
between the 2.6.36 MPC8315ERDB dts, and the one the vendor sent us 
(based on that kernel rev):

$ diff -u arch/powerpc/boot/dts/mpc8315erdb.dts ~/foo.dts
[tony@hum linux-stable]$ --- arch/powerpc/boot/dts/mpc8315erdb.dts    
2013-05-01 17:23:36.803167646 -0600
+++ /home/tony/foo.dts    2013-05-01 17:18:55.009632505 -0600
@@ -1,4 +1,10 @@
  /*
+ * Foo 8315 Device Tree Source
+ *
+ * Copyright 2010 FooCorp
+ *
+ * Based on:
+ *
   * MPC8315E RDB Device Tree Source
   *
   * Copyright 2007 Freescale Semiconductor Inc.
@@ -12,7 +18,7 @@
  /dts-v1/;

  / {
-    compatible = "fsl,mpc8315erdb";
+    compatible = "fsl,foo-8315";
      #address-cells = <1>;
      #size-cells = <1>;

That's it.  And for the copy from mpc831x_rdb.c to foo8315.c?

--- mpc831x_rdb.c    2013-05-01 17:23:36.860167147 -0600
+++ foo8315.c    2013-05-01 17:27:04.310352475 -0600
@@ -1,5 +1,5 @@
  /*
- * arch/powerpc/platforms/83xx/mpc831x_rdb.c
+ * arch/powerpc/platforms/83xx/foo8315.c
   *
   * Description: MPC831x RDB board specific routines.
   * This file is based on mpc834x_sys.c
@@ -26,14 +26,14 @@
  /*
   * Setup the architecture
   */
-static void __init mpc831x_rdb_setup_arch(void)
+static void __init foo8315_setup_arch(void)
  {
  #ifdef CONFIG_PCI
      struct device_node *np;
  #endif

      if (ppc_md.progress)
-        ppc_md.progress("mpc831x_rdb_setup_arch()", 0);
+        ppc_md.progress("foo8315_setup_arch()", 0);

  #ifdef CONFIG_PCI
      for_each_compatible_node(np, "pci", "fsl,mpc8349-pci")
@@ -44,7 +44,7 @@
      mpc831x_usb_cfg();
  }

-static void __init mpc831x_rdb_init_IRQ(void)
+static void __init foo8315_init_IRQ(void)
  {
      struct device_node *np;

@@ -63,12 +63,12 @@
  /*
   * Called very early, MMU is off, device-tree isn't unflattened
   */
-static int __init mpc831x_rdb_probe(void)
+static int __init foo8315_probe(void)
  {
      unsigned long root = of_get_flat_dt_root();

      return of_flat_dt_is_compatible(root, "MPC8313ERDB") ||
-           of_flat_dt_is_compatible(root, "fsl,mpc8315erdb");
+           of_flat_dt_is_compatible(root, "fsl,foo8315");
  }

  static struct of_device_id __initdata of_bus_ids[] = {
@@ -83,13 +83,13 @@
      of_platform_bus_probe(NULL, of_bus_ids, NULL);
      return 0;
  }
-machine_device_initcall(mpc831x_rdb, declare_of_platform_devices);
+machine_device_initcall(foo8315, declare_of_platform_devices);

-define_machine(mpc831x_rdb) {
-    .name            = "MPC831x RDB",
-    .probe            = mpc831x_rdb_probe,
-    .setup_arch        = mpc831x_rdb_setup_arch,
-    .init_IRQ        = mpc831x_rdb_init_IRQ,
+define_machine(foo8315) {
+    .name            = "foo-8315",
+    .probe            = foo8315_probe,
+    .setup_arch        = foo8315_setup_arch,
+    .init_IRQ        = foo8315_init_IRQ,
      .get_irq        = ipic_get_irq,
      .restart        = mpc83xx_restart,
      .time_init        = mpc83xx_time_init,

Given those diffs, it didn't seem much of a stretch to use compatible = 
"fsl,mpc8315erdb"

> Well, if this is only seen on your board so far (or rather, your 
> vendor's board which isn't upstream), and you're OK with updating the 
> device tree, then I have no objection.
Well, so far as I know, this project is the only consumer of these 
boards.  I've fed all my fixes/changes back to our vendor, but they're 
not interested in upstreaming it.

I have been trying to at least get the patches into the public arena, 
but I don't have the bandwidth to move to tip-of-tree and do testing 
there, as well as moving project along the actual release path (which is 
based on long-term releases, hence my patch being against 3.4.y).

For my use, this is a good compromise: I've documented the errata (even 
if we don't know the root cause), and it is now set up so that I can't 
lose the setting just by doing a config update (which was the problem 
with the orphan config setting).

> > It would also be nice if we could unravel exactly why that 
> CONFIG_8315_DS ever showed up in the first place.
>
> It would be nice, but I doubt that particular information is ever 
> going to surface...  IIRC I asked internally back when this first came 
> up, and didn't get an answer.
Right, that's my recollection as well.

I end up feeling a bit put-upon, though, when I'm asked for a 
comprehensive patch to cover something that the original authors can't 
explain.

>
>>> Or do you mean that you would not set this on any board's device 
>>> tree by default, and instead have users set it if they encounter 
>>> problems?
>>
>> No, I would expect to set it on all the boards, so using the 
>> compatibility hack above would work.
>
> You mean all the boards that have the bug, which doesn't include any 
> upstream device tree, right?
As mentioned above, my primary concern is the use of these cards in the 
project/product I'm working on.  My answer has been to apply this fix 
(and the matching change to the device tree I supply as a part of the 
boot image).  I feel that I'm trying to do the right thing by getting 
some of these changes publicly visible, but I fear that I'll also have 
to go down the route of "not enough time or money to properly upstream it".

"doesn't include upstream device tree" ... no, the device tree was 
supplied with the original set of patches from the vendor.

And it seems like it's a bit of a corner case -- even on other MPC8315 
boards, it seems that only 2-3 of us have ever run into this.  Maybe not 
many people use the SATA features, or they use them with older/slower 
drives that never try to negotiate above 1.5Gbps (given that it's a 6yo 
design or so).

Anyway.  Thanks for all the feedback, but at this point, I'm going to go 
with the patch I already supplied.  Hopefully it will make someone 
else's life easier at some later date.

Thanks again!

Take care,
Anthony

^ permalink raw reply

* Re: ppc/sata-fsl: orphan config value: CONFIG_MPC8315_DS
From: Scott Wood @ 2013-05-02  0:13 UTC (permalink / raw)
  To: Anthony Foiani
  Cc: Robert P.J.Day, linuxppc-dev@lists.ozlabs.org, Li Yang-R58472,
	Jeff Garzik, Adrian Bunk
In-Reply-To: <5181A6CA.9090903@scrye.com>

On 05/01/2013 06:35:38 PM, Anthony Foiani wrote:
> Scott --
>=20
> Thanks again for the quick reply.
>=20
> On 05/01/2013 12:05 PM, Scott Wood wrote:
>> On 04/30/2013 09:06:56 PM, Anthony Foiani wrote:
>>> Instead of a new property name, I would instead check for my =20
>>> specific board type (let's call it a foo-8315) in the top-level =20
>>> compatible list?  So I'd change my devtree to have this top-level =20
>>> compatible:
>>>=20
>>> / {
>>>     compatible =3D "example,foo-8315", "fsl,mpc8315erdb";
>>=20
>> It should really only have compatible =3D "example,foo-8315", since =20
>> it's not 100% compatible with fsl,mpc8315erdb (at least due to this =20
>> bug, but probably there are other differences as well).
>=20
> Then I guess I don't understand the proper use of "compatible" (or is =20
> the root node special?)

It's only special in that 100% compatibility is much less likely to be =20
true of an entire system than of a particular component.

> E.g., the DTS for the "parent" board (MPC8315ERDB) has multiple =20
> entries for the crypto "compatible" value:
>=20
> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch=
/powerpc/boot/dts/mpc8315erdb.dts?id=3Drefs/tags/v3.9#n286
> (or: *http://preview.tinyurl.com/btlqxgo* )
>=20
> |		crypto@30000 {
> 			compatible =3D "fsl,sec3.3", "fsl,sec3.1", =20
> "fsl,sec3.0",
> 				     "fsl,sec2.4", "fsl,sec2.2", =20
> "fsl,sec2.1",
> 				     "fsl,sec2.0";
> 			reg =3D <0x30000 0x10000>;|
>=20
> I read this as meaning: "if you have to ask if a certain feature is =20
> compatible with some 'foo', then this board provides that =20
> compatibility".  Not as "if a value is in the compatibility flag, =20
> then it is 100% compatible with that value".  (Although maybe that's =20
> true in the case of the SEC, so perhaps that a bad example.)

AFAIK there is backwards compatibility with these SEC versions.  If =20
not, they shouldn't be listed.

> For what it's worth, the upstream vendor did have a separate =20
> root-node "compatible" value -- which called a board-specific =20
> function in a board-specific C file, both of which were direct cut & =20
> paste copies from the MPC8315ERDB function / file.  My gut instinct =20
> is that this degree of duplication is unhealthy and incorrect, but if =20
> my solution is considered abuse of the device tree, then I can try to =20
> do it a different way next time.

It's quite possible to use the same C file for multiple similar boards =20
with different compatibles.  This is done often, including =20
mpc831x_erdb.c.

> Given those diffs, it didn't seem much of a stretch to use compatible =20
> =3D "fsl,mpc8315erdb"

The criteria for claiming compatibility should be based in the hardware =20
itself, not whether a particular file in Linux needs any changes.

>>>> Or do you mean that you would not set this on any board's device =20
>>>> tree by default, and instead have users set it if they encounter =20
>>>> problems?
>>>=20
>>> No, I would expect to set it on all the boards, so using the =20
>>> compatibility hack above would work.
>>=20
>> You mean all the boards that have the bug, which doesn't include any =20
>> upstream device tree, right?
> As mentioned above, my primary concern is the use of these cards in =20
> the project/product I'm working on.  My answer has been to apply this =20
> fix (and the matching change to the device tree I supply as a part of =20
> the boot image).  I feel that I'm trying to do the right thing by =20
> getting some of these changes publicly visible, but I fear that I'll =20
> also have to go down the route of "not enough time or money to =20
> properly upstream it".
>=20
> "doesn't include upstream device tree" ... no, the device tree was =20
> supplied with the original set of patches from the vendor.

I'm not saying that the device tree not being upstream is a problem -- =20
actually the opposite, that it means we don't have compatibility to =20
maintain with an already-accepted device tree.

-Scott=

^ permalink raw reply

* Re: [PATCH] powerpc: Bring all threads online prior to migration/hibernation
From: Robert Jennings @ 2013-05-02  0:39 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Nathan Fontenot, linuxppc-dev, stable
In-Reply-To: <1367442296.22115.48.camel@pasglop>

* Benjamin Herrenschmidt (benh@kernel.crashing.org) wrote:
> On Wed, 2013-05-01 at 10:25 -0500, Nathan Fontenot wrote:
> > On 04/26/2013 04:32 PM, Robert Jennings wrote:
> > > With this patch before a migration/hibernation all threads present but
> > > not online will be brought online.  After migration/hibernation those
> > > threads are taken back offline.
> > > 
> > > During migration/hibernation all online CPUs must call H_JOIN, this is
> > > required by the hypervisor.  Without this patch, threads that are offline
> > > (H_CEDE'd) will not be woken to make the H_JOIN call and the OS will be
> > > deadlocked (all threads either JOIN'd or CEDE'd).
> > > 
> > 
> > This fixes a long standing bug in partition migration.
> > 
> > Acked-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
> 
> I was about to apply this one but had to take it out of my branch as it
> breaks the UP build. Can you send a new revision of the patch ? It's a
> bug fix, I'll put it in at -rc1.

Yes, sorry.  I'll get you a fix for the -rc1 timeframe for sure.

> Cheers,
> Ben.
> 
> > > Cc: <stable@kernel.org>
> > > Signed-off-by: Robert Jennings <rcj@linux.vnet.ibm.com>
> > > ---
> > >  arch/powerpc/include/asm/rtas.h          |    2 +
> > >  arch/powerpc/kernel/rtas.c               |   95 ++++++++++++++++++++++++++++++
> > >  arch/powerpc/platforms/pseries/suspend.c |   22 +++++++
> > >  3 files changed, 119 insertions(+)
> > > 
> > > diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
> > > index aef00c6..ee38f29 100644
> > > --- a/arch/powerpc/include/asm/rtas.h
> > > +++ b/arch/powerpc/include/asm/rtas.h
> > > @@ -262,6 +262,8 @@ extern void rtas_progress(char *s, unsigned short hex);
> > >  extern void rtas_initialize(void);
> > >  extern int rtas_suspend_cpu(struct rtas_suspend_me_data *data);
> > >  extern int rtas_suspend_last_cpu(struct rtas_suspend_me_data *data);
> > > +extern int rtas_online_cpus_mask(cpumask_var_t cpus);
> > > +extern int rtas_offline_cpus_mask(cpumask_var_t cpus);
> > >  extern int rtas_ibm_suspend_me(struct rtas_args *);
> > >  
> > >  struct rtc_time;
> > > diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
> > > index 1fd6e7b..855ee98 100644
> > > --- a/arch/powerpc/kernel/rtas.c
> > > +++ b/arch/powerpc/kernel/rtas.c
> > > @@ -19,6 +19,7 @@
> > >  #include <linux/init.h>
> > >  #include <linux/capability.h>
> > >  #include <linux/delay.h>
> > > +#include <linux/cpu.h>
> > >  #include <linux/smp.h>
> > >  #include <linux/completion.h>
> > >  #include <linux/cpumask.h>
> > > @@ -807,6 +808,77 @@ static void rtas_percpu_suspend_me(void *info)
> > >  	__rtas_suspend_cpu((struct rtas_suspend_me_data *)info, 1);
> > >  }
> > >  
> > > +enum rtas_cpu_state {
> > > +	DOWN,
> > > +	UP,
> > > +};
> > > +
> > > +/* On return cpumask will be altered to indicate CPUs changed */
> > > +static int rtas_cpu_state_change_mask(enum rtas_cpu_state state,
> > > +				cpumask_var_t cpus)
> > > +{
> > > +	int cpu;
> > > +	int cpuret = 0;
> > > +	int ret = 0;
> > > +
> > > +	if (cpumask_empty(cpus))
> > > +		return 0;
> > > +
> > > +	for_each_cpu(cpu, cpus) {
> > > +		switch (state) {
> > > +		case DOWN:
> > > +			cpuret = cpu_down(cpu);
> > > +			break;
> > > +		case UP:
> > > +			cpuret = cpu_up(cpu);
> > > +			break;
> > > +		}
> > > +		if (cpuret) {
> > > +			pr_debug("%s: cpu_%s for cpu#%d returned %d.\n",
> > > +					__func__,
> > > +					((state == UP) ? "up" : "down"),
> > > +					cpu, cpuret);
> > > +			if (!ret)
> > > +				ret = cpuret;
> > > +			if (state == UP) {
> > > +				cpumask_shift_right(cpus, cpus, cpu);
> > > +				cpumask_shift_left(cpus, cpus, cpu);
> > > +				break;
> > > +			} else
> > > +				cpumask_clear_cpu(cpu, cpus);
> > > +		}
> > > +	}
> > > +
> > > +	return ret;
> > > +}
> > > +
> > > +int rtas_online_cpus_mask(cpumask_var_t cpus)
> > > +{
> > > +	int ret;
> > > +
> > > +	ret = rtas_cpu_state_change_mask(UP, cpus);
> > > +
> > > +	if (ret) {
> > > +		cpumask_var_t tmp_mask;
> > > +
> > > +		if (!alloc_cpumask_var(&tmp_mask, GFP_TEMPORARY))
> > > +			return ret;
> > > +
> > > +		cpumask_copy(tmp_mask, cpus);
> > > +		rtas_offline_cpus_mask(tmp_mask);
> > > +		free_cpumask_var(tmp_mask);
> > > +	}
> > > +
> > > +	return ret;
> > > +}
> > > +EXPORT_SYMBOL(rtas_online_cpus_mask);
> > > +
> > > +int rtas_offline_cpus_mask(cpumask_var_t cpus)
> > > +{
> > > +	return rtas_cpu_state_change_mask(DOWN, cpus);
> > > +}
> > > +EXPORT_SYMBOL(rtas_offline_cpus_mask);
> > > +
> > >  int rtas_ibm_suspend_me(struct rtas_args *args)
> > >  {
> > >  	long state;
> > > @@ -814,6 +886,8 @@ int rtas_ibm_suspend_me(struct rtas_args *args)
> > >  	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
> > >  	struct rtas_suspend_me_data data;
> > >  	DECLARE_COMPLETION_ONSTACK(done);
> > > +	cpumask_var_t offline_mask;
> > > +	int cpuret;
> > >  
> > >  	if (!rtas_service_present("ibm,suspend-me"))
> > >  		return -ENOSYS;
> > > @@ -837,11 +911,24 @@ int rtas_ibm_suspend_me(struct rtas_args *args)
> > >  		return 0;
> > >  	}
> > >  
> > > +	if (!alloc_cpumask_var(&offline_mask, GFP_TEMPORARY))
> > > +		return -ENOMEM;
> > > +
> > >  	atomic_set(&data.working, 0);
> > >  	atomic_set(&data.done, 0);
> > >  	atomic_set(&data.error, 0);
> > >  	data.token = rtas_token("ibm,suspend-me");
> > >  	data.complete = &done;
> > > +
> > > +	/* All present CPUs must be online */
> > > +	cpumask_andnot(offline_mask, cpu_present_mask, cpu_online_mask);
> > > +	cpuret = rtas_online_cpus_mask(offline_mask);
> > > +	if (cpuret) {
> > > +		pr_err("%s: Could not bring present CPUs online.\n", __func__);
> > > +		atomic_set(&data.error, cpuret);
> > > +		goto out;
> > > +	}
> > > +
> > >  	stop_topology_update();
> > >  
> > >  	/* Call function on all CPUs.  One of us will make the
> > > @@ -857,6 +944,14 @@ int rtas_ibm_suspend_me(struct rtas_args *args)
> > >  
> > >  	start_topology_update();
> > >  
> > > +	/* Take down CPUs not online prior to suspend */
> > > +	cpuret = rtas_offline_cpus_mask(offline_mask);
> > > +	if (cpuret)
> > > +		pr_warn("%s: Could not restore CPUs to offline state.\n",
> > > +				__func__);
> > > +
> > > +out:
> > > +	free_cpumask_var(offline_mask);
> > >  	return atomic_read(&data.error);
> > >  }
> > >  #else /* CONFIG_PPC_PSERIES */
> > > diff --git a/arch/powerpc/platforms/pseries/suspend.c b/arch/powerpc/platforms/pseries/suspend.c
> > > index 47226e0..5f997e7 100644
> > > --- a/arch/powerpc/platforms/pseries/suspend.c
> > > +++ b/arch/powerpc/platforms/pseries/suspend.c
> > > @@ -16,6 +16,7 @@
> > >    * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
> > >    */
> > >  
> > > +#include <linux/cpu.h>
> > >  #include <linux/delay.h>
> > >  #include <linux/suspend.h>
> > >  #include <linux/stat.h>
> > > @@ -126,11 +127,15 @@ static ssize_t store_hibernate(struct device *dev,
> > >  			       struct device_attribute *attr,
> > >  			       const char *buf, size_t count)
> > >  {
> > > +	cpumask_var_t offline_mask;
> > >  	int rc;
> > >  
> > >  	if (!capable(CAP_SYS_ADMIN))
> > >  		return -EPERM;
> > >  
> > > +	if (!alloc_cpumask_var(&offline_mask, GFP_TEMPORARY))
> > > +		return -ENOMEM;
> > > +
> > >  	stream_id = simple_strtoul(buf, NULL, 16);
> > >  
> > >  	do {
> > > @@ -140,15 +145,32 @@ static ssize_t store_hibernate(struct device *dev,
> > >  	} while (rc == -EAGAIN);
> > >  
> > >  	if (!rc) {
> > > +		/* All present CPUs must be online */
> > > +		cpumask_andnot(offline_mask, cpu_present_mask,
> > > +				cpu_online_mask);
> > > +		rc = rtas_online_cpus_mask(offline_mask);
> > > +		if (rc) {
> > > +			pr_err("%s: Could not bring present CPUs online.\n",
> > > +					__func__);
> > > +			goto out;
> > > +		}
> > > +
> > >  		stop_topology_update();
> > >  		rc = pm_suspend(PM_SUSPEND_MEM);
> > >  		start_topology_update();
> > > +
> > > +		/* Take down CPUs not online prior to suspend */
> > > +		if (!rtas_offline_cpus_mask(offline_mask))
> > > +			pr_warn("%s: Could not restore CPUs to offline "
> > > +					"state.\n", __func__);
> > >  	}
> > >  
> > >  	stream_id = 0;
> > >  
> > >  	if (!rc)
> > >  		rc = count;
> > > +out:
> > > +	free_cpumask_var(offline_mask);
> > >  	return rc;
> > >  }
> > >  
> > 
> > 
> 
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
> 

^ permalink raw reply

* net/eth/ibmveth: Fixup retrieval of MAC address
From: Benjamin Herrenschmidt @ 2013-05-02  1:35 UTC (permalink / raw)
  To: netdev; +Cc: linuxppc-dev, David Miller, David Gibson

Some ancient pHyp versions used to create a 8 bytes local-mac-address
property in the device-tree instead of a 6 bytes one for veth.

The Linux driver code to deal with that is an insane hack which also
happens to break with some choices of MAC addresses in qemu by testing
for a bit in the address rather than just looking at the size of the
property.

Sanitize this by doing the latter instead.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: <stable@vger.kernel.org>
---

I CC'ed stable bcs I'd like to switch qemu/kvm to 6-bytes properties as
soon as possible. Unfortunately doing so breaks the horrible hack unless
qemu has the right magic bit in the MAC which it may or may not have...

diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
index c859771..579a03e 100644
--- a/drivers/net/ethernet/ibm/ibmveth.c
+++ b/drivers/net/ethernet/ibm/ibmveth.c
@@ -1324,7 +1324,7 @@ static const struct net_device_ops ibmveth_netdev_ops = {
 
 static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
 {
-	int rc, i;
+	int rc, i, mac_len;
 	struct net_device *netdev;
 	struct ibmveth_adapter *adapter;
 	unsigned char *mac_addr_p;
@@ -1334,11 +1334,19 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
 		dev->unit_address);
 
 	mac_addr_p = (unsigned char *)vio_get_attribute(dev, VETH_MAC_ADDR,
-							NULL);
+							&mac_len);
 	if (!mac_addr_p) {
 		dev_err(&dev->dev, "Can't find VETH_MAC_ADDR attribute\n");
 		return -EINVAL;
 	}
+	/* Workaround for old/broken pHyp */
+	if (mac_len == 8)
+		mac_addr_p += 2;
+	if (mac_len != 6) {
+		dev_err(&dev->dev, "VETH_MAC_ADDR attribute wrong len %d\n",
+			mac_len);
+		return -EINVAL;
+	}
 
 	mcastFilterSize_p = (unsigned int *)vio_get_attribute(dev,
 						VETH_MCAST_FILTER_SIZE, NULL);
@@ -1363,17 +1371,6 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
 
 	netif_napi_add(netdev, &adapter->napi, ibmveth_poll, 16);
 
-	/*
-	 * Some older boxes running PHYP non-natively have an OF that returns
-	 * a 8-byte local-mac-address field (and the first 2 bytes have to be
-	 * ignored) while newer boxes' OF return a 6-byte field. Note that
-	 * IEEE 1275 specifies that local-mac-address must be a 6-byte field.
-	 * The RPA doc specifies that the first byte must be 10b, so we'll
-	 * just look for it to solve this 8 vs. 6 byte field issue
-	 */
-	if ((*mac_addr_p & 0x3) != 0x02)
-		mac_addr_p += 2;
-
 	adapter->mac_addr = 0;
 	memcpy(&adapter->mac_addr, mac_addr_p, 6);
 

^ permalink raw reply related

* [PATCH -next] kvm/ppc/mpic: fix missing unlock in set_base_addr()
From: Wei Yongjun @ 2013-05-02  5:17 UTC (permalink / raw)
  To: mtosatti, gleb, agraf, benh, paulus, scottwood
  Cc: yongjun_wei, linuxppc-dev, kvm-ppc, kvm

From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>

Add the missing unlock before return from function set_base_addr()
when disables the mapping.

Introduced by commit 5df554ad5b7522ea62b0ff9d5be35183494efc21
(kvm/ppc/mpic: in-kernel MPIC emulation)

Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
---
 arch/powerpc/kvm/mpic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c
index f3148f8..0047a70 100644
--- a/arch/powerpc/kvm/mpic.c
+++ b/arch/powerpc/kvm/mpic.c
@@ -1475,8 +1475,8 @@ static int set_base_addr(struct openpic *opp, struct kvm_device_attr *attr)
 
 	map_mmio(opp);
 
-	mutex_unlock(&opp->kvm->slots_lock);
 out:
+	mutex_unlock(&opp->kvm->slots_lock);
 	return 0;
 }
 

^ permalink raw reply related

* Re: [PATCH -V7 18/18] powerpc: Update tlbie/tlbiel as per ISA doc
From: David Gibson @ 2013-05-02  5:23 UTC (permalink / raw)
  To: Aneesh Kumar K.V; +Cc: paulus, linuxppc-dev, linux-mm
In-Reply-To: <87hain9m5e.fsf@linux.vnet.ibm.com>

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

On Wed, May 01, 2013 at 01:17:41PM +0530, Aneesh Kumar K.V wrote:
> David Gibson <dwg@au1.ibm.com> writes:
> 
> > On Tue, Apr 30, 2013 at 10:51:00PM +0530, Aneesh Kumar K.V wrote:
> >> David Gibson <dwg@au1.ibm.com> writes:
> >> 
> >> > On Mon, Apr 29, 2013 at 01:07:39AM +0530, Aneesh Kumar K.V wrote:
> >> >> From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
> >> >> 
> >> >> Encode the actual page correctly in tlbie/tlbiel. This make sure we handle
> >> >> multiple page size segment correctly.
> >> >
> >> > As mentioned in previous comments, this commit message needs to give
> >> > much more detail about what precisely the existing implementation is
> >> > doing wrong.
> >> >
> >> >> 
> >> >> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
> >> >> ---
> >> >>  arch/powerpc/mm/hash_native_64.c | 32 ++++++++++++++++++++++++++++++--
> >> >>  1 file changed, 30 insertions(+), 2 deletions(-)
> >> >> 
> >> >> diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
> >> >> index bb920ee..6a2aead 100644
> >> >> --- a/arch/powerpc/mm/hash_native_64.c
> >> >> +++ b/arch/powerpc/mm/hash_native_64.c
> >> >> @@ -61,7 +61,10 @@ static inline void __tlbie(unsigned long vpn, int psize, int apsize, int ssize)
> >> >>  
> >> >>  	switch (psize) {
> >> >>  	case MMU_PAGE_4K:
> >> >> +		/* clear out bits after (52) [0....52.....63] */
> >> >> +		va &= ~((1ul << (64 - 52)) - 1);
> >> >>  		va |= ssize << 8;
> >> >> +		va |= mmu_psize_defs[apsize].sllp << 6;
> >> >>  		asm volatile(ASM_FTR_IFCLR("tlbie %0,0", PPC_TLBIE(%1,%0), %2)
> >> >>  			     : : "r" (va), "r"(0), "i" (CPU_FTR_ARCH_206)
> >> >>  			     : "memory");
> >> >> @@ -69,9 +72,20 @@ static inline void __tlbie(unsigned long vpn, int psize, int apsize, int ssize)
> >> >>  	default:
> >> >>  		/* We need 14 to 14 + i bits of va */
> >> >>  		penc = mmu_psize_defs[psize].penc[apsize];
> >> >> -		va &= ~((1ul << mmu_psize_defs[psize].shift) - 1);
> >> >> +		va &= ~((1ul << mmu_psize_defs[apsize].shift) - 1);
> >> >>  		va |= penc << 12;
> >> >>  		va |= ssize << 8;
> >> >> +		/* Add AVAL part */
> >> >> +		if (psize != apsize) {
> >> >> +			/*
> >> >> +			 * MPSS, 64K base page size and 16MB parge page size
> >> >> +			 * We don't need all the bits, but rest of the bits
> >> >> +			 * must be ignored by the processor.
> >> >> +			 * vpn cover upto 65 bits of va. (0...65) and we need
> >> >> +			 * 58..64 bits of va.
> >> >
> >> > I can't understand what this comment is saying.  Why do we need to do
> >> > something different in the psize != apsize case?
> >> >
> >> >> +			 */
> >> >> +			va |= (vpn & 0xfe);
> >> >> +		}
> >> 
> >> That is as per ISA doc. It says if base page size == actual page size,
> >> (RB)56:62 must be zeros, which must be ignored by the processor.
> >> Otherwise it should be filled with the selected bits of VA as explained above.
> >
> > What you've just said here makes much more sense than what's written
> > in the comment in the code.
> >
> >> We only support MPSS with base page size = 64K and actual page size = 16MB.
> >
> > Is that actually relevant to this code though?
> 
> In a way yes. The number of bits we we select out of VA depends on the
> base page size and actual page size. We have a math around that
> documented in ISA. Now since we support only 64K and 16MB we can make it
> simpler by only selecting required bits and not making it a
> function. But then it is also not relevant to the code in that ISA also
> state other bits in (RB)56:62 must be zero. I wanted to capture both the
> details in the comment. 

Urgh, so the code assumings just that combination, but has no
assertion or check that its actually the case.  Very fragile.

Even though we don't do other MPSS combinations yet, I'd much prefer
to see the tlbie code get the encoding correct in all cases.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply

* [PATCH] powerpc: Emulate non privileged DSCR read and write
From: Anton Blanchard @ 2013-05-02  6:06 UTC (permalink / raw)
  To: benh, paulus; +Cc: linuxppc-dev


POWER8 allows read and write of the DSCR in userspace. We added
kernel emulation so applications could always use the instructions
regardless of the CPU type. 

Unfortunately there are two SPRs for the DSCR and we only added
emulation for the privileged one. Add code to match the non
privileged one.

A simple test was created to verify the fix:

http://ozlabs.org/~anton/junkcode/user_dscr_test.c

Without the patch we get a SIGILL and it passes with the patch.

Signed-off-by: Anton Blanchard <anton@samba.org>
Cc: <stable@kernel.org>
---

Index: b/arch/powerpc/include/asm/ppc-opcode.h
===================================================================
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -115,6 +115,10 @@
 #define PPC_INST_MFSPR_DSCR_MASK	0xfc1fffff
 #define PPC_INST_MTSPR_DSCR		0x7c1103a6
 #define PPC_INST_MTSPR_DSCR_MASK	0xfc1fffff
+#define PPC_INST_MFSPR_DSCR_USER	0x7c0302a6
+#define PPC_INST_MFSPR_DSCR_USER_MASK	0xfc1fffff
+#define PPC_INST_MTSPR_DSCR_USER	0x7c0303a6
+#define PPC_INST_MTSPR_DSCR_USER_MASK	0xfc1fffff
 #define PPC_INST_SLBFEE			0x7c0007a7
 
 #define PPC_INST_STRING			0x7c00042a
Index: b/arch/powerpc/kernel/traps.c
===================================================================
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -970,7 +970,10 @@ static int emulate_instruction(struct pt
 
 #ifdef CONFIG_PPC64
 	/* Emulate the mfspr rD, DSCR. */
-	if (((instword & PPC_INST_MFSPR_DSCR_MASK) == PPC_INST_MFSPR_DSCR) &&
+	if ((((instword & PPC_INST_MFSPR_DSCR_USER_MASK) ==
+		PPC_INST_MFSPR_DSCR_USER) ||
+	     ((instword & PPC_INST_MFSPR_DSCR_MASK) ==
+		PPC_INST_MFSPR_DSCR)) &&
 			cpu_has_feature(CPU_FTR_DSCR)) {
 		PPC_WARN_EMULATED(mfdscr, regs);
 		rd = (instword >> 21) & 0x1f;
@@ -978,7 +981,10 @@ static int emulate_instruction(struct pt
 		return 0;
 	}
 	/* Emulate the mtspr DSCR, rD. */
-	if (((instword & PPC_INST_MTSPR_DSCR_MASK) == PPC_INST_MTSPR_DSCR) &&
+	if ((((instword & PPC_INST_MTSPR_DSCR_USER_MASK) ==
+		PPC_INST_MTSPR_DSCR_USER) ||
+	     ((instword & PPC_INST_MTSPR_DSCR_MASK) ==
+		PPC_INST_MTSPR_DSCR)) &&
 			cpu_has_feature(CPU_FTR_DSCR)) {
 		PPC_WARN_EMULATED(mtdscr, regs);
 		rd = (instword >> 21) & 0x1f;

^ permalink raw reply

* Re: ppc/sata-fsl: orphan config value: CONFIG_MPC8315_DS
From: Anthony Foiani @ 2013-05-02  6:37 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: Li Yang-R58472, Jeff Garzik, Adrian Bunk, Anthony Foiani,
	Scott Wood, Robert P.J.Day, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <5180392D.1000103@pobox.com>


Jeff --

Thanks for the quick reply -- sorry that it took me a few days to get
back to you.

[Also, apologies if anyone gets a dupe -- I'm working on a new mail
configuration, and while I did test it, something went sideways the
first time I tried to send this.]

Jeff Garzik writes:
> Regarding this patch:  Search for "sata_spd_limit" and xxx_spd* functions

Ok, I see them, but it's not entirely clear how I'm supposed to use
them.

I think that maybe I want to set hw_sata_spd_limit in each port's link
in the ata_host structure, after ata_host_alloc_pinfo, but before
ata_host_activate.

Something like the patch at the end of this message?  It seems to have
correctly set the spd_ values, but the negotiated link speed is still
too high:

  # cd /sys/devices/e0000000.immr/e0019000.sata

  # find * -name '*_spd*' -print | xargs grep .
  ata2/link2/ata_link/link2/sata_spd:3.0 Gbps
  ata2/link2/ata_link/link2/hw_sata_spd_limit:1.5 Gbps
  ata2/link2/ata_link/link2/sata_spd_limit:1.5 Gbps

Or am I misinterpreting those values?

Maybe I need to call ata_set_sata_spd as well.  Can I do that before
discovery, or should it be a part of the port_start callback?  And if
the latter, shouldn't it be handled within the ata core, instead of
expecting each host driver to do that call?

With my original patch, I see the correct (throttled-down) value for
"sata_spd":

  # cd /sys/devices/e0000000.immr/e0019000.sata

  # find . -name '*_spd*' -print | xargs grep .
  ./ata2/link2/ata_link/link2/sata_spd:1.5 Gbps
  ./ata2/link2/ata_link/link2/hw_sata_spd_limit:1.5 Gbps
  ./ata2/link2/ata_link/link2/sata_spd_limit:1.5 Gbps

Thanks for any pointers.  Patch below.

Thanks again,
Anthony Foiani

(Pardon the extra context, but it seemed the easiest way to show how
this call slotted in between the alloc and the init.)

diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
index d6577b9..bd24445 100644
--- a/drivers/ata/sata_fsl.c
+++ b/drivers/ata/sata_fsl.c
@@ -714,44 +714,30 @@ static int sata_fsl_port_start(struct ata_port *ap)
 	/*
 	 * Now, we can bring the controller on-line & also initiate
 	 * the COMINIT sequence, we simply return here and the boot-probing
 	 * & device discovery process is re-initiated by libATA using a
 	 * Softreset EH (dummy) session. Hence, boot probing and device
 	 * discovey will be part of sata_fsl_softreset() callback.
 	 */
 
 	temp = ioread32(hcr_base + HCONTROL);
 	iowrite32((temp | HCONTROL_ONLINE_PHY_RST), hcr_base + HCONTROL);
 
 	VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
 	VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
 	VPRINTK("CHBA  = 0x%x\n", ioread32(hcr_base + CHBA));
 
-#ifdef CONFIG_MPC8315_DS
-	/*
-	 * Workaround for 8315DS board 3gbps link-up issue,
-	 * currently limit SATA port to GEN1 speed
-	 */
-	sata_fsl_scr_read(&ap->link, SCR_CONTROL, &temp);
-	temp &= ~(0xF << 4);
-	temp |= (0x1 << 4);
-	sata_fsl_scr_write(&ap->link, SCR_CONTROL, temp);
-
-	sata_fsl_scr_read(&ap->link, SCR_CONTROL, &temp);
-	dev_warn(dev, "scr_control, speed limited to %x\n", temp);
-#endif
-
 	return 0;
 }
 
 static void sata_fsl_port_stop(struct ata_port *ap)
 {
 	struct device *dev = ap->host->dev;
 	struct sata_fsl_port_priv *pp = ap->private_data;
 	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
 	void __iomem *hcr_base = host_priv->hcr_base;
 	u32 temp;
 
 	/*
 	 * Force host controller to go off-line, aborting current operations
 	 */
 	temp = ioread32(hcr_base + HCONTROL);
@@ -1432,30 +1418,39 @@ static int sata_fsl_probe(struct platform_device *ofdev)
 	}
 	host_priv->irq = irq;
 
 	if (of_device_is_compatible(ofdev->dev.of_node, "fsl,pq-sata-v2"))
 		host_priv->data_snoop = DATA_SNOOP_ENABLE_V2;
 	else
 		host_priv->data_snoop = DATA_SNOOP_ENABLE_V1;
 
 	/* allocate host structure */
 	host = ata_host_alloc_pinfo(&ofdev->dev, ppi, SATA_FSL_MAX_PORTS);
 	if (!host) {
 		retval = -ENOMEM;
 		goto error_exit_with_cleanup;
 	}
 
+	/* set speed limit if requested by device tree */
+	if (!of_property_read_u32(ofdev->dev.of_node, "sata-spd-limit",
+				  &temp)) {
+		int i;
+		for (i = 0; i < SATA_FSL_MAX_PORTS; ++i)
+			host->ports[i]->link.hw_sata_spd_limit = temp;
+		dev_warn(&ofdev->dev, "speed limit set to gen %u\n", temp);
+	}
+
 	/* host->iomap is not used currently */
 	host->private_data = host_priv;
 
 	/* initialize host controller */
 	sata_fsl_init_controller(host);
 
 	/*
 	 * Now, register with libATA core, this will also initiate the
 	 * device discovery process, invoking our port_start() handler &
 	 * error_handler() to execute a dummy Softreset EH session
 	 */
 	ata_host_activate(host, irq, sata_fsl_interrupt, SATA_FSL_IRQ_FLAG,
 			  &sata_fsl_sht);

^ permalink raw reply related

* RE: [PATCH 2/2 V7] powerpc/85xx: Add machine check handler to fix PCIe erratum on mpc85xx
From: Jia Hongtao-B38951 @ 2013-05-02  7:00 UTC (permalink / raw)
  To: Wood Scott-B07421; +Cc: linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1367267384.32182.14@snotra>



> -----Original Message-----
> From: Wood Scott-B07421
> Sent: Tuesday, April 30, 2013 4:30 AM
> To: Jia Hongtao-B38951
> Cc: Wood Scott-B07421; Segher Boessenkool; linuxppc-dev@lists.ozlabs.org;
> galak@kernel.crashing.org
> Subject: Re: [PATCH 2/2 V7] powerpc/85xx: Add machine check handler to
> fix PCIe erratum on mpc85xx
>=20
> On 04/26/2013 09:26:26 PM, Jia Hongtao-B38951 wrote:
> > > -----Original Message-----
> > > From: Wood Scott-B07421
> > > Sent: Friday, April 26, 2013 12:58 AM
> > > To: Segher Boessenkool
> > > Cc: Jia Hongtao-B38951; linuxppc-dev@lists.ozlabs.org;
> > > galak@kernel.crashing.org; Wood Scott-B07421
> > > Subject: Re: [PATCH 2/2 V7] powerpc/85xx: Add machine check handler
> > to
> > > fix PCIe erratum on mpc85xx
> > >
> > > On 04/25/2013 10:31:51 AM, Segher Boessenkool wrote:
> > > >> * Remove A variant of load instruction emulation
> > > >
> > > > Why is this?  You handle all other simple load insns, there is
> > nothing
> > > > special about LHA.  (I reviewed the V4 email thread, no reason
> > for the
> > > > chance is given there).
> > >
> > > The LHA implementation in V5 was incorrect (didn't sign-extend).
> > >
> > > -Scott
> >
> > In former email you doubt whether we need A variant or not.
> > Any particular reason for that?
> > If not should I emulate all the A ARX AU AUX and AX variant?
>=20
> I was just noting that the variants you left out from the earlier
> revisions (e.g. BRX) were much more likely to be used for I/O than some
> of the ones you included (e.g. "A").  Implementing all the normal
> load/store instructions would be better, if they're done correctly.
>=20
> -Scott

All right.
I have submitted a new version and please have a review.
http://patchwork.ozlabs.org/patch/240238/
http://patchwork.ozlabs.org/patch/240239/

Thanks.
-Hongtao

^ permalink raw reply

* [git pull] Please pull powerpc.git next branch
From: Benjamin Herrenschmidt @ 2013-05-02  7:35 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linuxppc-dev list, Linux Kernel list

Hi Linus !

Here's the next pack of powerpc changes !

The main highlights this time around are:

 - A pile of addition POWER8 bits and nits, such as updated performance
counter support (Michael Ellerman), new branch history buffer support
(Anshuman Khandual), base support for the new PCI host bridge when
not using the hypervisor (Gavin Shan) and other random related bits
and fixes from various contributors.

 - Some rework of our page table format by Aneesh Kumar which fixes
a thing or two and paves the way for THP support. THP itself will
not make it this time around however.

 - More Freescale updates, including Altivec support on the new
e6500 cores, new PCI controller support, and a pile of new boards
support and updates.

 - The usual batch of trivial cleanups & fixes.

Cheers,
Ben.

The following changes since commit 60d509fa6a9c4653a86ad830e4c4b30360b23f0e:

  Linux 3.9-rc8 (2013-04-21 14:38:45 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git next

for you to fetch changes up to 54d5999d98f2ab36ad71b9ef4d82cf5f399205f5:

  powerpc: Fix build error for book3e (2013-05-02 10:37:37 +1000)

----------------------------------------------------------------
Adhemerval Zanella (1):
      powerpc: Add VDSO version of time

Adrian-Leonard Radu (1):
      powerpc: Use PTR_RET instead of IS_ERR/PTR_ERR

Alex Grad (1):
      powerpc/kgdb: Removed kmalloc returned value cast

Alexey Kardashevskiy (1):
      powerpc: fixing ptrace_get_reg to return an error

Anatolij Gustschin (2):
      powerpc/mpc512x: create SoC devices for more nodes
      powerpc/512x: add ifm ac14xx board

Andy Shevchenko (1):
      powerpc/pmac/smu: Use %*ph to print small buffers

Aneesh Kumar K.V (16):
      powerpc: Use signed formatting when printing error
      powerpc: Save DAR and DSISR in pt_regs on MCE
      powerpc: Don't hard code the size of pte page
      powerpc: Don't truncate pgd_index wrongly
      powerpc: New hugepage directory format
      powerpc: Switch 16GB and 16MB explicit hugepages to a different page table format
      powerpc: Reduce the PTE_INDEX_SIZE
      powerpc: Move the pte free routines from common header
      powerpc: Reduce PTE table memory wastage
      powerpc: Use encode avpn where we need only avpn values
      powerpc: Decode the pte-lp-encoding bits correctly.
      powerpc: Fix hpte_decode to use the correct decoding for page sizes
      powerpc: print both base and actual page size on hash failure
      powerpc: Print page size info during boot
      powerpc: Update tlbie/tlbiel as per ISA doc
      powerpc: Fix build error for book3e

Anshuman Khandual (6):
      powerpc/perf: Add new BHRB related instructions for POWER8
      powerpc/perf: Add basic assembly code to read BHRB entries on POWER8
      powerpc/perf: Add new BHRB related generic functions, data and flags
      powerpc/perf: Define BHRB generic functions, data and flags for POWER8
      powerpc/perf: Enable branch stack sampling framework
      powerpc: Setup BHRB instructions facility in HFSCR for POWER8

Ben Collins (1):
      powerpc/85xx: sgy-cts1000 - Remove __dev* attributes

Benjamin Herrenschmidt (5):
      Merge remote-tracking branch 'mpe/master' into next
      Merge remote-tracking branch 'origin/master' into next
      powerpc/powernv: Fix missing Kconfig dependency for MSIs
      Merge remote-tracking branch 'agust/next' into next
      Merge remote-tracking branch 'kumar/next' into next

Bharat Bhushan (1):
      powerpc: Fix interrupt range check on debug exception

Brian King (2):
      pci: Set dev->dev.type in alloc_pci_dev
      powerpc: Set default VGA device

Chen Gang (1):
      powerpc/pseries/lparcfg: Fix possible overflow are more than 1026

Chen-Hui Zhao (1):
      powerpc/85xx: fix a bug with the parameter of mpic_reset_core()

Gavin Shan (8):
      powerpc/kernel: Cleanup on rtas_pci.c
      powerpc/powernv: Use MSI bitmap to manage IRQs
      powerpc/powernv: Supports PHB3
      powerpc/powernv: Add option CONFIG_POWERNV_MSI
      powerpc/powernv: Patch MSI EOI handler on P8
      powerpc/powernv: TCE invalidation for PHB3
      powerpc/powernv: Build DMA space for PE on PHB3
      powerpc/powernv: Fix invalid IOMMU table

Geoff Levand (1):
      powerpc/ps3: Update ps3_defconfig

Ian Munsie (1):
      powerpc: Add accounting for Doorbell interrupts

Jesse Larrew (4):
      powerpc/pseries: Add PRRN RTAS event handler
      powerpc/pseries: Update CPU maps when device tree is updated
      powerpc/pseries: Update NUMA VDSO information when updating CPU maps
      powerpc/pseries: RE-enable Virtual Processor Home Node updating

Jia Hongtao (1):
      powerpc/85xx: Add platform_device declaration to fsl_pci.h

Jiucheng Xu (1):
      powerpc/85xx: Reserve a partition of NOR flash for QE ucode firmware

Kevin Hao (3):
      powerpc/fsl-pci: don't unmap the PCI SoC controller registers in setup_pci_atmu
      powerpc/fsl-booke: add the reg prop for pci bridge device node for T4/B4
      powerpc/booke: Remove obsolete macro FINISH_EXCEPTION

Kumar Gala (11):
      powerpc/fsl-booke: Support detection of page sizes on e6500
      powerpc/85xx: Add AltiVec support for e6500
      powerpc/fsl-booke: Add initial silicon device tree for T4240
      powerpc/fsl-booke: Add initial T4240QDS board device tree
      powerpc/fsl-booke: Add initial T4240QDS board support
      powerpc/85xx: Update corenet64_smp_defconfig for T4240
      powerpc/qe: Fix Kconfig enablement of QE_USB support
      powerpc/fsl-booke: Update T4240 device config node in device tree
      powerpc/fsl-booke: Minor fixes to T4240 Si device tree
      powerpc/fsl-pci: Keep PCI SoC controller registers in pci_controller
      powerpc/85xx: Fix MPC8536DS 36-bit device tree

Li Zhong (4):
      powerpc: Use VPA subfunction macros instead of numbers for vpa calls
      powerpc: Move the setting of rflags out of loop in __hash_page_huge
      powerpc: Split the code trying to insert hpte repeatedly as an helper function
      powerpc: Try to insert the hptes repeatedly in kernel_map_linear_page()

Matteo Facchinetti (2):
      powerpc/512x: move mpc5121_generic platform to mpc512x_generic.
      powerpc/mpc512x: add platform code for MPC5125.

Michael Ellerman (12):
      powerpc: Remove unused postfix parameter to DEFINE_BITOP()
      powerpc/cell: Only iterate over online nodes in cbe_init_pm_irq()
      powerpc/spufs: Initialise inode->i_ino in spufs_new_inode()
      powerpc: Initialise PMU related regs on Power8
      powerpc/perf: Add an explict flag indicating presence of SLOT field
      powerpc/perf: Convert mmcra_sipr/sihv() to regs_sipr/sihv()
      powerpc/perf: Add an accessor for regs->result
      powerpc/perf: Add regs_no_sipr()
      powerpc/perf: Add support for SIER
      powerpc/perf: Power8 PMU support
      powerpc: Replace CPU_FTR_BCTAR with CPU_FTR_ARCH_207S
      powerpc: Context switch the new EBB SPRs

Michael Neuling (9):
      powerpc: Add HFSCR SPR definitions
      powerpc: Setup in HFSCR for POWER8
      powerpc/ptrace: Add DAWR debug feature info for userspace
      powerpc: Add HWCAP2 aux entry
      powerpc: Add isync to copy_and_flush
      powerpc/power8: Fix secondary CPUs hanging on boot for HV=0
      powerpc: Fix hardware IRQs with MMU on exceptions when HV=0
      powerpc: Fix usage of setup_pci_atmu()
      powerpc: Turn on the EBB H/FSCR bits

Michel Lespinasse (2):
      mm: remove free_area_cache use in powerpc architecture
      mm: use vm_unmapped_area() on powerpc architecture

Nathan Fontenot (10):
      powerpc/pseries: Expose pseries devicetree_update()
      powerpc/pseries: Correct buffer parsing in update_dt_node()
      powerpc/pseries: Move architecture vector definitions to prom.h
      powerpc/pseries: Use ARRAY_SIZE to iterate over firmware_features_table array
      powerpc/pseries: Update firmware_has_feature() to check architecture vector 5 bits
      powerpc/pseries: Update numa.c to use updated firmware_has_feature()
      powerpc/pseries: Use stop machine to update cpu maps
      powerpc/pseries: Enable PRRN handling
      powerpc/pseries: Add /proc interface to control topology updates
      powerpc/pseries: Correct builds break when CONFIG_SMP not defined

Nishanth Aravamudan (1):
      powerpc/pseries: close DDW race between functions of adapter

Oleg Nesterov (1):
      ptrace/powerpc: Don't flush_ptrace_hw_breakpoint() on fork()

Paul Bolle (12):
      powerpc: remove "config 8260_PCI9"
      powerpc: remove "config MPC10X_OPENPIC"
      powerpc/wsp: drop "select PPC_WSP_COPRO"
      powerpc: remove outdated default on PCI_PERMEDIA
      powerpc/40x: remove unused "config 405GPR"
      powerpc: remove dead CONFIG_HVC_SCOM code
      powerpc: remove PReP platform
      memblock: kill "config MAX_ACTIVE_REGIONS"
      powerpc: Fix typo "CONFIG_ICSWX_PID"
      powerpc: remove unused CONFIG_405EP
      powerpc: remove CONFIG_MPC10X_OPENPIC
      powerpc: drop even more unused Kconfig symbols

Paul Mackerras (2):
      powerpc: Fix build errors with UP configs in HV-style KVM
      powerpc: Fix "attempt to move .org backwards" error

Prabhakar Kushwaha (1):
      powerpc: add CONFIG(s) require for using flash controller

Ramneek Mehresh (1):
      powerpc/85xx: Add first usb controller node for Qonverge platforms

Rojhalat Ibrahim (1):
      powerpc/fsl-pci Make PCIe hotplug work with Freescale PCIe controllers

Roy ZANG (2):
      powerpc/85xx: Add support for FSL PCIe controller v3.0
      powerpc/85xx: enable Silicon image 3132 PCIe to SATA controller

Roy Zang (2):
      powerpc/85xx: enable E1000 NIC to mpc85xx_defconfig
      powerpc/fsl_pci: fix 64 bit pci size issue

Scott Wood (1):
      powerpc/85xx: add CONFIG_E1000E to corenet64_smp_defconfig

Sebastian Andrzej Siewior (1):
      powerpc/fsl-msi: use a different lockclass for the cascade interrupt

Shaveta Leekha (5):
      powerpc/85xx: add SEC-5.3 device tree
      powerpc/fsl-booke: Add initial silicon device tree files for B4860 and B4420
      powerpc/fsl-booke: Add initial B4860QDS and B4420QDS board device tree
      powerpc/fsl-booke: Add B4_QDS board support
      powerpc/85xx: Update corenet64_smp_defconfig for B4_QDS

Stephen George (2):
      powerpc/fsl-booke: Added device tree DCSR entries for T4240 Chassis v2 Debug IP
      powerpc/fsl-booke: Update DCSR EPU device tree entries for existing SoCs

Stephen Rothwell (2):
      powerpc: fix annotation of fake_numa_create_new_node()
      powerpc: Fix build failure after merge of the cgroup tree

Stuart Yoder (3):
      powerpc/e6500: Add architecture categories for e6500 cores
      powerpc: add missing deo arch category to e500mc/e5500 dts
      powerpc: Add paravirt idle loop for 64-bit Book-E

Tang Yuantian (1):
      powerpc/fsl: remove the PPC_CLOCK dependency

Vaidyanathan Srinivasan (1):
      powerpc: fix numa distance for form0 device tree

Vakul Garg (3):
      powerpc/85xx: Added SEC-5.0 device tree.
      powerpc/fsl: removed qoriq-sec4.1-0.dtsi.
      powerpc/fsl: Add property for 'era' in SEC dts crypto node

Valentina Manea (1):
      powerpc: place EXPORT_SYMBOL macro right after declaration

Vasant Hegde (4):
      powerpc/rtas_flash: Free kmem upon module exit
      powerpc/rtas_flash: Update return token comments
      powerpc/rtas_flash: New return code to indicate FW entitlement expiry
      powerpc/rtas_flash: Fix bad memory access

Wei Yongjun (1):
      powerpc: use for_each_compatible_node() macro

Yuanquan Chen (1):
      powerpc/pci: fix PCI-e devices rescan issue on powerpc platform

Zhang Yanfei (1):
      powerpc: remove cast for kmalloc/kzalloc return value

Zhicheng Fan (1):
      powerpc/dts: Fix the dts for p1025rdb 36bit

 .../devicetree/bindings/powerpc/fsl/cpus.txt       |   22 +
 Documentation/powerpc/00-INDEX                     |    4 -
 Documentation/powerpc/ptrace.txt                   |    1 +
 Documentation/powerpc/sound.txt                    |   81 ---
 Documentation/powerpc/zImage_layout.txt            |   47 --
 arch/metag/mm/Kconfig                              |    5 -
 arch/powerpc/Kconfig                               |   20 +-
 arch/powerpc/boot/dts/ac14xx.dts                   |  392 +++++++++++++
 arch/powerpc/boot/dts/b4420qds.dts                 |   50 ++
 arch/powerpc/boot/dts/b4860qds.dts                 |   61 ++
 arch/powerpc/boot/dts/b4qds.dts                    |  169 ++++++
 arch/powerpc/boot/dts/fsl/b4420si-post.dtsi        |   98 ++++
 arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi         |   73 +++
 arch/powerpc/boot/dts/fsl/b4860si-post.dtsi        |  142 +++++
 arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi         |   83 +++
 arch/powerpc/boot/dts/fsl/b4si-post.dtsi           |  268 +++++++++
 arch/powerpc/boot/dts/fsl/e500mc_power_isa.dtsi    |    1 +
 arch/powerpc/boot/dts/fsl/e5500_power_isa.dtsi     |    1 +
 arch/powerpc/boot/dts/fsl/e6500_power_isa.dtsi     |   65 +++
 arch/powerpc/boot/dts/fsl/p1023si-post.dtsi        |    1 +
 arch/powerpc/boot/dts/fsl/p2041si-post.dtsi        |    2 +-
 arch/powerpc/boot/dts/fsl/p3041si-post.dtsi        |    2 +-
 arch/powerpc/boot/dts/fsl/p4080si-post.dtsi        |    2 +-
 arch/powerpc/boot/dts/fsl/p5020si-post.dtsi        |    2 +-
 arch/powerpc/boot/dts/fsl/p5040si-post.dtsi        |    2 +-
 arch/powerpc/boot/dts/fsl/pq3-sec4.4-0.dtsi        |    1 +
 arch/powerpc/boot/dts/fsl/qonverge-usb2-dr-0.dtsi  |   41 ++
 arch/powerpc/boot/dts/fsl/qoriq-gpio-1.dtsi        |   41 ++
 arch/powerpc/boot/dts/fsl/qoriq-gpio-2.dtsi        |   41 ++
 arch/powerpc/boot/dts/fsl/qoriq-gpio-3.dtsi        |   41 ++
 arch/powerpc/boot/dts/fsl/qoriq-sec4.0-0.dtsi      |    1 +
 arch/powerpc/boot/dts/fsl/qoriq-sec4.2-0.dtsi      |    1 +
 .../{qoriq-sec4.1-0.dtsi => qoriq-sec5.0-0.dtsi}   |   27 +-
 arch/powerpc/boot/dts/fsl/qoriq-sec5.2-0.dtsi      |    1 +
 arch/powerpc/boot/dts/fsl/qoriq-sec5.3-0.dtsi      |  119 ++++
 arch/powerpc/boot/dts/fsl/t4240si-post.dtsi        |  442 +++++++++++++++
 arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi         |  128 +++++
 arch/powerpc/boot/dts/mpc5121.dtsi                 |    2 +-
 arch/powerpc/boot/dts/mpc5121ads.dts               |    2 +-
 arch/powerpc/boot/dts/mpc5125twr.dts               |  233 ++++++++
 arch/powerpc/boot/dts/mpc8536ds_36b.dts            |    6 +-
 arch/powerpc/boot/dts/p1021rdb-pc.dtsi             |   12 +-
 arch/powerpc/boot/dts/p1025rdb_36b.dts             |    5 +
 arch/powerpc/boot/dts/pdm360ng.dts                 |    2 +-
 arch/powerpc/boot/dts/t4240qds.dts                 |  224 ++++++++
 arch/powerpc/configs/corenet64_smp_defconfig       |   46 +-
 arch/powerpc/configs/mpc512x_defconfig             |    2 +-
 arch/powerpc/configs/mpc85xx_defconfig             |   40 +-
 arch/powerpc/configs/mpc85xx_smp_defconfig         |   32 ++
 arch/powerpc/configs/ps3_defconfig                 |    2 +-
 arch/powerpc/include/asm/bitops.h                  |   11 +-
 arch/powerpc/include/asm/cputable.h                |   11 +-
 arch/powerpc/include/asm/dma.h                     |    5 -
 arch/powerpc/include/asm/elf.h                     |    1 +
 arch/powerpc/include/asm/exception-64s.h           |    2 +-
 arch/powerpc/include/asm/firmware.h                |    6 +-
 arch/powerpc/include/asm/hardirq.h                 |    3 +
 arch/powerpc/include/asm/hugetlb.h                 |   30 +
 arch/powerpc/include/asm/io.h                      |    4 -
 arch/powerpc/include/asm/kvm_asm.h                 |    4 +
 arch/powerpc/include/asm/machdep.h                 |    3 +-
 arch/powerpc/include/asm/mmu-book3e.h              |   22 +
 arch/powerpc/include/asm/mmu-hash64.h              |   60 +-
 arch/powerpc/include/asm/opal.h                    |    2 +
 arch/powerpc/include/asm/page.h                    |   19 +
 arch/powerpc/include/asm/page_64.h                 |    3 +-
 arch/powerpc/include/asm/parport.h                 |    4 +-
 arch/powerpc/include/asm/pci-bridge.h              |   11 +-
 arch/powerpc/include/asm/perf_event_server.h       |    9 +
 arch/powerpc/include/asm/pgalloc-32.h              |   45 ++
 arch/powerpc/include/asm/pgalloc-64.h              |  158 +++++-
 arch/powerpc/include/asm/pgalloc.h                 |   46 +-
 arch/powerpc/include/asm/pgtable-ppc64-64k.h       |    6 +-
 arch/powerpc/include/asm/pgtable-ppc64.h           |    3 +-
 arch/powerpc/include/asm/pgtable.h                 |    8 +
 arch/powerpc/include/asm/ppc-opcode.h              |    8 +
 arch/powerpc/include/asm/processor.h               |   12 +-
 arch/powerpc/include/asm/prom.h                    |   69 +++
 arch/powerpc/include/asm/ptrace.h                  |    3 +-
 arch/powerpc/include/asm/reg.h                     |   23 +
 arch/powerpc/include/asm/rtas.h                    |    6 +
 arch/powerpc/include/asm/smp.h                     |    2 +
 arch/powerpc/include/asm/topology.h                |    5 +
 arch/powerpc/include/asm/xics.h                    |    1 +
 arch/powerpc/include/uapi/asm/ptrace.h             |    1 +
 arch/powerpc/kernel/asm-offsets.c                  |    3 +
 arch/powerpc/kernel/cpu_setup_fsl_booke.S          |   16 +
 arch/powerpc/kernel/cpu_setup_power.S              |   31 +-
 arch/powerpc/kernel/cputable.c                     |    9 +-
 arch/powerpc/kernel/dbell.c                        |    2 +
 arch/powerpc/kernel/entry_64.S                     |   20 +-
 arch/powerpc/kernel/epapr_hcalls.S                 |    2 +
 arch/powerpc/kernel/exceptions-64e.S               |   47 ++
 arch/powerpc/kernel/exceptions-64s.S               |   22 +-
 arch/powerpc/kernel/head_44x.S                     |    2 +
 arch/powerpc/kernel/head_64.S                      |    1 +
 arch/powerpc/kernel/head_booke.h                   |   21 +-
 arch/powerpc/kernel/head_fsl_booke.S               |    2 +
 arch/powerpc/kernel/idle_book3e.S                  |   32 +-
 arch/powerpc/kernel/iommu.c                        |    2 +-
 arch/powerpc/kernel/irq.c                          |   12 +
 arch/powerpc/kernel/kgdb.c                         |    2 +-
 arch/powerpc/kernel/lparcfg.c                      |    1 +
 arch/powerpc/kernel/nvram_64.c                     |    3 +-
 arch/powerpc/kernel/pci-common.c                   |   56 +-
 arch/powerpc/kernel/process.c                      |    8 +-
 arch/powerpc/kernel/prom_init.c                    |   98 +---
 arch/powerpc/kernel/ptrace.c                       |   31 +-
 arch/powerpc/kernel/ptrace32.c                     |   15 +-
 arch/powerpc/kernel/rtas_flash.c                   |   51 +-
 arch/powerpc/kernel/rtas_pci.c                     |    4 +-
 arch/powerpc/kernel/rtasd.c                        |   49 +-
 arch/powerpc/kernel/setup-common.c                 |    6 -
 arch/powerpc/kernel/setup_64.c                     |    4 +-
 arch/powerpc/kernel/time.c                         |    4 +-
 arch/powerpc/kernel/vdso.c                         |    4 +
 arch/powerpc/kernel/vdso32/gettimeofday.S          |   26 +
 arch/powerpc/kernel/vdso32/vdso32.lds.S            |    1 +
 arch/powerpc/kernel/vdso64/gettimeofday.S          |   26 +
 arch/powerpc/kernel/vdso64/vdso64.lds.S            |    1 +
 arch/powerpc/kvm/book3s_64_mmu_host.c              |    2 +-
 arch/powerpc/kvm/book3s_hv.c                       |    8 +-
 arch/powerpc/kvm/book3s_hv_interrupts.S            |    6 +
 arch/powerpc/kvm/book3s_pr.c                       |    2 +-
 arch/powerpc/mm/gup.c                              |   18 +-
 arch/powerpc/mm/hash_low_64.S                      |   22 +-
 arch/powerpc/mm/hash_native_64.c                   |  178 ++++--
 arch/powerpc/mm/hash_utils_64.c                    |  183 ++++--
 arch/powerpc/mm/hugetlbpage-hash64.c               |   33 +-
 arch/powerpc/mm/hugetlbpage.c                      |  192 +++++--
 arch/powerpc/mm/icswx.c                            |    2 +-
 arch/powerpc/mm/init_64.c                          |    3 +-
 arch/powerpc/mm/mem.c                              |    3 +-
 arch/powerpc/mm/mmu_context_hash64.c               |   37 ++
 arch/powerpc/mm/numa.c                             |  279 +++++++--
 arch/powerpc/mm/pgtable_64.c                       |  118 ++++
 arch/powerpc/mm/slice.c                            |  223 +++-----
 arch/powerpc/mm/tlb_nohash.c                       |   18 +-
 arch/powerpc/perf/Makefile                         |    5 +-
 arch/powerpc/perf/bhrb.S                           |   44 ++
 arch/powerpc/perf/core-book3s.c                    |  231 +++++++-
 arch/powerpc/perf/power5+-pmu.c                    |    2 +-
 arch/powerpc/perf/power5-pmu.c                     |    1 +
 arch/powerpc/perf/power8-pmu.c                     |  592 ++++++++++++++++++++
 arch/powerpc/platforms/40x/Kconfig                 |    7 -
 arch/powerpc/platforms/512x/Kconfig                |    8 +-
 arch/powerpc/platforms/512x/Makefile               |    2 +-
 arch/powerpc/platforms/512x/clock.c                |    9 +-
 arch/powerpc/platforms/512x/mpc512x.h              |    1 +
 .../512x/{mpc5121_generic.c => mpc512x_generic.c}  |   12 +-
 arch/powerpc/platforms/512x/mpc512x_shared.c       |   33 +-
 arch/powerpc/platforms/85xx/Kconfig                |   34 ++
 arch/powerpc/platforms/85xx/Makefile               |    2 +
 arch/powerpc/platforms/85xx/b4_qds.c               |  102 ++++
 arch/powerpc/platforms/85xx/corenet_ds.c           |    5 +-
 arch/powerpc/platforms/85xx/smp.c                  |    2 +-
 arch/powerpc/platforms/85xx/t4240_qds.c            |   98 ++++
 arch/powerpc/platforms/Kconfig                     |    4 +-
 arch/powerpc/platforms/Kconfig.cputype             |    2 +-
 arch/powerpc/platforms/cell/beat_htab.c            |   26 +-
 arch/powerpc/platforms/cell/pmu.c                  |    2 +-
 arch/powerpc/platforms/cell/spufs/file.c           |    2 +-
 arch/powerpc/platforms/cell/spufs/inode.c          |    1 +
 arch/powerpc/platforms/embedded6xx/Kconfig         |    5 -
 arch/powerpc/platforms/powernv/Kconfig             |    5 +
 arch/powerpc/platforms/powernv/opal-wrappers.S     |    1 +
 arch/powerpc/platforms/powernv/pci-ioda.c          |  307 ++++++++--
 arch/powerpc/platforms/powernv/pci-p5ioc2.c        |   15 +-
 arch/powerpc/platforms/powernv/pci.c               |  113 +---
 arch/powerpc/platforms/powernv/pci.h               |   26 +-
 arch/powerpc/platforms/prep/Kconfig                |   23 -
 arch/powerpc/platforms/ps3/htab.c                  |    8 +-
 arch/powerpc/platforms/ps3/time.c                  |    4 +-
 arch/powerpc/platforms/pseries/firmware.c          |   54 +-
 arch/powerpc/platforms/pseries/iommu.c             |   26 +
 arch/powerpc/platforms/pseries/lpar.c              |    8 +-
 arch/powerpc/platforms/pseries/mobility.c          |   41 +-
 arch/powerpc/platforms/pseries/plpar_wrappers.h    |   15 +-
 arch/powerpc/platforms/pseries/pseries.h           |    5 +-
 arch/powerpc/platforms/pseries/setup.c             |   40 +-
 arch/powerpc/platforms/wsp/Kconfig                 |    5 -
 arch/powerpc/sysdev/Kconfig                        |    1 +
 arch/powerpc/sysdev/fsl_msi.c                      |    4 +-
 arch/powerpc/sysdev/fsl_pci.c                      |  114 ++--
 arch/powerpc/sysdev/fsl_pci.h                      |   13 +
 arch/powerpc/sysdev/indirect_pci.c                 |   10 +-
 arch/powerpc/sysdev/qe_lib/Kconfig                 |    2 +-
 arch/powerpc/sysdev/rtc_cmos_setup.c               |    5 +-
 arch/powerpc/sysdev/xics/icp-native.c              |    2 +-
 arch/powerpc/xmon/xmon.c                           |    2 +-
 arch/sh/mm/Kconfig                                 |    7 -
 drivers/macintosh/smu.c                            |    6 +-
 drivers/macintosh/via-pmu.c                        |    5 +-
 drivers/pci/probe.c                                |    2 +-
 drivers/pnp/pnpbios/core.c                         |    9 +-
 drivers/video/cirrusfb.c                           |   62 +-
 fs/binfmt_elf.c                                    |    3 +
 fs/binfmt_elf_fdpic.c                              |    8 +-
 include/uapi/linux/auxvec.h                        |    1 +
 199 files changed, 6489 insertions(+), 1328 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/powerpc/fsl/cpus.txt
 delete mode 100644 Documentation/powerpc/sound.txt
 delete mode 100644 Documentation/powerpc/zImage_layout.txt
 create mode 100644 arch/powerpc/boot/dts/ac14xx.dts
 create mode 100644 arch/powerpc/boot/dts/b4420qds.dts
 create mode 100644 arch/powerpc/boot/dts/b4860qds.dts
 create mode 100644 arch/powerpc/boot/dts/b4qds.dts
 create mode 100644 arch/powerpc/boot/dts/fsl/b4420si-post.dtsi
 create mode 100644 arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi
 create mode 100644 arch/powerpc/boot/dts/fsl/b4860si-post.dtsi
 create mode 100644 arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi
 create mode 100644 arch/powerpc/boot/dts/fsl/b4si-post.dtsi
 create mode 100644 arch/powerpc/boot/dts/fsl/e6500_power_isa.dtsi
 create mode 100644 arch/powerpc/boot/dts/fsl/qonverge-usb2-dr-0.dtsi
 create mode 100644 arch/powerpc/boot/dts/fsl/qoriq-gpio-1.dtsi
 create mode 100644 arch/powerpc/boot/dts/fsl/qoriq-gpio-2.dtsi
 create mode 100644 arch/powerpc/boot/dts/fsl/qoriq-gpio-3.dtsi
 rename arch/powerpc/boot/dts/fsl/{qoriq-sec4.1-0.dtsi => qoriq-sec5.0-0.dtsi} (83%)
 create mode 100644 arch/powerpc/boot/dts/fsl/qoriq-sec5.3-0.dtsi
 create mode 100644 arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
 create mode 100644 arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi
 create mode 100644 arch/powerpc/boot/dts/mpc5125twr.dts
 create mode 100644 arch/powerpc/boot/dts/t4240qds.dts
 create mode 100644 arch/powerpc/perf/bhrb.S
 create mode 100644 arch/powerpc/perf/power8-pmu.c
 rename arch/powerpc/platforms/512x/{mpc5121_generic.c => mpc512x_generic.c} (83%)
 create mode 100644 arch/powerpc/platforms/85xx/b4_qds.c
 create mode 100644 arch/powerpc/platforms/85xx/t4240_qds.c
 delete mode 100644 arch/powerpc/platforms/prep/Kconfig

^ permalink raw reply

* [PATCH] powerpc/powernv: defer OPAL exception handler registration
From: Jeremy Kerr @ 2013-05-02  8:31 UTC (permalink / raw)
  To: Ben Herrenschmidt; +Cc: linuxppc-dev

Currently, the OPAL exception vectors are registered before the feature
fixups are processed. This means that the now-firmware-owned vectors
will likely be overwritten by the kernel.

This change moves the exception registration code to an early initcall,
rather than at machine_init time.

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>

---
 arch/powerpc/platforms/powernv/opal.c |   15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index aaa0dba..ade4463 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -34,7 +34,6 @@ int __init early_init_dt_scan_opal(unsigned long node,
 {
 	const void *basep, *entryp;
 	unsigned long basesz, entrysz;
-	u64 glue;
 
 	if (depth != 1 || strcmp(uname, "ibm,opal") != 0)
 		return 0;
@@ -61,6 +60,16 @@ int __init early_init_dt_scan_opal(unsigned long node,
 		printk("OPAL V1 detected !\n");
 	}
 
+	return 1;
+}
+
+static int __init opal_register_exception_handlers(void)
+{
+	u64 glue;
+
+	if (!(powerpc_firmware_features & FW_FEATURE_OPAL))
+		return -ENODEV;
+
 	/* Hookup some exception handlers. We use the fwnmi area at 0x7000
 	 * to provide the glue space to OPAL
 	 */
@@ -74,9 +83,11 @@ int __init early_init_dt_scan_opal(unsigned long node,
 	glue += 128;
 	opal_register_exception_handler(OPAL_SOFTPATCH_HANDLER, 0, glue);
 
-	return 1;
+	return 0;
 }
 
+early_initcall(opal_register_exception_handlers);
+
 int opal_get_chars(uint32_t vtermno, char *buf, int count)
 {
 	s64 len, rc;

^ permalink raw reply related

* Re: [PATCH 1/2 v15] iommu/fsl: Add additional iommu attributes required by the PAMU driver.
From: joro @ 2013-05-02 10:16 UTC (permalink / raw)
  To: Sethi Varun-B16395
  Cc: Wood Scott-B07421, linux-kernel@vger.kernel.org,
	Yoder Stuart-B08248, iommu@lists.linux-foundation.org,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <C5ECD7A89D1DC44195F34B25E172658D4CBC45@039-SN2MPN1-011.039d.mgd.msft.net>

On Tue, Apr 30, 2013 at 05:09:32PM +0000, Sethi Varun-B16395 wrote:
> Would you take this patchset for 3.10 merge?

Not this time. The final patch came in very late and is pretty big too.
For code of that size I would like to have a few weeks more testing in
next and probably also a non-Freescale Reviewed-by.


	Joerg

^ permalink raw reply

* Re: [PATCH -next] kvm/ppc/mpic: fix missing unlock in set_base_addr()
From: Alexander Graf @ 2013-05-02 11:17 UTC (permalink / raw)
  To: Wei Yongjun
  Cc: kvm, gleb, mtosatti, kvm-ppc, yongjun_wei, paulus, scottwood,
	linuxppc-dev
In-Reply-To: <CAPgLHd9S4JbRpB9ipzDyysWqAkismVMu2W=Z2mhuVHzJXv4NrQ@mail.gmail.com>


On 02.05.2013, at 07:17, Wei Yongjun wrote:

> From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
>=20
> Add the missing unlock before return from function set_base_addr()
> when disables the mapping.
>=20
> Introduced by commit 5df554ad5b7522ea62b0ff9d5be35183494efc21
> (kvm/ppc/mpic: in-kernel MPIC emulation)
>=20
> Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>

Thanks, applied to kvm-ppc-queue.


Alex

> ---
> arch/powerpc/kvm/mpic.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>=20
> diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c
> index f3148f8..0047a70 100644
> --- a/arch/powerpc/kvm/mpic.c
> +++ b/arch/powerpc/kvm/mpic.c
> @@ -1475,8 +1475,8 @@ static int set_base_addr(struct openpic *opp, =
struct kvm_device_attr *attr)
>=20
> 	map_mmio(opp);
>=20
> -	mutex_unlock(&opp->kvm->slots_lock);
> out:
> +	mutex_unlock(&opp->kvm->slots_lock);
> 	return 0;
> }
>=20
>=20

^ permalink raw reply

* RE: [PATCH 1/2 v15] iommu/fsl: Add additional iommu attributes required by the PAMU driver.
From: Sethi Varun-B16395 @ 2013-05-02 13:26 UTC (permalink / raw)
  To: joro@8bytes.org
  Cc: Wood Scott-B07421, Alex Williamson, linux-kernel@vger.kernel.org,
	Yoder Stuart-B08248, iommu@lists.linux-foundation.org,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <20130502101629.GA24440@8bytes.org>



> -----Original Message-----
> From: joro@8bytes.org [mailto:joro@8bytes.org]
> Sent: Thursday, May 02, 2013 3:46 PM
> To: Sethi Varun-B16395
> Cc: iommu@lists.linux-foundation.org; linuxppc-dev@lists.ozlabs.org;
> linux-kernel@vger.kernel.org; galak@kernel.crashing.org;
> benh@kernel.crashing.org; Yoder Stuart-B08248; Wood Scott-B07421
> Subject: Re: [PATCH 1/2 v15] iommu/fsl: Add additional iommu attributes
> required by the PAMU driver.
>=20
> On Tue, Apr 30, 2013 at 05:09:32PM +0000, Sethi Varun-B16395 wrote:
> > Would you take this patchset for 3.10 merge?
>=20
> Not this time. The final patch came in very late and is pretty big too.
> For code of that size I would like to have a few weeks more testing in
> next and probably also a non-Freescale Reviewed-by.
[Sethi Varun-B16395] I would request you and Alex Williamson to review the =
patch and provide a Reviewed-by.

-Varun

^ permalink raw reply

* [PATCH 1/2] powerpc/512x: add LocalPlus Bus FIFO device driver
From: Alexander Popov @ 2013-05-02 15:21 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Anatolij Gustschin,
	Grant Likely, Rob Herring, Timur Tabi
  Cc: devicetree-discuss, linuxppc-dev, linux-kernel

This is SCLPC device driver for the Freescale MPC512x.
It is needed for Direct Memory Access to the devices on LocalPlus Bus.

Signed-off-by: Alexander Popov <a13xp0p0v88@gmail.com>
---
 arch/powerpc/boot/dts/mpc5121.dtsi            |   8 +-
 arch/powerpc/include/asm/mpc5121.h            |  32 ++
 arch/powerpc/platforms/512x/Kconfig           |   6 +
 arch/powerpc/platforms/512x/Makefile          |   1 +
 arch/powerpc/platforms/512x/mpc512x_lpbfifo.c | 493 ++++++++++++++++++++++++++
 5 files changed, 539 insertions(+), 1 deletion(-)
 create mode 100644 arch/powerpc/platforms/512x/mpc512x_lpbfifo.c

diff --git a/arch/powerpc/boot/dts/mpc5121.dtsi b/arch/powerpc/boot/dts/mpc5121.dtsi
index 723e292..6c4d551 100644
--- a/arch/powerpc/boot/dts/mpc5121.dtsi
+++ b/arch/powerpc/boot/dts/mpc5121.dtsi
@@ -259,7 +259,13 @@
 		/* LocalPlus controller */
 		lpc@10000 {
 			compatible = "fsl,mpc5121-lpc";
-			reg = <0x10000 0x200>;
+			reg = <0x10000 0x100>;
+		};
+
+		sclpc@10100 {
+			compatible = "fsl,mpc512x-lpbfifo";
+			reg = <0x10100 0x50>;
+			interrupts = <7 0x8>;
 		};
 
 		pata@10200 {
diff --git a/arch/powerpc/include/asm/mpc5121.h b/arch/powerpc/include/asm/mpc5121.h
index 885c040..5ed6a8e 100644
--- a/arch/powerpc/include/asm/mpc5121.h
+++ b/arch/powerpc/include/asm/mpc5121.h
@@ -70,4 +70,36 @@ struct mpc512x_lpc {
 int mpc512x_cs_config(unsigned int cs, u32 val);
 int __init mpc5121_clk_init(void);
 
+/*
+ * SCLPC Module (LPB FIFO)
+ */
+enum lpb_dev_portsize {
+	LPB_DEV_PORTSIZE_UNDEFINED = 0,
+	LPB_DEV_PORTSIZE_1_BYTE = 1,
+	LPB_DEV_PORTSIZE_2_BYTES = 2,
+	LPB_DEV_PORTSIZE_4_BYTES = 4,
+	LPB_DEV_PORTSIZE_8_BYTES = 8,
+};
+
+enum mpc512x_lpbfifo_req_dir {
+	MPC512X_LPBFIFO_REQ_DIR_READ,
+	MPC512X_LPBFIFO_REQ_DIR_WRITE,
+};
+
+struct mpc512x_lpbfifo_request {
+	unsigned int cs;
+	phys_addr_t bus_phys;	/* physical address of some device on lpb */
+	void *ram_virt;		/* virtual address of some region in ram */
+
+	/* Details of transfer */
+	u32 size;
+	enum lpb_dev_portsize portsize;
+	enum mpc512x_lpbfifo_req_dir dir;
+
+	/* Call when the transfer is finished */
+	void (*callback)(struct mpc512x_lpbfifo_request *);
+};
+
+extern int mpc512x_lpbfifo_submit(struct mpc512x_lpbfifo_request *req);
+
 #endif /* __ASM_POWERPC_MPC5121_H__ */
diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig
index 381a592..2e75d3c 100644
--- a/arch/powerpc/platforms/512x/Kconfig
+++ b/arch/powerpc/platforms/512x/Kconfig
@@ -10,6 +10,12 @@ config PPC_MPC512x
 	select USB_EHCI_BIG_ENDIAN_MMIO
 	select USB_EHCI_BIG_ENDIAN_DESC
 
+config PPC_MPC512x_LPBFIFO
+	tristate "MPC512x LocalPlus bus FIFO driver"
+	depends on PPC_MPC512x && MPC512X_DMA
+	help
+	  Enable support for the Freescale MPC512x SCLPC.
+
 config MPC5121_ADS
 	bool "Freescale MPC5121E ADS"
 	depends on PPC_MPC512x
diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platforms/512x/Makefile
index 4efc1c4..f2dc44e 100644
--- a/arch/powerpc/platforms/512x/Makefile
+++ b/arch/powerpc/platforms/512x/Makefile
@@ -2,6 +2,7 @@
 # Makefile for the Freescale PowerPC 512x linux kernel.
 #
 obj-y				+= clock.o mpc512x_shared.o
+obj-$(CONFIG_PPC_MPC512x_LPBFIFO) += mpc512x_lpbfifo.o
 obj-$(CONFIG_MPC5121_ADS)	+= mpc5121_ads.o mpc5121_ads_cpld.o
 obj-$(CONFIG_MPC5121_GENERIC)	+= mpc5121_generic.o
 obj-$(CONFIG_PDM360NG)		+= pdm360ng.o
diff --git a/arch/powerpc/platforms/512x/mpc512x_lpbfifo.c b/arch/powerpc/platforms/512x/mpc512x_lpbfifo.c
new file mode 100644
index 0000000..7095e70
--- /dev/null
+++ b/arch/powerpc/platforms/512x/mpc512x_lpbfifo.c
@@ -0,0 +1,493 @@
+/*
+ * LocalPlus Bus SCLPC driver for the Freescale MPC512x.
+ *
+ * Copyright (C) Promcontroller, 2013.
+ *
+ * Author is Alexander Popov <a13xp0p0v88@gmail.com>.
+ *
+ * The driver design is based on mpc52xx_lpbfifo driver
+ * written by Grant Likely <grant.likely@secretlab.ca>.
+ *
+ * This file is released under the GPLv2.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <asm/io.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <asm/mpc5121.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-direction.h>
+#include <linux/dma-mapping.h>
+
+MODULE_AUTHOR("Alexander Popov <a13xp0p0v88@gmail.com>");
+MODULE_DESCRIPTION("MPC512x LocalPlus FIFO device driver");
+MODULE_LICENSE("GPL");
+
+#define DRV_NAME "mpc512x_lpbfifo"
+
+#define LPBFIFO_REG_PACKET_SIZE		(0x00)
+#define LPBFIFO_REG_START_ADDRESS	(0x04)
+#define LPBFIFO_REG_CONTROL		(0x08)
+#define LPBFIFO_REG_ENABLE		(0x0C)
+#define LPBFIFO_REG_STATUS		(0x14)
+#define LPBFIFO_REG_BYTES_DONE		(0x18)
+#define LPBFIFO_REG_EMB_SHARE_COUNTER	(0x1C)
+#define LPBFIFO_REG_EMB_PAUSE_CONTROL	(0x20)
+#define LPBFIFO_REG_FIFO_DATA		(0x40)
+#define LPBFIFO_REG_FIFO_STATUS		(0x44)
+#define LPBFIFO_REG_FIFO_CONTROL	(0x48)
+#define LPBFIFO_REG_FIFO_ALARM		(0x4C)
+
+#define DMA_LPC_CHANNEL_NUMBER		26
+#define DEFAULT_WORDS_PER_TRANSFER	1
+
+static struct mpc512x_lpbfifo {
+	struct device *dev;
+	struct resource res;
+	void __iomem *regs;
+	int irq;
+	spinlock_t lock;
+
+	/* Current state data */
+	int im_last; /* For "last one out turns off the lights" principle */
+	struct mpc512x_lpbfifo_request *req;
+	dma_addr_t ram_bus_addr;
+	struct dma_chan *chan;
+} lpbfifo;
+
+/*
+ * Before we can wrap up handling current mpc512x_lpbfifo_request
+ * and execute the callback registered in it we should:
+ *  1. recognize that everything is really done,
+ *  2. free memory and dmaengine channel.
+ *
+ * Writing from RAM to registers of some device on LPB (transmit)
+ * is not really done until the LPB FIFO completion irq triggers.
+ *
+ * For being sure that writing from registers of some device on LPB
+ * to RAM (receive) is really done we should wait
+ * for mpc512x_lpbfifo_callback() to be called by DMA driver.
+ * In this case LPB FIFO completion irq will not appear at all.
+ *
+ * Moreover, freeing memory and dmaengine channel is not safe until
+ * mpc512x_lpbfifo_callback() is called.
+ *
+ * So to make it simple:
+ * last one out turns off the lights.
+ */
+
+/*
+ * mpc512x_lpbfifo_irq - IRQ handler for LPB FIFO
+ */
+static irqreturn_t mpc512x_lpbfifo_irq(int irq, void *dev_id)
+{
+	struct mpc512x_lpbfifo_request *req;
+	unsigned long flags;
+	u32 status;
+
+	spin_lock_irqsave(&lpbfifo.lock, flags);
+
+	req = lpbfifo.req;
+	if (!req) {
+		spin_unlock_irqrestore(&lpbfifo.lock, flags);
+		pr_err("bogus LPBFIFO IRQ\n");
+		return IRQ_HANDLED;
+	}
+
+	if (req->dir == MPC512X_LPBFIFO_REQ_DIR_READ) {
+		spin_unlock_irqrestore(&lpbfifo.lock, flags);
+		pr_err("bogus LPBFIFO IRQ (we are waiting DMA IRQ)\n");
+		return IRQ_HANDLED;
+	}
+
+	/* Clear the interrupt flag */
+	status = in_8(lpbfifo.regs + LPBFIFO_REG_STATUS);
+	if (status & 0x01)
+		out_8(lpbfifo.regs + LPBFIFO_REG_STATUS, 0x01);
+	else
+		out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
+
+	if (!lpbfifo.im_last) {
+		/*  I'm not the last: DMA is still in progress. */
+		lpbfifo.im_last = 1;
+		spin_unlock_irqrestore(&lpbfifo.lock, flags);
+	} else {
+		/* I'm last. Let's wrap up. */
+		/* Set the FIFO as idle */
+		req = lpbfifo.req;
+		lpbfifo.req = NULL;
+
+		/* The spinlock must be dropped
+		 * before executing the callback,
+		 * otherwise we could end up with a deadlock
+		 * or nested spinlock condition. */
+		spin_unlock_irqrestore(&lpbfifo.lock, flags);
+		if (req->callback)
+			req->callback(req);
+	}
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * mpc512x_lpbfifo_callback is called by DMA driver
+ * when DMA transaction is finished.
+ */
+static void mpc512x_lpbfifo_callback(void *param)
+{
+	unsigned long flags;
+	struct mpc512x_lpbfifo_request *req;
+	enum dma_data_direction dir;
+
+	spin_lock_irqsave(&lpbfifo.lock, flags);
+
+	/* Free resources */
+	if (lpbfifo.req->dir == MPC512X_LPBFIFO_REQ_DIR_WRITE)
+		dir = DMA_TO_DEVICE;
+	else
+		dir = DMA_FROM_DEVICE;
+	dma_unmap_single(lpbfifo.chan->device->dev,
+			lpbfifo.ram_bus_addr, lpbfifo.req->size, dir);
+	dma_release_channel(lpbfifo.chan);
+
+	if (lpbfifo.req->dir == MPC512X_LPBFIFO_REQ_DIR_WRITE &&
+							!lpbfifo.im_last) {
+		/* I'm not the last: LPB FIFO is still writing data. */
+		lpbfifo.im_last = 1;
+		spin_unlock_irqrestore(&lpbfifo.lock, flags);
+	} else {
+		/* I'm the last or alone here. Let's wrap up. */
+		/* Set the FIFO as idle */
+		req = lpbfifo.req;
+		lpbfifo.req = NULL;
+
+		/* The spinlock must be dropped
+		 * before executing the callback,
+		 * otherwise we could end up with a deadlock
+		 * or nested spinlock condition. */
+		spin_unlock_irqrestore(&lpbfifo.lock, flags);
+		if (req->callback)
+			req->callback(req);
+	}
+}
+
+static bool channel_filter(struct dma_chan *chan, void *filter_param)
+{
+	if (chan->chan_id == DMA_LPC_CHANNEL_NUMBER)
+		return true;
+	else
+		return false;
+}
+
+static int mpc512x_lpbfifo_kick(struct mpc512x_lpbfifo_request *req)
+{
+	u32 bits;
+	int no_incr = 0;
+	u32 bpt;
+	dma_cap_mask_t cap_mask;
+	dma_filter_fn fn = channel_filter;
+	struct dma_device *dma_dev = NULL;
+	dma_addr_t dma_src_addr;
+	dma_addr_t dma_dst_addr;
+	struct dma_slave_config dma_conf = {};
+	struct dma_async_tx_descriptor *dma_tx = NULL;
+	dma_cookie_t cookie;
+	int e;
+
+	/* 1. Check requirements: */
+	/* Packet size must be a multiple of 4 bytes since
+	 * FIFO Data Word Register (which provides data to DMA controller)
+	 * allows only "full-word" (4 bytes) access
+	 * according Reference Manual */
+	if (!IS_ALIGNED(req->size, 4)) {
+		e = -EINVAL;
+		goto err_align;
+	}
+
+	/* Physical address of the device on LPB and packet size
+	 * must be aligned/multiple of BPT (bytes per transaction)
+	 * according Reference Manual */
+	if (req->portsize != LPB_DEV_PORTSIZE_UNDEFINED) {
+		bpt = req->portsize;
+		no_incr = 1;
+	} else
+		bpt = DEFAULT_WORDS_PER_TRANSFER << 2; /* makes life easier */
+
+	if (!IS_ALIGNED(req->bus_phys | req->size, bpt)) {
+			e = -EFAULT;
+			goto err_align;
+	}
+
+	/* 2. Prepare DMA */
+	dma_cap_zero(cap_mask);
+	dma_cap_set(DMA_MEMCPY, cap_mask);
+	lpbfifo.chan = dma_request_channel(cap_mask, fn, NULL);
+	dma_dev = lpbfifo.chan->device;
+
+	if (req->dir == MPC512X_LPBFIFO_REQ_DIR_WRITE) {
+		dma_conf.direction = DMA_MEM_TO_DEV;
+		dma_conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+
+		/* We should limit the maximum number of words
+		 * (units with FIFO Data Register size)
+		 * that can be read from / written to the FIFO
+		 * in one DMA burst.
+		 * This measure and FIFO watermarks will prevent
+		 * DMA controller from overtaking FIFO
+		 * and causing FIFO underflow / overflow error. */
+		dma_conf.dst_maxburst = DEFAULT_WORDS_PER_TRANSFER;
+
+		dma_src_addr = dma_map_single(dma_dev->dev,
+				req->ram_virt, req->size, DMA_TO_DEVICE);
+		if (dma_mapping_error(dma_dev->dev, dma_src_addr)) {
+			pr_err("dma_mapping_error\n");
+			e = -EFAULT;
+			goto err_dma_map;
+		}
+		lpbfifo.ram_bus_addr = dma_src_addr; /* will free it later */
+
+		dma_dst_addr = lpbfifo.res.start + LPBFIFO_REG_FIFO_DATA;
+	} else {
+		dma_conf.direction = DMA_DEV_TO_MEM;
+		dma_conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+
+		/* Ditto */
+		dma_conf.src_maxburst = DEFAULT_WORDS_PER_TRANSFER;
+
+		dma_src_addr = lpbfifo.res.start + LPBFIFO_REG_FIFO_DATA;
+
+		dma_dst_addr = dma_map_single(dma_dev->dev,
+				req->ram_virt, req->size, DMA_FROM_DEVICE);
+		if (dma_mapping_error(dma_dev->dev, dma_dst_addr)) {
+			pr_err("dma_mapping_error\n");
+			e = -EFAULT;
+			goto err_dma_map;
+		}
+		lpbfifo.ram_bus_addr = dma_dst_addr; /* Ditto */
+	}
+
+	/* Make DMA channel work with LPB FIFO data register */
+	if (dma_dev->device_control(lpbfifo.chan,
+				DMA_SLAVE_CONFIG, (unsigned long)&dma_conf)) {
+		goto err_dma_prep;
+	}
+
+	dma_tx = dma_dev->device_prep_dma_memcpy(lpbfifo.chan,
+		dma_dst_addr, dma_src_addr, req->size, DMA_PREP_INTERRUPT);
+	if (!dma_tx) {
+		pr_err("device_prep_dma_memcpy failed\n");
+		e = -ENOSPC;
+		goto err_dma_prep;
+	}
+
+	dma_tx->callback = mpc512x_lpbfifo_callback;
+	dma_tx->callback_param = NULL;
+
+	/* 3. Prepare FIFO */
+	/* Set and clear the reset bits;
+	 * is good practice in Reference Manual */
+	out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
+	out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x0);
+
+	/* Configure the watermarks.
+	 *
+	 * RAM->DMA->FIFO->LPB_DEV (write):
+	 *  High watermark (7 * 4) free bytes (according Reference Manual)
+	 *  Low watermark 996 bytes (whole FIFO - 28 bytes)
+	 *
+	 * LPB_DEV->FIFO->DMA->RAM (read):
+	 *  High watermark (1024 - 4) free bytes
+	 *   (whole FIFO - DEFAULT_WORDS_PER_TRANSFER)
+	 *  Low watermark 0 bytes
+	 */
+	if (req->dir == MPC512X_LPBFIFO_REQ_DIR_WRITE) {
+		out_be16(lpbfifo.regs + LPBFIFO_REG_FIFO_CONTROL, 0x0700);
+		out_be32(lpbfifo.regs + LPBFIFO_REG_FIFO_ALARM, 0x000003e4);
+	} else {
+		out_be16(lpbfifo.regs + LPBFIFO_REG_FIFO_CONTROL, 0x0);
+		out_be32(lpbfifo.regs + LPBFIFO_REG_FIFO_ALARM, 0x000003fc);
+	}
+
+	/* Start address is a physical address of the region
+	 * which belongs to the device on localplus bus */
+	out_be32(lpbfifo.regs + LPBFIFO_REG_START_ADDRESS, req->bus_phys);
+
+	/* Configure chip select, transfer direction,
+	 * address increment option and bytes per transfer option */
+	bits = (req->cs & 0x7) << 24;
+	if (req->dir == MPC512X_LPBFIFO_REQ_DIR_READ)
+		bits |= 3 << 16; /* read mode bit and flush bit */
+	if (no_incr)
+		bits |= 1 << 8;
+	bits |= bpt & 0x3f;
+	out_be32(lpbfifo.regs + LPBFIFO_REG_CONTROL, bits);
+
+	/* Unmask irqs */
+	bits = 0x00000201; /* set error irq & master enabled bit */
+	if (req->dir == MPC512X_LPBFIFO_REQ_DIR_WRITE)
+		bits |= 0x00000100; /* set completion irq too */
+	out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, bits);
+
+	/* 4. Set packet size and kick FIFO off */
+	bits = req->size;
+	bits |= (1<<31); /* set restart bit */
+	out_be32(lpbfifo.regs + LPBFIFO_REG_PACKET_SIZE, bits);
+
+
+	/* 5. Then kick DMA off */
+	cookie = dma_tx->tx_submit(dma_tx);
+	if (dma_submit_error(cookie)) {
+		pr_err("DMA tx_submit failed\n");
+		e = -ENOSPC;
+		goto err_dma_submit;
+	}
+
+	return 0;
+
+ err_dma_submit:
+
+ err_dma_prep:
+	if (req->dir == MPC512X_LPBFIFO_REQ_DIR_WRITE) {
+		dma_unmap_single(dma_dev->dev, dma_src_addr,
+						req->size, DMA_TO_DEVICE);
+	} else {
+		dma_unmap_single(dma_dev->dev, dma_dst_addr,
+						req->size, DMA_FROM_DEVICE);
+	}
+
+ err_dma_map:
+	dma_release_channel(lpbfifo.chan);
+
+ err_align:
+	return e;
+}
+
+int mpc512x_lpbfifo_submit(struct mpc512x_lpbfifo_request *req)
+{
+	unsigned long flags;
+	int result = 0;
+
+	if (!lpbfifo.regs)
+		return -ENODEV;
+
+	spin_lock_irqsave(&lpbfifo.lock, flags);
+
+	/* A transfer is in progress
+	 * if the req pointer is already set */
+	if (lpbfifo.req) {
+		spin_unlock_irqrestore(&lpbfifo.lock, flags);
+		return -EBUSY;
+	}
+
+	/* (128 kBytes - 4 Bytes) is a maximum packet size
+	 * that LPB FIFO and DMA controller can handle together
+	 * while exchanging DEFAULT_WORDS_PER_TRANSFER = 1
+	 * per hardware request */
+	if (req->size > 131068) {
+		spin_unlock_irqrestore(&lpbfifo.lock, flags);
+		return -ENOSPC;
+	}
+
+	/* Setup the transfer */
+	lpbfifo.im_last = 0;
+	lpbfifo.req = req;
+
+	result = mpc512x_lpbfifo_kick(req);
+	if (result != 0)
+		lpbfifo.req = NULL;	/* Set the FIFO as idle */
+
+	spin_unlock_irqrestore(&lpbfifo.lock, flags);
+
+	return result;
+}
+EXPORT_SYMBOL(mpc512x_lpbfifo_submit);
+
+static int mpc512x_lpbfifo_probe(struct platform_device *pdev)
+{
+	struct resource *r = &lpbfifo.res;
+	int e = 0, rc = -ENOMEM;
+
+	if (of_address_to_resource(pdev->dev.of_node, 0, r)) {
+		e = -ENODEV;
+		goto err_res;
+	}
+
+	if (!request_mem_region(r->start, resource_size(r), DRV_NAME)) {
+		e = -EBUSY;
+		goto err_res;
+	}
+
+	lpbfifo.irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+	if (!lpbfifo.irq) {
+		e = -ENODEV;
+		goto err_res;
+	}
+
+	lpbfifo.regs = ioremap(r->start, resource_size(r));
+	if (!lpbfifo.regs) {
+		e = -ENOMEM;
+		goto err_regs;
+	}
+
+	spin_lock_init(&lpbfifo.lock);
+
+	/* Put FIFO into reset state */
+	out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
+
+	lpbfifo.dev = &pdev->dev;
+
+	rc = request_irq(lpbfifo.irq,
+				mpc512x_lpbfifo_irq, 0, DRV_NAME, &lpbfifo);
+	if (rc) {
+		e = -ENODEV;
+		goto err_irq;
+	}
+
+	return 0;
+
+ err_irq:
+	iounmap(lpbfifo.regs);
+	lpbfifo.regs = NULL;
+
+ err_regs:
+	release_mem_region(r->start, resource_size(r));
+
+ err_res:
+	dev_err(&pdev->dev, "mpc512x_lpbfifo_probe() failed\n");
+	return e;
+}
+
+static int mpc512x_lpbfifo_remove(struct platform_device *pdev)
+{
+	/* Put FIFO in reset */
+	out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
+
+	free_irq(lpbfifo.irq, &lpbfifo);
+	iounmap(lpbfifo.regs);
+	release_mem_region(lpbfifo.res.start, resource_size(&lpbfifo.res));
+	lpbfifo.regs = NULL;
+	lpbfifo.dev = NULL;
+
+	return 0;
+}
+
+static const struct of_device_id mpc512x_lpbfifo_match[] = {
+	{ .compatible = "fsl,mpc512x-lpbfifo", },
+	{},
+};
+
+static struct platform_driver mpc512x_lpbfifo_driver = {
+	.probe = mpc512x_lpbfifo_probe,
+	.remove = mpc512x_lpbfifo_remove,
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = mpc512x_lpbfifo_match,
+	},
+};
+module_platform_driver(mpc512x_lpbfifo_driver);
-- 
1.7.11.3

^ 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