Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq
[pandora-kernel.git] / arch / arm / mm / dma-mapping.c
index 4771dba..0a0a1e7 100644 (file)
 #include <asm/tlbflush.h>
 #include <asm/sizes.h>
 
+#include "mm.h"
+
 static u64 get_coherent_dma_mask(struct device *dev)
 {
-       u64 mask = ISA_DMA_THRESHOLD;
+       u64 mask = (u64)arm_dma_limit;
 
        if (dev) {
                mask = dev->coherent_dma_mask;
@@ -41,10 +43,10 @@ static u64 get_coherent_dma_mask(struct device *dev)
                        return 0;
                }
 
-               if ((~mask) & ISA_DMA_THRESHOLD) {
+               if ((~mask) & (u64)arm_dma_limit) {
                        dev_warn(dev, "coherent DMA mask %#llx is smaller "
                                 "than system GFP_DMA mask %#llx\n",
-                                mask, (unsigned long long)ISA_DMA_THRESHOLD);
+                                mask, (u64)arm_dma_limit);
                        return 0;
                }
        }
@@ -149,6 +151,7 @@ static int __init consistent_init(void)
 {
        int ret = 0;
        pgd_t *pgd;
+       pud_t *pud;
        pmd_t *pmd;
        pte_t *pte;
        int i = 0;
@@ -156,7 +159,15 @@ static int __init consistent_init(void)
 
        do {
                pgd = pgd_offset(&init_mm, base);
-               pmd = pmd_alloc(&init_mm, pgd, base);
+
+               pud = pud_alloc(&init_mm, pgd, base);
+               if (!pud) {
+                       printk(KERN_ERR "%s: no pud tables\n", __func__);
+                       ret = -ENOMEM;
+                       break;
+               }
+
+               pmd = pmd_alloc(&init_mm, pud, base);
                if (!pmd) {
                        printk(KERN_ERR "%s: no pmd tables\n", __func__);
                        ret = -ENOMEM;
@@ -648,6 +659,33 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
 }
 EXPORT_SYMBOL(dma_sync_sg_for_device);
 
+/*
+ * Return whether the given device DMA address mask can be supported
+ * properly.  For example, if your device can only drive the low 24-bits
+ * during bus mastering, then you would pass 0x00ffffff as the mask
+ * to this function.
+ */
+int dma_supported(struct device *dev, u64 mask)
+{
+       if (mask < (u64)arm_dma_limit)
+               return 0;
+       return 1;
+}
+EXPORT_SYMBOL(dma_supported);
+
+int dma_set_mask(struct device *dev, u64 dma_mask)
+{
+       if (!dev->dma_mask || !dma_supported(dev, dma_mask))
+               return -EIO;
+
+#ifndef CONFIG_DMABOUNCE
+       *dev->dma_mask = dma_mask;
+#endif
+
+       return 0;
+}
+EXPORT_SYMBOL(dma_set_mask);
+
 #define PREALLOC_DMA_DEBUG_ENTRIES     4096
 
 static int __init dma_debug_do_init(void)