/** * adreno_drawctxt_wait() - sleep until a timestamp expires * @adreno_dev: pointer to the adreno_device struct * @drawctxt: Pointer to the draw context to sleep for * @timetamp: Timestamp to wait on * @timeout: Number of jiffies to wait (0 for infinite) * * Register an event to wait for a timestamp on a context and sleep until it * has past. Returns < 0 on error, -ETIMEDOUT if the timeout expires or 0 * on success */ int adreno_drawctxt_wait(struct adreno_device *adreno_dev, struct kgsl_context *context, uint32_t timestamp, unsigned int timeout) { struct kgsl_device *device = &adreno_dev->dev; struct adreno_context *drawctxt = ADRENO_CONTEXT(context); int ret; long ret_temp; if (kgsl_context_detached(context)) return -EINVAL; if (kgsl_context_invalid(context)) return -EDEADLK; /* Needs to hold the device mutex */ BUG_ON(!mutex_is_locked(&device->mutex)); trace_adreno_drawctxt_wait_start(-1, context->id, timestamp); ret = kgsl_add_event(device, &context->events, timestamp, wait_callback, (void *) drawctxt); if (ret) goto done; mutex_unlock(&device->mutex); if (timeout) { ret_temp = wait_event_interruptible_timeout( drawctxt->waiting, _check_context_timestamp(device, drawctxt, timestamp), msecs_to_jiffies(timeout)); if (ret_temp == 0) ret = -ETIMEDOUT; else if (ret_temp > 0) ret = 0; else ret = (int) ret_temp; } else { ret = wait_event_interruptible(drawctxt->waiting, _check_context_timestamp(device, drawctxt, timestamp)); } mutex_lock(&device->mutex); /* -EDEADLK if the context was invalidated while we were waiting */ if (kgsl_context_invalid(context)) ret = -EDEADLK; /* Return -EINVAL if the context was detached while we were waiting */ if (kgsl_context_detached(context)) ret = -EINVAL; done: trace_adreno_drawctxt_wait_done(-1, context->id, timestamp, ret); return ret; }
/** * adreno_drawctxt_wait() - sleep until a timestamp expires * @adreno_dev: pointer to the adreno_device struct * @drawctxt: Pointer to the draw context to sleep for * @timetamp: Timestamp to wait on * @timeout: Number of jiffies to wait (0 for infinite) * * Register an event to wait for a timestamp on a context and sleep until it * has past. Returns < 0 on error, -ETIMEDOUT if the timeout expires or 0 * on success */ int adreno_drawctxt_wait(struct adreno_device *adreno_dev, struct kgsl_context *context, uint32_t timestamp, unsigned int timeout) { struct kgsl_device *device = &adreno_dev->dev; struct adreno_context *drawctxt = ADRENO_CONTEXT(context); int ret; long ret_temp; if (kgsl_context_detached(context)) return -ENOENT; if (kgsl_context_invalid(context)) return -EDEADLK; trace_adreno_drawctxt_wait_start(-1, context->id, timestamp); ret = kgsl_add_event(device, &context->events, timestamp, wait_callback, (void *) drawctxt); if (ret) goto done; /* * If timeout is 0, wait forever. msecs_to_jiffies will force * values larger than INT_MAX to an infinite timeout. */ if (timeout == 0) timeout = UINT_MAX; ret_temp = wait_event_interruptible_timeout(drawctxt->waiting, _check_context_timestamp(device, context, timestamp), msecs_to_jiffies(timeout)); if (ret_temp == 0) { ret = -ETIMEDOUT; goto done; } else if (ret_temp < 0) { ret = (int) ret_temp; goto done; } ret = 0; /* -EDEADLK if the context was invalidated while we were waiting */ if (kgsl_context_invalid(context)) ret = -EDEADLK; /* Return -EINVAL if the context was detached while we were waiting */ if (kgsl_context_detached(context)) ret = -ENOENT; done: trace_adreno_drawctxt_wait_done(-1, context->id, timestamp, ret); return ret; }
/** * adreno_drawctxt_wait() - sleep until a timestamp expires * @adreno_dev: pointer to the adreno_device struct * @drawctxt: Pointer to the draw context to sleep for * @timetamp: Timestamp to wait on * @timeout: Number of jiffies to wait (0 for infinite) * * Register an event to wait for a timestamp on a context and sleep until it * has past. Returns < 0 on error, -ETIMEDOUT if the timeout expires or 0 * on success */ int adreno_drawctxt_wait(struct adreno_device *adreno_dev, struct kgsl_context *context, uint32_t timestamp, unsigned int timeout) { static unsigned int io_cnt; struct kgsl_device *device = &adreno_dev->dev; struct kgsl_pwrctrl *pwr = &device->pwrctrl; struct adreno_context *drawctxt = ADRENO_CONTEXT(context); int ret, io; if (kgsl_context_detached(context)) return -EINVAL; if (drawctxt->state == ADRENO_CONTEXT_STATE_INVALID) return -EDEADLK; /* Needs to hold the device mutex */ BUG_ON(!mutex_is_locked(&device->mutex)); trace_adreno_drawctxt_wait_start(context->id, timestamp); ret = kgsl_add_event(device, &context->events, timestamp, wait_callback, (void *) drawctxt); if (ret) goto done; /* * For proper power accounting sometimes we need to call * io_wait_interruptible_timeout and sometimes we need to call * plain old wait_interruptible_timeout. We call the regular * timeout N times out of 100, where N is a number specified by * the current power level */ io_cnt = (io_cnt + 1) % 100; io = (io_cnt < pwr->pwrlevels[pwr->active_pwrlevel].io_fraction) ? 0 : 1; kgsl_mutex_unlock(&device->mutex, &device->mutex_owner); if (timeout) { long ret_temp; ret_temp = adreno_wait_event_interruptible_timeout( drawctxt->waiting, _check_context_timestamp(device, drawctxt, timestamp), msecs_to_jiffies(timeout), io); if (ret_temp == 0) ret = -ETIMEDOUT; else if (ret_temp > 0) ret = 0; else ret = (int) ret_temp; } else { ret = (int) adreno_wait_event_interruptible(drawctxt->waiting, _check_context_timestamp(device, drawctxt, timestamp), io); } kgsl_mutex_lock(&device->mutex, &device->mutex_owner); /* -EDEADLK if the context was invalidated while we were waiting */ if (drawctxt->state == ADRENO_CONTEXT_STATE_INVALID) ret = -EDEADLK; /* Return -EINVAL if the context was detached while we were waiting */ if (kgsl_context_detached(context)) ret = -EINVAL; done: trace_adreno_drawctxt_wait_done(context->id, timestamp, ret); return ret; }
int adreno_drawctxt_wait(struct adreno_device *adreno_dev, struct kgsl_context *context, uint32_t timestamp, unsigned int timeout) { static unsigned int io_cnt; struct kgsl_device *device = &adreno_dev->dev; struct kgsl_pwrctrl *pwr = &device->pwrctrl; struct adreno_context *drawctxt = ADRENO_CONTEXT(context); int ret, io; if (kgsl_context_detached(context)) return -EINVAL; if (drawctxt->state == ADRENO_CONTEXT_STATE_INVALID) return -EDEADLK; BUG_ON(!mutex_is_locked(&device->mutex)); trace_adreno_drawctxt_wait_start(context->id, timestamp); ret = kgsl_add_event(device, context->id, timestamp, wait_callback, drawctxt, NULL); if (ret) goto done; io_cnt = (io_cnt + 1) % 100; io = (io_cnt < pwr->pwrlevels[pwr->active_pwrlevel].io_fraction) ? 0 : 1; mutex_unlock(&device->mutex); if (timeout) { ret = (int) adreno_wait_event_interruptible_timeout( drawctxt->waiting, _check_context_timestamp(device, drawctxt, timestamp), msecs_to_jiffies(timeout), io); if (ret == 0) ret = -ETIMEDOUT; else if (ret > 0) ret = 0; } else { ret = (int) adreno_wait_event_interruptible(drawctxt->waiting, _check_context_timestamp(device, drawctxt, timestamp), io); } mutex_lock(&device->mutex); if (drawctxt->state == ADRENO_CONTEXT_STATE_INVALID) ret = -EDEADLK; if (kgsl_context_detached(context)) ret = -EINVAL; done: trace_adreno_drawctxt_wait_done(context->id, timestamp, ret); return ret; }