aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/uvc/uvc_queue.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/uvc/uvc_queue.c')
-rw-r--r--drivers/media/video/uvc/uvc_queue.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c
index f14581bd707f..109a06384a8f 100644
--- a/drivers/media/video/uvc/uvc_queue.c
+++ b/drivers/media/video/uvc/uvc_queue.c
@@ -424,7 +424,7 @@ int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma)
424 break; 424 break;
425 } 425 }
426 426
427 if (i == queue->count || size != queue->buf_size) { 427 if (i == queue->count || PAGE_ALIGN(size) != queue->buf_size) {
428 ret = -EINVAL; 428 ret = -EINVAL;
429 goto done; 429 goto done;
430 } 430 }
@@ -436,6 +436,7 @@ int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma)
436 vma->vm_flags |= VM_IO; 436 vma->vm_flags |= VM_IO;
437 437
438 addr = (unsigned long)queue->mem + buffer->buf.m.offset; 438 addr = (unsigned long)queue->mem + buffer->buf.m.offset;
439#ifdef CONFIG_MMU
439 while (size > 0) { 440 while (size > 0) {
440 page = vmalloc_to_page((void *)addr); 441 page = vmalloc_to_page((void *)addr);
441 if ((ret = vm_insert_page(vma, start, page)) < 0) 442 if ((ret = vm_insert_page(vma, start, page)) < 0)
@@ -445,6 +446,7 @@ int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma)
445 addr += PAGE_SIZE; 446 addr += PAGE_SIZE;
446 size -= PAGE_SIZE; 447 size -= PAGE_SIZE;
447 } 448 }
449#endif
448 450
449 vma->vm_ops = &uvc_vm_ops; 451 vma->vm_ops = &uvc_vm_ops;
450 vma->vm_private_data = buffer; 452 vma->vm_private_data = buffer;
@@ -488,6 +490,36 @@ done:
488 return mask; 490 return mask;
489} 491}
490 492
493#ifndef CONFIG_MMU
494/*
495 * Get unmapped area.
496 *
497 * NO-MMU arch need this function to make mmap() work correctly.
498 */
499unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue,
500 unsigned long pgoff)
501{
502 struct uvc_buffer *buffer;
503 unsigned int i;
504 unsigned long ret;
505
506 mutex_lock(&queue->mutex);
507 for (i = 0; i < queue->count; ++i) {
508 buffer = &queue->buffer[i];
509 if ((buffer->buf.m.offset >> PAGE_SHIFT) == pgoff)
510 break;
511 }
512 if (i == queue->count) {
513 ret = -EINVAL;
514 goto done;
515 }
516 ret = (unsigned long)queue->mem + buffer->buf.m.offset;
517done:
518 mutex_unlock(&queue->mutex);
519 return ret;
520}
521#endif
522
491/* 523/*
492 * Enable or disable the video buffers queue. 524 * Enable or disable the video buffers queue.
493 * 525 *