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;