summaryrefslogtreecommitdiff
path: root/drivers/core/device.c
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2017-04-13 17:31:06 -0400
committerTom Rini <trini@konsulko.com>2017-04-13 17:31:06 -0400
commitb7b24a7a3cd74bb165d28a2959ed9143e3648fbf (patch)
tree062fd13092cee10dc8746a1339ecea18f08d21d6 /drivers/core/device.c
parent1622559066d890f1b7622be0ede8a5d64de66ef3 (diff)
parent22e10be456014400788f80d45fc5f5c0b9d4a81d (diff)
downloadu-boot-b7b24a7a3cd74bb165d28a2959ed9143e3648fbf.tar.gz
Merge git://git.denx.de/u-boot-dm
Here with some DM changes as well as the long-standing AT91 DM/DT conversion patches which I have picked up via dm.
Diffstat (limited to 'drivers/core/device.c')
-rw-r--r--drivers/core/device.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/drivers/core/device.c b/drivers/core/device.c
index e1b0ebffc5..09a115f753 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -255,8 +255,36 @@ static void *alloc_priv(int size, uint flags)
if (flags & DM_FLAG_ALLOC_PRIV_DMA) {
priv = memalign(ARCH_DMA_MINALIGN, size);
- if (priv)
+ if (priv) {
memset(priv, '\0', size);
+
+ /*
+ * Ensure that the zero bytes are flushed to memory.
+ * This prevents problems if the driver uses this as
+ * both an input and an output buffer:
+ *
+ * 1. Zeroes written to buffer (here) and sit in the
+ * cache
+ * 2. Driver issues a read command to DMA
+ * 3. CPU runs out of cache space and evicts some cache
+ * data in the buffer, writing zeroes to RAM from
+ * the memset() above
+ * 4. DMA completes
+ * 5. Buffer now has some DMA data and some zeroes
+ * 6. Data being read is now incorrect
+ *
+ * To prevent this, ensure that the cache is clean
+ * within this range at the start. The driver can then
+ * use normal flush-after-write, invalidate-before-read
+ * procedures.
+ *
+ * TODO(sjg@chromium.org): Drop this microblaze
+ * exception.
+ */
+#ifndef CONFIG_MICROBLAZE
+ flush_dcache_range((ulong)priv, (ulong)priv + size);
+#endif
+ }
} else {
priv = calloc(1, size);
}