]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
video: tegra: host: return -EBUSY if exclusive
authorShridhar Rasal <srasal@nvidia.com>
Mon, 14 Apr 2014 14:58:16 +0000 (20:28 +0530)
committerTom Cherry <tcherry@nvidia.com>
Fri, 16 May 2014 01:17:49 +0000 (18:17 -0700)
- For channel open request if device set for exclusive channel
  access then return busy error.

- change signature of nvhost_channel_map to include error and
  channel handle both.

Bug 1259844

Change-Id: I4a02bd54037edf8b665c11e31adc30eaed491b76
Signed-off-by: Shridhar Rasal <srasal@nvidia.com>
drivers/video/tegra/host/bus_client.c
drivers/video/tegra/host/nvhost_channel.c
drivers/video/tegra/host/nvhost_channel.h

index a29ddede70c55281a482d726ba0f0e041a00e1f7..42345065bb0eaaa3579975f9c5b42074e48076b1 100644 (file)
@@ -218,17 +218,21 @@ static int __nvhost_channelopen(struct inode *inode,
        if (inode) {
                pdata = container_of(inode->i_cdev,
                                struct nvhost_device_data, cdev);
-               ch = nvhost_channel_map(pdata);
-               if (!ch || !ch->dev) {
+               ret = nvhost_channel_map(pdata, &ch);
+               if (ret) {
                        pr_err("%s: failed to map channel\n", __func__);
-                       return -ENOMEM;
+                       return ret;
                }
        } else {
                if (!ch || !ch->dev) {
                        pr_err("%s: NULL channel request to get\n", __func__);
                        return -EINVAL;
                }
-               nvhost_getchannel(ch);
+               pdata = platform_get_drvdata(ch->dev);
+               if (!pdata->exclusive)
+                       nvhost_getchannel(ch);
+               else
+                       return -EBUSY;
        }
 
        mutex_lock(&channel_lock);
index ad63280a21e87c6b2ae26911abb16f32535888c3..aa96e4cdc79107c50013a6fb1ccea495b8cce327 100644 (file)
@@ -210,7 +210,8 @@ int nvhost_channel_unmap(struct nvhost_channel *ch)
 }
 
 /* Maps free channel with device */
-struct nvhost_channel *nvhost_channel_map(struct nvhost_device_data *pdata)
+int nvhost_channel_map(struct nvhost_device_data *pdata,
+                       struct nvhost_channel **channel)
 {
        struct nvhost_master *host = NULL;
        struct nvhost_channel *ch = NULL;
@@ -220,7 +221,7 @@ struct nvhost_channel *nvhost_channel_map(struct nvhost_device_data *pdata)
 
        if (!pdata) {
                pr_err("%s: NULL device data\n", __func__);
-               return NULL;
+               return -EINVAL;
        }
 
        host = nvhost_get_host(pdata->pdev);
@@ -230,11 +231,16 @@ struct nvhost_channel *nvhost_channel_map(struct nvhost_device_data *pdata)
 
        /* Check if already channel(s) assigned for device */
        if (pdata->num_channels == pdata->num_mapped_chs) {
+               if (pdata->exclusive) {
+                       mutex_unlock(&host->chlist_mutex);
+                       return -EBUSY;
+               }
                ch = nvhost_check_channel(pdata);
                if (ch)
                        nvhost_getchannel(ch);
                mutex_unlock(&host->chlist_mutex);
-               return ch;
+               *channel = ch;
+               return 0;
        }
 
        index = find_next_zero_bit(&host->allocated_channels,
@@ -249,7 +255,7 @@ struct nvhost_channel *nvhost_channel_map(struct nvhost_device_data *pdata)
                        pr_err("All host1x channels are mapped, BITMAP: %lu\n",
                                        host->allocated_channels);
                        mutex_unlock(&host->chlist_mutex);
-                       return NULL;
+                       return -ENOMEM;
                }
        }
 
@@ -258,7 +264,7 @@ struct nvhost_channel *nvhost_channel_map(struct nvhost_device_data *pdata)
        if (!ch) {
                dev_err(&host->dev->dev, "%s: No channel is free\n", __func__);
                mutex_unlock(&host->chlist_mutex);
-               return NULL;
+               return -EBUSY;
        }
        if (ch->chid == NVHOST_INVALID_CHANNEL) {
                ch->dev = pdata->pdev;
@@ -268,7 +274,7 @@ struct nvhost_channel *nvhost_channel_map(struct nvhost_device_data *pdata)
        } else {
                dev_err(&host->dev->dev, "%s: wrong channel map\n", __func__);
                mutex_unlock(&host->chlist_mutex);
-               return NULL;
+               return -EINVAL;
        }
 
        /* Initialize channel */
@@ -277,7 +283,7 @@ struct nvhost_channel *nvhost_channel_map(struct nvhost_device_data *pdata)
                dev_err(&ch->dev->dev, "%s: channel init failed\n", __func__);
                mutex_unlock(&host->chlist_mutex);
                nvhost_channel_unmap(ch);
-               return NULL;
+               return err;
        }
        nvhost_getchannel(ch);
        set_bit(ch->chid, &host->allocated_channels);
@@ -294,7 +300,7 @@ struct nvhost_channel *nvhost_channel_map(struct nvhost_device_data *pdata)
                        dev_err(&ch->dev->dev, "device init failed\n");
                        mutex_unlock(&host->chlist_mutex);
                        nvhost_channel_unmap(ch);
-                       return NULL;
+                       return err;
                }
        }
 
@@ -305,7 +311,8 @@ struct nvhost_channel *nvhost_channel_map(struct nvhost_device_data *pdata)
        dev_dbg(&ch->dev->dev, "channel %d mapped\n", ch->chid);
        mutex_unlock(&host->chlist_mutex);
 
-       return ch;
+       *channel = ch;
+       return 0;
 }
 
 /* Free channel memory and list */
index 04796e8d99e4ef637904acd1134a1ebbaaf73e98..baed282718a24d7684aac46bc6042452c49dcbff 100644 (file)
@@ -75,7 +75,8 @@ struct nvhost_channel {
 #define channel_op(ch)         (ch->ops)
 
 int nvhost_alloc_channels(struct nvhost_master *host);
-struct nvhost_channel *nvhost_channel_map(struct nvhost_device_data *pdata);
+int nvhost_channel_map(struct nvhost_device_data *pdata,
+                       struct nvhost_channel **ch);
 int nvhost_channel_unmap(struct nvhost_channel *ch);
 int nvhost_channel_release(struct nvhost_device_data *pdata);
 int nvhost_channel_list_free(struct nvhost_master *host);