From patchwork Tue Jun 24 23:57:31 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shuah Khan X-Patchwork-Id: 4414951 Return-Path: X-Original-To: patchwork-linux-media@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 124DF9F402 for ; Wed, 25 Jun 2014 00:04:15 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CB72D2035D for ; Wed, 25 Jun 2014 00:04:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5E928202E9 for ; Wed, 25 Jun 2014 00:04:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752714AbaFYAEL (ORCPT ); Tue, 24 Jun 2014 20:04:11 -0400 Received: from qmta03.emeryville.ca.mail.comcast.net ([76.96.30.32]:49048 "EHLO qmta03.emeryville.ca.mail.comcast.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752423AbaFYAEK (ORCPT ); Tue, 24 Jun 2014 20:04:10 -0400 X-Greylist: delayed 369 seconds by postgrey-1.27 at vger.kernel.org; Tue, 24 Jun 2014 20:04:10 EDT Received: from omta21.emeryville.ca.mail.comcast.net ([76.96.30.88]) by qmta03.emeryville.ca.mail.comcast.net with comcast id JPMs1o0011u4NiLA3Py13G; Tue, 24 Jun 2014 23:58:01 +0000 Received: from mail.gonehiking.org ([50.134.149.16]) by omta21.emeryville.ca.mail.comcast.net with comcast id JPxy1o00J0MU7Qa8hPxzcz; Tue, 24 Jun 2014 23:58:00 +0000 Received: from lorien.sisa.samsung.com (lorien-wl.internal [192.168.1.40]) by mail.gonehiking.org (Postfix) with ESMTP id A259D4064C; Tue, 24 Jun 2014 17:57:58 -0600 (MDT) From: Shuah Khan To: gregkh@linuxfoundation.org, m.chehab@samsung.com, olebowle@gmx.com, ttmesterr@gmail.com, dheitmueller@kernellabs.com, cb.xiong@samsung.com, yongjun_wei@trendmicro.com.cn, hans.verkuil@cisco.com, prabhakar.csengg@gmail.com, laurent.pinchart@ideasonboard.com, sakari.ailus@linux.intel.com, crope@iki.fi, wade_farnsworth@mentor.com, ricardo.ribalda@gmail.com Cc: Shuah Khan , linux-media@vger.kernel.org Subject: [PATCH 4/4] media: au0828 changes to use token devres for tuner access Date: Tue, 24 Jun 2014 17:57:31 -0600 Message-Id: <191ed75e7a6aafd9e2f85c642b08a963a9d1be1f.1403652043.git.shuah.kh@samsung.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: References: In-Reply-To: References: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=comcast.net; s=q20140121; t=1403654281; bh=uNKUEt3fxPQdrbrQInLW4FPdBUdfYW2xIE9ESLj1ny8=; h=Received:Received:Received:From:To:Subject:Date:Message-Id; b=jSqeDaLNkvsQIARAUrOWJNu2qL6ld6OaSFY/Zwgrw9WUR1J8y80+4PY1aJ9fAbd4I FyH7UY32AyzX6jlZtJxS239FWOQV3WqyRLJ+yBTn3dIh+qwQTIaQlwYiaIAoNhjexH ZmaLAj8XnUxRFKUNqp9vQcPJLe5yd5ow2xbwLD9533iqF9SGcKzEVyIL70ceT9rMKL 3NYT2ruDgIgM/ImucrjRrJcdzhPCQr5MNRKbQc+rC4+VoKNJxxnntcMkq6+ms9lGd/ 6w8jMR7zQdJ88sCWNcz0Sh3Y+A1uI3qLVpvEyi7/ZISEIzOT0EgSZtengcKykoaYMM S25zrhht3eAcA== Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID,T_RP_MATCHES_RCVD,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 au0828 is changed to use token devres as a large locking for exclusive access to tuner function. A new tuner_tkn field is added to struct au0828_dev. Tuner token is created from au0828 probe() and destroyed from disconnect(). Two new routines au0828_create_token_resources() and au0828_destroy_token_resources() create and destroy the tuner token. au0828-dvb exports the tuner token to dvb-frontend when it registers the digital frontend using the tuner_tkn field in struct dvb_frontend. au0828-video exports the tuner token to v4l2-core when it registers the analog function using tuner_tkn field in struct video_device. Before this change: - digital tv app disrupts an active analog app when it tries to use the tuner e.g: tvtime analog video stream stops when kaffeine starts - analog tv app disrupts another analog app when it tries to use the tuner e.g: tvtime audio glitches when xawtv starts and vice versa. - analog tv app disrupts an active digital app when it tries to use the tuner e.g: kaffeine digital stream stops when tvtime starts - digital tv app disrupts another digital tv app when it tries to use the tuner e.g: kaffeine digital stream stops when vlc starts and vice versa After this change: - digital tv app detects tuner is busy without disrupting the active app. - analog tv app detects tuner is busy without disrupting the active analog app. - analog tv app detects tuner is busy without disrupting the active digital app. - digital tv app detects tuner is busy without disrupting the active digital app. Signed-off-by: Shuah Khan --- drivers/media/usb/au0828/au0828-core.c | 42 +++++++++++++++++++++++++++++++ drivers/media/usb/au0828/au0828-dvb.c | 1 + drivers/media/usb/au0828/au0828-video.c | 4 +++ drivers/media/usb/au0828/au0828.h | 4 +++ 4 files changed, 51 insertions(+) diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index ab45a6f..df04a99 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -125,6 +125,37 @@ static int recv_control_msg(struct au0828_dev *dev, u16 request, u32 value, return status; } +/* interfaces to create and destroy token resources */ +static int au0828_create_token_resources(struct au0828_dev *dev) +{ + int rc = 0, len; + char buf[64]; + + /* create token devres for tuner */ + len = snprintf(buf, sizeof(buf), + "tuner:%s-%s-%d", + dev_name(&dev->usbdev->dev), + dev->usbdev->bus->bus_name, + dev->board.tuner_addr); + + dev->tuner_tkn = devm_kzalloc(&dev->usbdev->dev, len + 1, GFP_KERNEL); + if (!dev->tuner_tkn) + return -ENOMEM; + + strcpy(dev->tuner_tkn, buf); + rc = devm_token_create(&dev->usbdev->dev, dev->tuner_tkn); + if (rc) + return rc; + + pr_info("au0828_create_token_resources(): Tuner token created\n"); + return rc; +} + +static void au0828_destroy_token_resources(struct au0828_dev *dev) +{ + devm_token_destroy(&dev->usbdev->dev, dev->tuner_tkn); +} + static void au0828_usb_release(struct au0828_dev *dev) { /* I2C */ @@ -154,6 +185,8 @@ static void au0828_usb_disconnect(struct usb_interface *interface) /* Digital TV */ au0828_dvb_unregister(dev); + au0828_destroy_token_resources(dev); + usb_set_intfdata(interface, NULL); mutex_lock(&dev->mutex); dev->usbdev = NULL; @@ -213,6 +246,13 @@ static int au0828_usb_probe(struct usb_interface *interface, dev->usbdev = usbdev; dev->boardnr = id->driver_info; + /* create token resources */ + if (au0828_create_token_resources(dev)) { + mutex_unlock(&dev->lock); + kfree(dev); + return -ENOMEM; + } + #ifdef CONFIG_VIDEO_AU0828_V4L2 dev->v4l2_dev.release = au0828_usb_v4l2_release; @@ -221,6 +261,7 @@ static int au0828_usb_probe(struct usb_interface *interface, if (retval) { pr_err("%s() v4l2_device_register failed\n", __func__); + au0828_destroy_token_resources(dev); mutex_unlock(&dev->lock); kfree(dev); return retval; @@ -230,6 +271,7 @@ static int au0828_usb_probe(struct usb_interface *interface, if (retval) { pr_err("%s() v4l2_ctrl_handler_init failed\n", __func__); + au0828_destroy_token_resources(dev); mutex_unlock(&dev->lock); kfree(dev); return retval; diff --git a/drivers/media/usb/au0828/au0828-dvb.c b/drivers/media/usb/au0828/au0828-dvb.c index d8b5d94..1195d29 100755 --- a/drivers/media/usb/au0828/au0828-dvb.c +++ b/drivers/media/usb/au0828/au0828-dvb.c @@ -412,6 +412,7 @@ static int dvb_register(struct au0828_dev *dev) goto fail_adapter; } dvb->adapter.priv = dev; + dvb->frontend->tuner_tkn = dev->tuner_tkn; /* register frontend */ result = dvb_register_frontend(&dvb->adapter, dvb->frontend); diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 385894a..0b50bda 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -2018,6 +2018,9 @@ int au0828_analog_register(struct au0828_dev *dev, dev->vdev->lock = &dev->lock; set_bit(V4L2_FL_USE_FH_PRIO, &dev->vdev->flags); strcpy(dev->vdev->name, "au0828a video"); + /* is there another way v4l2 core can get struct device ?? */ + dev->vdev->dev_parent = &dev->usbdev->dev; + dev->vdev->tuner_tkn = dev->tuner_tkn; /* Setup the VBI device */ *dev->vbi_dev = au0828_video_template; @@ -2025,6 +2028,7 @@ int au0828_analog_register(struct au0828_dev *dev, dev->vbi_dev->lock = &dev->lock; set_bit(V4L2_FL_USE_FH_PRIO, &dev->vbi_dev->flags); strcpy(dev->vbi_dev->name, "au0828a vbi"); + dev->vbi_dev->tuner_tkn = dev->tuner_tkn; /* Register the v4l2 device */ video_set_drvdata(dev->vdev, dev); diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h index 7112b9d..11bc933 100644 --- a/drivers/media/usb/au0828/au0828.h +++ b/drivers/media/usb/au0828/au0828.h @@ -23,6 +23,7 @@ #include #include #include +#include /* Analog */ #include @@ -198,6 +199,9 @@ struct au0828_dev { struct au0828_board board; u8 ctrlmsg[64]; + /* token resources */ + char *tuner_tkn; /* tuner token id */ + /* I2C */ struct i2c_adapter i2c_adap; struct i2c_algorithm i2c_algo;