diff options
author | Shridhar Rasal <srasal@nvidia.com> | 2014-06-29 09:17:52 +0530 |
---|---|---|
committer | Winnie Hsu <whsu@nvidia.com> | 2014-10-17 10:56:12 -0700 |
commit | 83296fee29da1a2e6973157aa9f9d913071657bc (patch) | |
tree | 2f8a0bddb311b3f4be131b6e9d4fdd35dad423e5 | |
parent | 8ea724b67e4366615059a83dfe28d3f49c48d25f (diff) |
video: tegra: host: revise channel refcnt API's
Use only one API to subtract channel refcnts.
To check unbanalaced channel refcnt add WARN_ON when count
goes below zero.
Print error number when channel unmap fails.
Bug 1526504
Change-Id: If88f028a44c9b796d8eaae4affcd0026758cfbe8
(cherry picked from commit f98ce1fc2066e2309af2ef7a52801abadbd40f00)
Signed-off-by: Shridhar Rasal <srasal@nvidia.com>
Reviewed-on: http://git-master/r/496479
Reviewed-on: http://git-master/r/538723
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Shreshtha Sahu <ssahu@nvidia.com>
Tested-by: Shreshtha Sahu <ssahu@nvidia.com>
Reviewed-by: Venkat Moganty <vmoganty@nvidia.com>
-rw-r--r-- | drivers/video/tegra/host/bus_client.c | 7 | ||||
-rw-r--r-- | drivers/video/tegra/host/host1x/host1x_channel.c | 6 | ||||
-rw-r--r-- | drivers/video/tegra/host/nvhost_channel.c | 20 | ||||
-rw-r--r-- | drivers/video/tegra/host/nvhost_channel.h | 3 | ||||
-rw-r--r-- | drivers/video/tegra/host/nvhost_intr.c | 2 |
5 files changed, 18 insertions, 20 deletions
diff --git a/drivers/video/tegra/host/bus_client.c b/drivers/video/tegra/host/bus_client.c index 819f0cee59c8..634384329992 100644 --- a/drivers/video/tegra/host/bus_client.c +++ b/drivers/video/tegra/host/bus_client.c @@ -202,7 +202,7 @@ static int nvhost_channelrelease(struct inode *inode, struct file *filp) nvhost_job_put(priv->job); mutex_unlock(&channel_lock); - nvhost_putchannel(priv->ch); + nvhost_putchannel(priv->ch, 1); kfree(priv); return 0; } @@ -220,7 +220,8 @@ static int __nvhost_channelopen(struct inode *inode, struct nvhost_device_data, cdev); ret = nvhost_channel_map(pdata, &ch); if (ret) { - pr_err("%s: failed to map channel\n", __func__); + pr_err("%s: failed to map channel, error: %d\n", + __func__, ret); return ret; } } else { @@ -244,7 +245,7 @@ static int __nvhost_channelopen(struct inode *inode, priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { - nvhost_putchannel(ch); + nvhost_putchannel(ch, 1); goto fail; } filp->private_data = priv; diff --git a/drivers/video/tegra/host/host1x/host1x_channel.c b/drivers/video/tegra/host/host1x/host1x_channel.c index 46f319ea83f6..5b2b4998af92 100644 --- a/drivers/video/tegra/host/host1x/host1x_channel.c +++ b/drivers/video/tegra/host/host1x/host1x_channel.c @@ -318,7 +318,7 @@ static int host1x_channel_submit(struct nvhost_job *job) err = mutex_lock_interruptible(&ch->submitlock); if (err) { nvhost_module_idle_mult(ch->dev, job->num_syncpts); - nvhost_putchannel_mult(ch, job->num_syncpts); + nvhost_putchannel(ch, job->num_syncpts); goto error; } @@ -326,7 +326,7 @@ static int host1x_channel_submit(struct nvhost_job *job) completed_waiters[i] = nvhost_intr_alloc_waiter(); if (!completed_waiters[i]) { nvhost_module_idle_mult(ch->dev, job->num_syncpts); - nvhost_putchannel_mult(ch, job->num_syncpts); + nvhost_putchannel(ch, job->num_syncpts); mutex_unlock(&ch->submitlock); err = -ENOMEM; goto error; @@ -342,7 +342,7 @@ static int host1x_channel_submit(struct nvhost_job *job) err = nvhost_cdma_begin(&ch->cdma, job); if (err) { nvhost_module_idle_mult(ch->dev, job->num_syncpts); - nvhost_putchannel_mult(ch, job->num_syncpts); + nvhost_putchannel(ch, job->num_syncpts); mutex_unlock(&ch->submitlock); goto error; } diff --git a/drivers/video/tegra/host/nvhost_channel.c b/drivers/video/tegra/host/nvhost_channel.c index 3e7455509f96..9f0ca9e1268e 100644 --- a/drivers/video/tegra/host/nvhost_channel.c +++ b/drivers/video/tegra/host/nvhost_channel.c @@ -125,7 +125,7 @@ int nvhost_channel_release(struct nvhost_device_data *pdata) for (i = 0; i < pdata->num_channels; i++) { ch = pdata->channels[i]; if (ch && ch->dev) - nvhost_putchannel(ch); + nvhost_putchannel(ch, 1); } return 0; } @@ -377,19 +377,17 @@ void nvhost_getchannel(struct nvhost_channel *ch) atomic_inc(&ch->refcount); } -void nvhost_putchannel(struct nvhost_channel *ch) +void nvhost_putchannel(struct nvhost_channel *ch, int cnt) { - if (!atomic_dec_if_positive(&ch->refcount)) - nvhost_channel_unmap(ch); -} - + int ref; -void nvhost_putchannel_mult(struct nvhost_channel *ch, int cnt) -{ - int i; + ref = atomic_sub_return(cnt, &ch->refcount); - for (i = 0; i < cnt; i++) - nvhost_putchannel(ch); + /* WARN on negative reference, with zero reference unmap channel*/ + if (!ref) + nvhost_channel_unmap(ch); + else if (ref < 0) + WARN_ON(1); } int nvhost_channel_suspend(struct nvhost_channel *ch) diff --git a/drivers/video/tegra/host/nvhost_channel.h b/drivers/video/tegra/host/nvhost_channel.h index 9f165a380f4a..84643a28aca8 100644 --- a/drivers/video/tegra/host/nvhost_channel.h +++ b/drivers/video/tegra/host/nvhost_channel.h @@ -85,8 +85,7 @@ void nvhost_set_notifier(struct nvhost_channel *ch, __u32 error); void nvhost_free_error_notifiers(struct nvhost_channel *ch); void nvhost_getchannel(struct nvhost_channel *ch); -void nvhost_putchannel(struct nvhost_channel *ch); -void nvhost_putchannel_mult(struct nvhost_channel *ch, int cnt); +void nvhost_putchannel(struct nvhost_channel *ch, int cnt); int nvhost_channel_suspend(struct nvhost_channel *ch); int nvhost_channel_read_reg(struct nvhost_channel *channel, diff --git a/drivers/video/tegra/host/nvhost_intr.c b/drivers/video/tegra/host/nvhost_intr.c index 18b714c7e482..b856f26cb5f8 100644 --- a/drivers/video/tegra/host/nvhost_intr.c +++ b/drivers/video/tegra/host/nvhost_intr.c @@ -175,7 +175,7 @@ static void action_submit_complete(struct nvhost_waitlist *waiter) channel->cdma.med_prio_count, channel->cdma.low_prio_count); - nvhost_putchannel_mult(channel, nr_completed); + nvhost_putchannel(channel, nr_completed); } |