powerpc/dma: Add optional platform override of dma_set_mask()
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Mon, 30 Aug 2010 19:23:52 +0000 (19:23 +0000)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Thu, 2 Sep 2010 04:07:32 +0000 (14:07 +1000)
Some platforms may want to override dma_set_mask() to take into
account some specific "features" such as the availability of
a direct-map window in addition to an iommu.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/include/asm/dma-mapping.h
arch/powerpc/include/asm/machdep.h
arch/powerpc/kernel/dma.c

index 8c9c6ad..6d2416a 100644 (file)
@@ -127,19 +127,7 @@ static inline int dma_supported(struct device *dev, u64 mask)
        return dma_ops->dma_supported(dev, mask);
 }
 
-static inline int dma_set_mask(struct device *dev, u64 dma_mask)
-{
-       struct dma_map_ops *dma_ops = get_dma_ops(dev);
-
-       if (unlikely(dma_ops == NULL))
-               return -EIO;
-       if (dma_ops->set_dma_mask != NULL)
-               return dma_ops->set_dma_mask(dev, dma_mask);
-       if (!dev->dma_mask || !dma_supported(dev, dma_mask))
-               return -EIO;
-       *dev->dma_mask = dma_mask;
-       return 0;
-}
+extern int dma_set_mask(struct device *dev, u64 dma_mask);
 
 static inline void *dma_alloc_coherent(struct device *dev, size_t size,
                                       dma_addr_t *dma_handle, gfp_t flag)
index adc8e6c..d045b01 100644 (file)
@@ -102,6 +102,9 @@ struct machdep_calls {
        void            (*pci_dma_dev_setup)(struct pci_dev *dev);
        void            (*pci_dma_bus_setup)(struct pci_bus *bus);
 
+       /* Platform set_dma_mask override */
+       int             (*dma_set_mask)(struct device *dev, u64 dma_mask);
+
        int             (*probe)(void);
        void            (*setup_arch)(void); /* Optional, may be NULL */
        void            (*init_early)(void);
index 84d6367..f368c07 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/memblock.h>
 #include <asm/bug.h>
 #include <asm/abs_addr.h>
+#include <asm/machdep.h>
 
 /*
  * Generic direct DMA implementation
@@ -154,6 +155,23 @@ EXPORT_SYMBOL(dma_direct_ops);
 
 #define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
 
+int dma_set_mask(struct device *dev, u64 dma_mask)
+{
+       struct dma_map_ops *dma_ops = get_dma_ops(dev);
+
+       if (ppc_md.dma_set_mask)
+               return ppc_md.dma_set_mask(dev, dma_mask);
+       if (unlikely(dma_ops == NULL))
+               return -EIO;
+       if (dma_ops->set_dma_mask != NULL)
+               return dma_ops->set_dma_mask(dev, dma_mask);
+       if (!dev->dma_mask || !dma_supported(dev, dma_mask))
+               return -EIO;
+       *dev->dma_mask = dma_mask;
+       return 0;
+}
+EXPORT_SYMBOL(dma_set_mask);
+
 static int __init dma_init(void)
 {
        dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);