]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
ENGR00293323 PXP: add WC and cacheable dma buffer support for PXP device
authorFancy Fang <B47543@freescale.com>
Wed, 25 Dec 2013 10:04:56 +0000 (18:04 +0800)
committerLothar Waßmann <LW@KARO-electronics.de>
Wed, 20 Aug 2014 08:06:52 +0000 (10:06 +0200)
This change add support for new dma buffer type(writecombine and cacheable)
which allows user application has more choices for the buffer type. And if
the dma buffer is cacheable, then add flush interfaces to make it cache
coherent when necessary.

Signed-off-by: Fancy Fang <B47543@freescale.com>
drivers/dma/pxp/pxp_device.c
include/uapi/linux/pxp_device.h

index 1342ce64ab4400dbf9998fb19ab38c8591501769..2b52ee1aad6e392779393f45abd92429f21c32a4 100644 (file)
@@ -447,7 +447,19 @@ static int pxp_device_mmap(struct file *file, struct vm_area_struct *vma)
                (vma->vm_pgoff + vma_pages(vma)))
                return -ENOMEM;
 
-       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+       switch (obj->mem_type) {
+       case MEMORY_TYPE_UNCACHED:
+               vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+               break;
+       case MEMORY_TYPE_WC:
+               vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+               break;
+       case MEMORY_TYPE_CACHED:
+               break;
+       default:
+               pr_err("%s: invalid memory type!\n", __func__);
+               return -EINVAL;
+       }
 
        return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
                               request_size, vma->vm_page_prot) ? -EAGAIN : 0;
@@ -579,6 +591,7 @@ static long pxp_device_ioctl(struct file *filp,
                        if (!obj)
                                return -ENOMEM;
                        obj->size = buffer.size;
+                       obj->mem_type = buffer.mtype;
 
                        ret = pxp_alloc_dma_buffer(obj);
                        if (ret == -1) {
@@ -633,6 +646,44 @@ static long pxp_device_ioctl(struct file *filp,
                        pxp_free_dma_buffer(obj);
                        kfree(obj);
 
+                       break;
+               }
+       case PXP_IOC_FLUSH_PHYMEM:
+               {
+                       int ret;
+                       struct pxp_mem_flush flush;
+                       struct pxp_buf_obj *obj;
+
+                       ret = copy_from_user(&flush,
+                                            (struct pxp_mem_flush *)arg,
+                                            sizeof(struct pxp_mem_flush));
+                       if (ret)
+                               return -EACCES;
+
+                       obj = pxp_buffer_object_lookup(file_priv, flush.handle);
+                       if (!obj)
+                               return -EINVAL;
+
+                       switch (flush.type) {
+                       case CACHE_CLEAN:
+                               dma_sync_single_for_device(NULL, obj->offset,
+                                               obj->size, DMA_TO_DEVICE);
+                               break;
+                       case CACHE_INVALIDATE:
+                               dma_sync_single_for_device(NULL, obj->offset,
+                                               obj->size, DMA_FROM_DEVICE);
+                               break;
+                       case CACHE_FLUSH:
+                               dma_sync_single_for_device(NULL, obj->offset,
+                                               obj->size, DMA_TO_DEVICE);
+                               dma_sync_single_for_device(NULL, obj->offset,
+                                               obj->size, DMA_FROM_DEVICE);
+                               break;
+                       default:
+                               pr_err("%s: invalid cache flush type\n", __func__);
+                               return -EINVAL;
+                       }
+
                        break;
                }
        case PXP_IOC_WAIT4CMPLT:
index e63a6e6eb4181b071ec98faf36fde50649ad0fcf..fce89ce066bb8652802d286f5b80c0d5bd92f0e7 100644 (file)
@@ -31,6 +31,12 @@ struct pxp_mem_desc {
        unsigned int size;
        dma_addr_t phys_addr;
        unsigned int virt_uaddr;                /* virtual user space address */
+       unsigned int mtype;
+};
+
+struct pxp_mem_flush {
+       unsigned int handle;
+       unsigned int type;
 };
 
 #define PXP_IOC_MAGIC  'P'
@@ -42,5 +48,16 @@ struct pxp_mem_desc {
 #define PXP_IOC_GET_PHYMEM    _IOWR(PXP_IOC_MAGIC, 4, struct pxp_mem_desc)
 #define PXP_IOC_PUT_PHYMEM    _IOW(PXP_IOC_MAGIC, 5, struct pxp_mem_desc)
 #define PXP_IOC_WAIT4CMPLT    _IOWR(PXP_IOC_MAGIC, 6, struct pxp_mem_desc)
+#define PXP_IOC_FLUSH_PHYMEM   _IOR(PXP_IOC_MAGIC, 7, struct pxp_mem_flush)
+
+/* Memory types supported*/
+#define MEMORY_TYPE_UNCACHED 0x0
+#define MEMORY_TYPE_WC      0x1
+#define MEMORY_TYPE_CACHED   0x2
+
+/* Cache flush operations */
+#define CACHE_CLEAN      0x1
+#define CACHE_INVALIDATE 0x2
+#define CACHE_FLUSH      0x4
 
 #endif