From ea168e3351cdb9a738ebfa4ad931a81b2f6d48dd Mon Sep 17 00:00:00 2001 From: Alexandru Gagniuc Date: Tue, 4 Apr 2017 10:46:56 -0700 Subject: core/uclass: Print name of device in uclass_find_device_by_seq() uclass_find_device_by_seq() prints seq and req_seq when debugging is enabled, but this information is not very useful by itself. Add the name of he driver to this information. This improves debugging as it shows which devices are being considered. Signed-off-by: Alexandru Gagniuc Acked-by: Simon Glass --- drivers/core/uclass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/core') diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index d94d43a98d2..04fb45b01a5 100644 --- a/drivers/core/uclass.c +++ b/drivers/core/uclass.c @@ -250,7 +250,7 @@ int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq, return ret; list_for_each_entry(dev, &uc->dev_head, uclass_node) { - debug(" - %d %d\n", dev->req_seq, dev->seq); + debug(" - %d %d '%s'\n", dev->req_seq, dev->seq, dev->name); if ((find_req_seq ? dev->req_seq : dev->seq) == seq_or_req_seq) { *devp = dev; -- cgit v1.3.1 From 5a8a8045a928702d9b3fb6f73a4e9717040e09a9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 4 Apr 2017 13:00:19 -0600 Subject: dm: core: Ensure DMA regions start up with the cache clean There is a strange interaction with drivers which use DMA if the cache starts off in a dirty state. Buffer space which the driver reads (but has not previously written) can contain zero bytes from alloc_priv(). This can cause corruption of the memory used by DMA for incoming data. Fix this and add a comment to explain the problem. This allows the dwc2 driver to work correctly with driver model, for example. Signed-off-by: Simon Glass --- drivers/core/device.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'drivers/core') diff --git a/drivers/core/device.c b/drivers/core/device.c index e1b0ebffc55..09a115f753d 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); } -- cgit v1.3.1