static int adreno_drawctxt_wait_global(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 = 0; /* Needs to hold the device mutex */ BUG_ON(!mutex_is_locked(&device->mutex)); if (!_kgsl_context_get(context)) { ret = -EINVAL; goto done; } /* * If the context is invalid then return immediately - we may end up * waiting for a timestamp that will never come */ if (drawctxt->state == ADRENO_CONTEXT_STATE_INVALID) { kgsl_context_put(context); goto done; } trace_adreno_drawctxt_wait_start(KGSL_MEMSTORE_GLOBAL, timestamp); ret = kgsl_add_event(device, &device->global_events, timestamp, global_wait_callback, (void *) drawctxt); if (ret) { kgsl_context_put(context); goto done; } kgsl_mutex_unlock(&device->mutex, &device->mutex_owner); if (timeout) { ret = (int) wait_event_timeout(drawctxt->waiting, _check_global_timestamp(device, drawctxt, timestamp), msecs_to_jiffies(timeout)); if (ret == 0) ret = -ETIMEDOUT; else if (ret > 0) ret = 0; } else { wait_event(drawctxt->waiting, _check_global_timestamp(device, drawctxt, timestamp)); } kgsl_mutex_lock(&device->mutex, &device->mutex_owner); if (ret) kgsl_cancel_events_timestamp(device, &device->global_events, timestamp); done: trace_adreno_drawctxt_wait_done(KGSL_MEMSTORE_GLOBAL, timestamp, ret); return ret; }
/** * adreno_drawctxt_wait_rb() - Wait for the last RB timestamp at which this * context submitted a command to the corresponding RB * @adreno_dev: The device on which the timestamp is active * @context: The context which subbmitted command to RB * @timestamp: The RB timestamp of last command submitted to RB by context * @timeout: Timeout value for the wait */ static int adreno_drawctxt_wait_rb(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 = 0; /* Needs to hold the device mutex */ BUG_ON(!mutex_is_locked(&device->mutex)); /* * If the context is invalid then return immediately - we may end up * waiting for a timestamp that will never come */ if (kgsl_context_invalid(context)) goto done; trace_adreno_drawctxt_wait_start(drawctxt->rb->id, context->id, timestamp); ret = adreno_ringbuffer_waittimestamp(drawctxt->rb, timestamp, timeout); done: trace_adreno_drawctxt_wait_done(drawctxt->rb->id, 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 -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; }
int adreno_drawctxt_wait_global(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 = 0; BUG_ON(!mutex_is_locked(&device->mutex)); if (!_kgsl_context_get(context)) { ret = -EINVAL; goto done; } if (drawctxt->state == ADRENO_CONTEXT_STATE_INVALID) { kgsl_context_put(context); goto done; } trace_adreno_drawctxt_wait_start(KGSL_MEMSTORE_GLOBAL, timestamp); ret = kgsl_add_event(device, KGSL_MEMSTORE_GLOBAL, timestamp, global_wait_callback, drawctxt, NULL); if (ret) { kgsl_context_put(context); goto done; } mutex_unlock(&device->mutex); if (timeout) { ret = (int) wait_event_timeout(drawctxt->waiting, _check_global_timestamp(device, drawctxt, timestamp), msecs_to_jiffies(timeout)); if (ret == 0) ret = -ETIMEDOUT; else if (ret > 0) ret = 0; } else { wait_event(drawctxt->waiting, _check_global_timestamp(device, drawctxt, timestamp)); } mutex_lock(&device->mutex); if (ret) kgsl_cancel_events_timestamp(device, NULL, timestamp); done: trace_adreno_drawctxt_wait_done(KGSL_MEMSTORE_GLOBAL, 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; }