From patchwork Tue Jun 25 15:17:34 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Prabhakar X-Patchwork-Id: 2777531 Return-Path: X-Original-To: patchwork-davinci@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 9D1549F3A0 for ; Tue, 25 Jun 2013 15:19:47 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1D3CF202F4 for ; Tue, 25 Jun 2013 15:19:46 +0000 (UTC) Received: from bear.ext.ti.com (bear.ext.ti.com [192.94.94.41]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 84137202EF for ; Tue, 25 Jun 2013 15:19:44 +0000 (UTC) Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by bear.ext.ti.com (8.13.7/8.13.7) with ESMTP id r5PFIGbH025777; Tue, 25 Jun 2013 10:18:16 -0500 Received: from DLEE71.ent.ti.com (dlee71.ent.ti.com [157.170.170.114]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id r5PFIGJV016085; Tue, 25 Jun 2013 10:18:16 -0500 Received: from dlelxv23.itg.ti.com (172.17.1.198) by DLEE71.ent.ti.com (157.170.170.114) with Microsoft SMTP Server id 14.2.342.3; Tue, 25 Jun 2013 10:18:15 -0500 Received: from linux.omap.com (dlelxs01.itg.ti.com [157.170.227.31]) by dlelxv23.itg.ti.com (8.13.8/8.13.8) with ESMTP id r5PFIFI7005045; Tue, 25 Jun 2013 10:18:15 -0500 Received: from linux.omap.com (localhost [127.0.0.1]) by linux.omap.com (Postfix) with ESMTP id 242EE8062B; Tue, 25 Jun 2013 10:18:15 -0500 (CDT) X-Original-To: davinci-linux-open-source@linux.davincidsp.com Delivered-To: davinci-linux-open-source@linux.davincidsp.com Received: from dflp53.itg.ti.com (dflp53.itg.ti.com [128.247.5.6]) by linux.omap.com (Postfix) with ESMTP id 5EB5280626 for ; Tue, 25 Jun 2013 10:18:10 -0500 (CDT) Received: from white.ext.ti.com (white.ext.ti.com [192.94.93.38]) by dflp53.itg.ti.com (8.13.8/8.13.8) with ESMTP id r5PFIAP5023181 for ; Tue, 25 Jun 2013 10:18:10 -0500 (CDT) Received: from mail6.bemta12.messagelabs.com (mail6.bemta12.messagelabs.com [216.82.250.247]) by white.ext.ti.com (8.13.7/8.13.7) with ESMTP id r5PFI931009082 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 25 Jun 2013 10:18:09 -0500 Received: from [216.82.250.51:6359] by server-12.bemta-12.messagelabs.com id 90/C0-24760-1B4B9C15; Tue, 25 Jun 2013 15:18:09 +0000 X-Env-Sender: prabhakar.csengg@gmail.com X-Msg-Ref: server-12.tower-108.messagelabs.com!1372173481!9048732!1 X-Originating-IP: [209.85.160.44] X-SpamReason: No, hits=0.2 required=7.0 tests=ML_RADAR_SPEW_LINKS_14, RCVD_ILLEGAL_IP,spamassassin: X-StarScan-Received: X-StarScan-Version: 6.9.9; banners=-,-,- X-VirusChecked: Checked Received: (qmail 6338 invoked from network); 25 Jun 2013 15:18:03 -0000 Received: from mail-pb0-f44.google.com (HELO mail-pb0-f44.google.com) (209.85.160.44) by server-12.tower-108.messagelabs.com with RC4-SHA encrypted SMTP; 25 Jun 2013 15:18:03 -0000 Received: by mail-pb0-f44.google.com with SMTP id uo1so12760319pbc.31 for ; Tue, 25 Jun 2013 08:18:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=S67jNm4qH3r+A9as4Z8vaRf3Izd/4vyMu+t3qPoAFjM=; b=obkbwoMp6M5+9AQZNyOOxvCW7Gj6g0PDsOqBa6ebMhxBJ7x1DSe1maTUoacBMWkc59 5gKt4C/BMBsGr1GBsZl3PrR/S5oleVfmgkD7Df/ZZqbskr6+4VONCbZ5b1yKgVd68/L5 vjUDGE2JVdGSIvLjvIYfQb+RPrymJm8zo6uHTaZG6vIK3qG1Vg7qyn74Y6rsESZmB97P pN9Kuj9AcTPjEh77vNL5wl+iZK3omkQuG3CFUcLraqrwKfe3GyxrEDQRKdLwczH1fp09 gW2GhC2gyrNGmy8nEWKs8J61tQ/rlZZX1PaqjFMK7pmF2aiLY84lipcTd4IZKQ1khMCP /cfQ== X-Received: by 10.67.2.7 with SMTP id bk7mr371782pad.50.1372173481364; Tue, 25 Jun 2013 08:18:01 -0700 (PDT) Received: from localhost.localdomain ([1.23.213.228]) by mx.google.com with ESMTPSA id fn9sm25737447pab.2.2013.06.25.08.17.56 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 25 Jun 2013 08:18:00 -0700 (PDT) From: Prabhakar Lad To: DLOS , Mauro Carvalho Chehab , LMML Subject: [PATCH 1/2] media: davinci: vpif: capture: add V4L2-async support Date: Tue, 25 Jun 2013 20:47:34 +0530 Message-ID: <1372173455-509-2-git-send-email-prabhakar.csengg@gmail.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1372173455-509-1-git-send-email-prabhakar.csengg@gmail.com> References: <1372173455-509-1-git-send-email-prabhakar.csengg@gmail.com> CC: LKML , Sakari Ailus , Laurent Pinchart , Hans Verkuil , Guennadi Liakhovetski X-BeenThere: davinci-linux-open-source@linux.davincidsp.com X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: Errors-To: davinci-linux-open-source-bounces@linux.davincidsp.com X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: "Lad, Prabhakar" Add support for asynchronous subdevice probing, using the v4l2-async API. The legacy synchronous mode is still supported too, which allows to gradually update drivers and platforms. Signed-off-by: Prabhakar Lad Cc: Guennadi Liakhovetski Cc: Hans Verkuil Cc: Laurent Pinchart Cc: Sakari Ailus Cc: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpif_capture.c | 151 +++++++++++++++++-------- drivers/media/platform/davinci/vpif_capture.h | 2 + include/media/davinci/vpif_types.h | 2 + 3 files changed, 107 insertions(+), 48 deletions(-) diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index 5514175..b11d7a7 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c @@ -1979,6 +1979,76 @@ vpif_init_free_channel_objects: return err; } +static int vpif_async_bound(struct v4l2_async_notifier *notifier, + struct v4l2_subdev *subdev, + struct v4l2_async_subdev *asd) +{ + int i; + + for (i = 0; i < vpif_obj.config->subdev_count; i++) + if (!strcmp(vpif_obj.config->subdev_info[i].name, + subdev->name)) { + vpif_obj.sd[i] = subdev; + return 0; + } + + return -EINVAL; +} + +static int vpif_probe_complete(void) +{ + struct common_obj *common; + struct channel_obj *ch; + int i, j, err, k; + + for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) { + ch = vpif_obj.dev[j]; + ch->channel_id = j; + common = &(ch->common[VPIF_VIDEO_INDEX]); + spin_lock_init(&common->irqlock); + mutex_init(&common->lock); + ch->video_dev->lock = &common->lock; + /* Initialize prio member of channel object */ + v4l2_prio_init(&ch->prio); + video_set_drvdata(ch->video_dev, ch); + + /* select input 0 */ + err = vpif_set_input(vpif_obj.config, ch, 0); + if (err) + goto probe_out; + + err = video_register_device(ch->video_dev, + VFL_TYPE_GRABBER, (j ? 1 : 0)); + if (err) + goto probe_out; + } + + v4l2_info(&vpif_obj.v4l2_dev, "VPIF capture driver initialized\n"); + return 0; + +probe_out: + for (k = 0; k < j; k++) { + /* Get the pointer to the channel object */ + ch = vpif_obj.dev[k]; + /* Unregister video device */ + video_unregister_device(ch->video_dev); + } + kfree(vpif_obj.sd); + for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) { + ch = vpif_obj.dev[i]; + /* Note: does nothing if ch->video_dev == NULL */ + video_device_release(ch->video_dev); + } + v4l2_device_unregister(&vpif_obj.v4l2_dev); + + return err; +} + +static int vpif_async_complete(struct v4l2_async_notifier *notifier) +{ + return vpif_probe_complete(); +} + /** * vpif_probe : This function probes the vpif capture driver * @pdev: platform device pointer @@ -1989,12 +2059,10 @@ vpif_init_free_channel_objects: static __init int vpif_probe(struct platform_device *pdev) { struct vpif_subdev_info *subdevdata; - struct vpif_capture_config *config; - int i, j, k, err; + int i, j, err; int res_idx = 0; struct i2c_adapter *i2c_adap; struct channel_obj *ch; - struct common_obj *common; struct video_device *vfd; struct resource *res; int subdev_count; @@ -2068,10 +2136,9 @@ static __init int vpif_probe(struct platform_device *pdev) } } - i2c_adap = i2c_get_adapter(1); - config = pdev->dev.platform_data; + vpif_obj.config = pdev->dev.platform_data; - subdev_count = config->subdev_count; + subdev_count = vpif_obj.config->subdev_count; vpif_obj.sd = kzalloc(sizeof(struct v4l2_subdev *) * subdev_count, GFP_KERNEL); if (vpif_obj.sd == NULL) { @@ -2080,54 +2147,42 @@ static __init int vpif_probe(struct platform_device *pdev) goto vpif_sd_error; } - for (i = 0; i < subdev_count; i++) { - subdevdata = &config->subdev_info[i]; - vpif_obj.sd[i] = - v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev, - i2c_adap, - &subdevdata->board_info, - NULL); - - if (!vpif_obj.sd[i]) { - vpif_err("Error registering v4l2 subdevice\n"); - err = -ENODEV; + if (!vpif_obj.config->asd_sizes) { + i2c_adap = i2c_get_adapter(1); + for (i = 0; i < subdev_count; i++) { + subdevdata = &vpif_obj.config->subdev_info[i]; + vpif_obj.sd[i] = + v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev, + i2c_adap, + &subdevdata-> + board_info, + NULL); + + if (!vpif_obj.sd[i]) { + vpif_err("Error registering v4l2 subdevice\n"); + goto probe_subdev_out; + } + v4l2_info(&vpif_obj.v4l2_dev, + "registered sub device %s\n", + subdevdata->name); + } + vpif_probe_complete(); + } else { + vpif_obj.notifier.subdev = vpif_obj.config->asd; + vpif_obj.notifier.num_subdevs = vpif_obj.config->asd_sizes[0]; + vpif_obj.notifier.bound = vpif_async_bound; + vpif_obj.notifier.complete = vpif_async_complete; + err = v4l2_async_notifier_register(&vpif_obj.v4l2_dev, + &vpif_obj.notifier); + if (err) { + vpif_err("Error registering async notifier\n"); + err = -EINVAL; goto probe_subdev_out; } - v4l2_info(&vpif_obj.v4l2_dev, "registered sub device %s\n", - subdevdata->name); } - for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) { - ch = vpif_obj.dev[j]; - ch->channel_id = j; - common = &(ch->common[VPIF_VIDEO_INDEX]); - spin_lock_init(&common->irqlock); - mutex_init(&common->lock); - ch->video_dev->lock = &common->lock; - /* Initialize prio member of channel object */ - v4l2_prio_init(&ch->prio); - video_set_drvdata(ch->video_dev, ch); - - /* select input 0 */ - err = vpif_set_input(config, ch, 0); - if (err) - goto probe_out; - - err = video_register_device(ch->video_dev, - VFL_TYPE_GRABBER, (j ? 1 : 0)); - if (err) - goto probe_out; - } - v4l2_info(&vpif_obj.v4l2_dev, "VPIF capture driver initialized\n"); return 0; -probe_out: - for (k = 0; k < j; k++) { - /* Get the pointer to the channel object */ - ch = vpif_obj.dev[k]; - /* Unregister video device */ - video_unregister_device(ch->video_dev); - } probe_subdev_out: /* free sub devices memory */ kfree(vpif_obj.sd); diff --git a/drivers/media/platform/davinci/vpif_capture.h b/drivers/media/platform/davinci/vpif_capture.h index 0ebb312..5a29d9a 100644 --- a/drivers/media/platform/davinci/vpif_capture.h +++ b/drivers/media/platform/davinci/vpif_capture.h @@ -142,6 +142,8 @@ struct vpif_device { struct v4l2_device v4l2_dev; struct channel_obj *dev[VPIF_CAPTURE_NUM_CHANNELS]; struct v4l2_subdev **sd; + struct v4l2_async_notifier notifier; + struct vpif_capture_config *config; }; struct vpif_config_params { diff --git a/include/media/davinci/vpif_types.h b/include/media/davinci/vpif_types.h index 3882e06..e08bcde 100644 --- a/include/media/davinci/vpif_types.h +++ b/include/media/davinci/vpif_types.h @@ -81,5 +81,7 @@ struct vpif_capture_config { struct vpif_subdev_info *subdev_info; int subdev_count; const char *card_name; + struct v4l2_async_subdev **asd; /* Flat array, arranged in groups */ + int *asd_sizes; /* 0-terminated array of asd group sizes */ }; #endif /* _VPIF_TYPES_H */