tegra: video: host: remove cancelled actions at power down
authorVarun Wadekar <vwadekar@nvidia.com>
Tue, 23 Nov 2010 14:13:43 +0000 (19:43 +0530)
committerErik Gilling <konkers@android.com>
Mon, 6 Dec 2010 22:18:13 +0000 (14:18 -0800)
Change-Id: I2a82ecadafacec53990db25cb456809dbffd999b
Author: Alex Frid <afrid@nvidia.com>
Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
drivers/video/tegra/host/nvhost_channel.c
drivers/video/tegra/host/nvhost_intr.c

index 80c0f877618e519761bd42545d72603602af2145..40b67181c33d0deb14cecc5d8a685d7e18eb062d 100644 (file)
@@ -214,6 +214,7 @@ static void power_3d(struct nvhost_module *mod, enum nvhost_power_action action)
                        struct nvhost_op_pair save;
                        struct nvhost_cpuinterrupt ctxsw;
                        u32 syncval;
+                       void *ref;
                        syncval = nvhost_syncpt_incr_max(&ch->dev->syncpt,
                                                        NVSYNCPT_3D,
                                                        ch->cur_ctx->save_incrs);
@@ -232,10 +233,11 @@ static void power_3d(struct nvhost_module *mod, enum nvhost_power_action action)
                        nvhost_intr_add_action(&ch->dev->intr, NVSYNCPT_3D,
                                               syncval,
                                               NVHOST_INTR_ACTION_WAKEUP,
-                                              &wq, NULL);
+                                              &wq, &ref);
                        wait_event(wq,
                                   nvhost_syncpt_min_cmp(&ch->dev->syncpt,
                                                         NVSYNCPT_3D, syncval));
+                       nvhost_intr_put_ref(&ch->dev->intr, ref);
                        nvhost_cdma_update(&ch->cdma);
                }
                mutex_unlock(&ch->submitlock);
index 795736f58b86b72bfd5084b96fa80014305f6c8d..848d8b1e84e0ad1452bcb3f075a7cd9f481fbab5 100644 (file)
@@ -418,9 +418,24 @@ void nvhost_intr_deinit(struct nvhost_intr *intr)
 
        for (id = 0, syncpt = intr->syncpt;
             id < NV_HOST1X_SYNCPT_NB_PTS;
-            ++id, ++syncpt)
+            ++id, ++syncpt) {
+               struct nvhost_waitlist *waiter, *next;
+               list_for_each_entry_safe(waiter, next, &syncpt->wait_head, list) {
+                       if (atomic_cmpxchg(&waiter->state, WLS_CANCELLED, WLS_HANDLED)
+                               == WLS_CANCELLED) {
+                               list_del(&waiter->list);
+                               kref_put(&waiter->refcount, waiter_release);
+                       }
+               }
+
+               if(!list_empty(&syncpt->wait_head)) {  // output diagnostics
+                       printk("%s id=%d\n",__func__,id);
+                       BUG_ON(1);
+               }
+
                if (syncpt->irq_requested)
                        free_irq(syncpt->irq, syncpt);
+       }
 
        if (intr->host1x_isr_started) {
                free_irq(intr->host1x_irq, intr);