From patchwork Mon May 14 21:39:05 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sylwester Nawrocki X-Patchwork-Id: 11243 Received: from mail.tu-berlin.de ([130.149.7.33]) by www.linuxtv.org with esmtp (Exim 4.72) (envelope-from ) id 1SU2z5-0005ZA-BJ for patchwork@linuxtv.org; Mon, 14 May 2012 23:39:15 +0200 X-tubIT-Incoming-IP: 209.132.180.67 Received: from vger.kernel.org ([209.132.180.67]) by mail.tu-berlin.de (exim-4.75/mailfrontend-3) with esmtp for id 1SU2z3-000098-FR; Mon, 14 May 2012 23:39:15 +0200 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932397Ab2ENVjL (ORCPT ); Mon, 14 May 2012 17:39:11 -0400 Received: from mail-we0-f174.google.com ([74.125.82.174]:55879 "EHLO mail-we0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932394Ab2ENVjI (ORCPT ); Mon, 14 May 2012 17:39:08 -0400 Received: by weyu7 with SMTP id u7so2086973wey.19 for ; Mon, 14 May 2012 14:39:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:cc:subject :references:in-reply-to:content-type; bh=WHiU/Rz2fFzzGQMxX9t0Kygifx/bTKcrre97Al1E33M=; b=NEKNf+hBRTnldiP4y+CNW9RijXpLtcxxWWumhUvHJC2pkY1ptDmmhf5LeBOu8Q3iOj 6EVPrw+S9VCwW1nukRaW6q9YNRvLlStTdRG/KMjF10WD2RUZesGWaPwukubOFcgMJvBF 8qjH8ShZ3OChaq8424rfk5datNiTMah8511Q5f6kod1OjVEpxmJB5srOUQwYeBgLDObs VwQFCyAuuOeRqlLjDJluz41nGbpB/YImFG/5UhfLvux1mQtKRmANgZtGcedsgbt4arp2 MCHGbeoUUCCC7PyUD01I3xxl4SpEjl9ec07GSEorHQuSVQmOp3j2imP/MvLzpmYSoSI8 sSeQ== Received: by 10.180.81.66 with SMTP id y2mr23692393wix.22.1337031547100; Mon, 14 May 2012 14:39:07 -0700 (PDT) Received: from [192.168.1.110] (031011252076.warszawa.vectranet.pl. [31.11.252.76]) by mx.google.com with ESMTPS id et10sm26308063wib.2.2012.05.14.14.39.05 (version=SSLv3 cipher=OTHER); Mon, 14 May 2012 14:39:06 -0700 (PDT) Message-ID: <4FB17B79.2000207@gmail.com> Date: Mon, 14 May 2012 23:39:05 +0200 From: Sylwester Nawrocki User-Agent: Mozilla/5.0 (X11; Linux i686; rv:12.0) Gecko/20120430 Thunderbird/12.0.1 MIME-Version: 1.0 To: Mauro Carvalho Chehab CC: "linux-media@vger.kernel.org" , Sylwester Nawrocki Subject: Re: [GIT PULL FOR 3.5] s5p-fimc driver updates References: <4FA3F635.60409@samsung.com> <4FAB80D5.50500@samsung.com> In-Reply-To: <4FAB80D5.50500@samsung.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-PMX-Version: 5.6.1.2065439, Antispam-Engine: 2.7.2.376379, Antispam-Data: 2012.5.14.213018 X-PMX-Spam: Gauge=IIIIIIIII, Probability=9%, Report=' FORGED_FROM_GMAIL 0.1, MULTIPLE_RCPTS 0.1, HTML_00_01 0.05, HTML_00_10 0.05, MIME_TEXT_ONLY_MP_MIXED 0.05, BODYTEXTP_SIZE_3000_LESS 0, BODY_SIZE_10000_PLUS 0, URI_ENDS_IN_HTML 0, __ANY_URI 0, __BAT_BOUNDARY 0, __BOUNCE_CHALLENGE_SUBJ 0, __BOUNCE_NDR_SUBJ_EXEMPT 0, __CP_MEDIA_BODY 0, __CP_URI_IN_BODY 0, __CT 0, __CTYPE_HAS_BOUNDARY 0, __CTYPE_MULTIPART 0, __CTYPE_MULTIPART_MIXED 0, __FRAUD_WEBMAIL 0, __FRAUD_WEBMAIL_FROM 0, __FROM_GMAIL 0, __HAS_MSGID 0, __HAS_X_MAILING_LIST 0, __MIME_TEXT_ONLY 0, __MIME_VERSION 0, __MOZILLA_MSGID 0, __MULTIPLE_RCPTS_CC_X2 0, __PHISH_SPEAR_STRUCTURE_1 0, __SANE_MSGID 0, __SUBJ_ALPHA_END 0, __TO_MALFORMED_2 0, __URI_NO_WWW 0, __URI_NS , __USER_AGENT 0' On 05/10/2012 10:48 AM, Sylwester Nawrocki wrote: > On 05/04/2012 05:31 PM, Sylwester Nawrocki wrote: >> Hi Mauro, >> >> The following changes since commit 34b2debaa62bfa384ef91b61cf2c40c48e86a5e2: >> >> s5p-fimc: Correct memory allocation for VIDIOC_CREATE_BUFS (2012-05-04 17:07:24 +0200) >> >> are available in the git repository at: >> >> git://git.infradead.org/users/kmpark/linux-samsung v4l-fimc-exynos4x12 >> >> for you to fetch changes up to bab96b068afa07105139be09d3830cc9ed580382: >> >> s5p-fimc: Use selection API in place of crop operations (2012-05-04 17:18:38 +0200) > > Mauro, > > I've found a few issues in this series afterwards and re-edited 3 commits there. > Here is an updated pull request: > > The following changes since commit ae45d3e9aea0ab951dbbca2238fbfbf3993f1e7f: > > s5p-fimc: Correct memory allocation for VIDIOC_CREATE_BUFS (2012-05-09 16:07:49 +0200) > > are available in the git repository at: > > git://git.infradead.org/users/kmpark/linux-samsung v4l-fimc-exynos4x12 > > for you to fetch changes up to 5feefe6656583de6fd4ef1d53b19031dd5efeec1: > > s5p-fimc: Use selection API in place of crop operations (2012-05-09 16:11:29 +0200) > > ---------------------------------------------------------------- > Sylwester Nawrocki (14): > V4L: Extend V4L2_CID_COLORFX with more image effects > s5p-fimc: Avoid crash with null platform_data > s5p-fimc: Move m2m node driver into separate file It seems there is a conflict now with this patch: http://git.linuxtv.org/media_tree.git/commit/5126f2590bee412e3053de851cb07f531e4be36a Attached are updated versions of the two conflicting patches, the others don't need touching. I could provide rebased version of the whole change set tomorrow - if needed. Kind regards, Sylwester > s5p-fimc: Use v4l2_subdev internal ops to register video nodes > s5p-fimc: Refactor the register interface functions > s5p-fimc: Add FIMC-LITE register definitions > s5p-fimc: Rework the video pipeline control functions > s5p-fimc: Prefix format enumerations with FIMC_FMT_ > s5p-fimc: Minor cleanups > s5p-fimc: Make sure an interrupt is properly requested > s5p-fimc: Add support for Exynos4x12 FIMC-LITE > s5p-fimc: Update copyright notices > s5p-fimc: Add color effect control > s5p-fimc: Use selection API in place of crop operations From 610f467a3cb02ca34ce48bb8d6cc3f2409571f93 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Mon, 14 May 2012 23:15:21 +0200 Subject: [PATCH 2/2] s5p-fimc: Use v4l2_subdev internal ops to register video nodes In order to be able to select only FIMC-LITE support, which is added with subsequent patches, the regular FIMC support is now contained only in fimc-core.c, fimc-m2m.c and fimc-capture.c files. The graph and pipeline management is now solely handled in fimc-mdevice.[ch]. This means the FIMC driver can now be excluded with Kconfig option, leaving only FIMC-LITE and allowing this driver to be reused in SoCs that have only FIMC-LITE and no regular FIMC IP. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park --- drivers/media/video/s5p-fimc/fimc-capture.c | 142 +++++++++++++++------------ drivers/media/video/s5p-fimc/fimc-core.c | 13 ++- drivers/media/video/s5p-fimc/fimc-core.h | 7 +- drivers/media/video/s5p-fimc/fimc-m2m.c | 18 +++- drivers/media/video/s5p-fimc/fimc-mdevice.c | 89 +++++++---------- drivers/media/video/s5p-fimc/fimc-mdevice.h | 1 + 6 files changed, 139 insertions(+), 131 deletions(-) diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 2c7a4f8..51cb447 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c @@ -993,7 +993,7 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc) if (!(pad->flags & MEDIA_PAD_FL_SINK)) break; /* Don't call FIMC subdev operation to avoid nested locking */ - if (sd == fimc->vid_cap.subdev) { + if (sd == &fimc->vid_cap.subdev) { struct fimc_frame *ff = &vid_cap->ctx->s_frame; sink_fmt.format.width = ff->f_width; sink_fmt.format.height = ff->f_height; @@ -1489,53 +1489,6 @@ static struct v4l2_subdev_ops fimc_subdev_ops = { .pad = &fimc_subdev_pad_ops, }; -static int fimc_create_capture_subdev(struct fimc_dev *fimc, - struct v4l2_device *v4l2_dev) -{ - struct v4l2_subdev *sd; - int ret; - - sd = kzalloc(sizeof(*sd), GFP_KERNEL); - if (!sd) - return -ENOMEM; - - v4l2_subdev_init(sd, &fimc_subdev_ops); - sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE; - snprintf(sd->name, sizeof(sd->name), "FIMC.%d", fimc->pdev->id); - - fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK; - fimc->vid_cap.sd_pads[FIMC_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; - ret = media_entity_init(&sd->entity, FIMC_SD_PADS_NUM, - fimc->vid_cap.sd_pads, 0); - if (ret) - goto me_err; - ret = v4l2_device_register_subdev(v4l2_dev, sd); - if (ret) - goto sd_err; - - fimc->vid_cap.subdev = sd; - v4l2_set_subdevdata(sd, fimc); - sd->entity.ops = &fimc_sd_media_ops; - return 0; -sd_err: - media_entity_cleanup(&sd->entity); -me_err: - kfree(sd); - return ret; -} - -static void fimc_destroy_capture_subdev(struct fimc_dev *fimc) -{ - struct v4l2_subdev *sd = fimc->vid_cap.subdev; - - if (!sd) - return; - media_entity_cleanup(&sd->entity); - v4l2_device_unregister_subdev(sd); - kfree(sd); - fimc->vid_cap.subdev = NULL; -} - /* Set default format at the sensor and host interface */ static int fimc_capture_set_default_format(struct fimc_dev *fimc) { @@ -1554,7 +1507,7 @@ static int fimc_capture_set_default_format(struct fimc_dev *fimc) } /* fimc->lock must be already initialized */ -int fimc_register_capture_device(struct fimc_dev *fimc, +static int fimc_register_capture_device(struct fimc_dev *fimc, struct v4l2_device *v4l2_dev) { struct video_device *vfd; @@ -1572,7 +1525,7 @@ int fimc_register_capture_device(struct fimc_dev *fimc, ctx->out_path = FIMC_DMA; ctx->state = FIMC_CTX_CAP; ctx->s_frame.fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, 0); - ctx->d_frame.fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, 0); + ctx->d_frame.fmt = ctx->s_frame.fmt; vfd = video_device_alloc(); if (!vfd) { @@ -1580,8 +1533,7 @@ int fimc_register_capture_device(struct fimc_dev *fimc, goto err_vd_alloc; } - snprintf(vfd->name, sizeof(vfd->name), "%s.capture", - dev_name(&fimc->pdev->dev)); + snprintf(vfd->name, sizeof(vfd->name), "fimc.%d.capture", fimc->id); vfd->fops = &fimc_capture_fops; vfd->ioctl_ops = &fimc_capture_ioctl_ops; @@ -1616,18 +1568,22 @@ int fimc_register_capture_device(struct fimc_dev *fimc, vb2_queue_init(q); - fimc->vid_cap.vd_pad.flags = MEDIA_PAD_FL_SINK; - ret = media_entity_init(&vfd->entity, 1, &fimc->vid_cap.vd_pad, 0); + vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK; + ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad, 0); if (ret) goto err_ent; - ret = fimc_create_capture_subdev(fimc, v4l2_dev); + + ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); if (ret) - goto err_sd_reg; + goto err_vd; + + v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n", + vfd->name, video_device_node_name(vfd)); vfd->ctrl_handler = &ctx->ctrl_handler; return 0; -err_sd_reg: +err_vd: media_entity_cleanup(&vfd->entity); err_ent: video_device_release(vfd); @@ -1636,17 +1592,73 @@ err_vd_alloc: return ret; } -void fimc_unregister_capture_device(struct fimc_dev *fimc) +static int fimc_capture_subdev_registered(struct v4l2_subdev *sd) { - struct video_device *vfd = fimc->vid_cap.vfd; + struct fimc_dev *fimc = v4l2_get_subdevdata(sd); + int ret; - if (vfd) { - media_entity_cleanup(&vfd->entity); - /* Can also be called if video device was - not registered */ - video_unregister_device(vfd); + ret = fimc_register_m2m_device(fimc, sd->v4l2_dev); + if (ret) + return ret; + + ret = fimc_register_capture_device(fimc, sd->v4l2_dev); + if (ret) + fimc_unregister_m2m_device(fimc); + + return ret; +} + +static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd) +{ + struct fimc_dev *fimc = v4l2_get_subdevdata(sd); + + if (fimc == NULL) + return; + + fimc_unregister_m2m_device(fimc); + + if (fimc->vid_cap.vfd) { + media_entity_cleanup(&fimc->vid_cap.vfd->entity); + video_unregister_device(fimc->vid_cap.vfd); + fimc->vid_cap.vfd = NULL; } - fimc_destroy_capture_subdev(fimc); + kfree(fimc->vid_cap.ctx); fimc->vid_cap.ctx = NULL; } + +static const struct v4l2_subdev_internal_ops fimc_capture_sd_internal_ops = { + .registered = fimc_capture_subdev_registered, + .unregistered = fimc_capture_subdev_unregistered, +}; + +int fimc_initialize_capture_subdev(struct fimc_dev *fimc) +{ + struct v4l2_subdev *sd = &fimc->vid_cap.subdev; + int ret; + + v4l2_subdev_init(sd, &fimc_subdev_ops); + sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE; + snprintf(sd->name, sizeof(sd->name), "FIMC.%d", fimc->pdev->id); + + fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK; + fimc->vid_cap.sd_pads[FIMC_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; + ret = media_entity_init(&sd->entity, FIMC_SD_PADS_NUM, + fimc->vid_cap.sd_pads, 0); + if (ret) + return ret; + + sd->entity.ops = &fimc_sd_media_ops; + sd->internal_ops = &fimc_capture_sd_internal_ops; + v4l2_set_subdevdata(sd, fimc); + return 0; +} + +void fimc_unregister_capture_subdev(struct fimc_dev *fimc) +{ + struct v4l2_subdev *sd = &fimc->vid_cap.subdev; + + v4l2_device_unregister_subdev(sd); + media_entity_cleanup(&sd->entity); + v4l2_set_subdevdata(sd, NULL); +} diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index 749db4d..add24cd 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c @@ -842,8 +842,6 @@ static int fimc_probe(struct platform_device *pdev) clk_set_rate(fimc->clock[CLK_BUS], drv_data->lclk_frequency); clk_enable(fimc->clock[CLK_BUS]); - platform_set_drvdata(pdev, fimc); - ret = devm_request_irq(&pdev->dev, res->start, fimc_irq_handler, 0, pdev->name, fimc); if (ret) { @@ -851,10 +849,15 @@ static int fimc_probe(struct platform_device *pdev) goto err_clk; } + ret = fimc_initialize_capture_subdev(fimc); + if (ret) + goto err_clk; + + platform_set_drvdata(pdev, fimc); pm_runtime_enable(&pdev->dev); ret = pm_runtime_get_sync(&pdev->dev); if (ret < 0) - goto err_clk; + goto err_sd; /* Initialize contiguous memory allocator */ fimc->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); if (IS_ERR(fimc->alloc_ctx)) { @@ -866,9 +869,10 @@ static int fimc_probe(struct platform_device *pdev) pm_runtime_put(&pdev->dev); return 0; - err_pm: pm_runtime_put(&pdev->dev); +err_sd: + fimc_unregister_capture_subdev(fimc); err_clk: fimc_clk_put(fimc); return ret; @@ -953,6 +957,7 @@ static int __devexit fimc_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); + fimc_unregister_capture_subdev(fimc); vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx); clk_disable(fimc->clock[CLK_BUS]); diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h index 288631a..ef7c6a2 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.h +++ b/drivers/media/video/s5p-fimc/fimc-core.h @@ -331,7 +331,7 @@ struct fimc_vid_cap { struct fimc_ctx *ctx; struct vb2_alloc_ctx *alloc_ctx; struct video_device *vfd; - struct v4l2_subdev *subdev; + struct v4l2_subdev subdev; struct media_pad vd_pad; struct v4l2_mbus_framefmt mf; struct media_pad sd_pads[FIMC_SD_PADS_NUM]; @@ -737,9 +737,8 @@ void fimc_m2m_job_finish(struct fimc_ctx *ctx, int vb_state); /* -----------------------------------------------------*/ /* fimc-capture.c */ -int fimc_register_capture_device(struct fimc_dev *fimc, - struct v4l2_device *v4l2_dev); -void fimc_unregister_capture_device(struct fimc_dev *fimc); +int fimc_initialize_capture_subdev(struct fimc_dev *fimc); +void fimc_unregister_capture_subdev(struct fimc_dev *fimc); int fimc_capture_ctrls_create(struct fimc_dev *fimc); void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification, void *arg); diff --git a/drivers/media/video/s5p-fimc/fimc-m2m.c b/drivers/media/video/s5p-fimc/fimc-m2m.c index 4a755ff..bb81126 100644 --- a/drivers/media/video/s5p-fimc/fimc-m2m.c +++ b/drivers/media/video/s5p-fimc/fimc-m2m.c @@ -777,7 +777,8 @@ int fimc_register_m2m_device(struct fimc_dev *fimc, * This driver needs auditing so that this flag can be removed. */ set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags); - snprintf(vfd->name, sizeof(vfd->name), "%s.m2m", dev_name(&pdev->dev)); + + snprintf(vfd->name, sizeof(vfd->name), "fimc.%d.m2m", fimc->id); video_set_drvdata(vfd, fimc); fimc->m2m.vfd = vfd; @@ -789,9 +790,20 @@ int fimc_register_m2m_device(struct fimc_dev *fimc, } ret = media_entity_init(&vfd->entity, 0, NULL, 0); - if (!ret) - return 0; + if (ret) + goto err_me; + + ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); + if (ret) + goto err_vd; + + v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n", + vfd->name, video_device_node_name(vfd)); + return 0; +err_vd: + media_entity_cleanup(&vfd->entity); +err_me: v4l2_m2m_release(fimc->m2m.m2m_dev); err_init: video_device_release(fimc->m2m.vfd); diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.c b/drivers/media/video/s5p-fimc/fimc-mdevice.c index f97ac02..c319842 100644 --- a/drivers/media/video/s5p-fimc/fimc-mdevice.c +++ b/drivers/media/video/s5p-fimc/fimc-mdevice.c @@ -304,8 +304,9 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd) static int fimc_register_callback(struct device *dev, void *p) { struct fimc_dev *fimc = dev_get_drvdata(dev); + struct v4l2_subdev *sd = &fimc->vid_cap.subdev; struct fimc_md *fmd = p; - int ret; + int ret = 0; if (!fimc || !fimc->pdev) return 0; @@ -313,12 +314,14 @@ static int fimc_register_callback(struct device *dev, void *p) return 0; fmd->fimc[fimc->pdev->id] = fimc; - ret = fimc_register_m2m_device(fimc, &fmd->v4l2_dev); - if (ret) - return ret; - ret = fimc_register_capture_device(fimc, &fmd->v4l2_dev); - if (!ret) - fimc->vid_cap.user_subdev_api = fmd->user_subdev_api; + sd->grp_id = FIMC_GROUP_ID; + + ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd); + if (ret) { + v4l2_err(&fmd->v4l2_dev, "Failed to register FIMC.%d (%d)\n", + fimc->id, ret); + } + return ret; } @@ -401,8 +404,7 @@ static void fimc_md_unregister_entities(struct fimc_md *fmd) for (i = 0; i < FIMC_MAX_DEVS; i++) { if (fmd->fimc[i] == NULL) continue; - fimc_unregister_m2m_device(fmd->fimc[i]); - fimc_unregister_capture_device(fmd->fimc[i]); + v4l2_device_unregister_subdev(&fmd->fimc[i]->vid_cap.subdev); fmd->fimc[i] = NULL; } for (i = 0; i < CSIS_MAX_ENTITIES; i++) { @@ -420,35 +422,6 @@ static void fimc_md_unregister_entities(struct fimc_md *fmd) } } -static int fimc_md_register_video_nodes(struct fimc_md *fmd) -{ - struct video_device *vdev; - int i, ret = 0; - - for (i = 0; i < FIMC_MAX_DEVS && !ret; i++) { - if (!fmd->fimc[i]) - continue; - - vdev = fmd->fimc[i]->m2m.vfd; - if (vdev) { - ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); - if (ret) - break; - v4l2_info(&fmd->v4l2_dev, "Registered %s as /dev/%s\n", - vdev->name, video_device_node_name(vdev)); - } - - vdev = fmd->fimc[i]->vid_cap.vfd; - if (vdev == NULL) - continue; - ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); - v4l2_info(&fmd->v4l2_dev, "Registered %s as /dev/%s\n", - vdev->name, video_device_node_name(vdev)); - } - - return ret; -} - /** * __fimc_md_create_fimc_links - create links to all FIMC entities * @fmd: fimc media device @@ -479,7 +452,7 @@ static int __fimc_md_create_fimc_links(struct fimc_md *fmd, continue; flags = (i == fimc_id) ? MEDIA_LNK_FL_ENABLED : 0; - sink = &fmd->fimc[i]->vid_cap.subdev->entity; + sink = &fmd->fimc[i]->vid_cap.subdev.entity; ret = media_entity_create_link(source, pad, sink, FIMC_SD_PAD_SINK, flags); if (ret) @@ -588,7 +561,7 @@ static int fimc_md_create_links(struct fimc_md *fmd) for (i = 0; i < FIMC_MAX_DEVS; i++) { if (!fmd->fimc[i]) continue; - source = &fmd->fimc[i]->vid_cap.subdev->entity; + source = &fmd->fimc[i]->vid_cap.subdev.entity; sink = &fmd->fimc[i]->vid_cap.vfd->entity; ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE, sink, 0, flags); @@ -817,42 +790,48 @@ static int fimc_md_probe(struct platform_device *pdev) ret = media_device_register(&fmd->media_dev); if (ret < 0) { v4l2_err(v4l2_dev, "Failed to register media device: %d\n", ret); - goto err2; + goto err_md; } ret = fimc_md_get_clocks(fmd); if (ret) - goto err3; + goto err_clk; fmd->user_subdev_api = false; + + /* Protect the media graph while we're registering entities */ + mutex_lock(&fmd->media_dev.graph_mutex); + ret = fimc_md_register_platform_entities(fmd); if (ret) - goto err3; + goto err_unlock; if (pdev->dev.platform_data) { ret = fimc_md_register_sensor_entities(fmd); if (ret) - goto err3; + goto err_unlock; } ret = fimc_md_create_links(fmd); if (ret) - goto err3; + goto err_unlock; ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev); if (ret) - goto err3; - ret = fimc_md_register_video_nodes(fmd); - if (ret) - goto err3; + goto err_unlock; ret = device_create_file(&pdev->dev, &dev_attr_subdev_conf_mode); - if (!ret) { - platform_set_drvdata(pdev, fmd); - return 0; - } -err3: + if (ret) + goto err_unlock; + + platform_set_drvdata(pdev, fmd); + mutex_unlock(&fmd->media_dev.graph_mutex); + return 0; + +err_unlock: + mutex_unlock(&fmd->media_dev.graph_mutex); +err_clk: media_device_unregister(&fmd->media_dev); fimc_md_put_clocks(fmd); fimc_md_unregister_entities(fmd); -err2: +err_md: v4l2_device_unregister(&fmd->v4l2_dev); return ret; } diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.h b/drivers/media/video/s5p-fimc/fimc-mdevice.h index da37808..4f3b69c 100644 --- a/drivers/media/video/s5p-fimc/fimc-mdevice.h +++ b/drivers/media/video/s5p-fimc/fimc-mdevice.h @@ -24,6 +24,7 @@ #define SENSOR_GROUP_ID (1 << 8) #define CSIS_GROUP_ID (1 << 9) #define WRITEBACK_GROUP_ID (1 << 10) +#define FIMC_GROUP_ID (1 << 11) #define FIMC_MAX_SENSORS 8 #define FIMC_MAX_CAMCLKS 2 -- 1.7.4.1