diff options
| author | Rodrigo Vivi <rodrigo.vivi@intel.com> | 2021-05-18 00:48:02 +0300 |
|---|---|---|
| committer | Rodrigo Vivi <rodrigo.vivi@intel.com> | 2021-05-18 00:48:02 +0300 |
| commit | d22fe808f9a3456f16015e79f1b86a10ce13099f (patch) | |
| tree | 8e8c99d742696a810297d54d650f308f6156d466 /drivers/gpu/host1x/intr.c | |
| parent | 1a7910368cba1e76b992b116fc8ba28503e6dcc1 (diff) | |
| parent | 6efb943b8616ec53a5e444193dccf1af9ad627b5 (diff) | |
| download | linux-d22fe808f9a3456f16015e79f1b86a10ce13099f.tar.xz | |
Merge drm/drm-next into drm-intel-next
Time to get back in sync...
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Diffstat (limited to 'drivers/gpu/host1x/intr.c')
| -rw-r--r-- | drivers/gpu/host1x/intr.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/drivers/gpu/host1x/intr.c b/drivers/gpu/host1x/intr.c index 9245add23b5d..6d1f3c0fdbe7 100644 --- a/drivers/gpu/host1x/intr.c +++ b/drivers/gpu/host1x/intr.c @@ -235,25 +235,37 @@ int host1x_intr_add_action(struct host1x *host, struct host1x_syncpt *syncpt, host1x_hw_intr_enable_syncpt_intr(host, syncpt->id); } - spin_unlock(&syncpt->intr.lock); - if (ref) *ref = waiter; + + spin_unlock(&syncpt->intr.lock); + return 0; } -void host1x_intr_put_ref(struct host1x *host, unsigned int id, void *ref) +void host1x_intr_put_ref(struct host1x *host, unsigned int id, void *ref, + bool flush) { struct host1x_waitlist *waiter = ref; struct host1x_syncpt *syncpt; - while (atomic_cmpxchg(&waiter->state, WLS_PENDING, WLS_CANCELLED) == - WLS_REMOVED) - schedule(); + atomic_cmpxchg(&waiter->state, WLS_PENDING, WLS_CANCELLED); syncpt = host->syncpt + id; - (void)process_wait_list(host, syncpt, - host1x_syncpt_load(host->syncpt + id)); + + spin_lock(&syncpt->intr.lock); + if (atomic_cmpxchg(&waiter->state, WLS_CANCELLED, WLS_HANDLED) == + WLS_CANCELLED) { + list_del(&waiter->list); + kref_put(&waiter->refcount, waiter_release); + } + spin_unlock(&syncpt->intr.lock); + + if (flush) { + /* Wait until any concurrently executing handler has finished. */ + while (atomic_read(&waiter->state) != WLS_HANDLED) + schedule(); + } kref_put(&waiter->refcount, waiter_release); } |
