* [PATCH] powerpc: Use lwarx hint bit in spinlocks
From: Anton Blanchard @ 2010-02-10 2:50 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev
Recent versions of the PowerPC architecture added a hint bit to the larx
instructions to differentiate between an atomic operation and a lock operation:
> 0 Other programs might attempt to modify the word in storage addressed by EA
> even if the subsequent Store Conditional succeeds.
>
> 1 Other programs will not attempt to modify the word in storage addressed by
> EA until the program that has acquired the lock performs a subsequent store
> releasing the lock.
To avoid a binutils dependency this patch create macros for the extended lwarx
format and uses it in the spinlock code. To test this change I used a simple
test case that acquires and releases a global pthread mutex:
pthread_mutex_lock(&mutex);
pthread_mutex_unlock(&mutex);
On a 32 core POWER6 running 32 test threads we spend almost all our time in
the futex spinlock code (as expected):
94.37% perf [kernel] [k] ._raw_spin_lock
|
|--99.95%-- ._raw_spin_lock
| |
| |--63.29%-- .futex_wake
| |
| |--36.64%-- .futex_wait_setup
which is a good test for this patch. The results (in lock/unlock operations
per second) are:
before: 1538203 ops/sec
after: 2189219 ops/sec
An improvement of 42%
Signed-off-by: Anton Blanchard <anton@samba.org>
---
We've had issues in the past with chips that do the wrong thing and don't
ignore instruction reserved bits. One option might be to limit this change to
64bit and verify on that limited set of CPUs.
Index: powerpc.git/arch/powerpc/include/asm/ppc-opcode.h
===================================================================
--- powerpc.git.orig/arch/powerpc/include/asm/ppc-opcode.h 2010-01-04 09:13:10.773027301 +1100
+++ powerpc.git/arch/powerpc/include/asm/ppc-opcode.h 2010-02-10 13:46:20.423071697 +1100
@@ -24,6 +24,7 @@
#define PPC_INST_ISEL_MASK 0xfc00003e
#define PPC_INST_LSWI 0x7c0004aa
#define PPC_INST_LSWX 0x7c00042a
+#define PPC_INST_LWARX 0x7c000029
#define PPC_INST_LWSYNC 0x7c2004ac
#define PPC_INST_LXVD2X 0x7c000698
#define PPC_INST_MCRXR 0x7c000400
@@ -55,15 +56,20 @@
#define __PPC_RA(a) (((a) & 0x1f) << 16)
#define __PPC_RB(b) (((b) & 0x1f) << 11)
#define __PPC_RS(s) (((s) & 0x1f) << 21)
+#define __PPC_RT(s) __PPC_RS(s)
#define __PPC_XS(s) ((((s) & 0x1f) << 21) | (((s) & 0x20) >> 5))
#define __PPC_T_TLB(t) (((t) & 0x3) << 21)
#define __PPC_WC(w) (((w) & 0x3) << 21)
+#define __PPC_EH(eh) (((eh) & 0x1) << 0)
/* Deal with instructions that older assemblers aren't aware of */
#define PPC_DCBAL(a, b) stringify_in_c(.long PPC_INST_DCBAL | \
__PPC_RA(a) | __PPC_RB(b))
#define PPC_DCBZL(a, b) stringify_in_c(.long PPC_INST_DCBZL | \
__PPC_RA(a) | __PPC_RB(b))
+#define PPC_LWARX(t, a, b, eh) stringify_in_c(.long PPC_INST_LWARX | \
+ __PPC_RT(t) | __PPC_RA(a) | \
+ __PPC_RB(b) | __PPC_EH(eh))
#define PPC_MSGSND(b) stringify_in_c(.long PPC_INST_MSGSND | \
__PPC_RB(b))
#define PPC_RFCI stringify_in_c(.long PPC_INST_RFCI)
Index: powerpc.git/arch/powerpc/include/asm/spinlock.h
===================================================================
--- powerpc.git.orig/arch/powerpc/include/asm/spinlock.h 2010-01-04 09:13:10.783027472 +1100
+++ powerpc.git/arch/powerpc/include/asm/spinlock.h 2010-02-10 13:46:20.433071870 +1100
@@ -27,6 +27,7 @@
#endif
#include <asm/asm-compat.h>
#include <asm/synch.h>
+#include <asm/ppc-opcode.h>
#define arch_spin_is_locked(x) ((x)->slock != 0)
@@ -60,7 +61,7 @@ static inline unsigned long __arch_spin_
token = LOCK_TOKEN;
__asm__ __volatile__(
-"1: lwarx %0,0,%2\n\
+"1: " PPC_LWARX(%0,0,%2,1) "\n\
cmpwi 0,%0,0\n\
bne- 2f\n\
stwcx. %1,0,%2\n\
@@ -186,7 +187,7 @@ static inline long __arch_read_trylock(a
long tmp;
__asm__ __volatile__(
-"1: lwarx %0,0,%1\n"
+"1: " PPC_LWARX(%0,0,%1,1) "\n"
__DO_SIGN_EXTEND
" addic. %0,%0,1\n\
ble- 2f\n"
@@ -211,7 +212,7 @@ static inline long __arch_write_trylock(
token = WRLOCK_TOKEN;
__asm__ __volatile__(
-"1: lwarx %0,0,%2\n\
+"1: " PPC_LWARX(%0,0,%2,1) "\n\
cmpwi 0,%0,0\n\
bne- 2f\n"
PPC405_ERR77(0,%1)
^ permalink raw reply
* Re: [PATCH] powerpc: Use lwarx hint bit in spinlocks
From: Josh Boyer @ 2010-02-10 3:19 UTC (permalink / raw)
To: Anton Blanchard; +Cc: linuxppc-dev
In-Reply-To: <20100210025010.GC3702@kryten>
On Wed, Feb 10, 2010 at 01:50:11PM +1100, Anton Blanchard wrote:
>
>Recent versions of the PowerPC architecture added a hint bit to the larx
>instructions to differentiate between an atomic operation and a lock operation:
>
>> 0 Other programs might attempt to modify the word in storage addressed by EA
>> even if the subsequent Store Conditional succeeds.
>>
>> 1 Other programs will not attempt to modify the word in storage addressed by
>> EA until the program that has acquired the lock performs a subsequent store
>> releasing the lock.
>
>To avoid a binutils dependency this patch create macros for the extended lwarx
>format and uses it in the spinlock code. To test this change I used a simple
>test case that acquires and releases a global pthread mutex:
>
> pthread_mutex_lock(&mutex);
> pthread_mutex_unlock(&mutex);
>
>On a 32 core POWER6 running 32 test threads we spend almost all our time in
>the futex spinlock code (as expected):
>
> 94.37% perf [kernel] [k] ._raw_spin_lock
> |
> |--99.95%-- ._raw_spin_lock
> | |
> | |--63.29%-- .futex_wake
> | |
> | |--36.64%-- .futex_wait_setup
>
>which is a good test for this patch. The results (in lock/unlock operations
>per second) are:
>
>before: 1538203 ops/sec
>after: 2189219 ops/sec
>
>An improvement of 42%
>
>Signed-off-by: Anton Blanchard <anton@samba.org>
>---
>
>We've had issues in the past with chips that do the wrong thing and don't
>ignore instruction reserved bits. One option might be to limit this change to
>64bit and verify on that limited set of CPUs.
In the off chance that someone actually does an SMP 44x, I think the hint bit
here would just be ignored (I could test possibly if we want to verify).
However, I thought the FSL parts didn't like toggling the reserved bits and
those already are SMP in some cases.
Kumar?
josh
^ permalink raw reply
* PPC: Possible bug in prom_parse.c:of_irq_map_raw?
From: John Williams @ 2010-02-10 3:21 UTC (permalink / raw)
To: Linux Kernel list, linuxppc-dev, Grant Likely, Michal Simek
Hi,
Perhaps this is my misunderstanding, but I'm looking at the bit of
code in of_irq_map_raw() that iterates the interrupt-map DTS node,
which I am seeing to behave strangely when handling the interrupt-map
property on a PCI bridge node.
Early in the function, we get the #address-cells value from the node -
in this case the PCI bridge, and store it in local var addrsize:
/* Look for this #address-cells. We have to implement the old linux
* trick of looking for the parent here as some device-trees rely on it
*/
old = of_node_get(ipar);
do {
tmp = of_get_property(old, "#address-cells", NULL);
tnode = of_get_parent(old);
of_node_put(old);
old = tnode;
} while(old && tmp == NULL);
of_node_put(old);
old = NULL;
addrsize = (tmp == NULL) ? 2 : *tmp;
DBG(" -> addrsize=%d\n", addrsize);
Later, once we've found the interrupt-map and are iterating over it
attempting to match on PCI device addresses, there is this little
fragment:
/* Get the interrupt parent */
if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
newpar = of_node_get(of_irq_dflt_pic);
else
newpar =
of_find_node_by_phandle((phandle)*imap);
imap++;
--imaplen;
/* Check if not found */
if (newpar == NULL) {
DBG(" -> imap parent not found !\n");
goto fail;
}
/* Get #interrupt-cells and #address-cells of new
* parent
*/
tmp = of_get_property(newpar, "#interrupt-cells", NULL);
if (tmp == NULL) {
DBG(" -> parent lacks #interrupt-cells !\n");
goto fail;
}
newintsize = *tmp;
tmp = of_get_property(newpar, "#address-cells", NULL);
newaddrsize = (tmp == NULL) ? 0 : *tmp;
Finally, later in the loop we update addrsize=newaddrsize
As I read this code, and the behaviour I'm seeing, is that if the
interrupt controller parent device doesn't have an #address-cells
entry, then this get_property will return fail, therefore setting
newaddrsize to zero. This then means that subsequent match attempts
when iterating the interrupt-map always fail, because the match length
(addrsize) is 0.
Maybe I'm missing something here, but shouldn't this last bit of code
instead be:
tmp = of_get_property(newpar, "#address-cells", NULL);
newaddrsize = (tmp == NULL) ? addrsize : *tmp;
^^^^^^^^^
?
In other words, if the parent node has an #address-cells value, then
use it, otherwise stick to the #address-cells value we picked up for
the actual node in question (ie the PCI bridge).
The way this is manifesting itself in the system I'm looking at is
that only the PCI device matching the first entry in the PCI bridge
interrupt-map property is correctly matching. For PCI devices that
require more than one pass through the interrupt-map loop, addrsize
goes to zero and no further match is possible.
I might be able to hack around this in the device-tree by setting
#address-cells=<3> in the interrupt controller node, but that doesn't
smell right either - it's only true for PCI devices for a start,
whereas this controller handles interrupts from many sources on the
32-bit PLB bus as well. I looked at the ML510 DTS in boot/dts and
it's not doing anything like this.
As a footnote, I'm actually doing this in MicroBlaze whose PCI
infrastructure is not yet in mainline, however we copied this bit of
code directly from PPC and the logic is the same.
Thanks,
John
--
John Williams
PetaLogix - Linux Solutions for a Reconfigurable World
w: www.petalogix.com p: +61-7-30090663 f: +61-7-30090663
^ permalink raw reply
* [git pull] Please pull powerpc.git merge branch
From: Benjamin Herrenschmidt @ 2010-02-10 3:52 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Andrew Morton, linuxppc-dev list, Linux Kernel list
Hi Linus !
Here's a fix for a nasty regression that went in this release cycle
and breaks 64K pages on HW that only does 4K such as 970's.
Cheers,
Ben.
The following changes since commit ac73fddfc523bf3c3525d16356b44527c44fae6d:
Linus Torvalds (1):
Merge branch 'for-linus' of git://neil.brown.name/md
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git merge
David Gibson (1):
powerpc: Fix address masking bug in hpte_need_flush()
arch/powerpc/mm/tlb_hash64.c | 12 +++++++++---
1 files changed, 9 insertions(+), 3 deletions(-)
^ permalink raw reply
* Re: [PATCH] Restrict initial stack space expansion to rlimit
From: KOSAKI Motohiro @ 2010-02-10 5:12 UTC (permalink / raw)
To: Helge Deller
Cc: Michael Neuling, linux-parisc, stable, aeb, Oleg Nesterov,
miltonm, James Morris, linuxppc-dev, Paul Mackerras,
Anton Blanchard, kosaki.motohiro, Serge Hallyn, linux-fsdevel,
Americo Wang, Andrew Morton, Linus Torvalds, Ingo Molnar,
linux-kernel, Alexander Viro
In-Reply-To: <4B71E13C.2050905@gmx.de>
> On 02/09/2010 10:51 PM, Michael Neuling wrote:
> >>> I'd still like someone with a CONFIG_STACK_GROWSUP arch to test/ACK it
> >>> as well.
> >>
> >> There's only one CONFIG_GROWSUP arch - parisc.
> >> Could someone please test it on parisc?
>
> I did.
>
> > How about doing:
> > 'ulimit -s 15; ls'
> > before and after the patch is applied. Before it's applied, 'ls' should
> > be killed. After the patch is applied, 'ls' should no longer be killed.
> >
> > I'm suggesting a stack limit of 15KB since it's small enough to trigger
> > 20*PAGE_SIZE. Also 15KB not a multiple of PAGE_SIZE, which is a trickier
> > case to handle correctly with this code.
> >
> > 4K pages on parisc should be fine to test with.
>
> Mikey, thanks for the suggested test plan.
>
> I'm not sure if your patch does it correct for parisc/stack-grows-up-case.
>
> I tested your patch on a 4k pages kernel:
> root@c3000:~# uname -a
> Linux c3000 2.6.33-rc7-32bit #221 Tue Feb 9 23:17:06 CET 2010 parisc GNU/Linux
>
> Without your patch:
> root@c3000:~# ulimit -s 15; ls
> Killed
> -> correct.
>
> With your patch:
> root@c3000:~# ulimit -s 15; ls
> Killed
> _or_:
> root@c3000:~# ulimit -s 15; ls
> Segmentation fault
> -> ??
>
> Any idea?
My x86_64 box also makes segmentation fault. I think "ulimit -s 15" is too small stack for ls.
"ulimit -s 27; ls " wroks perfectly fine.
^ permalink raw reply
* Re: [PATCH] Restrict initial stack space expansion to rlimit
From: Michael Neuling @ 2010-02-10 5:30 UTC (permalink / raw)
To: KOSAKI Motohiro
Cc: linux-parisc, stable, Helge Deller, aeb, Oleg Nesterov, miltonm,
James Morris, linuxppc-dev, Paul Mackerras, Alexander Viro,
Serge Hallyn, linux-fsdevel, Americo Wang, Andrew Morton,
Linus Torvalds, Ingo Molnar, linux-kernel, Anton Blanchard
In-Reply-To: <20100210141016.4D18.A69D9226@jp.fujitsu.com>
In message <20100210141016.4D18.A69D9226@jp.fujitsu.com> you wrote:
> > On 02/09/2010 10:51 PM, Michael Neuling wrote:
> > >>> I'd still like someone with a CONFIG_STACK_GROWSUP arch to test/ACK it
> > >>> as well.
> > >>
> > >> There's only one CONFIG_GROWSUP arch - parisc.
> > >> Could someone please test it on parisc?
> >
> > I did.
> >
> > > How about doing:
> > > 'ulimit -s 15; ls'
> > > before and after the patch is applied. Before it's applied, 'ls' should
> > > be killed. After the patch is applied, 'ls' should no longer be killed.
> > >
> > > I'm suggesting a stack limit of 15KB since it's small enough to trigger
> > > 20*PAGE_SIZE. Also 15KB not a multiple of PAGE_SIZE, which is a trickier
> > > case to handle correctly with this code.
> > >
> > > 4K pages on parisc should be fine to test with.
> >
> > Mikey, thanks for the suggested test plan.
> >
> > I'm not sure if your patch does it correct for parisc/stack-grows-up-case.
> >
> > I tested your patch on a 4k pages kernel:
> > root@c3000:~# uname -a
> > Linux c3000 2.6.33-rc7-32bit #221 Tue Feb 9 23:17:06 CET 2010 parisc GNU/Li
nux
> >
> > Without your patch:
> > root@c3000:~# ulimit -s 15; ls
> > Killed
> > -> correct.
> >
> > With your patch:
> > root@c3000:~# ulimit -s 15; ls
> > Killed
> > _or_:
> > root@c3000:~# ulimit -s 15; ls
> > Segmentation fault
> > -> ??
> >
> > Any idea?
>
> My x86_64 box also makes segmentation fault. I think "ulimit -s 15" is too sm
all stack for ls.
> "ulimit -s 27; ls " wroks perfectly fine.
Arrh. I asked Helge offline earlier to check what use to work on parisc
on 2.6.31.
I guess PPC has a nice clean non-bloated ABI :-D
Mikey
^ permalink raw reply
* Re: [PATCH] Restrict initial stack space expansion to rlimit
From: Michael Neuling @ 2010-02-10 5:31 UTC (permalink / raw)
To: KOSAKI Motohiro
Cc: linux-parisc, stable, Helge Deller, aeb, Oleg Nesterov, miltonm,
James Morris, linuxppc-dev, Paul Mackerras, Alexander Viro,
Serge Hallyn, linux-fsdevel, Americo Wang, Andrew Morton,
Linus Torvalds, Ingo Molnar, linux-kernel, Anton Blanchard
In-Reply-To: <20100210141016.4D18.A69D9226@jp.fujitsu.com>
In message <20100210141016.4D18.A69D9226@jp.fujitsu.com> you wrote:
> > On 02/09/2010 10:51 PM, Michael Neuling wrote:
> > >>> I'd still like someone with a CONFIG_STACK_GROWSUP arch to test/ACK it
> > >>> as well.
> > >>
> > >> There's only one CONFIG_GROWSUP arch - parisc.
> > >> Could someone please test it on parisc?
> >
> > I did.
> >
> > > How about doing:
> > > 'ulimit -s 15; ls'
> > > before and after the patch is applied. Before it's applied, 'ls' should
> > > be killed. After the patch is applied, 'ls' should no longer be killed.
> > >
> > > I'm suggesting a stack limit of 15KB since it's small enough to trigger
> > > 20*PAGE_SIZE. Also 15KB not a multiple of PAGE_SIZE, which is a trickier
> > > case to handle correctly with this code.
> > >
> > > 4K pages on parisc should be fine to test with.
> >
> > Mikey, thanks for the suggested test plan.
> >
> > I'm not sure if your patch does it correct for parisc/stack-grows-up-case.
> >
> > I tested your patch on a 4k pages kernel:
> > root@c3000:~# uname -a
> > Linux c3000 2.6.33-rc7-32bit #221 Tue Feb 9 23:17:06 CET 2010 parisc GNU/Li
nux
> >
> > Without your patch:
> > root@c3000:~# ulimit -s 15; ls
> > Killed
> > -> correct.
> >
> > With your patch:
> > root@c3000:~# ulimit -s 15; ls
> > Killed
> > _or_:
> > root@c3000:~# ulimit -s 15; ls
> > Segmentation fault
> > -> ??
> >
> > Any idea?
>
> My x86_64 box also makes segmentation fault. I think "ulimit -s 15" is too sm
all stack for ls.
> "ulimit -s 27; ls " wroks perfectly fine.
Arrh. I asked Helge offline earlier to check what use to work on parisc
on 2.6.31.
I guess PPC has a nice clean non-bloated ABI :-D
Mikey
^ permalink raw reply
* [PATCH] powerpc/44x: Update Glacier dts
From: Stefan Roese @ 2010-02-10 9:08 UTC (permalink / raw)
To: linuxppc-dev
Sync Glacier dts with latest Canyonlands version:
- Add l2 cache support
- Add NDFC support
- Add RTC support
- Add AD7414 hwmon support
- Change EMAC compatible node from emac4 to emac4sync and correct the
register size
- Add support for ISA holes on 4xx PCI/X/E
(as done in Benjamin Herrenschmidt's patch for Canyonlands)
- Add Crypto device node
Signed-off-by: Stefan Roese <sr@denx.de>
Cc: Josh Boyer <jwboyer@linux.vnet.ibm.com>
---
arch/powerpc/boot/dts/glacier.dts | 76 ++++++++++++++++++++++++++++++++----
1 files changed, 67 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/boot/dts/glacier.dts b/arch/powerpc/boot/dts/glacier.dts
index f6f6189..d62a4fb 100644
--- a/arch/powerpc/boot/dts/glacier.dts
+++ b/arch/powerpc/boot/dts/glacier.dts
@@ -1,7 +1,7 @@
/*
* Device Tree Source for AMCC Glacier (460GT)
*
- * Copyright 2008 DENX Software Engineering, Stefan Roese <sr@denx.de>
+ * Copyright 2008-2010 DENX Software Engineering, Stefan Roese <sr@denx.de>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without
@@ -42,6 +42,7 @@
d-cache-size = <32768>;
dcr-controller;
dcr-access-method = "native";
+ next-level-cache = <&L2C0>;
};
};
@@ -106,6 +107,16 @@
dcr-reg = <0x00c 0x002>;
};
+ L2C0: l2c {
+ compatible = "ibm,l2-cache-460gt", "ibm,l2-cache";
+ dcr-reg = <0x020 0x008 /* Internal SRAM DCR's */
+ 0x030 0x008>; /* L2 cache DCR's */
+ cache-line-size = <32>; /* 32 bytes */
+ cache-size = <262144>; /* L2, 256K */
+ interrupt-parent = <&UIC1>;
+ interrupts = <11 1>;
+ };
+
plb {
compatible = "ibm,plb-460gt", "ibm,plb4";
#address-cells = <2>;
@@ -118,6 +129,13 @@
dcr-reg = <0x010 0x002>;
};
+ CRYPTO: crypto@180000 {
+ compatible = "amcc,ppc460gt-crypto", "amcc,ppc4xx-crypto";
+ reg = <4 0x00180000 0x80400>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <0x1d 0x4>;
+ };
+
MAL0: mcmal {
compatible = "ibm,mcmal-460gt", "ibm,mcmal2";
dcr-reg = <0x180 0x062>;
@@ -186,6 +204,29 @@
reg = <0x03fa0000 0x00060000>;
};
};
+
+ ndfc@3,0 {
+ compatible = "ibm,ndfc";
+ reg = <0x00000003 0x00000000 0x00002000>;
+ ccr = <0x00001000>;
+ bank-settings = <0x80002222>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ nand {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x00000000 0x00100000>;
+ };
+ partition@100000 {
+ label = "user";
+ reg = <0x00000000 0x03f00000>;
+ };
+ };
+ };
};
UART0: serial@ef600300 {
@@ -237,6 +278,20 @@
reg = <0xef600700 0x00000014>;
interrupt-parent = <&UIC0>;
interrupts = <0x2 0x4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ rtc@68 {
+ compatible = "stm,m41t80";
+ reg = <0x68>;
+ interrupt-parent = <&UIC2>;
+ interrupts = <0x19 0x8>;
+ };
+ sttm@48 {
+ compatible = "ad,ad7414";
+ reg = <0x48>;
+ interrupt-parent = <&UIC1>;
+ interrupts = <0x14 0x8>;
+ };
};
IIC1: i2c@ef600800 {
@@ -275,7 +330,7 @@
EMAC0: ethernet@ef600e00 {
device_type = "network";
- compatible = "ibm,emac-460gt", "ibm,emac4";
+ compatible = "ibm,emac-460gt", "ibm,emac4sync";
interrupt-parent = <&EMAC0>;
interrupts = <0x0 0x1>;
#interrupt-cells = <1>;
@@ -283,7 +338,7 @@
#size-cells = <0>;
interrupt-map = </*Status*/ 0x0 &UIC2 0x10 0x4
/*Wake*/ 0x1 &UIC2 0x14 0x4>;
- reg = <0xef600e00 0x00000074>;
+ reg = <0xef600e00 0x000000c4>;
local-mac-address = [000000000000]; /* Filled in by U-Boot */
mal-device = <&MAL0>;
mal-tx-channel = <0>;
@@ -305,7 +360,7 @@
EMAC1: ethernet@ef600f00 {
device_type = "network";
- compatible = "ibm,emac-460gt", "ibm,emac4";
+ compatible = "ibm,emac-460gt", "ibm,emac4sync";
interrupt-parent = <&EMAC1>;
interrupts = <0x0 0x1>;
#interrupt-cells = <1>;
@@ -313,7 +368,7 @@
#size-cells = <0>;
interrupt-map = </*Status*/ 0x0 &UIC2 0x11 0x4
/*Wake*/ 0x1 &UIC2 0x15 0x4>;
- reg = <0xef600f00 0x00000074>;
+ reg = <0xef600f00 0x000000c4>;
local-mac-address = [000000000000]; /* Filled in by U-Boot */
mal-device = <&MAL0>;
mal-tx-channel = <1>;
@@ -336,7 +391,7 @@
EMAC2: ethernet@ef601100 {
device_type = "network";
- compatible = "ibm,emac-460gt", "ibm,emac4";
+ compatible = "ibm,emac-460gt", "ibm,emac4sync";
interrupt-parent = <&EMAC2>;
interrupts = <0x0 0x1>;
#interrupt-cells = <1>;
@@ -344,7 +399,7 @@
#size-cells = <0>;
interrupt-map = </*Status*/ 0x0 &UIC2 0x12 0x4
/*Wake*/ 0x1 &UIC2 0x16 0x4>;
- reg = <0xef601100 0x00000074>;
+ reg = <0xef601100 0x000000c4>;
local-mac-address = [000000000000]; /* Filled in by U-Boot */
mal-device = <&MAL0>;
mal-tx-channel = <2>;
@@ -366,7 +421,7 @@
EMAC3: ethernet@ef601200 {
device_type = "network";
- compatible = "ibm,emac-460gt", "ibm,emac4";
+ compatible = "ibm,emac-460gt", "ibm,emac4sync";
interrupt-parent = <&EMAC3>;
interrupts = <0x0 0x1>;
#interrupt-cells = <1>;
@@ -374,7 +429,7 @@
#size-cells = <0>;
interrupt-map = </*Status*/ 0x0 &UIC2 0x13 0x4
/*Wake*/ 0x1 &UIC2 0x17 0x4>;
- reg = <0xef601200 0x00000074>;
+ reg = <0xef601200 0x000000c4>;
local-mac-address = [000000000000]; /* Filled in by U-Boot */
mal-device = <&MAL0>;
mal-tx-channel = <3>;
@@ -414,6 +469,7 @@
* later cannot be changed
*/
ranges = <0x02000000 0x00000000 0x80000000 0x0000000d 0x80000000 0x00000000 0x80000000
+ 0x02000000 0x00000000 0x00000000 0x0000000c 0x0ee00000 0x00000000 0x00100000
0x01000000 0x00000000 0x00000000 0x0000000c 0x08000000 0x00000000 0x00010000>;
/* Inbound 2GB range starting at 0 */
@@ -444,6 +500,7 @@
* later cannot be changed
*/
ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x00000000 0x00000000 0x80000000
+ 0x02000000 0x00000000 0x00000000 0x0000000f 0x00000000 0x00000000 0x00100000
0x01000000 0x00000000 0x00000000 0x0000000f 0x80000000 0x00000000 0x00010000>;
/* Inbound 2GB range starting at 0 */
@@ -485,6 +542,7 @@
* later cannot be changed
*/
ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x80000000 0x00000000 0x80000000
+ 0x02000000 0x00000000 0x00000000 0x0000000f 0x00100000 0x00000000 0x00100000
0x01000000 0x00000000 0x00000000 0x0000000f 0x80010000 0x00000000 0x00010000>;
/* Inbound 2GB range starting at 0 */
--
1.6.6.1
^ permalink raw reply related
* [PATCH] powerpc/44x: Fix L2-cache support for 460GT
From: Stefan Roese @ 2010-02-10 9:08 UTC (permalink / raw)
To: linuxppc-dev
Also set L2C_CFG_RDBW on 460GT platforms and not only on 460EX.
Signed-off-by: Stefan Roese <sr@denx.de>
Cc: Josh Boyer <jwboyer@linux.vnet.ibm.com>
---
arch/powerpc/sysdev/ppc4xx_soc.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/sysdev/ppc4xx_soc.c b/arch/powerpc/sysdev/ppc4xx_soc.c
index 5b32adc..5c01435 100644
--- a/arch/powerpc/sysdev/ppc4xx_soc.c
+++ b/arch/powerpc/sysdev/ppc4xx_soc.c
@@ -174,7 +174,8 @@ static int __init ppc4xx_l2c_probe(void)
| L2C_CFG_CPIM | L2C_CFG_TPIM | L2C_CFG_LIM | L2C_CFG_SMCM;
/* Check for 460EX/GT special handling */
- if (of_device_is_compatible(np, "ibm,l2-cache-460ex"))
+ if (of_device_is_compatible(np, "ibm,l2-cache-460ex") ||
+ of_device_is_compatible(np, "ibm,l2-cache-460gt"))
r |= L2C_CFG_RDBW;
mtdcr(dcrbase_l2c + DCRN_L2C0_CFG, r);
--
1.6.6.1
^ permalink raw reply related
* [PATCH] powerpc/44x: Update Arches dts
From: Stefan Roese @ 2010-02-10 9:08 UTC (permalink / raw)
To: linuxppc-dev
Sync Arches dts with latest Canyonlands version:
- Add 16k FIFO size to supported EMAC nodes
- Add next-level-cache property
- Add Crypto device node
Signed-off-by: Stefan Roese <sr@denx.de>
Cc: Josh Boyer <jwboyer@linux.vnet.ibm.com>
---
arch/powerpc/boot/dts/arches.dts | 12 ++++++++++++
1 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/boot/dts/arches.dts b/arch/powerpc/boot/dts/arches.dts
index 414ef8b..30f4120 100644
--- a/arch/powerpc/boot/dts/arches.dts
+++ b/arch/powerpc/boot/dts/arches.dts
@@ -60,6 +60,7 @@
d-cache-size = <32768>;
dcr-controller;
dcr-access-method = "native";
+ next-level-cache = <&L2C0>;
};
};
@@ -146,6 +147,13 @@
dcr-reg = <0x010 0x002>;
};
+ CRYPTO: crypto@180000 {
+ compatible = "amcc,ppc460gt-crypto", "amcc,ppc4xx-crypto";
+ reg = <4 0x00180000 0x80400>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <0x1d 0x4>;
+ };
+
MAL0: mcmal {
compatible = "ibm,mcmal-460gt", "ibm,mcmal2";
dcr-reg = <0x180 0x062>;
@@ -274,6 +282,7 @@
max-frame-size = <9000>;
rx-fifo-size = <4096>;
tx-fifo-size = <2048>;
+ rx-fifo-size-gige = <16384>;
phy-mode = "sgmii";
phy-map = <0xffffffff>;
gpcs-address = <0x0000000a>;
@@ -302,6 +311,7 @@
max-frame-size = <9000>;
rx-fifo-size = <4096>;
tx-fifo-size = <2048>;
+ rx-fifo-size-gige = <16384>;
phy-mode = "sgmii";
phy-map = <0x00000000>;
gpcs-address = <0x0000000b>;
@@ -331,6 +341,8 @@
max-frame-size = <9000>;
rx-fifo-size = <4096>;
tx-fifo-size = <2048>;
+ rx-fifo-size-gige = <16384>;
+ tx-fifo-size-gige = <16384>; /* emac2&3 only */
phy-mode = "sgmii";
phy-map = <0x00000001>;
gpcs-address = <0x0000000C>;
--
1.6.6.1
^ permalink raw reply related
* Re: [net-next-2.6 PATCH 2/3] fs_enet: Add support for MPC512x to fs_enet driver
From: Wolfgang Grandegger @ 2010-02-10 9:15 UTC (permalink / raw)
To: David Miller; +Cc: wd, dzu, netdev, linuxppc-dev, agust, kosmo
In-Reply-To: <20100209.121356.216640014.davem@davemloft.net>
Hi David,
David Miller wrote:
> From: Anatolij Gustschin <agust@denx.de>
> Date: Tue, 9 Feb 2010 15:23:17 +0100
>
>> In my understanding, in the ESP scsi driver the set of defines for
>> the register offsets is common for all chip drivers. The chip driver
>> methods for register access translate the offsets because the
>> registers on some chips are at different intervals (4-byte, 1-byte,
>> 16-byte for mac_esp.c). But the register order is the same for
>> different chips.
>>
>> In our case non only the register order is not the same for 8xx
>> FEC and 5121 FEC, but there are also other differences, different
>> reserved areas between several registers, some registers are
>> available only on 8xx and some only on 5121.
>
> That only means you would need to use a table based register address
> translation scheme, rather than a simple calculation. Something
> like:
>
> static unsigned int chip_xxx_table[] =
> {
> [GENERIC_REG_FOO] = CHIP_XXX_FOO,
> ...
> };
>
> static u32 chip_xxx_read_reg(struct chip *p, unsigned int reg)
> {
> unsigned int reg_off = chip_xxx_table[reg];
>
> return readl(p->regs + reg_off);
> }
>
> And this table can have special tokens in entries for
> registers which do not exist on a chip, so you can trap
> attempted access to them in these read/write handlers.
Yes, that could be done, but to honest, I do not see any improvement in
respect to the previous patch where the register offset were defined via
pointers within a structure.
> Please stop looking for excuses to fork this driver, a
> unified driver I think can be done cleanly.
Other people suggested to fork the driver because it's getting too ugly.
Wolfgang.
^ permalink raw reply
* [PATCH v6 0/4] i2c-mpc: add support for the Freescale MPC512x and other fixes
From: Wolfgang Grandegger @ 2010-02-10 10:05 UTC (permalink / raw)
To: Linux-i2c
Cc: Devicetree-discuss, Linuxppc-dev, Wolfgang Grandegger, Ben Dooks
From: Wolfgang Grandegger <wg@denx.de>
This patch series adds support for the MPC512x from Freescale to the
i2c-mpc driver. At that occasion, issues with __devinit[data] have
been fixed and the doc of the FSL I2C dts bindings updated. It has
been tested on a MPC5121ADS, TQM5200 and TQM8560 board
Changes since v1:
- use macro MPC_I2C_CLOCK_PRESERVE/SAFE for the special clock settings.
- document the special DTS node "fsl,mpc5121-i2c-ctrl".
- update and correct the Kconfig help.
- some other minor fixes as suggested by Wolfram.
Changes since v2:
- use __init[data] instead of __devinit[data] for this driver.
Changes since v3:
- switch back to __devinit[data] as pointed out by Ben.
Changes since v4:
- check MPC_I2C_CLOCK_SAFE instead of "!clock" as suggested by Wolfram.
- update MODULE_DESCRIPTION().
Changes since v5 (suggested by Grant Likely):
- various correctings for labling initialization functions and data
(this is tricky because section mismatches are not always obvious).
- add a separate patch for renaming the setclock into setup functions.
- correct the doc of the I2C bindings, e.g. don't mention the legacy
clock setting and remove obsolte parts.
Wolfgang
Wolfgang Grandegger (4):
i2c-mpc: use __devinit[data] for initialization functions and data
i2c-mpc: rename "setclock" initialization functions to "setup"
i2c-mpc: add support for the MPC512x processors from Freescale
powerpc: doc/dts-bindings: update doc of FSL I2C bindings
Documentation/powerpc/dts-bindings/fsl/i2c.txt | 30 +++-
drivers/i2c/busses/Kconfig | 7 +-
drivers/i2c/busses/i2c-mpc.c | 194 +++++++++++++++---------
3 files changed, 146 insertions(+), 85 deletions(-)
^ permalink raw reply
* [PATCH v6 1/4] i2c-mpc: use __devinit[data] for initialization functions and data
From: Wolfgang Grandegger @ 2010-02-10 10:05 UTC (permalink / raw)
To: Linux-i2c
Cc: Devicetree-discuss, Linuxppc-dev, Wolfgang Grandegger, Ben Dooks
In-Reply-To: <1265796330-15976-1-git-send-email-wg@grandegger.com>
From: Wolfgang Grandegger <wg@denx.de>
"__devinit[data]" has not yet been used for all initialization functions
and data. To avoid truncating lines, the struct "mpc_i2c_match_data" has
been renamed to "mpc_i2c_data", which is even the better name.
Signed-off-by: Wolfgang Grandegger <wg@denx.de>
Tested-by: Wolfram Sang <w.sang@pengutronix.de>
---
drivers/i2c/busses/i2c-mpc.c | 99 +++++++++++++++++++----------------------
1 files changed, 46 insertions(+), 53 deletions(-)
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index f627001..ba4e7af 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -66,7 +66,7 @@ struct mpc_i2c_divider {
u16 fdr; /* including dfsrr */
};
-struct mpc_i2c_match_data {
+struct mpc_i2c_data {
void (*setclock)(struct device_node *node,
struct mpc_i2c *i2c,
u32 clock, u32 prescaler);
@@ -165,7 +165,7 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
}
#ifdef CONFIG_PPC_MPC52xx
-static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] = {
+static struct mpc_i2c_divider mpc_i2c_dividers_52xx[] __devinitdata = {
{20, 0x20}, {22, 0x21}, {24, 0x22}, {26, 0x23},
{28, 0x24}, {30, 0x01}, {32, 0x25}, {34, 0x02},
{36, 0x26}, {40, 0x27}, {44, 0x04}, {48, 0x28},
@@ -186,7 +186,8 @@ static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] = {
{10240, 0x9d}, {12288, 0x9e}, {15360, 0x9f}
};
-int mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, int prescaler)
+static int __devinit mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock,
+ int prescaler)
{
const struct mpc_i2c_divider *div = NULL;
unsigned int pvr = mfspr(SPRN_PVR);
@@ -215,9 +216,9 @@ int mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, int prescaler)
return div ? (int)div->fdr : -EINVAL;
}
-static void mpc_i2c_setclock_52xx(struct device_node *node,
- struct mpc_i2c *i2c,
- u32 clock, u32 prescaler)
+static void __devinit mpc_i2c_setclock_52xx(struct device_node *node,
+ struct mpc_i2c *i2c,
+ u32 clock, u32 prescaler)
{
int ret, fdr;
@@ -230,15 +231,15 @@ static void mpc_i2c_setclock_52xx(struct device_node *node,
dev_info(i2c->dev, "clock %d Hz (fdr=%d)\n", clock, fdr);
}
#else /* !CONFIG_PPC_MPC52xx */
-static void mpc_i2c_setclock_52xx(struct device_node *node,
- struct mpc_i2c *i2c,
- u32 clock, u32 prescaler)
+static void __devinit mpc_i2c_setclock_52xx(struct device_node *node,
+ struct mpc_i2c *i2c,
+ u32 clock, u32 prescaler)
{
}
#endif /* CONFIG_PPC_MPC52xx*/
#ifdef CONFIG_FSL_SOC
-static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] = {
+static struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] __devinitdata = {
{160, 0x0120}, {192, 0x0121}, {224, 0x0122}, {256, 0x0123},
{288, 0x0100}, {320, 0x0101}, {352, 0x0601}, {384, 0x0102},
{416, 0x0602}, {448, 0x0126}, {480, 0x0103}, {512, 0x0127},
@@ -258,7 +259,7 @@ static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] = {
{49152, 0x011e}, {61440, 0x011f}
};
-u32 mpc_i2c_get_sec_cfg_8xxx(void)
+static u32 __devinit mpc_i2c_get_sec_cfg_8xxx(void)
{
struct device_node *node = NULL;
u32 __iomem *reg;
@@ -287,7 +288,8 @@ u32 mpc_i2c_get_sec_cfg_8xxx(void)
return val;
}
-int mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, u32 prescaler)
+static int __devinit mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock,
+ u32 prescaler)
{
const struct mpc_i2c_divider *div = NULL;
u32 divider;
@@ -320,9 +322,9 @@ int mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, u32 prescaler)
return div ? (int)div->fdr : -EINVAL;
}
-static void mpc_i2c_setclock_8xxx(struct device_node *node,
- struct mpc_i2c *i2c,
- u32 clock, u32 prescaler)
+static void __devinit mpc_i2c_setclock_8xxx(struct device_node *node,
+ struct mpc_i2c *i2c,
+ u32 clock, u32 prescaler)
{
int ret, fdr;
@@ -338,9 +340,9 @@ static void mpc_i2c_setclock_8xxx(struct device_node *node,
}
#else /* !CONFIG_FSL_SOC */
-static void mpc_i2c_setclock_8xxx(struct device_node *node,
- struct mpc_i2c *i2c,
- u32 clock, u32 prescaler)
+static void __devinit mpc_i2c_setclock_8xxx(struct device_node *node,
+ struct mpc_i2c *i2c,
+ u32 clock, u32 prescaler)
{
}
#endif /* CONFIG_FSL_SOC */
@@ -529,8 +531,8 @@ static int __devinit fsl_i2c_probe(struct of_device *op,
clock = *prop;
if (match->data) {
- struct mpc_i2c_match_data *data =
- (struct mpc_i2c_match_data *)match->data;
+ struct mpc_i2c_data *data =
+ (struct mpc_i2c_data *)match->data;
data->setclock(op->node, i2c, clock, data->prescaler);
} else {
/* Backwards compatibility */
@@ -582,44 +584,35 @@ static int __devexit fsl_i2c_remove(struct of_device *op)
return 0;
};
+static struct mpc_i2c_data mpc_i2c_data_52xx __devinitdata = {
+ .setup = mpc_i2c_setup_52xx,
+};
+
+static struct mpc_i2c_data mpc_i2c_data_8313 __devinitdata = {
+ .setup = mpc_i2c_setup_8xxx,
+};
+
+static struct mpc_i2c_data mpc_i2c_data_8543 __devinitdata = {
+ .setup = mpc_i2c_setup_8xxx,
+ .prescaler = 2,
+};
+
+static struct mpc_i2c_data mpc_i2c_data_8544 __devinitdata = {
+ .setup = mpc_i2c_setup_8xxx,
+ .prescaler = 3,
+};
+
static const struct of_device_id mpc_i2c_of_match[] = {
- {.compatible = "mpc5200-i2c",
- .data = &(struct mpc_i2c_match_data) {
- .setclock = mpc_i2c_setclock_52xx,
- },
- },
- {.compatible = "fsl,mpc5200b-i2c",
- .data = &(struct mpc_i2c_match_data) {
- .setclock = mpc_i2c_setclock_52xx,
- },
- },
- {.compatible = "fsl,mpc5200-i2c",
- .data = &(struct mpc_i2c_match_data) {
- .setclock = mpc_i2c_setclock_52xx,
- },
- },
- {.compatible = "fsl,mpc8313-i2c",
- .data = &(struct mpc_i2c_match_data) {
- .setclock = mpc_i2c_setclock_8xxx,
- },
- },
- {.compatible = "fsl,mpc8543-i2c",
- .data = &(struct mpc_i2c_match_data) {
- .setclock = mpc_i2c_setclock_8xxx,
- .prescaler = 2,
- },
- },
- {.compatible = "fsl,mpc8544-i2c",
- .data = &(struct mpc_i2c_match_data) {
- .setclock = mpc_i2c_setclock_8xxx,
- .prescaler = 3,
- },
+ {.compatible = "mpc5200-i2c", .data = &mpc_i2c_data_52xx, },
+ {.compatible = "fsl,mpc5200b-i2c", .data = &mpc_i2c_data_52xx, },
+ {.compatible = "fsl,mpc5200-i2c", .data = &mpc_i2c_data_52xx, },
+ {.compatible = "fsl,mpc8313-i2c", .data = &mpc_i2c_data_8313, },
+ {.compatible = "fsl,mpc8543-i2c", .data = &mpc_i2c_data_8543, },
+ {.compatible = "fsl,mpc8544-i2c", .data = &mpc_i2c_data_8544, },
/* Backward compatibility */
- },
{.compatible = "fsl-i2c", },
{},
};
-
MODULE_DEVICE_TABLE(of, mpc_i2c_of_match);
--
1.6.2.5
^ permalink raw reply related
* [PATCH v6 2/4] i2c-mpc: rename "setclock" initialization functions to "setup"
From: Wolfgang Grandegger @ 2010-02-10 10:05 UTC (permalink / raw)
To: Linux-i2c
Cc: Devicetree-discuss, Linuxppc-dev, Wolfgang Grandegger, Ben Dooks
In-Reply-To: <1265796330-15976-2-git-send-email-wg@grandegger.com>
From: Wolfgang Grandegger <wg@denx.de>
To prepare support for the MPC512x processors from Freescale the
"setclock" initialization functions have been renamed to "setup"
because I2C interrupts must be enabled for the MPC512x by this
function as well.
Signed-off-by: Wolfgang Grandegger <wg@denx.de>
---
drivers/i2c/busses/i2c-mpc.c | 34 ++++++++++++++++------------------
1 files changed, 16 insertions(+), 18 deletions(-)
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index ba4e7af..51d5280 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -67,9 +67,8 @@ struct mpc_i2c_divider {
};
struct mpc_i2c_data {
- void (*setclock)(struct device_node *node,
- struct mpc_i2c *i2c,
- u32 clock, u32 prescaler);
+ void (*setup)(struct device_node *node, struct mpc_i2c *i2c,
+ u32 clock, u32 prescaler);
u32 prescaler;
};
@@ -216,9 +215,9 @@ static int __devinit mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock,
return div ? (int)div->fdr : -EINVAL;
}
-static void __devinit mpc_i2c_setclock_52xx(struct device_node *node,
- struct mpc_i2c *i2c,
- u32 clock, u32 prescaler)
+static void __devinit mpc_i2c_setup_52xx(struct device_node *node,
+ struct mpc_i2c *i2c,
+ u32 clock, u32 prescaler)
{
int ret, fdr;
@@ -231,9 +230,9 @@ static void __devinit mpc_i2c_setclock_52xx(struct device_node *node,
dev_info(i2c->dev, "clock %d Hz (fdr=%d)\n", clock, fdr);
}
#else /* !CONFIG_PPC_MPC52xx */
-static void __devinit mpc_i2c_setclock_52xx(struct device_node *node,
- struct mpc_i2c *i2c,
- u32 clock, u32 prescaler)
+static void __devinit mpc_i2c_setup_52xx(struct device_node *node,
+ struct mpc_i2c *i2c,
+ u32 clock, u32 prescaler)
{
}
#endif /* CONFIG_PPC_MPC52xx*/
@@ -322,9 +321,9 @@ static int __devinit mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock,
return div ? (int)div->fdr : -EINVAL;
}
-static void __devinit mpc_i2c_setclock_8xxx(struct device_node *node,
- struct mpc_i2c *i2c,
- u32 clock, u32 prescaler)
+static void __devinit mpc_i2c_setup_8xxx(struct device_node *node,
+ struct mpc_i2c *i2c,
+ u32 clock, u32 prescaler)
{
int ret, fdr;
@@ -340,9 +339,9 @@ static void __devinit mpc_i2c_setclock_8xxx(struct device_node *node,
}
#else /* !CONFIG_FSL_SOC */
-static void __devinit mpc_i2c_setclock_8xxx(struct device_node *node,
- struct mpc_i2c *i2c,
- u32 clock, u32 prescaler)
+static void __devinit mpc_i2c_setup_8xxx(struct device_node *node,
+ struct mpc_i2c *i2c,
+ u32 clock, u32 prescaler)
{
}
#endif /* CONFIG_FSL_SOC */
@@ -533,12 +532,11 @@ static int __devinit fsl_i2c_probe(struct of_device *op,
if (match->data) {
struct mpc_i2c_data *data =
(struct mpc_i2c_data *)match->data;
- data->setclock(op->node, i2c, clock, data->prescaler);
+ data->setup(op->node, i2c, clock, data->prescaler);
} else {
/* Backwards compatibility */
if (of_get_property(op->node, "dfsrr", NULL))
- mpc_i2c_setclock_8xxx(op->node, i2c,
- clock, 0);
+ mpc_i2c_setup_8xxx(op->node, i2c, clock, 0);
}
}
--
1.6.2.5
^ permalink raw reply related
* [PATCH v6 3/4] i2c-mpc: add support for the MPC512x processors from Freescale
From: Wolfgang Grandegger @ 2010-02-10 10:05 UTC (permalink / raw)
To: Linux-i2c
Cc: Devicetree-discuss, Linuxppc-dev, Wolfgang Grandegger, Ben Dooks
In-Reply-To: <1265796330-15976-3-git-send-email-wg@grandegger.com>
From: Wolfgang Grandegger <wg@denx.de>
As I2C interrupts must be enabled for the MPC512x by the setup function
as well, "fsl,preserve-clocking" is handled in a slighly different way.
Also, the old settings are now reported calling dev_dbg(). For the
MPC512x the clock setup function of the MPC52xx can be re-used.
Furthermore, the Kconfig help has been updated and corrected.
Signed-off-by: Wolfgang Grandegger <wg@denx.de>
Reviewed-by: Wolfram Sang <w.sang@pengutronix.de>
---
drivers/i2c/busses/Kconfig | 7 +--
drivers/i2c/busses/i2c-mpc.c | 93 +++++++++++++++++++++++++++++++++--------
2 files changed, 78 insertions(+), 22 deletions(-)
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 5f318ce..5477e41 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -418,13 +418,12 @@ config I2C_IXP2000
instead.
config I2C_MPC
- tristate "MPC107/824x/85xx/52xx/86xx"
+ tristate "MPC107/824x/85xx/512x/52xx/83xx/86xx"
depends on PPC32
help
If you say yes to this option, support will be included for the
- built-in I2C interface on the MPC107/Tsi107/MPC8240/MPC8245 and
- MPC85xx/MPC8641 family processors. The driver may also work on 52xx
- family processors, though interrupts are known not to work.
+ built-in I2C interface on the MPC107, Tsi107, MPC512x, MPC52xx,
+ MPC8240, MPC8245, MPC83xx, MPC85xx and MPC8641 family processors.
This driver can also be built as a module. If so, the module
will be called i2c-mpc.
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index 51d5280..106bf90 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -31,6 +31,9 @@
#define DRV_NAME "mpc-i2c"
+#define MPC_I2C_CLOCK_LEGACY 0
+#define MPC_I2C_CLOCK_PRESERVE (~0U)
+
#define MPC_I2C_FDR 0x04
#define MPC_I2C_CR 0x08
#define MPC_I2C_SR 0x0c
@@ -163,7 +166,7 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
return 0;
}
-#ifdef CONFIG_PPC_MPC52xx
+#if defined(CONFIG_PPC_MPC52xx) || defined(CONFIG_PPC_MPC512x)
static struct mpc_i2c_divider mpc_i2c_dividers_52xx[] __devinitdata = {
{20, 0x20}, {22, 0x21}, {24, 0x22}, {26, 0x23},
{28, 0x24}, {30, 0x01}, {32, 0x25}, {34, 0x02},
@@ -193,7 +196,7 @@ static int __devinit mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock,
u32 divider;
int i;
- if (!clock)
+ if (clock == MPC_I2C_CLOCK_LEGACY)
return -EINVAL;
/* Determine divider value */
@@ -221,6 +224,12 @@ static void __devinit mpc_i2c_setup_52xx(struct device_node *node,
{
int ret, fdr;
+ if (clock == MPC_I2C_CLOCK_PRESERVE) {
+ dev_dbg(i2c->dev, "using fdr %d\n",
+ readb(i2c->base + MPC_I2C_FDR));
+ return;
+ }
+
ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler);
fdr = (ret >= 0) ? ret : 0x3f; /* backward compatibility */
@@ -229,13 +238,49 @@ static void __devinit mpc_i2c_setup_52xx(struct device_node *node,
if (ret >= 0)
dev_info(i2c->dev, "clock %d Hz (fdr=%d)\n", clock, fdr);
}
-#else /* !CONFIG_PPC_MPC52xx */
+#else /* !(CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x) */
static void __devinit mpc_i2c_setup_52xx(struct device_node *node,
struct mpc_i2c *i2c,
u32 clock, u32 prescaler)
{
}
-#endif /* CONFIG_PPC_MPC52xx*/
+#endif /* CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x */
+
+#ifdef CONFIG_PPC_MPC512x
+static void __devinit mpc_i2c_setup_512x(struct device_node *node,
+ struct mpc_i2c *i2c,
+ u32 clock, u32 prescaler)
+{
+ struct device_node *node_ctrl;
+ void __iomem *ctrl;
+ const u32 *pval;
+ u32 idx;
+
+ /* Enable I2C interrupts for mpc5121 */
+ node_ctrl = of_find_compatible_node(NULL, NULL,
+ "fsl,mpc5121-i2c-ctrl");
+ if (node_ctrl) {
+ ctrl = of_iomap(node_ctrl, 0);
+ if (ctrl) {
+ /* Interrupt enable bits for i2c-0/1/2: bit 24/26/28 */
+ pval = of_get_property(node, "reg", NULL);
+ idx = (*pval & 0xff) / 0x20;
+ setbits32(ctrl, 1 << (24 + idx * 2));
+ iounmap(ctrl);
+ }
+ of_node_put(node_ctrl);
+ }
+
+ /* The clock setup for the 52xx works also fine for the 512x */
+ mpc_i2c_setup_52xx(node, i2c, clock, prescaler);
+}
+#else /* CONFIG_PPC_MPC512x */
+static void __devinit mpc_i2c_setup_512x(struct device_node *node,
+ struct mpc_i2c *i2c,
+ u32 clock, u32 prescaler)
+{
+}
+#endif /* CONFIG_PPC_MPC512x */
#ifdef CONFIG_FSL_SOC
static struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] __devinitdata = {
@@ -294,7 +339,7 @@ static int __devinit mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock,
u32 divider;
int i;
- if (!clock)
+ if (clock == MPC_I2C_CLOCK_LEGACY)
return -EINVAL;
/* Determine proper divider value */
@@ -327,6 +372,13 @@ static void __devinit mpc_i2c_setup_8xxx(struct device_node *node,
{
int ret, fdr;
+ if (clock == MPC_I2C_CLOCK_PRESERVE) {
+ dev_dbg(i2c->dev, "using dfsrr %d, fdr %d\n",
+ readb(i2c->base + MPC_I2C_DFSRR),
+ readb(i2c->base + MPC_I2C_FDR));
+ return;
+ }
+
ret = mpc_i2c_get_fdr_8xxx(node, clock, prescaler);
fdr = (ret >= 0) ? ret : 0x1031; /* backward compatibility */
@@ -495,7 +547,7 @@ static int __devinit fsl_i2c_probe(struct of_device *op,
{
struct mpc_i2c *i2c;
const u32 *prop;
- u32 clock = 0;
+ u32 clock = MPC_I2C_CLOCK_LEGACY;
int result = 0;
int plen;
@@ -524,20 +576,21 @@ static int __devinit fsl_i2c_probe(struct of_device *op,
}
}
- if (!of_get_property(op->node, "fsl,preserve-clocking", NULL)) {
+ if (of_get_property(op->node, "fsl,preserve-clocking", NULL)) {
+ clock = MPC_I2C_CLOCK_PRESERVE;
+ } else {
prop = of_get_property(op->node, "clock-frequency", &plen);
if (prop && plen == sizeof(u32))
clock = *prop;
+ }
- if (match->data) {
- struct mpc_i2c_data *data =
- (struct mpc_i2c_data *)match->data;
- data->setup(op->node, i2c, clock, data->prescaler);
- } else {
- /* Backwards compatibility */
- if (of_get_property(op->node, "dfsrr", NULL))
- mpc_i2c_setup_8xxx(op->node, i2c, clock, 0);
- }
+ if (match->data) {
+ struct mpc_i2c_data *data = match->data;
+ data->setup(op->node, i2c, clock, data->prescaler);
+ } else {
+ /* Backwards compatibility */
+ if (of_get_property(op->node, "dfsrr", NULL))
+ mpc_i2c_setup_8xxx(op->node, i2c, clock, 0);
}
dev_set_drvdata(&op->dev, i2c);
@@ -582,6 +635,10 @@ static int __devexit fsl_i2c_remove(struct of_device *op)
return 0;
};
+static struct mpc_i2c_data mpc_i2c_data_512x __devinitdata = {
+ .setup = mpc_i2c_setup_512x,
+};
+
static struct mpc_i2c_data mpc_i2c_data_52xx __devinitdata = {
.setup = mpc_i2c_setup_52xx,
};
@@ -604,6 +661,7 @@ static const struct of_device_id mpc_i2c_of_match[] = {
{.compatible = "mpc5200-i2c", .data = &mpc_i2c_data_52xx, },
{.compatible = "fsl,mpc5200b-i2c", .data = &mpc_i2c_data_52xx, },
{.compatible = "fsl,mpc5200-i2c", .data = &mpc_i2c_data_52xx, },
+ {.compatible = "fsl,mpc5121-i2c", .data = &mpc_i2c_data_512x, },
{.compatible = "fsl,mpc8313-i2c", .data = &mpc_i2c_data_8313, },
{.compatible = "fsl,mpc8543-i2c", .data = &mpc_i2c_data_8543, },
{.compatible = "fsl,mpc8544-i2c", .data = &mpc_i2c_data_8544, },
@@ -613,7 +671,6 @@ static const struct of_device_id mpc_i2c_of_match[] = {
};
MODULE_DEVICE_TABLE(of, mpc_i2c_of_match);
-
/* Structure for a device driver */
static struct of_platform_driver mpc_i2c_driver = {
.match_table = mpc_i2c_of_match,
@@ -646,5 +703,5 @@ module_exit(fsl_i2c_exit);
MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>");
MODULE_DESCRIPTION("I2C-Bus adapter for MPC107 bridge and "
- "MPC824x/85xx/52xx processors");
+ "MPC824x/83xx/85xx/86xx/512x/52xx processors");
MODULE_LICENSE("GPL");
--
1.6.2.5
^ permalink raw reply related
* [PATCH v6 4/4] powerpc: doc/dts-bindings: update doc of FSL I2C bindings
From: Wolfgang Grandegger @ 2010-02-10 10:05 UTC (permalink / raw)
To: Linux-i2c
Cc: Devicetree-discuss, Linuxppc-dev, Wolfgang Grandegger, Ben Dooks
In-Reply-To: <1265796330-15976-4-git-send-email-wg@grandegger.com>
From: Wolfgang Grandegger <wg@denx.de>
This patch adds the MPC5121 to the list of supported devices,
enhances the doc of the "clock-frequency" property and removes
the obsolete "cell-index", "device_type" and "fsl-i2c" property.
Furthermore an example for the MPC5121 has been added.
Signed-off-by: Wolfgang Grandegger <wg@denx.de>
Reviewed-by: Wolfram Sang <w.sang@pengutronix.de>
---
Documentation/powerpc/dts-bindings/fsl/i2c.txt | 30 +++++++++++++++++------
1 files changed, 22 insertions(+), 8 deletions(-)
diff --git a/Documentation/powerpc/dts-bindings/fsl/i2c.txt b/Documentation/powerpc/dts-bindings/fsl/i2c.txt
index b6d2e21..50da203 100644
--- a/Documentation/powerpc/dts-bindings/fsl/i2c.txt
+++ b/Documentation/powerpc/dts-bindings/fsl/i2c.txt
@@ -2,15 +2,14 @@
Required properties :
- - device_type : Should be "i2c"
- reg : Offset and length of the register set for the device
+ - compatible : should be "fsl,CHIP-i2c" where CHIP is the name of a
+ compatible processor, e.g. mpc8313, mpc8543, mpc8544, mpc5121,
+ mpc5200 or mpc5200b. For the mpc5121, an additional node
+ "fsl,mpc5121-i2c-ctrl" is required as shown in the example below.
Recommended properties :
- - compatible : compatibility list with 2 entries, the first should
- be "fsl,CHIP-i2c" where CHIP is the name of a compatible processor,
- e.g. mpc8313, mpc8543, mpc8544, mpc5200 or mpc5200b. The second one
- should be "fsl-i2c".
- interrupts : <a b> where a is the interrupt number and b is a
field that represents an encoding of the sense and level
information for the interrupt. This should be encoded based on
@@ -24,25 +23,40 @@ Recommended properties :
Examples :
+ /* MPC5121 based board */
+ i2c@1740 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,mpc5121-i2c", "fsl-i2c";
+ reg = <0x1740 0x20>;
+ interrupts = <11 0x8>;
+ interrupt-parent = <&ipic>;
+ clock-frequency = <100000>;
+ };
+
+ i2ccontrol@1760 {
+ compatible = "fsl,mpc5121-i2c-ctrl";
+ reg = <0x1760 0x8>;
+ };
+
+ /* MPC5200B based board */
i2c@3d00 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
- cell-index = <0>;
reg = <0x3d00 0x40>;
interrupts = <2 15 0>;
interrupt-parent = <&mpc5200_pic>;
fsl,preserve-clocking;
};
+ /* MPC8544 base board */
i2c@3100 {
#address-cells = <1>;
#size-cells = <0>;
- cell-index = <1>;
compatible = "fsl,mpc8544-i2c", "fsl-i2c";
reg = <0x3100 0x100>;
interrupts = <43 2>;
interrupt-parent = <&mpic>;
clock-frequency = <400000>;
};
-
--
1.6.2.5
^ permalink raw reply related
* Re: [PATCH v4 1/3] i2c-mpc: use __devinit[data] for initialization functions and data
From: Wolfgang Grandegger @ 2010-02-10 10:09 UTC (permalink / raw)
To: Grant Likely
Cc: Ben Dooks, Devicetree-discuss, Linuxppc-dev, Linux-i2c,
Wolfgang Grandegger
In-Reply-To: <fa686aa41002090941je3e4fdqbecf2616a8b90e42@mail.gmail.com>
Grant Likely wrote:
> On Thu, Jan 28, 2010 at 6:25 AM, Wolfgang Grandegger <wg@grandegger.com> wrote:
>> From: Wolfgang Grandegger <wg@denx.de>
>>
>> "__devinit[data]" has not yet been used for all initialization functions
>> and data. To avoid truncating lines, the struct "mpc_i2c_match_data" has
>> been renamed to "mpc_i2c_data", which is even the better name.
>>
>> Signed-off-by: Wolfgang Grandegger <wg@denx.de>
>
> Several comments below.
>
>> ---
>> drivers/i2c/busses/i2c-mpc.c | 103 +++++++++++++++++++----------------------
>> 1 files changed, 48 insertions(+), 55 deletions(-)
>>
>> diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
>> index f627001..275ebe6 100644
>> --- a/drivers/i2c/busses/i2c-mpc.c
>> +++ b/drivers/i2c/busses/i2c-mpc.c
>> @@ -66,7 +66,7 @@ struct mpc_i2c_divider {
>> u16 fdr; /* including dfsrr */
>> };
>>
>> -struct mpc_i2c_match_data {
>> +struct mpc_i2c_data {
>> void (*setclock)(struct device_node *node,
>> struct mpc_i2c *i2c,
>> u32 clock, u32 prescaler);
>> @@ -165,7 +165,7 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
>> }
>>
>> #ifdef CONFIG_PPC_MPC52xx
>> -static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] = {
>> +static const struct __devinitdata mpc_i2c_divider mpc_i2c_dividers_52xx[] = {
>
> __devinitdata goes at the end, immediately before the '='. Ditto
> throughout the file.
This made a difference and revealed section mismatches. "const" seems to
be incompatible with "__devinitdata".
>> {20, 0x20}, {22, 0x21}, {24, 0x22}, {26, 0x23},
>> {28, 0x24}, {30, 0x01}, {32, 0x25}, {34, 0x02},
>> {36, 0x26}, {40, 0x27}, {44, 0x04}, {48, 0x28},
>> @@ -582,44 +584,35 @@ static int __devexit fsl_i2c_remove(struct of_device *op)
>> return 0;
>> };
>>
>> +static struct mpc_i2c_data __devinitdata mpc_i2c_data_52xx = {
>> + .setclock = mpc_i2c_setclock_52xx,
>> +};
>> +
>> +static struct mpc_i2c_data __devinitdata mpc_i2c_data_8313 = {
>> + .setclock = mpc_i2c_setclock_8xxx,
>> +};
>> +
>> +static struct mpc_i2c_data __devinitdata mpc_i2c_data_8543 = {
>> + .setclock = mpc_i2c_setclock_8xxx,
>> + .prescaler = 2,
>> +};
>> +
>> +static struct mpc_i2c_data __devinitdata mpc_i2c_data_8544 = {
>> + .setclock = mpc_i2c_setclock_8xxx,
>> + .prescaler = 3,
>> +};
>> +
>> static const struct of_device_id mpc_i2c_of_match[] = {
>
> You can make this __devinitdata too.
This results in a section mismatch as it's referenced by fsl_i2c_init().
I just sent out v6. Hope it's OK now.
Thanks,
Wolfgang.
^ permalink raw reply
* Re: [PATCH v6 2/4] i2c-mpc: rename "setclock" initialization functions to "setup"
From: Wolfram Sang @ 2010-02-10 10:21 UTC (permalink / raw)
To: Wolfgang Grandegger
Cc: Wolfgang Grandegger, Devicetree-discuss, Linuxppc-dev, Linux-i2c,
Ben Dooks
In-Reply-To: <1265796330-15976-3-git-send-email-wg@grandegger.com>
[-- Attachment #1: Type: text/plain, Size: 604 bytes --]
On Wed, Feb 10, 2010 at 11:05:28AM +0100, Wolfgang Grandegger wrote:
> From: Wolfgang Grandegger <wg@denx.de>
>
> To prepare support for the MPC512x processors from Freescale the
> "setclock" initialization functions have been renamed to "setup"
> because I2C interrupts must be enabled for the MPC512x by this
> function as well.
>
> Signed-off-by: Wolfgang Grandegger <wg@denx.de>
Acked-by: Wolfram Sang <w.sang@pengutronix.de>
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* Re: [net-next-2.6 PATCH 2/3] fs_enet: Add support for MPC512x to fs_enet driver
From: Wolfgang Grandegger @ 2010-02-10 10:20 UTC (permalink / raw)
To: David Miller; +Cc: wd, dzu, netdev, linuxppc-dev, agust, kosmo
In-Reply-To: <4B72794A.9010805@grandegger.com>
Wolfgang Grandegger wrote:
> Hi David,
>
> David Miller wrote:
>> From: Anatolij Gustschin <agust@denx.de>
>> Date: Tue, 9 Feb 2010 15:23:17 +0100
>>
>>> In my understanding, in the ESP scsi driver the set of defines for
>>> the register offsets is common for all chip drivers. The chip driver
>>> methods for register access translate the offsets because the
>>> registers on some chips are at different intervals (4-byte, 1-byte,
>>> 16-byte for mac_esp.c). But the register order is the same for
>>> different chips.
>>>
>>> In our case non only the register order is not the same for 8xx
>>> FEC and 5121 FEC, but there are also other differences, different
>>> reserved areas between several registers, some registers are
>>> available only on 8xx and some only on 5121.
>> That only means you would need to use a table based register address
>> translation scheme, rather than a simple calculation. Something
>> like:
>>
>> static unsigned int chip_xxx_table[] =
>> {
>> [GENERIC_REG_FOO] = CHIP_XXX_FOO,
>> ...
>> };
>>
>> static u32 chip_xxx_read_reg(struct chip *p, unsigned int reg)
>> {
>> unsigned int reg_off = chip_xxx_table[reg];
>>
>> return readl(p->regs + reg_off);
>> }
>>
>> And this table can have special tokens in entries for
>> registers which do not exist on a chip, so you can trap
>> attempted access to them in these read/write handlers.
>
> Yes, that could be done, but to honest, I do not see any improvement in
> respect to the previous patch where the register offset were defined via
> pointers within a structure.
>
>> Please stop looking for excuses to fork this driver, a
>> unified driver I think can be done cleanly.
>
> Other people suggested to fork the driver because it's getting too ugly.
That said, I think there is consensus that it does not make sense, and
it's even not possible, to provide a kernel image which runs on both,
the 8xx and the mpc512x. Therefore, there is also no need for sharing
this driver at run time. Compile time selection would allow a more
elegant and transparent implementation. Would that be an acceptable
solution?
Wolfgang.
^ permalink raw reply
* Re: [PATCH v4 1/3] i2c-mpc: use __devinit[data] for initialization functions and data
From: Stephen Rothwell @ 2010-02-10 10:32 UTC (permalink / raw)
To: Wolfgang Grandegger
Cc: Devicetree-discuss, Linux-i2c, Ben Dooks, Linuxppc-dev,
Wolfgang Grandegger
In-Reply-To: <4B7285D5.9060008@grandegger.com>
[-- Attachment #1: Type: text/plain, Size: 510 bytes --]
Hi Wolfgang,
On Wed, 10 Feb 2010 11:09:25 +0100 Wolfgang Grandegger <wg@grandegger.com> wrote:
>
> > __devinitdata goes at the end, immediately before the '='. Ditto
> > throughout the file.
>
> This made a difference and revealed section mismatches. "const" seems to
> be incompatible with "__devinitdata".
Maybe try no "const" and "__devinitconst" (I am not sure if both will
work).
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply
* Re: [PATCH v4 1/3] i2c-mpc: use __devinit[data] for initialization functions and data
From: Wolfgang Grandegger @ 2010-02-10 10:53 UTC (permalink / raw)
To: Stephen Rothwell
Cc: Devicetree-discuss, Linux-i2c, Ben Dooks, Linuxppc-dev,
Wolfgang Grandegger
In-Reply-To: <20100210213203.48a9105e.sfr@canb.auug.org.au>
Stephen Rothwell wrote:
> Hi Wolfgang,
>
> On Wed, 10 Feb 2010 11:09:25 +0100 Wolfgang Grandegger <wg@grandegger.com> wrote:
>>> __devinitdata goes at the end, immediately before the '='. Ditto
>>> throughout the file.
>> This made a difference and revealed section mismatches. "const" seems to
>> be incompatible with "__devinitdata".
>
> Maybe try no "const" and "__devinitconst" (I am not sure if both will
> work).
Yes, that works, even together with "const". To avoid rolling out the
whole patch series again, I can prepare a follow-up patch fixing this issue.
Wolfgang.
^ permalink raw reply
* [PATCH 1/6] powerpc: Use lwarx hint in spinlocks
From: Anton Blanchard @ 2010-02-10 10:57 UTC (permalink / raw)
To: benh; +Cc: npiggin, linuxppc-dev
Recent versions of the PowerPC architecture added a hint bit to the larx
instructions to differentiate between an atomic operation and a lock operation:
> 0 Other programs might attempt to modify the word in storage addressed by EA
> even if the subsequent Store Conditional succeeds.
>
> 1 Other programs will not attempt to modify the word in storage addressed by
> EA until the program that has acquired the lock performs a subsequent store
> releasing the lock.
To avoid a binutils dependency this patch create macros for the extended lwarx
format and uses it in the spinlock code. To test this change I used a simple
test case that acquires and releases a global pthread mutex:
pthread_mutex_lock(&mutex);
pthread_mutex_unlock(&mutex);
On a 32 core POWER6, running 32 test threads we spend almost all our time in
the futex spinlock code:
94.37% perf [kernel] [k] ._raw_spin_lock
|
|--99.95%-- ._raw_spin_lock
| |
| |--63.29%-- .futex_wake
| |
| |--36.64%-- .futex_wait_setup
Which is a good test for this patch. The results (in lock/unlock operations per
second) are:
before: 1538203 ops/sec
after: 2189219 ops/sec
An improvement of 42%
A 32 core POWER7 improves even more:
before: 1279529 ops/sec
after: 2282076 ops/sec
An improvement of 78%
Signed-off-by: Anton Blanchard <anton@samba.org>
---
v2: We do this only for 64bit until we can verify all 32bit CPUs.
Tested so far: 970 (thanks Ben), POWER5, POWER6, POWER7
Still to test: RS64, POWER3, POWER4
Index: powerpc.git/arch/powerpc/include/asm/ppc-opcode.h
===================================================================
--- powerpc.git.orig/arch/powerpc/include/asm/ppc-opcode.h 2010-02-10 15:28:58.453072362 +1100
+++ powerpc.git/arch/powerpc/include/asm/ppc-opcode.h 2010-02-10 15:33:08.963071793 +1100
@@ -24,6 +24,7 @@
#define PPC_INST_ISEL_MASK 0xfc00003e
#define PPC_INST_LSWI 0x7c0004aa
#define PPC_INST_LSWX 0x7c00042a
+#define PPC_INST_LWARX 0x7c000029
#define PPC_INST_LWSYNC 0x7c2004ac
#define PPC_INST_LXVD2X 0x7c000698
#define PPC_INST_MCRXR 0x7c000400
@@ -55,15 +56,28 @@
#define __PPC_RA(a) (((a) & 0x1f) << 16)
#define __PPC_RB(b) (((b) & 0x1f) << 11)
#define __PPC_RS(s) (((s) & 0x1f) << 21)
+#define __PPC_RT(s) __PPC_RS(s)
#define __PPC_XS(s) ((((s) & 0x1f) << 21) | (((s) & 0x20) >> 5))
#define __PPC_T_TLB(t) (((t) & 0x3) << 21)
#define __PPC_WC(w) (((w) & 0x3) << 21)
+/*
+ * Only use the larx hint bit on 64bit CPUs. Once we verify it doesn't have
+ * any side effects on all 32bit processors, we can do this all the time.
+ */
+#ifdef CONFIG_PPC64
+#define __PPC_EH(eh) (((eh) & 0x1) << 0)
+#else
+#define __PPC_EH(eh) 0
+#endif
/* Deal with instructions that older assemblers aren't aware of */
#define PPC_DCBAL(a, b) stringify_in_c(.long PPC_INST_DCBAL | \
__PPC_RA(a) | __PPC_RB(b))
#define PPC_DCBZL(a, b) stringify_in_c(.long PPC_INST_DCBZL | \
__PPC_RA(a) | __PPC_RB(b))
+#define PPC_LWARX(t, a, b, eh) stringify_in_c(.long PPC_INST_LWARX | \
+ __PPC_RT(t) | __PPC_RA(a) | \
+ __PPC_RB(b) | __PPC_EH(eh))
#define PPC_MSGSND(b) stringify_in_c(.long PPC_INST_MSGSND | \
__PPC_RB(b))
#define PPC_RFCI stringify_in_c(.long PPC_INST_RFCI)
Index: powerpc.git/arch/powerpc/include/asm/spinlock.h
===================================================================
--- powerpc.git.orig/arch/powerpc/include/asm/spinlock.h 2010-02-10 15:28:58.473072327 +1100
+++ powerpc.git/arch/powerpc/include/asm/spinlock.h 2010-02-10 15:29:29.454322618 +1100
@@ -27,6 +27,7 @@
#endif
#include <asm/asm-compat.h>
#include <asm/synch.h>
+#include <asm/ppc-opcode.h>
#define arch_spin_is_locked(x) ((x)->slock != 0)
@@ -60,7 +61,7 @@ static inline unsigned long __arch_spin_
token = LOCK_TOKEN;
__asm__ __volatile__(
-"1: lwarx %0,0,%2\n\
+"1: " PPC_LWARX(%0,0,%2,1) "\n\
cmpwi 0,%0,0\n\
bne- 2f\n\
stwcx. %1,0,%2\n\
@@ -186,7 +187,7 @@ static inline long __arch_read_trylock(a
long tmp;
__asm__ __volatile__(
-"1: lwarx %0,0,%1\n"
+"1: " PPC_LWARX(%0,0,%1,1) "\n"
__DO_SIGN_EXTEND
" addic. %0,%0,1\n\
ble- 2f\n"
@@ -211,7 +212,7 @@ static inline long __arch_write_trylock(
token = WRLOCK_TOKEN;
__asm__ __volatile__(
-"1: lwarx %0,0,%2\n\
+"1: " PPC_LWARX(%0,0,%2,1) "\n\
cmpwi 0,%0,0\n\
bne- 2f\n"
PPC405_ERR77(0,%1)
^ permalink raw reply
* [PATCH 2/6] powerpc: Use lwarx/ldarx hint in bit locks
From: Anton Blanchard @ 2010-02-10 11:02 UTC (permalink / raw)
To: benh; +Cc: npiggin, linuxppc-dev
In-Reply-To: <20100210105728.GA3399@kryten>
This patch implements the lwarx/ldarx hint bit for bit locks.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Index: powerpc.git/arch/powerpc/include/asm/asm-compat.h
===================================================================
--- powerpc.git.orig/arch/powerpc/include/asm/asm-compat.h 2010-02-10 17:16:07.003090026 +1100
+++ powerpc.git/arch/powerpc/include/asm/asm-compat.h 2010-02-10 17:16:39.144321846 +1100
@@ -2,6 +2,7 @@
#define _ASM_POWERPC_ASM_COMPAT_H
#include <asm/types.h>
+#include <asm/ppc-opcode.h>
#ifdef __ASSEMBLY__
# define stringify_in_c(...) __VA_ARGS__
@@ -24,7 +25,7 @@
#define PPC_LONG stringify_in_c(.llong)
#define PPC_LONG_ALIGN stringify_in_c(.balign 8)
#define PPC_TLNEI stringify_in_c(tdnei)
-#define PPC_LLARX stringify_in_c(ldarx)
+#define PPC_LLARX(t, a, b, eh) PPC_LDARX(t, a, b, eh)
#define PPC_STLCX stringify_in_c(stdcx.)
#define PPC_CNTLZL stringify_in_c(cntlzd)
@@ -46,7 +47,7 @@
#define PPC_LONG stringify_in_c(.long)
#define PPC_LONG_ALIGN stringify_in_c(.balign 4)
#define PPC_TLNEI stringify_in_c(twnei)
-#define PPC_LLARX stringify_in_c(lwarx)
+#define PPC_LLARX(t, a, b, eh) PPC_LWARX(t, a, b, eh)
#define PPC_STLCX stringify_in_c(stwcx.)
#define PPC_CNTLZL stringify_in_c(cntlzw)
#define PPC_MTOCRF stringify_in_c(mtcrf)
Index: powerpc.git/arch/powerpc/include/asm/bitops.h
===================================================================
--- powerpc.git.orig/arch/powerpc/include/asm/bitops.h 2010-02-10 17:16:07.013074408 +1100
+++ powerpc.git/arch/powerpc/include/asm/bitops.h 2010-02-10 17:16:14.253072938 +1100
@@ -65,7 +65,7 @@ static __inline__ void fn(unsigned long
unsigned long *p = (unsigned long *)_p; \
__asm__ __volatile__ ( \
prefix \
-"1:" PPC_LLARX "%0,0,%3\n" \
+"1:" PPC_LLARX(%0,0,%3,0) "\n" \
stringify_in_c(op) "%0,%0,%2\n" \
PPC405_ERR77(0,%3) \
PPC_STLCX "%0,0,%3\n" \
@@ -103,31 +103,31 @@ static __inline__ void change_bit(int nr
/* Like DEFINE_BITOP(), with changes to the arguments to 'op' and the output
* operands. */
-#define DEFINE_TESTOP(fn, op, prefix, postfix) \
-static __inline__ unsigned long fn( \
- unsigned long mask, \
- volatile unsigned long *_p) \
-{ \
- unsigned long old, t; \
- unsigned long *p = (unsigned long *)_p; \
- __asm__ __volatile__ ( \
- prefix \
-"1:" PPC_LLARX "%0,0,%3\n" \
- stringify_in_c(op) "%1,%0,%2\n" \
- PPC405_ERR77(0,%3) \
- PPC_STLCX "%1,0,%3\n" \
- "bne- 1b\n" \
- postfix \
- : "=&r" (old), "=&r" (t) \
- : "r" (mask), "r" (p) \
- : "cc", "memory"); \
- return (old & mask); \
-}
-
-DEFINE_TESTOP(test_and_set_bits, or, LWSYNC_ON_SMP, ISYNC_ON_SMP)
-DEFINE_TESTOP(test_and_set_bits_lock, or, "", ISYNC_ON_SMP)
-DEFINE_TESTOP(test_and_clear_bits, andc, LWSYNC_ON_SMP, ISYNC_ON_SMP)
-DEFINE_TESTOP(test_and_change_bits, xor, LWSYNC_ON_SMP, ISYNC_ON_SMP)
+#define DEFINE_TESTOP(fn, op, prefix, postfix, eh) \
+static __inline__ unsigned long fn( \
+ unsigned long mask, \
+ volatile unsigned long *_p) \
+{ \
+ unsigned long old, t; \
+ unsigned long *p = (unsigned long *)_p; \
+ __asm__ __volatile__ ( \
+ prefix \
+"1:" PPC_LLARX(%0,0,%3,eh) "\n" \
+ stringify_in_c(op) "%1,%0,%2\n" \
+ PPC405_ERR77(0,%3) \
+ PPC_STLCX "%1,0,%3\n" \
+ "bne- 1b\n" \
+ postfix \
+ : "=&r" (old), "=&r" (t) \
+ : "r" (mask), "r" (p) \
+ : "cc", "memory"); \
+ return (old & mask); \
+}
+
+DEFINE_TESTOP(test_and_set_bits, or, LWSYNC_ON_SMP, ISYNC_ON_SMP, 0)
+DEFINE_TESTOP(test_and_set_bits_lock, or, "", ISYNC_ON_SMP, 1)
+DEFINE_TESTOP(test_and_clear_bits, andc, LWSYNC_ON_SMP, ISYNC_ON_SMP, 0)
+DEFINE_TESTOP(test_and_change_bits, xor, LWSYNC_ON_SMP, ISYNC_ON_SMP, 0)
static __inline__ int test_and_set_bit(unsigned long nr,
volatile unsigned long *addr)
Index: powerpc.git/arch/powerpc/include/asm/local.h
===================================================================
--- powerpc.git.orig/arch/powerpc/include/asm/local.h 2010-02-10 17:16:07.023072625 +1100
+++ powerpc.git/arch/powerpc/include/asm/local.h 2010-02-10 17:16:14.253072938 +1100
@@ -24,7 +24,7 @@ static __inline__ long local_add_return(
long t;
__asm__ __volatile__(
-"1:" PPC_LLARX "%0,0,%2 # local_add_return\n\
+"1:" PPC_LLARX(%0,0,%2,0) " # local_add_return\n\
add %0,%1,%0\n"
PPC405_ERR77(0,%2)
PPC_STLCX "%0,0,%2 \n\
@@ -43,7 +43,7 @@ static __inline__ long local_sub_return(
long t;
__asm__ __volatile__(
-"1:" PPC_LLARX "%0,0,%2 # local_sub_return\n\
+"1:" PPC_LLARX(%0,0,%2,0) " # local_sub_return\n\
subf %0,%1,%0\n"
PPC405_ERR77(0,%2)
PPC_STLCX "%0,0,%2 \n\
@@ -60,7 +60,7 @@ static __inline__ long local_inc_return(
long t;
__asm__ __volatile__(
-"1:" PPC_LLARX "%0,0,%1 # local_inc_return\n\
+"1:" PPC_LLARX(%0,0,%1,0) " # local_inc_return\n\
addic %0,%0,1\n"
PPC405_ERR77(0,%1)
PPC_STLCX "%0,0,%1 \n\
@@ -87,7 +87,7 @@ static __inline__ long local_dec_return(
long t;
__asm__ __volatile__(
-"1:" PPC_LLARX "%0,0,%1 # local_dec_return\n\
+"1:" PPC_LLARX(%0,0,%1,0) " # local_dec_return\n\
addic %0,%0,-1\n"
PPC405_ERR77(0,%1)
PPC_STLCX "%0,0,%1\n\
@@ -117,7 +117,7 @@ static __inline__ int local_add_unless(l
long t;
__asm__ __volatile__ (
-"1:" PPC_LLARX "%0,0,%1 # local_add_unless\n\
+"1:" PPC_LLARX(%0,0,%1,0) " # local_add_unless\n\
cmpw 0,%0,%3 \n\
beq- 2f \n\
add %0,%2,%0 \n"
@@ -147,7 +147,7 @@ static __inline__ long local_dec_if_posi
long t;
__asm__ __volatile__(
-"1:" PPC_LLARX "%0,0,%1 # local_dec_if_positive\n\
+"1:" PPC_LLARX(%0,0,%1,0) " # local_dec_if_positive\n\
cmpwi %0,1\n\
addi %0,%0,-1\n\
blt- 2f\n"
Index: powerpc.git/arch/powerpc/include/asm/ppc-opcode.h
===================================================================
--- powerpc.git.orig/arch/powerpc/include/asm/ppc-opcode.h 2010-02-10 17:16:07.013074408 +1100
+++ powerpc.git/arch/powerpc/include/asm/ppc-opcode.h 2010-02-10 17:16:14.263072384 +1100
@@ -22,6 +22,7 @@
#define PPC_INST_DCBZL 0x7c2007ec
#define PPC_INST_ISEL 0x7c00001e
#define PPC_INST_ISEL_MASK 0xfc00003e
+#define PPC_INST_LDARX 0x7c0000a8
#define PPC_INST_LSWI 0x7c0004aa
#define PPC_INST_LSWX 0x7c00042a
#define PPC_INST_LWARX 0x7c000029
@@ -75,6 +76,9 @@
__PPC_RA(a) | __PPC_RB(b))
#define PPC_DCBZL(a, b) stringify_in_c(.long PPC_INST_DCBZL | \
__PPC_RA(a) | __PPC_RB(b))
+#define PPC_LDARX(t, a, b, eh) stringify_in_c(.long PPC_INST_LDARX | \
+ __PPC_RT(t) | __PPC_RA(a) | \
+ __PPC_RB(b) | __PPC_EH(eh))
#define PPC_LWARX(t, a, b, eh) stringify_in_c(.long PPC_INST_LWARX | \
__PPC_RT(t) | __PPC_RA(a) | \
__PPC_RB(b) | __PPC_EH(eh))
^ permalink raw reply
* [PATCH 3/6] powerpc: Convert open coded native hashtable bit lock
From: Anton Blanchard @ 2010-02-10 11:03 UTC (permalink / raw)
To: benh; +Cc: npiggin, linuxppc-dev
In-Reply-To: <20100210110236.GB3399@kryten>
Now we have real bit locks use them instead of open coding it.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
index 056d23a..9e1aa4f 100644
--- a/arch/powerpc/mm/hash_native_64.c
+++ b/arch/powerpc/mm/hash_native_64.c
@@ -122,7 +122,7 @@ static inline void native_lock_hpte(struct hash_pte *hptep)
unsigned long *word = &hptep->v;
while (1) {
- if (!test_and_set_bit(HPTE_LOCK_BIT, word))
+ if (!test_and_set_bit_lock(HPTE_LOCK_BIT, word))
break;
while(test_bit(HPTE_LOCK_BIT, word))
cpu_relax();
@@ -133,8 +133,7 @@ static inline void native_unlock_hpte(struct hash_pte *hptep)
{
unsigned long *word = &hptep->v;
- asm volatile("lwsync":::"memory");
- clear_bit(HPTE_LOCK_BIT, word);
+ clear_bit_unlock(HPTE_LOCK_BIT, word);
}
static long native_hpte_insert(unsigned long hpte_group, unsigned long va,
^ permalink raw reply related
* [PATCH 4/6] powerpc: Rename LWSYNC_ON_SMP to PPC_RELEASE_BARRIER, ISYNC_ON_SMP to PPC_ACQUIRE_BARRIER
From: Anton Blanchard @ 2010-02-10 11:04 UTC (permalink / raw)
To: benh; +Cc: npiggin, linuxppc-dev
In-Reply-To: <20100210110306.GC3399@kryten>
For performance reasons we are about to change ISYNC_ON_SMP to sometimes be
lwsync. Now that the macro name doesn't make sense, change it and LWSYNC_ON_SMP
to better explain what the barriers are doing.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Index: powerpc.git/arch/powerpc/include/asm/atomic.h
===================================================================
--- powerpc.git.orig/arch/powerpc/include/asm/atomic.h 2010-02-10 17:12:30.264322204 +1100
+++ powerpc.git/arch/powerpc/include/asm/atomic.h 2010-02-10 17:13:05.355571902 +1100
@@ -49,13 +49,13 @@ static __inline__ int atomic_add_return(
int t;
__asm__ __volatile__(
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: lwarx %0,0,%2 # atomic_add_return\n\
add %0,%1,%0\n"
PPC405_ERR77(0,%2)
" stwcx. %0,0,%2 \n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
: "=&r" (t)
: "r" (a), "r" (&v->counter)
: "cc", "memory");
@@ -85,13 +85,13 @@ static __inline__ int atomic_sub_return(
int t;
__asm__ __volatile__(
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: lwarx %0,0,%2 # atomic_sub_return\n\
subf %0,%1,%0\n"
PPC405_ERR77(0,%2)
" stwcx. %0,0,%2 \n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
: "=&r" (t)
: "r" (a), "r" (&v->counter)
: "cc", "memory");
@@ -119,13 +119,13 @@ static __inline__ int atomic_inc_return(
int t;
__asm__ __volatile__(
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: lwarx %0,0,%1 # atomic_inc_return\n\
addic %0,%0,1\n"
PPC405_ERR77(0,%1)
" stwcx. %0,0,%1 \n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
: "=&r" (t)
: "r" (&v->counter)
: "cc", "xer", "memory");
@@ -163,13 +163,13 @@ static __inline__ int atomic_dec_return(
int t;
__asm__ __volatile__(
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: lwarx %0,0,%1 # atomic_dec_return\n\
addic %0,%0,-1\n"
PPC405_ERR77(0,%1)
" stwcx. %0,0,%1\n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
: "=&r" (t)
: "r" (&v->counter)
: "cc", "xer", "memory");
@@ -194,7 +194,7 @@ static __inline__ int atomic_add_unless(
int t;
__asm__ __volatile__ (
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: lwarx %0,0,%1 # atomic_add_unless\n\
cmpw 0,%0,%3 \n\
beq- 2f \n\
@@ -202,7 +202,7 @@ static __inline__ int atomic_add_unless(
PPC405_ERR77(0,%2)
" stwcx. %0,0,%1 \n\
bne- 1b \n"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
" subf %0,%2,%0 \n\
2:"
: "=&r" (t)
@@ -227,7 +227,7 @@ static __inline__ int atomic_dec_if_posi
int t;
__asm__ __volatile__(
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: lwarx %0,0,%1 # atomic_dec_if_positive\n\
cmpwi %0,1\n\
addi %0,%0,-1\n\
@@ -235,7 +235,7 @@ static __inline__ int atomic_dec_if_posi
PPC405_ERR77(0,%1)
" stwcx. %0,0,%1\n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
"\n\
2:" : "=&b" (t)
: "r" (&v->counter)
@@ -286,12 +286,12 @@ static __inline__ long atomic64_add_retu
long t;
__asm__ __volatile__(
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: ldarx %0,0,%2 # atomic64_add_return\n\
add %0,%1,%0\n\
stdcx. %0,0,%2 \n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
: "=&r" (t)
: "r" (a), "r" (&v->counter)
: "cc", "memory");
@@ -320,12 +320,12 @@ static __inline__ long atomic64_sub_retu
long t;
__asm__ __volatile__(
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: ldarx %0,0,%2 # atomic64_sub_return\n\
subf %0,%1,%0\n\
stdcx. %0,0,%2 \n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
: "=&r" (t)
: "r" (a), "r" (&v->counter)
: "cc", "memory");
@@ -352,12 +352,12 @@ static __inline__ long atomic64_inc_retu
long t;
__asm__ __volatile__(
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: ldarx %0,0,%1 # atomic64_inc_return\n\
addic %0,%0,1\n\
stdcx. %0,0,%1 \n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
: "=&r" (t)
: "r" (&v->counter)
: "cc", "xer", "memory");
@@ -394,12 +394,12 @@ static __inline__ long atomic64_dec_retu
long t;
__asm__ __volatile__(
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: ldarx %0,0,%1 # atomic64_dec_return\n\
addic %0,%0,-1\n\
stdcx. %0,0,%1\n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
: "=&r" (t)
: "r" (&v->counter)
: "cc", "xer", "memory");
@@ -419,13 +419,13 @@ static __inline__ long atomic64_dec_if_p
long t;
__asm__ __volatile__(
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: ldarx %0,0,%1 # atomic64_dec_if_positive\n\
addic. %0,%0,-1\n\
blt- 2f\n\
stdcx. %0,0,%1\n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
"\n\
2:" : "=&r" (t)
: "r" (&v->counter)
@@ -451,14 +451,14 @@ static __inline__ int atomic64_add_unles
long t;
__asm__ __volatile__ (
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: ldarx %0,0,%1 # atomic_add_unless\n\
cmpd 0,%0,%3 \n\
beq- 2f \n\
add %0,%2,%0 \n"
" stdcx. %0,0,%1 \n\
bne- 1b \n"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
" subf %0,%2,%0 \n\
2:"
: "=&r" (t)
Index: powerpc.git/arch/powerpc/include/asm/futex.h
===================================================================
--- powerpc.git.orig/arch/powerpc/include/asm/futex.h 2010-02-10 17:12:30.274322058 +1100
+++ powerpc.git/arch/powerpc/include/asm/futex.h 2010-02-10 17:13:05.355571902 +1100
@@ -11,7 +11,7 @@
#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
__asm__ __volatile ( \
- LWSYNC_ON_SMP \
+ PPC_RELEASE_BARRIER \
"1: lwarx %0,0,%2\n" \
insn \
PPC405_ERR77(0, %2) \
@@ -90,14 +90,14 @@ futex_atomic_cmpxchg_inatomic(int __user
return -EFAULT;
__asm__ __volatile__ (
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: lwarx %0,0,%2 # futex_atomic_cmpxchg_inatomic\n\
cmpw 0,%0,%3\n\
bne- 3f\n"
PPC405_ERR77(0,%2)
"2: stwcx. %4,0,%2\n\
bne- 1b\n"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
"3: .section .fixup,\"ax\"\n\
4: li %0,%5\n\
b 3b\n\
Index: powerpc.git/arch/powerpc/include/asm/mutex.h
===================================================================
--- powerpc.git.orig/arch/powerpc/include/asm/mutex.h 2010-02-10 17:12:30.244322286 +1100
+++ powerpc.git/arch/powerpc/include/asm/mutex.h 2010-02-10 17:13:05.355571902 +1100
@@ -15,7 +15,7 @@ static inline int __mutex_cmpxchg_lock(a
PPC405_ERR77(0,%1)
" stwcx. %3,0,%1\n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
"\n\
2:"
: "=&r" (t)
@@ -35,7 +35,7 @@ static inline int __mutex_dec_return_loc
PPC405_ERR77(0,%1)
" stwcx. %0,0,%1\n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
: "=&r" (t)
: "r" (&v->counter)
: "cc", "memory");
@@ -48,7 +48,7 @@ static inline int __mutex_inc_return_unl
int t;
__asm__ __volatile__(
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: lwarx %0,0,%1 # mutex unlock\n\
addic %0,%0,1\n"
PPC405_ERR77(0,%1)
Index: powerpc.git/arch/powerpc/include/asm/synch.h
===================================================================
--- powerpc.git.orig/arch/powerpc/include/asm/synch.h 2010-02-10 17:12:30.274322058 +1100
+++ powerpc.git/arch/powerpc/include/asm/synch.h 2010-02-10 17:13:05.355571902 +1100
@@ -37,11 +37,11 @@ static inline void isync(void)
#endif
#ifdef CONFIG_SMP
-#define ISYNC_ON_SMP "\n\tisync\n"
-#define LWSYNC_ON_SMP stringify_in_c(LWSYNC) "\n"
+#define PPC_ACQUIRE_BARRIER "\n\tisync\n"
+#define PPC_RELEASE_BARRIER stringify_in_c(LWSYNC) "\n"
#else
-#define ISYNC_ON_SMP
-#define LWSYNC_ON_SMP
+#define PPC_ACQUIRE_BARRIER
+#define PPC_RELEASE_BARRIER
#endif
#endif /* __KERNEL__ */
Index: powerpc.git/arch/powerpc/include/asm/bitops.h
===================================================================
--- powerpc.git.orig/arch/powerpc/include/asm/bitops.h 2010-02-10 17:12:50.094322149 +1100
+++ powerpc.git/arch/powerpc/include/asm/bitops.h 2010-02-10 17:13:15.125572158 +1100
@@ -78,7 +78,7 @@ static __inline__ void fn(unsigned long
DEFINE_BITOP(set_bits, or, "", "")
DEFINE_BITOP(clear_bits, andc, "", "")
-DEFINE_BITOP(clear_bits_unlock, andc, LWSYNC_ON_SMP, "")
+DEFINE_BITOP(clear_bits_unlock, andc, PPC_RELEASE_BARRIER, "")
DEFINE_BITOP(change_bits, xor, "", "")
static __inline__ void set_bit(int nr, volatile unsigned long *addr)
@@ -124,10 +124,14 @@ static __inline__ unsigned long fn( \
return (old & mask); \
}
-DEFINE_TESTOP(test_and_set_bits, or, LWSYNC_ON_SMP, ISYNC_ON_SMP, 0)
-DEFINE_TESTOP(test_and_set_bits_lock, or, "", ISYNC_ON_SMP, 1)
-DEFINE_TESTOP(test_and_clear_bits, andc, LWSYNC_ON_SMP, ISYNC_ON_SMP, 0)
-DEFINE_TESTOP(test_and_change_bits, xor, LWSYNC_ON_SMP, ISYNC_ON_SMP, 0)
+DEFINE_TESTOP(test_and_set_bits, or, PPC_RELEASE_BARRIER,
+ PPC_ACQUIRE_BARRIER, 0)
+DEFINE_TESTOP(test_and_set_bits_lock, or, "",
+ PPC_ACQUIRE_BARRIER, 1)
+DEFINE_TESTOP(test_and_clear_bits, andc, PPC_RELEASE_BARRIER,
+ PPC_ACQUIRE_BARRIER, 0)
+DEFINE_TESTOP(test_and_change_bits, xor, PPC_RELEASE_BARRIER,
+ PPC_ACQUIRE_BARRIER, 0)
static __inline__ int test_and_set_bit(unsigned long nr,
volatile unsigned long *addr)
@@ -158,7 +162,7 @@ static __inline__ int test_and_change_bi
static __inline__ void __clear_bit_unlock(int nr, volatile unsigned long *addr)
{
- __asm__ __volatile__(LWSYNC_ON_SMP "" ::: "memory");
+ __asm__ __volatile__(PPC_RELEASE_BARRIER "" ::: "memory");
__clear_bit(nr, addr);
}
Index: powerpc.git/arch/powerpc/include/asm/system.h
===================================================================
--- powerpc.git.orig/arch/powerpc/include/asm/system.h 2010-02-10 17:12:30.284321702 +1100
+++ powerpc.git/arch/powerpc/include/asm/system.h 2010-02-10 17:13:05.355571902 +1100
@@ -232,12 +232,12 @@ __xchg_u32(volatile void *p, unsigned lo
unsigned long prev;
__asm__ __volatile__(
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: lwarx %0,0,%2 \n"
PPC405_ERR77(0,%2)
" stwcx. %3,0,%2 \n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
: "=&r" (prev), "+m" (*(volatile unsigned int *)p)
: "r" (p), "r" (val)
: "cc", "memory");
@@ -275,12 +275,12 @@ __xchg_u64(volatile void *p, unsigned lo
unsigned long prev;
__asm__ __volatile__(
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: ldarx %0,0,%2 \n"
PPC405_ERR77(0,%2)
" stdcx. %3,0,%2 \n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
: "=&r" (prev), "+m" (*(volatile unsigned long *)p)
: "r" (p), "r" (val)
: "cc", "memory");
@@ -366,14 +366,14 @@ __cmpxchg_u32(volatile unsigned int *p,
unsigned int prev;
__asm__ __volatile__ (
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: lwarx %0,0,%2 # __cmpxchg_u32\n\
cmpw 0,%0,%3\n\
bne- 2f\n"
PPC405_ERR77(0,%2)
" stwcx. %4,0,%2\n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
"\n\
2:"
: "=&r" (prev), "+m" (*p)
@@ -412,13 +412,13 @@ __cmpxchg_u64(volatile unsigned long *p,
unsigned long prev;
__asm__ __volatile__ (
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: ldarx %0,0,%2 # __cmpxchg_u64\n\
cmpd 0,%0,%3\n\
bne- 2f\n\
stdcx. %4,0,%2\n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
"\n\
2:"
: "=&r" (prev), "+m" (*p)
Index: powerpc.git/arch/powerpc/include/asm/spinlock.h
===================================================================
--- powerpc.git.orig/arch/powerpc/include/asm/spinlock.h 2010-02-10 17:12:48.464321650 +1100
+++ powerpc.git/arch/powerpc/include/asm/spinlock.h 2010-02-10 17:13:05.355571902 +1100
@@ -65,9 +65,10 @@ static inline unsigned long __arch_spin_
cmpwi 0,%0,0\n\
bne- 2f\n\
stwcx. %1,0,%2\n\
- bne- 1b\n\
- isync\n\
-2:" : "=&r" (tmp)
+ bne- 1b\n"
+ PPC_ACQUIRE_BARRIER
+"2:"
+ : "=&r" (tmp)
: "r" (token), "r" (&lock->slock)
: "cr0", "memory");
@@ -145,7 +146,7 @@ static inline void arch_spin_unlock(arch
{
SYNC_IO;
__asm__ __volatile__("# arch_spin_unlock\n\t"
- LWSYNC_ON_SMP: : :"memory");
+ PPC_RELEASE_BARRIER: : :"memory");
lock->slock = 0;
}
@@ -193,9 +194,9 @@ static inline long __arch_read_trylock(a
ble- 2f\n"
PPC405_ERR77(0,%1)
" stwcx. %0,0,%1\n\
- bne- 1b\n\
- isync\n\
-2:" : "=&r" (tmp)
+ bne- 1b\n"
+ PPC_ACQUIRE_BARRIER
+"2:" : "=&r" (tmp)
: "r" (&rw->lock)
: "cr0", "xer", "memory");
@@ -217,9 +218,9 @@ static inline long __arch_write_trylock(
bne- 2f\n"
PPC405_ERR77(0,%1)
" stwcx. %1,0,%2\n\
- bne- 1b\n\
- isync\n\
-2:" : "=&r" (tmp)
+ bne- 1b\n"
+ PPC_ACQUIRE_BARRIER
+"2:" : "=&r" (tmp)
: "r" (token), "r" (&rw->lock)
: "cr0", "memory");
@@ -270,7 +271,7 @@ static inline void arch_read_unlock(arch
__asm__ __volatile__(
"# read_unlock\n\t"
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: lwarx %0,0,%1\n\
addic %0,%0,-1\n"
PPC405_ERR77(0,%1)
@@ -284,7 +285,7 @@ static inline void arch_read_unlock(arch
static inline void arch_write_unlock(arch_rwlock_t *rw)
{
__asm__ __volatile__("# write_unlock\n\t"
- LWSYNC_ON_SMP: : :"memory");
+ PPC_RELEASE_BARRIER: : :"memory");
rw->lock = 0;
}
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox