summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/memory-barriers.txt124
1 files changed, 66 insertions, 58 deletions
diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt
index 3522f0cc772f..1660dde75e14 100644
--- a/Documentation/memory-barriers.txt
+++ b/Documentation/memory-barriers.txt
@@ -2517,80 +2517,88 @@ guarantees:
(*) readX(), writeX():
- The readX() and writeX() MMIO accessors take a pointer to the peripheral
- being accessed as an __iomem * parameter. For pointers mapped with the
- default I/O attributes (e.g. those returned by ioremap()), then the
- ordering guarantees are as follows:
-
- 1. All readX() and writeX() accesses to the same peripheral are ordered
- with respect to each other. For example, this ensures that MMIO register
- writes by the CPU to a particular device will arrive in program order.
-
- 2. A writeX() by the CPU to the peripheral will first wait for the
- completion of all prior CPU writes to memory. For example, this ensures
- that writes by the CPU to an outbound DMA buffer allocated by
- dma_alloc_coherent() will be visible to a DMA engine when the CPU writes
- to its MMIO control register to trigger the transfer.
-
- 3. A readX() by the CPU from the peripheral will complete before any
- subsequent CPU reads from memory can begin. For example, this ensures
- that reads by the CPU from an incoming DMA buffer allocated by
- dma_alloc_coherent() will not see stale data after reading from the DMA
- engine's MMIO status register to establish that the DMA transfer has
- completed.
-
- 4. A readX() by the CPU from the peripheral will complete before any
- subsequent delay() loop can begin execution. For example, this ensures
- that two MMIO register writes by the CPU to a peripheral will arrive at
- least 1us apart if the first write is immediately read back with readX()
- and udelay(1) is called prior to the second writeX().
-
- __iomem pointers obtained with non-default attributes (e.g. those returned
- by ioremap_wc()) are unlikely to provide many of these guarantees.
+ The readX() and writeX() MMIO accessors take a pointer to the
+ peripheral being accessed as an __iomem * parameter. For pointers
+ mapped with the default I/O attributes (e.g. those returned by
+ ioremap()), the ordering guarantees are as follows:
+
+ 1. All readX() and writeX() accesses to the same peripheral are ordered
+ with respect to each other. This ensures that MMIO register writes by
+ the CPU to a particular device will arrive in program order.
+
+ 2. A writeX() by the CPU to the peripheral will first wait for the
+ completion of all prior CPU writes to memory. This ensures that
+ writes by the CPU to an outbound DMA buffer allocated by
+ dma_alloc_coherent() will be visible to a DMA engine when the CPU
+ writes to its MMIO control register to trigger the transfer.
+
+ 3. A readX() by the CPU from the peripheral will complete before any
+ subsequent CPU reads from memory can begin. This ensures that reads
+ by the CPU from an incoming DMA buffer allocated by
+ dma_alloc_coherent() will not see stale data after reading from the
+ DMA engine's MMIO status register to establish that the DMA transfer
+ has completed.
+
+ 4. A readX() by the CPU from the peripheral will complete before any
+ subsequent delay() loop can begin execution. This ensures that two
+ MMIO register writes by the CPU to a peripheral will arrive at least
+ 1us apart if the first write is immediately read back with readX()
+ and udelay(1) is called prior to the second writeX():
+
+ writel(42, DEVICE_REGISTER_0); // Arrives at the device...
+ readl(DEVICE_REGISTER_0);
+ udelay(1);
+ writel(42, DEVICE_REGISTER_1); // ...at least 1us before this.
+
+ The ordering properties of __iomem pointers obtained with non-default
+ attributes (e.g. those returned by ioremap_wc()) are specific to the
+ underlying architecture and therefore the guarantees listed above cannot
+ generally be relied upon for accesses to these types of mappings.
(*) readX_relaxed(), writeX_relaxed():
- These are similar to readX() and writeX(), but provide weaker memory
- ordering guarantees. Specifically, they do not guarantee ordering with
- respect to normal memory accesses or delay() loops (i.e bullets 2-4 above)
- but they are still guaranteed to be ordered with respect to other accesses
- to the same peripheral when operating on __iomem pointers mapped with the
- default I/O attributes.
+ These are similar to readX() and writeX(), but provide weaker memory
+ ordering guarantees. Specifically, they do not guarantee ordering with
+ respect to normal memory accesses or delay() loops (i.e. bullets 2-4
+ above) but they are still guaranteed to be ordered with respect to other
+ accesses to the same peripheral when operating on __iomem pointers
+ mapped with the default I/O attributes.
(*) readsX(), writesX():
- The readsX() and writesX() MMIO accessors are designed for accessing
- register-based, memory-mapped FIFOs residing on peripherals that are not
- capable of performing DMA. Consequently, they provide only the ordering
- guarantees of readX_relaxed() and writeX_relaxed(), as documented above.
+ The readsX() and writesX() MMIO accessors are designed for accessing
+ register-based, memory-mapped FIFOs residing on peripherals that are not
+ capable of performing DMA. Consequently, they provide only the ordering
+ guarantees of readX_relaxed() and writeX_relaxed(), as documented above.
(*) inX(), outX():
- The inX() and outX() accessors are intended to access legacy port-mapped
- I/O peripherals, which may require special instructions on some
- architectures (notably x86). The port number of the peripheral being
- accessed is passed as an argument.
+ The inX() and outX() accessors are intended to access legacy port-mapped
+ I/O peripherals, which may require special instructions on some
+ architectures (notably x86). The port number of the peripheral being
+ accessed is passed as an argument.
- Since many CPU architectures ultimately access these peripherals via an
- internal virtual memory mapping, the portable ordering guarantees provided
- by inX() and outX() are the same as those provided by readX() and writeX()
- respectively when accessing a mapping with the default I/O attributes.
+ Since many CPU architectures ultimately access these peripherals via an
+ internal virtual memory mapping, the portable ordering guarantees
+ provided by inX() and outX() are the same as those provided by readX()
+ and writeX() respectively when accessing a mapping with the default I/O
+ attributes.
- Device drivers may expect outX() to emit a non-posted write transaction
- that waits for a completion response from the I/O peripheral before
- returning. This is not guaranteed by all architectures and is therefore
- not part of the portable ordering semantics.
+ Device drivers may expect outX() to emit a non-posted write transaction
+ that waits for a completion response from the I/O peripheral before
+ returning. This is not guaranteed by all architectures and is therefore
+ not part of the portable ordering semantics.
(*) insX(), outsX():
- As above, the insX() and outsX() accessors provide the same ordering
- guarantees as readsX() and writesX() respectively when accessing a mapping
- with the default I/O attributes.
+ As above, the insX() and outsX() accessors provide the same ordering
+ guarantees as readsX() and writesX() respectively when accessing a
+ mapping with the default I/O attributes.
- (*) ioreadX(), iowriteX()
+ (*) ioreadX(), iowriteX():
- These will perform appropriately for the type of access they're actually
- doing, be it inX()/outX() or readX()/writeX().
+ These will perform appropriately for the type of access they're actually
+ doing, be it inX()/outX() or readX()/writeX().
All of these accessors assume that the underlying peripheral is little-endian,
and will therefore perform byte-swapping operations on big-endian architectures.