From patchwork Wed Nov 2 13:23:24 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9409105 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 BEF6760234 for ; Wed, 2 Nov 2016 13:30:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AC29B2A17A for ; Wed, 2 Nov 2016 13:30:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A0CE12A17C; Wed, 2 Nov 2016 13:30:02 +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,RCVD_IN_DNSWL_HI autolearn=ham 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 273642A17B for ; Wed, 2 Nov 2016 13:30:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754772AbcKBN3y (ORCPT ); Wed, 2 Nov 2016 09:29:54 -0400 Received: from smtp-4.sys.kth.se ([130.237.48.193]:49638 "EHLO smtp-4.sys.kth.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754583AbcKBN3s (ORCPT ); Wed, 2 Nov 2016 09:29:48 -0400 Received: from smtp-4.sys.kth.se (localhost.localdomain [127.0.0.1]) by smtp-4.sys.kth.se (Postfix) with ESMTP id DC41A3289; Wed, 2 Nov 2016 14:29:46 +0100 (CET) X-Virus-Scanned: by amavisd-new at kth.se Received: from smtp-4.sys.kth.se ([127.0.0.1]) by smtp-4.sys.kth.se (smtp-4.sys.kth.se [127.0.0.1]) (amavisd-new, port 10024) with LMTP id c9qz74jvFZkK; Wed, 2 Nov 2016 14:29:46 +0100 (CET) X-KTH-Auth: niso [89.233.230.99] X-KTH-mail-from: niklas.soderlund+renesas@ragnatech.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by smtp-4.sys.kth.se (Postfix) with ESMTPSA id AEAC832C3; Wed, 2 Nov 2016 14:29:45 +0100 (CET) From: =?UTF-8?q?Niklas=20S=C3=B6derlund?= To: Laurent Pinchart , Hans Verkuil Cc: linux-media@vger.kernel.org, linux-renesas-soc@vger.kernel.org, tomoharu.fukawa.eb@renesas.com, Sakari Ailus , =?UTF-8?q?Niklas=20S=C3=B6derlund?= Subject: [PATCH 27/32] media: rcar-vin: start/stop the CSI2 bridge stream Date: Wed, 2 Nov 2016 14:23:24 +0100 Message-Id: <20161102132329.436-28-niklas.soderlund+renesas@ragnatech.se> X-Mailer: git-send-email 2.10.2 In-Reply-To: <20161102132329.436-1-niklas.soderlund+renesas@ragnatech.se> References: <20161102132329.436-1-niklas.soderlund+renesas@ragnatech.se> MIME-Version: 1.0 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 On Gen3 the CSI2 bridge stream needs to be start/stop in conjunction with the video source. Create helpers to deal with both the Gen2 single subdevice case and the Gen3 CSI2 group case. In the Gen3 case there might be other simultaneous users of the bridge and source devices so examine each entity stream_count before acting on any particular device. Signed-off-by: Niklas Söderlund --- drivers/media/platform/rcar-vin/rcar-dma.c | 84 +++++++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index 322e4c1..872f138 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -1089,15 +1089,87 @@ static void rvin_buffer_queue(struct vb2_buffer *vb) spin_unlock_irqrestore(&vin->qlock, flags); } +static int __rvin_start_streaming(struct rvin_dev *vin) +{ + struct v4l2_subdev *source, *bridge = NULL; + struct media_pipeline *pipe; + int ret; + + source = vin_to_source(vin); + if (!source) + return -EINVAL; + + if (vin_have_bridge(vin)) { + bridge = vin_to_bridge(vin); + + if (!bridge) + return -EINVAL; + + mutex_lock(&vin->group->lock); + + pipe = bridge->entity.pipe ? bridge->entity.pipe : + &vin->vdev.pipe; + ret = media_entity_pipeline_start(&vin->vdev.entity, pipe); + if (ret) { + mutex_unlock(&vin->group->lock); + return ret; + } + + /* Only need to start stream if it's not running */ + if (bridge->entity.stream_count <= 1) + v4l2_subdev_call(bridge, video, s_stream, 1); + if (source->entity.stream_count <= 1) + v4l2_subdev_call(source, video, s_stream, 1); + + mutex_unlock(&vin->group->lock); + } else { + v4l2_subdev_call(source, video, s_stream, 1); + } + + return 0; +} + +static int __rvin_stop_streaming(struct rvin_dev *vin) +{ + struct v4l2_subdev *source, *bridge = NULL; + + source = vin_to_source(vin); + if (!source) + return -EINVAL; + + if (vin_have_bridge(vin)) { + bridge = vin_to_bridge(vin); + + if (!bridge) + return -EINVAL; + + mutex_lock(&vin->group->lock); + + media_entity_pipeline_stop(&vin->vdev.entity); + + /* Only need to stop stream if there are no other users */ + if (bridge->entity.stream_count <= 0) + v4l2_subdev_call(bridge, video, s_stream, 0); + if (source->entity.stream_count <= 0) + v4l2_subdev_call(source, video, s_stream, 0); + + mutex_unlock(&vin->group->lock); + } else { + v4l2_subdev_call(source, video, s_stream, 0); + } + + return 0; +} + static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count) { struct rvin_dev *vin = vb2_get_drv_priv(vq); - struct v4l2_subdev *sd; unsigned long flags; int ret; - sd = vin_to_source(vin); - v4l2_subdev_call(sd, video, s_stream, 1); + ret = __rvin_start_streaming(vin); + if (ret) + return ret; spin_lock_irqsave(&vin->qlock, flags); @@ -1122,7 +1194,7 @@ static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count) /* Return all buffers if something went wrong */ if (ret) { return_all_buffers(vin, VB2_BUF_STATE_QUEUED); - v4l2_subdev_call(sd, video, s_stream, 0); + __rvin_stop_streaming(vin); } spin_unlock_irqrestore(&vin->qlock, flags); @@ -1133,7 +1205,6 @@ static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count) static void rvin_stop_streaming(struct vb2_queue *vq) { struct rvin_dev *vin = vb2_get_drv_priv(vq); - struct v4l2_subdev *sd; unsigned long flags; int retries = 0; @@ -1172,8 +1243,7 @@ static void rvin_stop_streaming(struct vb2_queue *vq) spin_unlock_irqrestore(&vin->qlock, flags); - sd = vin_to_source(vin); - v4l2_subdev_call(sd, video, s_stream, 0); + __rvin_stop_streaming(vin); /* disable interrupts */ rvin_disable_interrupts(vin);