cns3xxx: fix missing and incomplete cache flushes on DMA cache sync for cpu - fixes...
authorFelix Fietkau <nbd@openwrt.org>
Sun, 1 May 2011 15:53:56 +0000 (15:53 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Sun, 1 May 2011 15:53:56 +0000 (15:53 +0000)
SVN-Revision: 26797

target/linux/cns3xxx/patches-2.6.31/300-flush_cache_on_dma_cache_sync_for_cpu.patch [new file with mode: 0644]
target/linux/cns3xxx/patches-2.6.31/301-dma_cache_ownership_maint.patch [new file with mode: 0644]

diff --git a/target/linux/cns3xxx/patches-2.6.31/300-flush_cache_on_dma_cache_sync_for_cpu.patch b/target/linux/cns3xxx/patches-2.6.31/300-flush_cache_on_dma_cache_sync_for_cpu.patch
new file mode 100644 (file)
index 0000000..d9051cd
--- /dev/null
@@ -0,0 +1,21 @@
+--- a/arch/arm/include/asm/dma-mapping.h
++++ b/arch/arm/include/asm/dma-mapping.h
+@@ -350,7 +350,8 @@ static inline dma_addr_t dma_map_page(st
+ static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
+               size_t size, enum dma_data_direction dir)
+ {
+-      /* nothing to do */
++      if (dir != DMA_TO_DEVICE)
++              dma_cache_maint(dma_to_virt(dev, handle), size, DMA_FROM_DEVICE);
+ }
+ #endif /* CONFIG_DMABOUNCE */
+@@ -398,6 +399,8 @@ static inline void dma_sync_single_range
+ {
+       BUG_ON(!valid_dma_direction(dir));
++      if (dir != DMA_TO_DEVICE)
++              dma_cache_maint(dma_to_virt(dev, handle) + offset, size, DMA_FROM_DEVICE);
+       dmabounce_sync_for_cpu(dev, handle, offset, size, dir);
+ }
diff --git a/target/linux/cns3xxx/patches-2.6.31/301-dma_cache_ownership_maint.patch b/target/linux/cns3xxx/patches-2.6.31/301-dma_cache_ownership_maint.patch
new file mode 100644 (file)
index 0000000..a52ae24
--- /dev/null
@@ -0,0 +1,67 @@
+--- a/arch/arm/mm/cache-v6.S
++++ b/arch/arm/mm/cache-v6.S
+@@ -179,6 +179,10 @@ ENTRY(v6_flush_kern_dcache_page)
+  *    - end     - virtual end address of region
+  */
+ ENTRY(v6_dma_inv_range)
++#ifdef CONFIG_SMP
++      ldrb    r2, [r0]
++      strb    r2, [r0]
++#endif
+       tst     r0, #D_CACHE_LINE_SIZE - 1
+       bic     r0, r0, #D_CACHE_LINE_SIZE - 1
+ #ifdef HARVARD_CACHE
+@@ -187,6 +191,10 @@ ENTRY(v6_dma_inv_range)
+       mcrne   p15, 0, r0, c7, c11, 1          @ clean unified line
+ #endif
+       tst     r1, #D_CACHE_LINE_SIZE - 1
++#ifdef CONFIG_SMP
++      ldrneb  r2, [r1, #-1]
++      strneb  r2, [r1, #-1]
++#endif
+       bic     r1, r1, #D_CACHE_LINE_SIZE - 1
+ #ifdef HARVARD_CACHE
+       mcrne   p15, 0, r1, c7, c14, 1          @ clean & invalidate D line
+@@ -201,6 +209,10 @@ ENTRY(v6_dma_inv_range)
+ #endif
+       add     r0, r0, #D_CACHE_LINE_SIZE
+       cmp     r0, r1
++#ifdef CONFIG_SMP
++      ldrlo   r2, [r0]
++      strlo   r2, [r0]
++#endif
+       blo     1b
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
+@@ -214,6 +226,9 @@ ENTRY(v6_dma_inv_range)
+ ENTRY(v6_dma_clean_range)
+       bic     r0, r0, #D_CACHE_LINE_SIZE - 1
+ 1:
++#ifdef CONFIG_SMP
++      ldr r2, [r0]
++#endif
+ #ifdef HARVARD_CACHE
+       mcr     p15, 0, r0, c7, c10, 1          @ clean D line
+ #else
+@@ -232,6 +247,10 @@ ENTRY(v6_dma_clean_range)
+  *    - end     - virtual end address of region
+  */
+ ENTRY(v6_dma_flush_range)
++#ifdef CONFIG_SMP
++      ldrb    r2, [r0]
++      strb    r2, [r0]
++#endif
+       bic     r0, r0, #D_CACHE_LINE_SIZE - 1
+ 1:
+ #ifdef HARVARD_CACHE
+@@ -241,6 +260,10 @@ ENTRY(v6_dma_flush_range)
+ #endif
+       add     r0, r0, #D_CACHE_LINE_SIZE
+       cmp     r0, r1
++#ifdef CONFIG_SMP
++      ldrlob   r2, [r0]
++      strlob   r2, [r0]
++#endif
+       blo     1b
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer