From patchwork Tue Sep 6 09:04:15 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Jarzmik X-Patchwork-Id: 9316153 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 5140660760 for ; Tue, 6 Sep 2016 09:07:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5DA5125E13 for ; Tue, 6 Sep 2016 09:07:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 51EBB28BCA; Tue, 6 Sep 2016 09:07:04 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 73EB725E13 for ; Tue, 6 Sep 2016 09:07:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754086AbcIFJEq (ORCPT ); Tue, 6 Sep 2016 05:04:46 -0400 Received: from smtp10.smtpout.orange.fr ([80.12.242.132]:19168 "EHLO smtp.smtpout.orange.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755806AbcIFJEc (ORCPT ); Tue, 6 Sep 2016 05:04:32 -0400 Received: from belgarion.home ([109.222.86.9]) by mwinf5d20 with ME id g94T1t00B0C5QSM0394VYd; Tue, 06 Sep 2016 11:04:30 +0200 X-ME-Helo: belgarion.home X-ME-Date: Tue, 06 Sep 2016 11:04:30 +0200 X-ME-IP: 109.222.86.9 From: Robert Jarzmik To: Mauro Carvalho Chehab , Guennadi Liakhovetski , Jiri Kosina , Hans Verkuil Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Robert Jarzmik Subject: [PATCH v6 05/14] media: platform: pxa_camera: trivial move of functions Date: Tue, 6 Sep 2016 11:04:15 +0200 Message-Id: <1473152664-5077-5-git-send-email-robert.jarzmik@free.fr> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1473152664-5077-1-git-send-email-robert.jarzmik@free.fr> References: <1473152664-5077-1-git-send-email-robert.jarzmik@free.fr> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Move the functions in the file to be regrouped into meaningful blocks : 1. pxa camera core handling functions, manipulating the herdware 2. videobuf2 functions, dealing with video buffers 3. video ioctl (vidioc) related functions 4. driver probing, removal, suspend and resume This patch doesn't modify a single line of code. Signed-off-by: Robert Jarzmik --- drivers/media/platform/soc_camera/pxa_camera.c | 473 +++++++++++++------------ 1 file changed, 241 insertions(+), 232 deletions(-) diff --git a/drivers/media/platform/soc_camera/pxa_camera.c b/drivers/media/platform/soc_camera/pxa_camera.c index d565bcb9f2d6..62e3f69a17ec 100644 --- a/drivers/media/platform/soc_camera/pxa_camera.c +++ b/drivers/media/platform/soc_camera/pxa_camera.c @@ -538,238 +538,6 @@ out: spin_unlock_irqrestore(&pcdev->lock, flags); } -static void pxa_buffer_cleanup(struct pxa_buffer *buf) -{ - int i; - - for (i = 0; i < 3 && buf->descs[i]; i++) { - dmaengine_desc_free(buf->descs[i]); - kfree(buf->sg[i]); - buf->descs[i] = NULL; - buf->sg[i] = NULL; - buf->sg_len[i] = 0; - buf->plane_sizes[i] = 0; - } - buf->nb_planes = 0; -} - -static int pxa_buffer_init(struct pxa_camera_dev *pcdev, - struct pxa_buffer *buf) -{ - struct vb2_buffer *vb = &buf->vbuf.vb2_buf; - struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); - int nb_channels = pcdev->channels; - int i, ret = 0; - unsigned long size = vb2_plane_size(vb, 0); - - switch (nb_channels) { - case 1: - buf->plane_sizes[0] = size; - break; - case 3: - buf->plane_sizes[0] = size / 2; - buf->plane_sizes[1] = size / 4; - buf->plane_sizes[2] = size / 4; - break; - default: - return -EINVAL; - }; - buf->nb_planes = nb_channels; - - ret = sg_split(sgt->sgl, sgt->nents, 0, nb_channels, - buf->plane_sizes, buf->sg, buf->sg_len, GFP_KERNEL); - if (ret < 0) { - dev_err(pcdev_to_dev(pcdev), - "sg_split failed: %d\n", ret); - return ret; - } - for (i = 0; i < nb_channels; i++) { - ret = pxa_init_dma_channel(pcdev, buf, i, - buf->sg[i], buf->sg_len[i]); - if (ret) { - pxa_buffer_cleanup(buf); - return ret; - } - } - INIT_LIST_HEAD(&buf->queue); - - return ret; -} - -static void pxac_vb2_cleanup(struct vb2_buffer *vb) -{ - struct pxa_buffer *buf = vb2_to_pxa_buffer(vb); - struct pxa_camera_dev *pcdev = vb2_get_drv_priv(vb->vb2_queue); - - dev_dbg(pcdev_to_dev(pcdev), - "%s(vb=%p)\n", __func__, vb); - pxa_buffer_cleanup(buf); -} - -static void pxac_vb2_queue(struct vb2_buffer *vb) -{ - struct pxa_buffer *buf = vb2_to_pxa_buffer(vb); - struct pxa_camera_dev *pcdev = vb2_get_drv_priv(vb->vb2_queue); - - dev_dbg(pcdev_to_dev(pcdev), - "%s(vb=%p) nb_channels=%d size=%lu active=%p\n", - __func__, vb, pcdev->channels, vb2_get_plane_payload(vb, 0), - pcdev->active); - - list_add_tail(&buf->queue, &pcdev->capture); - - pxa_dma_add_tail_buf(pcdev, buf); -} - -/* - * Please check the DMA prepared buffer structure in : - * Documentation/video4linux/pxa_camera.txt - * Please check also in pxa_camera_check_link_miss() to understand why DMA chain - * modification while DMA chain is running will work anyway. - */ -static int pxac_vb2_prepare(struct vb2_buffer *vb) -{ - struct pxa_camera_dev *pcdev = vb2_get_drv_priv(vb->vb2_queue); - struct pxa_buffer *buf = vb2_to_pxa_buffer(vb); - struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue); - int ret = 0; - - switch (pcdev->channels) { - case 1: - case 3: - vb2_set_plane_payload(vb, 0, icd->sizeimage); - break; - default: - return -EINVAL; - } - - dev_dbg(pcdev_to_dev(pcdev), - "%s (vb=%p) nb_channels=%d size=%lu\n", - __func__, vb, pcdev->channels, vb2_get_plane_payload(vb, 0)); - - WARN_ON(!icd->current_fmt); - -#ifdef DEBUG - /* - * This can be useful if you want to see if we actually fill - * the buffer with something - */ - for (i = 0; i < vb->num_planes; i++) - memset((void *)vb2_plane_vaddr(vb, i), - 0xaa, vb2_get_plane_payload(vb, i)); -#endif - - /* - * I think, in buf_prepare you only have to protect global data, - * the actual buffer is yours - */ - buf->inwork = 0; - pxa_videobuf_set_actdma(pcdev, buf); - - return ret; -} - -static int pxac_vb2_init(struct vb2_buffer *vb) -{ - struct pxa_camera_dev *pcdev = vb2_get_drv_priv(vb->vb2_queue); - struct pxa_buffer *buf = vb2_to_pxa_buffer(vb); - - dev_dbg(pcdev_to_dev(pcdev), - "%s(nb_channels=%d)\n", - __func__, pcdev->channels); - - return pxa_buffer_init(pcdev, buf); -} - -static int pxac_vb2_queue_setup(struct vb2_queue *vq, - unsigned int *nbufs, - unsigned int *num_planes, unsigned int sizes[], - struct device *alloc_devs[]) -{ - struct pxa_camera_dev *pcdev = vb2_get_drv_priv(vq); - struct soc_camera_device *icd = soc_camera_from_vb2q(vq); - int size = icd->sizeimage; - - dev_dbg(pcdev_to_dev(pcdev), - "%s(vq=%p nbufs=%d num_planes=%d size=%d)\n", - __func__, vq, *nbufs, *num_planes, size); - /* - * Called from VIDIOC_REQBUFS or in compatibility mode For YUV422P - * format, even if there are 3 planes Y, U and V, we reply there is only - * one plane, containing Y, U and V data, one after the other. - */ - if (*num_planes) - return sizes[0] < size ? -EINVAL : 0; - - *num_planes = 1; - switch (pcdev->channels) { - case 1: - case 3: - sizes[0] = size; - break; - default: - return -EINVAL; - } - - if (!*nbufs) - *nbufs = 1; - - return 0; -} - -static int pxac_vb2_start_streaming(struct vb2_queue *vq, unsigned int count) -{ - struct pxa_camera_dev *pcdev = vb2_get_drv_priv(vq); - - dev_dbg(pcdev_to_dev(pcdev), "%s(count=%d) active=%p\n", - __func__, count, pcdev->active); - - if (!pcdev->active) - pxa_camera_start_capture(pcdev); - - return 0; -} - -static void pxac_vb2_stop_streaming(struct vb2_queue *vq) -{ - vb2_wait_for_all_buffers(vq); -} - -static struct vb2_ops pxac_vb2_ops = { - .queue_setup = pxac_vb2_queue_setup, - .buf_init = pxac_vb2_init, - .buf_prepare = pxac_vb2_prepare, - .buf_queue = pxac_vb2_queue, - .buf_cleanup = pxac_vb2_cleanup, - .start_streaming = pxac_vb2_start_streaming, - .stop_streaming = pxac_vb2_stop_streaming, - .wait_prepare = vb2_ops_wait_prepare, - .wait_finish = vb2_ops_wait_finish, -}; - -static int pxa_camera_init_videobuf2(struct vb2_queue *vq, - struct soc_camera_device *icd) -{ - struct soc_camera_host *ici = to_soc_camera_host(icd->parent); - struct pxa_camera_dev *pcdev = ici->priv; - int ret; - - vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; - vq->drv_priv = pcdev; - vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; - vq->buf_struct_size = sizeof(struct pxa_buffer); - - vq->ops = &pxac_vb2_ops; - vq->mem_ops = &vb2_dma_sg_memops; - - ret = vb2_queue_init(vq); - dev_dbg(pcdev_to_dev(pcdev), - "vb2_queue_init(vq=%p): %d\n", vq, ret); - - return ret; -} - static u32 mclk_get_divisor(struct platform_device *pdev, struct pxa_camera_dev *pcdev) { @@ -1051,6 +819,244 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd, __raw_writel(cicr0, pcdev->base + CICR0); } +/* + * Videobuf2 section + */ +static void pxa_buffer_cleanup(struct pxa_buffer *buf) +{ + int i; + + for (i = 0; i < 3 && buf->descs[i]; i++) { + dmaengine_desc_free(buf->descs[i]); + kfree(buf->sg[i]); + buf->descs[i] = NULL; + buf->sg[i] = NULL; + buf->sg_len[i] = 0; + buf->plane_sizes[i] = 0; + } + buf->nb_planes = 0; +} + +static int pxa_buffer_init(struct pxa_camera_dev *pcdev, + struct pxa_buffer *buf) +{ + struct vb2_buffer *vb = &buf->vbuf.vb2_buf; + struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); + int nb_channels = pcdev->channels; + int i, ret = 0; + unsigned long size = vb2_plane_size(vb, 0); + + switch (nb_channels) { + case 1: + buf->plane_sizes[0] = size; + break; + case 3: + buf->plane_sizes[0] = size / 2; + buf->plane_sizes[1] = size / 4; + buf->plane_sizes[2] = size / 4; + break; + default: + return -EINVAL; + }; + buf->nb_planes = nb_channels; + + ret = sg_split(sgt->sgl, sgt->nents, 0, nb_channels, + buf->plane_sizes, buf->sg, buf->sg_len, GFP_KERNEL); + if (ret < 0) { + dev_err(pcdev_to_dev(pcdev), + "sg_split failed: %d\n", ret); + return ret; + } + for (i = 0; i < nb_channels; i++) { + ret = pxa_init_dma_channel(pcdev, buf, i, + buf->sg[i], buf->sg_len[i]); + if (ret) { + pxa_buffer_cleanup(buf); + return ret; + } + } + INIT_LIST_HEAD(&buf->queue); + + return ret; +} + +static void pxac_vb2_cleanup(struct vb2_buffer *vb) +{ + struct pxa_buffer *buf = vb2_to_pxa_buffer(vb); + struct pxa_camera_dev *pcdev = vb2_get_drv_priv(vb->vb2_queue); + + dev_dbg(pcdev_to_dev(pcdev), + "%s(vb=%p)\n", __func__, vb); + pxa_buffer_cleanup(buf); +} + +static void pxac_vb2_queue(struct vb2_buffer *vb) +{ + struct pxa_buffer *buf = vb2_to_pxa_buffer(vb); + struct pxa_camera_dev *pcdev = vb2_get_drv_priv(vb->vb2_queue); + + dev_dbg(pcdev_to_dev(pcdev), + "%s(vb=%p) nb_channels=%d size=%lu active=%p\n", + __func__, vb, pcdev->channels, vb2_get_plane_payload(vb, 0), + pcdev->active); + + list_add_tail(&buf->queue, &pcdev->capture); + + pxa_dma_add_tail_buf(pcdev, buf); +} + +/* + * Please check the DMA prepared buffer structure in : + * Documentation/video4linux/pxa_camera.txt + * Please check also in pxa_camera_check_link_miss() to understand why DMA chain + * modification while DMA chain is running will work anyway. + */ +static int pxac_vb2_prepare(struct vb2_buffer *vb) +{ + struct pxa_camera_dev *pcdev = vb2_get_drv_priv(vb->vb2_queue); + struct pxa_buffer *buf = vb2_to_pxa_buffer(vb); + struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue); + int ret = 0; + + switch (pcdev->channels) { + case 1: + case 3: + vb2_set_plane_payload(vb, 0, icd->sizeimage); + break; + default: + return -EINVAL; + } + + dev_dbg(pcdev_to_dev(pcdev), + "%s (vb=%p) nb_channels=%d size=%lu\n", + __func__, vb, pcdev->channels, vb2_get_plane_payload(vb, 0)); + + WARN_ON(!icd->current_fmt); + +#ifdef DEBUG + /* + * This can be useful if you want to see if we actually fill + * the buffer with something + */ + for (i = 0; i < vb->num_planes; i++) + memset((void *)vb2_plane_vaddr(vb, i), + 0xaa, vb2_get_plane_payload(vb, i)); +#endif + + /* + * I think, in buf_prepare you only have to protect global data, + * the actual buffer is yours + */ + buf->inwork = 0; + pxa_videobuf_set_actdma(pcdev, buf); + + return ret; +} + +static int pxac_vb2_init(struct vb2_buffer *vb) +{ + struct pxa_camera_dev *pcdev = vb2_get_drv_priv(vb->vb2_queue); + struct pxa_buffer *buf = vb2_to_pxa_buffer(vb); + + dev_dbg(pcdev_to_dev(pcdev), + "%s(nb_channels=%d)\n", + __func__, pcdev->channels); + + return pxa_buffer_init(pcdev, buf); +} + +static int pxac_vb2_queue_setup(struct vb2_queue *vq, + unsigned int *nbufs, + unsigned int *num_planes, unsigned int sizes[], + struct device *alloc_devs[]) +{ + struct pxa_camera_dev *pcdev = vb2_get_drv_priv(vq); + struct soc_camera_device *icd = soc_camera_from_vb2q(vq); + int size = icd->sizeimage; + + dev_dbg(pcdev_to_dev(pcdev), + "%s(vq=%p nbufs=%d num_planes=%d size=%d)\n", + __func__, vq, *nbufs, *num_planes, size); + /* + * Called from VIDIOC_REQBUFS or in compatibility mode For YUV422P + * format, even if there are 3 planes Y, U and V, we reply there is only + * one plane, containing Y, U and V data, one after the other. + */ + if (*num_planes) + return sizes[0] < size ? -EINVAL : 0; + + *num_planes = 1; + switch (pcdev->channels) { + case 1: + case 3: + sizes[0] = size; + break; + default: + return -EINVAL; + } + + if (!*nbufs) + *nbufs = 1; + + return 0; +} + +static int pxac_vb2_start_streaming(struct vb2_queue *vq, unsigned int count) +{ + struct pxa_camera_dev *pcdev = vb2_get_drv_priv(vq); + + dev_dbg(pcdev_to_dev(pcdev), "%s(count=%d) active=%p\n", + __func__, count, pcdev->active); + + if (!pcdev->active) + pxa_camera_start_capture(pcdev); + + return 0; +} + +static void pxac_vb2_stop_streaming(struct vb2_queue *vq) +{ + vb2_wait_for_all_buffers(vq); +} + +static struct vb2_ops pxac_vb2_ops = { + .queue_setup = pxac_vb2_queue_setup, + .buf_init = pxac_vb2_init, + .buf_prepare = pxac_vb2_prepare, + .buf_queue = pxac_vb2_queue, + .buf_cleanup = pxac_vb2_cleanup, + .start_streaming = pxac_vb2_start_streaming, + .stop_streaming = pxac_vb2_stop_streaming, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, +}; + +static int pxa_camera_init_videobuf2(struct vb2_queue *vq, + struct soc_camera_device *icd) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + struct pxa_camera_dev *pcdev = ici->priv; + int ret; + + vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; + vq->drv_priv = pcdev; + vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + vq->buf_struct_size = sizeof(struct pxa_buffer); + + vq->ops = &pxac_vb2_ops; + vq->mem_ops = &vb2_dma_sg_memops; + + ret = vb2_queue_init(vq); + dev_dbg(pcdev_to_dev(pcdev), + "vb2_queue_init(vq=%p): %d\n", vq, ret); + + return ret; +} + +/* + * Video ioctls section + */ static int pxa_camera_set_bus_param(struct soc_camera_device *icd) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); @@ -1501,6 +1507,9 @@ static int pxa_camera_querycap(struct soc_camera_host *ici, return 0; } +/* + * Driver probe, remove, suspend and resume operations + */ static int pxa_camera_suspend(struct device *dev) { struct soc_camera_host *ici = to_soc_camera_host(dev);