video: tegra: host: Use non-interruptible wait
Terje Bergstrom [Mon, 10 Jun 2013 08:53:03 +0000 (11:53 +0300)]
Introduce a non-interruptible variant of nvhost_syncpt_wait_timeout().
As we're not capable of dealing with signals when closing a channel,
take that into use when unbinding a channel.

Bug 1304227

Change-Id: Ieab60bf3e6a71a9da42f6503ff292092fa4d1f70
Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com>
Reviewed-on: http://git-master/r/241875
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Tested-by: Bharat Nihalani <bnihalani@nvidia.com>

drivers/video/tegra/host/gk20a/channel_gk20a.c
drivers/video/tegra/host/host1x/host1x.c
drivers/video/tegra/host/nvhost_syncpt.c
drivers/video/tegra/host/nvhost_syncpt.h

index 91b47f3..8d134df 100644 (file)
@@ -1329,7 +1329,7 @@ int gk20a_channel_finish(struct channel_gk20a *ch, long timeout)
        err = nvhost_syncpt_wait_timeout(sp,
                                         ch->last_submit_fence.syncpt_id,
                                         ch->last_submit_fence.syncpt_value,
-                                        timeout, &fence.value, NULL);
+                                        timeout, &fence.value, NULL, false);
        if (WARN_ON(err))
                dev_warn(dev_from_gk20a(ch->g),
                         "timed out waiting for gk20a channel to finish");
index 765ebc8..8a1c8f6 100644 (file)
@@ -144,7 +144,7 @@ static int nvhost_ioctl_ctrl_syncpt_waitex(struct nvhost_ctrl_userctx *ctx,
 
        err = nvhost_syncpt_wait_timeout(&ctx->dev->syncpt, args->id,
                                        args->thresh, timeout, &args->value,
-                                       NULL);
+                                       NULL, true);
        trace_nvhost_ioctl_ctrl_syncpt_wait(args->id, args->thresh,
          args->timeout, args->value, err);
 
@@ -166,7 +166,7 @@ static int nvhost_ioctl_ctrl_syncpt_waitmex(struct nvhost_ctrl_userctx *ctx,
 
        err = nvhost_syncpt_wait_timeout(&ctx->dev->syncpt, args->id,
                                        args->thresh, timeout, &args->value,
-                                       &ts);
+                                       &ts, true);
        args->tv_sec = ts.tv_sec;
        args->tv_nsec = ts.tv_nsec;
        trace_nvhost_ioctl_ctrl_syncpt_wait(args->id, args->thresh,
index b82f816..e380064 100644 (file)
@@ -188,7 +188,7 @@ static bool syncpt_update_min_is_expired(
  */
 int nvhost_syncpt_wait_timeout(struct nvhost_syncpt *sp, u32 id,
                        u32 thresh, u32 timeout, u32 *value,
-                       struct timespec *ts)
+                       struct timespec *ts, bool interruptible)
 {
        DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
        void *ref;
@@ -248,7 +248,13 @@ int nvhost_syncpt_wait_timeout(struct nvhost_syncpt *sp, u32 id,
        /* wait for the syncpoint, or timeout, or signal */
        while (timeout) {
                u32 check = min_t(u32, SYNCPT_CHECK_PERIOD, timeout);
-               int remain = wait_event_interruptible_timeout(wq,
+               int remain;
+               if (interruptible)
+                       remain = wait_event_interruptible_timeout(wq,
+                               syncpt_update_min_is_expired(sp, id, thresh),
+                               check);
+               else
+                       remain = wait_event_timeout(wq,
                                syncpt_update_min_is_expired(sp, id, thresh),
                                check);
                if (remain > 0 || nvhost_syncpt_is_expired(sp, id, thresh)) {
@@ -833,7 +839,8 @@ int nvhost_syncpt_wait_timeout_ext(struct platform_device *dev, u32 id,
        pdev = to_platform_device(dev->dev.parent);
        sp = &(nvhost_get_host(pdev)->syncpt);
 
-       return nvhost_syncpt_wait_timeout(sp, id, thresh, timeout, value, ts);
+       return nvhost_syncpt_wait_timeout(sp, id, thresh, timeout, value, ts,
+                       true);
 }
 EXPORT_SYMBOL(nvhost_syncpt_wait_timeout_ext);
 
index e29018b..3c1e7d3 100644 (file)
@@ -137,12 +137,14 @@ void nvhost_syncpt_cpu_set_wait_base(struct platform_device *pdev, u32 id,
 void nvhost_syncpt_incr(struct nvhost_syncpt *sp, u32 id);
 
 int nvhost_syncpt_wait_timeout(struct nvhost_syncpt *sp, u32 id, u32 thresh,
-                       u32 timeout, u32 *value, struct timespec *ts);
+                       u32 timeout, u32 *value, struct timespec *ts,
+                       bool interruptible);
 
 static inline int nvhost_syncpt_wait(struct nvhost_syncpt *sp, u32 id, u32 thresh)
 {
        return nvhost_syncpt_wait_timeout(sp, id, thresh,
-                                         (u32)MAX_SCHEDULE_TIMEOUT, NULL, NULL);
+                                         (u32)MAX_SCHEDULE_TIMEOUT,
+                                         NULL, NULL, true);
 }
 
 int nvhost_syncpt_patch_wait(struct nvhost_syncpt *sp, void *patch_addr);