sparc: remove the sparc32_dma_ops indirection
[linux-2.6-microblaze.git] / arch / sparc / mm / io-unit.c
index c8cb27d..2088d29 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/mm.h>
 #include <linux/highmem.h>     /* pte_offset_map => kmap_atomic */
 #include <linux/bitops.h>
-#include <linux/scatterlist.h>
+#include <linux/dma-mapping.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 
@@ -140,18 +140,26 @@ nexti:    scan = find_next_zero_bit(iounit->bmap, limit, scan);
        return vaddr;
 }
 
-static __u32 iounit_get_scsi_one(struct device *dev, char *vaddr, unsigned long len)
+static dma_addr_t iounit_map_page(struct device *dev, struct page *page,
+               unsigned long offset, size_t len, enum dma_data_direction dir,
+               unsigned long attrs)
 {
+       void *vaddr = page_address(page) + offset;
        struct iounit_struct *iounit = dev->archdata.iommu;
        unsigned long ret, flags;
        
+       /* XXX So what is maxphys for us and how do drivers know it? */
+       if (!len || len > 256 * 1024)
+               return DMA_MAPPING_ERROR;
+
        spin_lock_irqsave(&iounit->lock, flags);
        ret = iounit_get_area(iounit, (unsigned long)vaddr, len);
        spin_unlock_irqrestore(&iounit->lock, flags);
        return ret;
 }
 
-static void iounit_get_scsi_sgl(struct device *dev, struct scatterlist *sg, int sz)
+static int iounit_map_sg(struct device *dev, struct scatterlist *sg, int sz,
+               enum dma_data_direction dir, unsigned long attrs)
 {
        struct iounit_struct *iounit = dev->archdata.iommu;
        unsigned long flags;
@@ -165,9 +173,11 @@ static void iounit_get_scsi_sgl(struct device *dev, struct scatterlist *sg, int
                sg = sg_next(sg);
        }
        spin_unlock_irqrestore(&iounit->lock, flags);
+       return sz;
 }
 
-static void iounit_release_scsi_one(struct device *dev, __u32 vaddr, unsigned long len)
+static void iounit_unmap_page(struct device *dev, dma_addr_t vaddr, size_t len,
+               enum dma_data_direction dir, unsigned long attrs)
 {
        struct iounit_struct *iounit = dev->archdata.iommu;
        unsigned long flags;
@@ -181,7 +191,8 @@ static void iounit_release_scsi_one(struct device *dev, __u32 vaddr, unsigned lo
        spin_unlock_irqrestore(&iounit->lock, flags);
 }
 
-static void iounit_release_scsi_sgl(struct device *dev, struct scatterlist *sg, int sz)
+static void iounit_unmap_sg(struct device *dev, struct scatterlist *sg, int sz,
+               enum dma_data_direction dir, unsigned long attrs)
 {
        struct iounit_struct *iounit = dev->archdata.iommu;
        unsigned long flags;
@@ -201,14 +212,27 @@ static void iounit_release_scsi_sgl(struct device *dev, struct scatterlist *sg,
 }
 
 #ifdef CONFIG_SBUS
-static int iounit_map_dma_area(struct device *dev, dma_addr_t *pba, unsigned long va, unsigned long addr, int len)
+static void *iounit_alloc(struct device *dev, size_t len,
+               dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
 {
        struct iounit_struct *iounit = dev->archdata.iommu;
-       unsigned long page, end;
+       unsigned long va, addr, page, end, ret;
        pgprot_t dvma_prot;
        iopte_t __iomem *iopte;
 
-       *pba = addr;
+       /* XXX So what is maxphys for us and how do drivers know it? */
+       if (!len || len > 256 * 1024)
+               return NULL;
+
+       len = PAGE_ALIGN(len);
+       va = __get_free_pages(gfp, get_order(len));
+       if (!va)
+               return NULL;
+
+       addr = ret = sparc_dma_alloc_resource(dev, len);
+       if (!addr)
+               goto out_free_pages;
+       *dma_handle = addr;
 
        dvma_prot = __pgprot(SRMMU_CACHE | SRMMU_ET_PTE | SRMMU_PRIV);
        end = PAGE_ALIGN((addr + len));
@@ -237,27 +261,32 @@ static int iounit_map_dma_area(struct device *dev, dma_addr_t *pba, unsigned lon
        flush_cache_all();
        flush_tlb_all();
 
-       return 0;
+       return (void *)ret;
+
+out_free_pages:
+       free_pages(va, get_order(len));
+       return NULL;
 }
 
-static void iounit_unmap_dma_area(struct device *dev, unsigned long addr, int len)
+static void iounit_free(struct device *dev, size_t size, void *cpu_addr,
+               dma_addr_t dma_addr, unsigned long attrs)
 {
        /* XXX Somebody please fill this in */
 }
 #endif
 
-static const struct sparc32_dma_ops iounit_dma_ops = {
-       .get_scsi_one           = iounit_get_scsi_one,
-       .get_scsi_sgl           = iounit_get_scsi_sgl,
-       .release_scsi_one       = iounit_release_scsi_one,
-       .release_scsi_sgl       = iounit_release_scsi_sgl,
+static const struct dma_map_ops iounit_dma_ops = {
 #ifdef CONFIG_SBUS
-       .map_dma_area           = iounit_map_dma_area,
-       .unmap_dma_area         = iounit_unmap_dma_area,
+       .alloc                  = iounit_alloc,
+       .free                   = iounit_free,
 #endif
+       .map_page               = iounit_map_page,
+       .unmap_page             = iounit_unmap_page,
+       .map_sg                 = iounit_map_sg,
+       .unmap_sg               = iounit_unmap_sg,
 };
 
 void __init ld_mmu_iounit(void)
 {
-       sparc32_dma_ops = &iounit_dma_ops;
+       dma_ops = &iounit_dma_ops;
 }