mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 19:51:31 -04:00
Merge branch 'akpm'
* akpm: (182 commits)
fbdev: bf54x-lq043fb: use kzalloc over kmalloc/memset
fbdev: *bfin*: fix __dev{init,exit} markings
fbdev: *bfin*: drop unnecessary calls to memset
fbdev: bfin-t350mcqb-fb: drop unused local variables
fbdev: blackfin has __raw I/O accessors, so use them in fb.h
fbdev: s1d13xxxfb: add accelerated bitblt functions
tcx: use standard fields for framebuffer physical address and length
fbdev: add support for handoff from firmware to hw framebuffers
intelfb: fix a bug when changing video timing
fbdev: use framebuffer_release() for freeing fb_info structures
radeon: P2G2CLK_ALWAYS_ONb tested twice, should 2nd be P2G2CLK_DAC_ALWAYS_ONb?
s3c-fb: CPUFREQ frequency scaling support
s3c-fb: fix resource releasing on error during probing
carminefb: fix possible access beyond end of carmine_modedb[]
acornfb: remove fb_mmap function
mb862xxfb: use CONFIG_OF instead of CONFIG_PPC_OF
mb862xxfb: restrict compliation of platform driver to PPC
Samsung SoC Framebuffer driver: add Alpha Channel support
atmel-lcdc: fix pixclock upper bound detection
offb: use framebuffer_alloc() to allocate fb_info struct
...
Manually fix up conflicts due to kmemcheck in mm/slab.c
This commit is contained in:
commit
517d08699b
247 changed files with 5666 additions and 2683 deletions
|
|
@ -17,6 +17,7 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <media/videobuf-dma-contig.h>
|
||||
|
||||
|
|
@ -25,6 +26,7 @@ struct videobuf_dma_contig_memory {
|
|||
void *vaddr;
|
||||
dma_addr_t dma_handle;
|
||||
unsigned long size;
|
||||
int is_userptr;
|
||||
};
|
||||
|
||||
#define MAGIC_DC_MEM 0x0733ac61
|
||||
|
|
@ -108,6 +110,82 @@ static struct vm_operations_struct videobuf_vm_ops = {
|
|||
.close = videobuf_vm_close,
|
||||
};
|
||||
|
||||
/**
|
||||
* videobuf_dma_contig_user_put() - reset pointer to user space buffer
|
||||
* @mem: per-buffer private videobuf-dma-contig data
|
||||
*
|
||||
* This function resets the user space pointer
|
||||
*/
|
||||
static void videobuf_dma_contig_user_put(struct videobuf_dma_contig_memory *mem)
|
||||
{
|
||||
mem->is_userptr = 0;
|
||||
mem->dma_handle = 0;
|
||||
mem->size = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* videobuf_dma_contig_user_get() - setup user space memory pointer
|
||||
* @mem: per-buffer private videobuf-dma-contig data
|
||||
* @vb: video buffer to map
|
||||
*
|
||||
* This function validates and sets up a pointer to user space memory.
|
||||
* Only physically contiguous pfn-mapped memory is accepted.
|
||||
*
|
||||
* Returns 0 if successful.
|
||||
*/
|
||||
static int videobuf_dma_contig_user_get(struct videobuf_dma_contig_memory *mem,
|
||||
struct videobuf_buffer *vb)
|
||||
{
|
||||
struct mm_struct *mm = current->mm;
|
||||
struct vm_area_struct *vma;
|
||||
unsigned long prev_pfn, this_pfn;
|
||||
unsigned long pages_done, user_address;
|
||||
int ret;
|
||||
|
||||
mem->size = PAGE_ALIGN(vb->size);
|
||||
mem->is_userptr = 0;
|
||||
ret = -EINVAL;
|
||||
|
||||
down_read(&mm->mmap_sem);
|
||||
|
||||
vma = find_vma(mm, vb->baddr);
|
||||
if (!vma)
|
||||
goto out_up;
|
||||
|
||||
if ((vb->baddr + mem->size) > vma->vm_end)
|
||||
goto out_up;
|
||||
|
||||
pages_done = 0;
|
||||
prev_pfn = 0; /* kill warning */
|
||||
user_address = vb->baddr;
|
||||
|
||||
while (pages_done < (mem->size >> PAGE_SHIFT)) {
|
||||
ret = follow_pfn(vma, user_address, &this_pfn);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
if (pages_done == 0)
|
||||
mem->dma_handle = this_pfn << PAGE_SHIFT;
|
||||
else if (this_pfn != (prev_pfn + 1))
|
||||
ret = -EFAULT;
|
||||
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
prev_pfn = this_pfn;
|
||||
user_address += PAGE_SIZE;
|
||||
pages_done++;
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
mem->is_userptr = 1;
|
||||
|
||||
out_up:
|
||||
up_read(¤t->mm->mmap_sem);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *__videobuf_alloc(size_t size)
|
||||
{
|
||||
struct videobuf_dma_contig_memory *mem;
|
||||
|
|
@ -154,12 +232,11 @@ static int __videobuf_iolock(struct videobuf_queue *q,
|
|||
case V4L2_MEMORY_USERPTR:
|
||||
dev_dbg(q->dev, "%s memory method USERPTR\n", __func__);
|
||||
|
||||
/* The only USERPTR currently supported is the one needed for
|
||||
read() method.
|
||||
*/
|
||||
/* handle pointer from user space */
|
||||
if (vb->baddr)
|
||||
return -EINVAL;
|
||||
return videobuf_dma_contig_user_get(mem, vb);
|
||||
|
||||
/* allocate memory for the read() method */
|
||||
mem->size = PAGE_ALIGN(vb->size);
|
||||
mem->vaddr = dma_alloc_coherent(q->dev, mem->size,
|
||||
&mem->dma_handle, GFP_KERNEL);
|
||||
|
|
@ -400,7 +477,7 @@ void videobuf_dma_contig_free(struct videobuf_queue *q,
|
|||
So, it should free memory only if the memory were allocated for
|
||||
read() operation.
|
||||
*/
|
||||
if ((buf->memory != V4L2_MEMORY_USERPTR) || buf->baddr)
|
||||
if (buf->memory != V4L2_MEMORY_USERPTR)
|
||||
return;
|
||||
|
||||
if (!mem)
|
||||
|
|
@ -408,6 +485,13 @@ void videobuf_dma_contig_free(struct videobuf_queue *q,
|
|||
|
||||
MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
|
||||
|
||||
/* handle user space pointer case */
|
||||
if (buf->baddr) {
|
||||
videobuf_dma_contig_user_put(mem);
|
||||
return;
|
||||
}
|
||||
|
||||
/* read() method */
|
||||
dma_free_coherent(q->dev, mem->size, mem->vaddr, mem->dma_handle);
|
||||
mem->vaddr = NULL;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue