]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
video: tegra: host: Use mutex in intr handling
authorArto Merilainen <amerilainen@nvidia.com>
Tue, 21 Apr 2015 08:02:11 +0000 (11:02 +0300)
committermobile promotions <svcmobile_promotions@nvidia.com>
Fri, 4 Sep 2015 00:30:22 +0000 (17:30 -0700)
Currently syncpoint interrupts are using spinlocks despite the handler
in itself is always running in threaded context. This patch converts
syncpoint interrupt spinlock into mutex to allow list users sleep.

Bug 1598036
Bug 1671794

Change-Id: Ic1e71961820c5561a73eb9ef0e5ff30db271d76b
Signed-off-by: Arto Merilainen <amerilainen@nvidia.com>
Reviewed-on: http://git-master/r/733588
(cherry picked from commit 2a7e2fcfda9b1879ad745e87f933c85ff1e52370)
Reviewed-on: http://git-master/r/776928
Reviewed-by: Automatic_Commit_Validation_User
Tested-by: Gagan Grover <ggrover@nvidia.com>
Reviewed-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-by: Gaurav Singh <gauravsingh@nvidia.com>
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
drivers/video/tegra/host/nvhost_intr.c
drivers/video/tegra/host/nvhost_intr.h

index cc6aa03aee50f08c5f67487ef92a0505bd8cf34f..764d0bb4df2239552effbd0063478a691d44c008 100644 (file)
@@ -69,26 +69,6 @@ static inline bool nvhost_intr_is_virtual_dev(struct nvhost_intr_syncpt *sp)
        return nvhost_dev_is_virtual(host->dev);
 }
 
-static inline void nvhost_intr_syncpt_lock(struct nvhost_intr_syncpt *sp)
-__acquires(&sp->lock.m)
-__acquires(&sp->lock.s)
-{
-       if (nvhost_intr_is_virtual_dev(sp))
-               mutex_lock(&sp->lock.m);
-       else
-               spin_lock(&sp->lock.s);
-}
-
-static inline void nvhost_intr_syncpt_unlock(struct nvhost_intr_syncpt *sp)
-__releases(&sp->lock.m)
-__releases(&sp->lock.s)
-{
-       if (nvhost_intr_is_virtual_dev(sp))
-               mutex_unlock(&sp->lock.m);
-       else
-               spin_unlock(&sp->lock.s);
-}
-
 static void waiter_release(struct kref *kref)
 {
        kfree(container_of(kref, struct nvhost_waitlist, refcount));
@@ -288,7 +268,8 @@ static int process_wait_list(struct nvhost_intr *intr,
        for (i = 0; i < NVHOST_INTR_ACTION_COUNT; ++i)
                INIT_LIST_HEAD(completed + i);
 
-       nvhost_intr_syncpt_lock(syncpt);
+       /* take lock on waiter list */
+       mutex_lock(&syncpt->lock);
 
        remove_completed_waiters(&syncpt->wait_head, threshold,
                syncpt->isr_recv, completed);
@@ -300,7 +281,7 @@ static int process_wait_list(struct nvhost_intr *intr,
                reset_threshold_interrupt(intr, &syncpt->wait_head,
                                          syncpt->id);
 
-       nvhost_intr_syncpt_unlock(syncpt);
+       mutex_unlock(&syncpt->lock);
 
        run_handlers(completed);
 
@@ -343,7 +324,7 @@ bool nvhost_intr_has_pending_jobs(struct nvhost_intr *intr, u32 id,
        bool res = false;
 
        syncpt = intr->syncpt + id;
-       nvhost_intr_syncpt_lock(syncpt);
+       mutex_lock(&syncpt->lock);
        list_for_each_entry(waiter, &syncpt->wait_head, list)
                if (((waiter->action ==
                        NVHOST_INTR_ACTION_SUBMIT_COMPLETE) &&
@@ -352,7 +333,7 @@ bool nvhost_intr_has_pending_jobs(struct nvhost_intr *intr, u32 id,
                        break;
                }
 
-       nvhost_intr_syncpt_unlock(syncpt);
+       mutex_unlock(&syncpt->lock);
 
        return res;
 }
@@ -384,7 +365,7 @@ int nvhost_intr_add_action(struct nvhost_intr *intr, u32 id, u32 thresh,
 
        syncpt = intr->syncpt + id;
 
-       nvhost_intr_syncpt_lock(syncpt);
+       mutex_lock(&syncpt->lock);
 
        queue_was_empty = list_empty(&syncpt->wait_head);
 
@@ -397,7 +378,7 @@ int nvhost_intr_add_action(struct nvhost_intr *intr, u32 id, u32 thresh,
                        intr_op().enable_syncpt_intr(intr, id);
        }
 
-       nvhost_intr_syncpt_unlock(syncpt);
+       mutex_unlock(&syncpt->lock);
 
        if (ref)
                *ref = waiter;
@@ -498,8 +479,7 @@ int nvhost_intr_init(struct nvhost_intr *intr, u32 irq_gen, u32 irq_sync)
             ++id, ++syncpt) {
                syncpt->intr = &host->intr;
                syncpt->id = id;
-               mutex_init(&syncpt->lock.m);
-               spin_lock_init(&syncpt->lock.s);
+               mutex_init(&syncpt->lock);
                INIT_LIST_HEAD(&syncpt->wait_head);
                snprintf(syncpt->thresh_irq_name,
                        sizeof(syncpt->thresh_irq_name),
index 8181d1b5e57a803cd9413c372f23d3045a35babf..1e003e9c1fc2944627f5c99064bb1fe7c85577cb 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Tegra Graphics Host Interrupt Management
  *
- * Copyright (c) 2010-2014, NVIDIA Corporation.  All rights reserved.
+ * Copyright (c) 2010-2015, NVIDIA Corporation.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -69,10 +69,7 @@ struct nvhost_intr;
 struct nvhost_intr_syncpt {
        struct nvhost_intr *intr;
        u8 id;
-       struct {
-               spinlock_t s;
-               struct mutex m;
-       } lock;
+       struct mutex lock;
        struct list_head wait_head;
        char thresh_irq_name[12];
        struct work_struct work;