summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChong Zhang <chzhang@nvidia.com>2010-12-23 10:35:34 -0800
committerBharat Nihalani <bnihalani@nvidia.com>2010-12-24 04:40:12 -0800
commitb400775fb142061f69c40cedb4106c91e26668dc (patch)
treed8f7f94799ee2e80fc86992c0eff0319142937b7
parent13781a2879898c190e2007751b865a2e4c932e3e (diff)
Allow AVP to have multiple clients.
Ref-count the AVP open/release requests; if AVP already opened, just inc the refcount and let the request succeed. bug 772210 Change-Id: I061e02e4c82fc6915ed5b73a536a7707d5c055db Reviewed-on: http://git-master/r/13661 Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com> Tested-by: Bharat Nihalani <bnihalani@nvidia.com>
-rw-r--r--drivers/media/video/tegra/avp/avp.c29
1 files changed, 13 insertions, 16 deletions
diff --git a/drivers/media/video/tegra/avp/avp.c b/drivers/media/video/tegra/avp/avp.c
index ced838ac6e2b..29cbfc01e44f 100644
--- a/drivers/media/video/tegra/avp/avp.c
+++ b/drivers/media/video/tegra/avp/avp.c
@@ -111,7 +111,7 @@ struct avp_info {
struct trpc_node *rpc_node;
struct miscdevice misc_dev;
- bool opened;
+ int refcount;
struct mutex open_lock;
spinlock_t state_lock;
@@ -1328,16 +1328,13 @@ static int tegra_avp_open(struct inode *inode, struct file *file)
nonseekable_open(inode, file);
mutex_lock(&avp->open_lock);
- /* only one userspace client at a time */
- if (avp->opened) {
- pr_err("%s: already have client, aborting\n", __func__);
- ret = -EBUSY;
- goto out;
- }
- ret = avp_init(avp, TEGRA_AVP_KERNEL_FW);
- avp->opened = !ret;
-out:
+ if (!avp->refcount)
+ ret = avp_init(avp, TEGRA_AVP_KERNEL_FW);
+
+ if (!ret)
+ avp->refcount++;
+
mutex_unlock(&avp->open_lock);
return ret;
}
@@ -1349,15 +1346,16 @@ static int tegra_avp_release(struct inode *inode, struct file *file)
pr_info("%s: release\n", __func__);
mutex_lock(&avp->open_lock);
- if (!avp->opened) {
+ if (!avp->refcount) {
pr_err("%s: releasing while in invalid state\n", __func__);
ret = -EINVAL;
goto out;
}
+ if (avp->refcount > 0)
+ avp->refcount--;
+ if (!avp->refcount)
+ avp_uninit(avp);
- avp_uninit(avp);
-
- avp->opened = false;
out:
mutex_unlock(&avp->open_lock);
return ret;
@@ -1681,12 +1679,11 @@ static int tegra_avp_remove(struct platform_device *pdev)
return 0;
mutex_lock(&avp->open_lock);
- if (avp->opened) {
+ if (avp->refcount) {
mutex_unlock(&avp->open_lock);
return -EBUSY;
}
/* ensure that noone can open while we tear down */
- avp->opened = true;
mutex_unlock(&avp->open_lock);
misc_deregister(&avp->misc_dev);