diff options
author | Lennert Buytenhek <buytenh@wantstofly.org> | 2005-10-29 11:28:28 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2005-10-29 11:28:28 -0400 |
commit | b4a1f67fbfb848ded8cf0c6c305224534144ab2d (patch) | |
tree | 58988f4a66886659518e971fdc2445ecb9e81ecf | |
parent | ecbea7a2dae94092db9566bcd1f38535e9b3cde9 (diff) |
[ARM] 3053/1: introduce ixp2000_reg_wrb (ixp2000_reg_write plus readback)
Patch from Lennert Buytenhek
Introduce ixp2000_reg_wrb, which is a variant of ixp2000_reg_write
that does a readback from the target register, to make sure that
the write has been flushed out of the write buffer.
Unlike the previous (ineffective) readback in ixp2000_reg_write, this
readback is followed by an instruction that depends on the value of
the readback so that the CPU actually stalls until the readback has
completed.
Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
Signed-off-by: Deepak Saxena <dsaxena@plexity.net>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r-- | include/asm-arm/arch-ixp2000/platform.h | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/include/asm-arm/arch-ixp2000/platform.h b/include/asm-arm/arch-ixp2000/platform.h index 6e5b6a955abe..a66317ab2071 100644 --- a/include/asm-arm/arch-ixp2000/platform.h +++ b/include/asm-arm/arch-ixp2000/platform.h | |||
@@ -26,6 +26,31 @@ static inline void ixp2000_reg_write(volatile void *reg, unsigned long val) | |||
26 | } | 26 | } |
27 | 27 | ||
28 | /* | 28 | /* |
29 | * On the IXP2400, we can't use XCB=000 due to chip bugs. We use | ||
30 | * XCB=101 instead, but that makes all I/O accesses bufferable. This | ||
31 | * is not a problem in general, but we do have to be slightly more | ||
32 | * careful because I/O writes are no longer automatically flushed out | ||
33 | * of the write buffer. | ||
34 | * | ||
35 | * In cases where we want to make sure that a write has been flushed | ||
36 | * out of the write buffer before we proceed, for example when masking | ||
37 | * a device interrupt before re-enabling IRQs in CPSR, we can use this | ||
38 | * function, ixp2000_reg_wrb, which performs a write, a readback, and | ||
39 | * issues a dummy instruction dependent on the value of the readback | ||
40 | * (mov rX, rX) to make sure that the readback has completed before we | ||
41 | * continue. | ||
42 | */ | ||
43 | static inline void ixp2000_reg_wrb(volatile void *reg, unsigned long val) | ||
44 | { | ||
45 | unsigned long dummy; | ||
46 | |||
47 | *((volatile unsigned long *)reg) = val; | ||
48 | |||
49 | dummy = *((volatile unsigned long *)reg); | ||
50 | __asm__ __volatile__("mov %0, %0" : "+r" (dummy)); | ||
51 | } | ||
52 | |||
53 | /* | ||
29 | * Boards may multiplex different devices on the 2nd channel of | 54 | * Boards may multiplex different devices on the 2nd channel of |
30 | * the slowport interface that each need different configuration | 55 | * the slowport interface that each need different configuration |
31 | * settings. For example, the IXDP2400 uses channel 2 on the interface | 56 | * settings. For example, the IXDP2400 uses channel 2 on the interface |