diff options
Diffstat (limited to 'drivers/media/video/uvc/uvc_queue.c')
-rw-r--r-- | drivers/media/video/uvc/uvc_queue.c | 34 |
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 | */ | ||
499 | unsigned 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; | ||
517 | done: | ||
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 | * |