From patchwork Fri Apr 29 10:11:35 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bob Liu X-Patchwork-Id: 740671 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p3T9sDXu021526 for ; Fri, 29 Apr 2011 09:54:13 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751161Ab1D2JyL (ORCPT ); Fri, 29 Apr 2011 05:54:11 -0400 Received: from ch1ehsobe006.messaging.microsoft.com ([216.32.181.186]:56778 "EHLO CH1EHSOBE001.bigfish.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1750992Ab1D2JyK (ORCPT ); Fri, 29 Apr 2011 05:54:10 -0400 Received: from mail38-ch1-R.bigfish.com (216.32.181.169) by CH1EHSOBE001.bigfish.com (10.43.70.51) with Microsoft SMTP Server id 14.1.225.8; Fri, 29 Apr 2011 09:54:09 +0000 Received: from mail38-ch1 (localhost.localdomain [127.0.0.1]) by mail38-ch1-R.bigfish.com (Postfix) with ESMTP id ECDF6C78583 for ; Fri, 29 Apr 2011 09:54:08 +0000 (UTC) X-SpamScore: 1 X-BigFish: VS1(zzzz1202hzz8275bhz2ei87h668h839h62h) X-Spam-TCS-SCL: 1:0 X-Forefront-Antispam-Report: KIP:(null); UIP:(null); IPVD:NLI; H:nwd2mail11.analog.com; RD:nwd2mail11.analog.com; EFVD:NLI X-FB-DOMAIN-IP-MATCH: fail Received: from mail38-ch1 (localhost.localdomain [127.0.0.1]) by mail38-ch1 (MessageSwitch) id 1304070848631516_2340; Fri, 29 Apr 2011 09:54:08 +0000 (UTC) Received: from CH1EHSMHS011.bigfish.com (snatpool1.int.messaging.microsoft.com [10.43.68.252]) by mail38-ch1.bigfish.com (Postfix) with ESMTP id 9757736804F for ; Fri, 29 Apr 2011 09:54:08 +0000 (UTC) Received: from nwd2mail11.analog.com (137.71.25.57) by CH1EHSMHS011.bigfish.com (10.43.70.11) with Microsoft SMTP Server id 14.1.225.8; Fri, 29 Apr 2011 09:54:08 +0000 X-IronPort-AV: E=Sophos;i="4.64,286,1301889600"; d="scan'208";a="32392279" Received: from nwd2hubcas1.ad.analog.com ([10.64.73.29]) by nwd2mail11.analog.com with ESMTP; 29 Apr 2011 05:54:08 -0400 Received: from zeus.spd.analog.com (10.64.82.11) by NWD2HUBCAS1.ad.analog.com (10.64.73.29) with Microsoft SMTP Server id 8.1.358.0; Fri, 29 Apr 2011 05:54:07 -0400 Received: from linux.site ([10.99.22.20]) by zeus.spd.analog.com (8.14.1/8.14.1) with ESMTP id p3T9s4sL011503; Fri, 29 Apr 2011 05:54:05 -0400 (EDT) Received: from localhost.localdomain (unknown [10.99.29.101]) by linux.site (Postfix) with ESMTP id 78A564288DC6; Thu, 28 Apr 2011 20:06:01 -0600 (MDT) From: Bob Liu To: CC: , , , , , , , , , , , , , , , Bob Liu Subject: [PATCH 2/2] media:uvc_driver: Add support for NOMMU arch Date: Fri, 29 Apr 2011 18:11:35 +0800 Message-ID: <1304071895-27898-2-git-send-email-lliubbo@gmail.com> X-Mailer: git-send-email 1.6.3.3 In-Reply-To: <1304071895-27898-1-git-send-email-lliubbo@gmail.com> References: <1304071895-27898-1-git-send-email-lliubbo@gmail.com> MIME-Version: 1.0 X-OriginatorOrg: analog.com Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Fri, 29 Apr 2011 09:54:13 +0000 (UTC) Add support to uvc driver for NOMMU arch including add function uvc_queue_get_unmapped_area() and make some changes in uvc_queue_mmap(). So that uvc camera can be used on nommu arch like blackfin. Signed-off-by: Bob Liu --- drivers/media/video/uvc/uvc_queue.c | 34 +++++++++++++++++++++++++++++++++- drivers/media/video/uvc/uvc_v4l2.c | 17 +++++++++++++++++ drivers/media/video/uvc/uvcvideo.h | 4 ++++ 3 files changed, 54 insertions(+), 1 deletions(-) diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c index f14581b..109a063 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) break; } - if (i == queue->count || size != queue->buf_size) { + if (i == queue->count || PAGE_ALIGN(size) != queue->buf_size) { ret = -EINVAL; goto done; } @@ -436,6 +436,7 @@ int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma) vma->vm_flags |= VM_IO; addr = (unsigned long)queue->mem + buffer->buf.m.offset; +#ifdef CONFIG_MMU while (size > 0) { page = vmalloc_to_page((void *)addr); 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) addr += PAGE_SIZE; size -= PAGE_SIZE; } +#endif vma->vm_ops = &uvc_vm_ops; vma->vm_private_data = buffer; @@ -488,6 +490,36 @@ done: return mask; } +#ifndef CONFIG_MMU +/* + * Get unmapped area. + * + * NO-MMU arch need this function to make mmap() work correctly. + */ +unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue, + unsigned long pgoff) +{ + struct uvc_buffer *buffer; + unsigned int i; + unsigned long ret; + + mutex_lock(&queue->mutex); + for (i = 0; i < queue->count; ++i) { + buffer = &queue->buffer[i]; + if ((buffer->buf.m.offset >> PAGE_SHIFT) == pgoff) + break; + } + if (i == queue->count) { + ret = -EINVAL; + goto done; + } + ret = (unsigned long)queue->mem + buffer->buf.m.offset; +done: + mutex_unlock(&queue->mutex); + return ret; +} +#endif + /* * Enable or disable the video buffers queue. * diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index 9005a8d..d0da5d0 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c @@ -1081,6 +1081,20 @@ static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait) return uvc_queue_poll(&stream->queue, file, wait); } +#ifndef CONFIG_MMU +static unsigned long uvc_v4l2_get_unmapped_area(struct file *file, + unsigned long addr, unsigned long len, unsigned long pgoff, + unsigned long flags) +{ + struct uvc_fh *handle = file->private_data; + struct uvc_streaming *stream = handle->stream; + + uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_get_unmapped_area\n"); + + return uvc_queue_get_unmapped_area(&stream->queue, pgoff); +} +#endif + const struct v4l2_file_operations uvc_fops = { .owner = THIS_MODULE, .open = uvc_v4l2_open, @@ -1089,5 +1103,8 @@ const struct v4l2_file_operations uvc_fops = { .read = uvc_v4l2_read, .mmap = uvc_v4l2_mmap, .poll = uvc_v4l2_poll, +#ifndef CONFIG_MMU + .get_unmapped_area = uvc_v4l2_get_unmapped_area, +#endif }; diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index 45f01e7..6aa63c0 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h @@ -580,6 +580,10 @@ extern int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma); extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue, struct file *file, poll_table *wait); +#ifndef CONFIG_MMU +extern unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue, + unsigned long pgoff); +#endif extern int uvc_queue_allocated(struct uvc_video_queue *queue); static inline int uvc_queue_streaming(struct uvc_video_queue *queue) {