Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394...
[pandora-kernel.git] / arch / powerpc / lib / dma-noncoherent.c
index 48f3d13..5d83907 100644 (file)
@@ -306,13 +306,15 @@ EXPORT_SYMBOL(__dma_free_coherent);
 static int __init dma_alloc_init(void)
 {
        pgd_t *pgd;
+       pud_t *pud;
        pmd_t *pmd;
        pte_t *pte;
        int ret = 0;
 
        do {
                pgd = pgd_offset(&init_mm, CONSISTENT_BASE);
-               pmd = pmd_alloc(&init_mm, pgd, CONSISTENT_BASE);
+               pud = pud_alloc(&init_mm, pgd, CONSISTENT_BASE);
+               pmd = pmd_alloc(&init_mm, pud, CONSISTENT_BASE);
                if (!pmd) {
                        printk(KERN_ERR "%s: no pmd tables\n", __func__);
                        ret = -ENOMEM;
@@ -346,8 +348,15 @@ void __dma_sync(void *vaddr, size_t size, int direction)
        switch (direction) {
        case DMA_NONE:
                BUG();
-       case DMA_FROM_DEVICE:   /* invalidate only */
-               invalidate_dcache_range(start, end);
+       case DMA_FROM_DEVICE:
+               /*
+                * invalidate only when cache-line aligned otherwise there is
+                * the potential for discarding uncommitted data from the cache
+                */
+               if ((start & (L1_CACHE_BYTES - 1)) || (size & (L1_CACHE_BYTES - 1)))
+                       flush_dcache_range(start, end);
+               else
+                       invalidate_dcache_range(start, end);
                break;
        case DMA_TO_DEVICE:             /* writeback only */
                clean_dcache_range(start, end);