From 27ced8b3152e0d1a3f8141d2f9c0519b64c375c0 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Tue, 12 Jan 2021 10:41:11 +0000 Subject: [PATCH] gpu: host1x: Update to UAPI series v5 Update the host1x driver to the 'Host1x/Tegra UAPI v5' series [0]. This fixes a few minor bugs found in the previous series. [0] https://patchwork.ozlabs.org/project/linux-tegra/list/?series=223684 Bug 200687525 Change-Id: I680bfb9e8db73b9e2571551f22fadca1f2974498 Signed-off-by: Jon Hunter Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2469983 Tested-by: mobile promotions Reviewed-by: Mikko Perttunen Reviewed-by: mobile promotions GVS: Gerrit_Virtual_Submit --- drivers/gpu/host1x/bus.c | 1 + drivers/gpu/host1x/cdma.c | 2 +- drivers/gpu/host1x/fence.c | 4 ++-- drivers/gpu/host1x/intr.c | 9 ++++++++- drivers/gpu/host1x/intr.h | 4 +++- drivers/gpu/host1x/job.c | 2 +- drivers/gpu/host1x/syncpt.c | 2 +- 7 files changed, 17 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c index 38f90ad0..01538262 100644 --- a/drivers/gpu/host1x/bus.c +++ b/drivers/gpu/host1x/bus.c @@ -32,6 +32,7 @@ struct host1x_subdev { /** * host1x_subdev_add() - add a new subdevice with an associated device node * @device: host1x device to add the subdevice to + * @driver: host1x driver containing the subdevices * @np: device node */ static int host1x_subdev_add(struct host1x_device *device, diff --git a/drivers/gpu/host1x/cdma.c b/drivers/gpu/host1x/cdma.c index 8b9e7b4e..286e2f97 100644 --- a/drivers/gpu/host1x/cdma.c +++ b/drivers/gpu/host1x/cdma.c @@ -453,7 +453,7 @@ syncpt_incr: u32 *mapped = cdma->push_buffer.mapped; /* - * Overwrite opcodes with 0 word writes to + * Overwrite opcodes with 0 word writes * to offset 0xbad. This does nothing but * has a easily detected signature in debug * traces. diff --git a/drivers/gpu/host1x/fence.c b/drivers/gpu/host1x/fence.c index b2484606..e96ad93f 100644 --- a/drivers/gpu/host1x/fence.c +++ b/drivers/gpu/host1x/fence.c @@ -114,7 +114,7 @@ void host1x_fence_signal(struct host1x_syncpt_fence *f) */ cancel_delayed_work_sync(&f->timeout_work); - host1x_intr_put_ref(f->sp->host, f->sp->id, f->waiter_ref); + host1x_intr_put_ref(f->sp->host, f->sp->id, f->waiter_ref, false); dma_fence_signal(&f->base); dma_fence_put(&f->base); @@ -133,7 +133,7 @@ static void do_fence_timeout(struct work_struct *work) * Cancel pending timeout work - if it races, it will * not get 'f->signaling' and return. */ - host1x_intr_put_ref(f->sp->host, f->sp->id, f->waiter_ref); + host1x_intr_put_ref(f->sp->host, f->sp->id, f->waiter_ref, true); dma_fence_set_error(&f->base, -ETIMEDOUT); dma_fence_signal(&f->base); diff --git a/drivers/gpu/host1x/intr.c b/drivers/gpu/host1x/intr.c index 19b59c5c..bcffc4d7 100644 --- a/drivers/gpu/host1x/intr.c +++ b/drivers/gpu/host1x/intr.c @@ -251,7 +251,8 @@ int host1x_intr_add_action(struct host1x *host, struct host1x_syncpt *syncpt, 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; @@ -268,6 +269,12 @@ void host1x_intr_put_ref(struct host1x *host, unsigned int id, void *ref) } spin_unlock(&syncpt->intr.lock); + if (flush) { + /* Wait until any concurrently executing handler has finished. */ + while (atomic_read(&waiter->state) != WLS_HANDLED) + cpu_relax(); + } + kref_put(&waiter->refcount, waiter_release); } diff --git a/drivers/gpu/host1x/intr.h b/drivers/gpu/host1x/intr.h index dedbd0f7..e4c34609 100644 --- a/drivers/gpu/host1x/intr.h +++ b/drivers/gpu/host1x/intr.h @@ -76,8 +76,10 @@ int host1x_intr_add_action(struct host1x *host, struct host1x_syncpt *syncpt, * Unreference an action submitted to host1x_intr_add_action(). * You must call this if you passed non-NULL as ref. * @ref the ref returned from host1x_intr_add_action() + * @flush wait until any pending handlers have completed before returning. */ -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); /* Initialize host1x sync point interrupt */ int host1x_intr_init(struct host1x *host, unsigned int irq_sync); diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c index d7bb5d18..ae484d86 100644 --- a/drivers/gpu/host1x/job.c +++ b/drivers/gpu/host1x/job.c @@ -84,7 +84,7 @@ static void job_free(struct kref *ref) if (job->waiter) host1x_intr_put_ref(job->syncpt->host, job->syncpt->id, - job->waiter); + job->waiter, false); if (job->syncpt) host1x_syncpt_put(job->syncpt); diff --git a/drivers/gpu/host1x/syncpt.c b/drivers/gpu/host1x/syncpt.c index d0be7bdb..100270ac 100644 --- a/drivers/gpu/host1x/syncpt.c +++ b/drivers/gpu/host1x/syncpt.c @@ -295,7 +295,7 @@ int host1x_syncpt_wait(struct host1x_syncpt *sp, u32 thresh, long timeout, } } - host1x_intr_put_ref(sp->host, sp->id, ref); + host1x_intr_put_ref(sp->host, sp->id, ref, true); done: return err;