int roadmap_changed;
int new_buffers;
int first_event;
+ int pp_need_destroy;
struct list_head link;
} tdm_sprd_pp_data;
return TDM_ERROR_NONE;
}
-
void
tdm_sprd_pp_handler(struct drm_sprd_ipp_event *hw_ipp_p)
{
TDM_ERR("invalid params");
return;
}
+
RETURN_VOID_IF_FAIL(_tdm_sprd_pp_check_struct(pp_data));
TDM_DBG("pp %p(%d) index(%d, %d) prop_id(%u)", pp_data, pp_data->stamp, hw_ipp_p->buf_id[0],
hw_ipp_p->buf_id[1], hw_ipp_p->prop_id);
TDM_DBG("pp %p(%d) got a first event. ", pp_data, pp_data->stamp);
pp_data->first_event = 1;
}
+
+ if (pp_data->pp_need_destroy) {
+ TDM_DBG("pp %p(%d) Deferred event of delete", pp_data, pp_data->stamp);
+ LIST_DEL(&pp_data->link);
+ free(pp_data);
+ return;
+ }
+
if ((done_task = pp_data->current_task_p) == NULL) {
TDM_ERR("pp %p(%d) received wrong event", pp_data, pp_data->stamp);
return;
done_task->status = TASK_DONE;
TDM_DBG("pp %p(%d). Task %p(%d) done step %d of %d", pp_data, pp_data->stamp, done_task, done_task->stamp,
done_task->current_step+1, done_task->max_step);
+
if (_tdm_sprd_pp_cmd(pp_data,
done_task->prop_id[done_task->current_step],
IPP_PAUSE) != TDM_ERROR_NONE) {
pp_data->stamp, done_task->prop_id[done_task->current_step]);
return;
}
+
if (_tdm_sprd_pp_worker(pp_data) != TDM_ERROR_NONE) {
TDM_ERR("pp %p(%d) worker return ERROR", pp_data,
pp_data->stamp);
pp_data->sprd_data = sprd_data;
pp_data->stamp = pp_stamp++;
+ pp_data->pp_need_destroy = 0;
if (!pp_list_init) {
pp_list_init = 1;
LIST_INITHEAD(&pp_list);
}
+ /* Find old pp_data and remove*/
+ tdm_sprd_pp_data *pp_data_cur = NULL, *pp_data_next = NULL;
+ LIST_FOR_EACH_ENTRY_SAFE(pp_data_cur, pp_data_next, &pp_list, link) {
+ if (pp_data_cur->pp_need_destroy) {
+ LIST_DEL(&pp_data_cur->link);
+ free(pp_data_cur);
+ }
+ }
+
LIST_INITHEAD(&pp_data->pending_buffer_list);
LIST_INITHEAD(&pp_data->pending_tasks_list);
LIST_INITHEAD(&pp_data->prop_id_list);
tdm_sprd_prop_id *prop_id = NULL, *next_prop_id = NULL;
RETURN_VOID_IF_FAIL(_tdm_sprd_pp_check_struct(pp_data));
TDM_DBG("pp %p(%d). Destroy", pp_data, pp_data->stamp);
+
+ LIST_FOR_EACH_ENTRY_SAFE (prop_id, next_prop_id, &pp_data->prop_id_list, link) {
+ _tdm_sprd_pp_cmd(pp_data, prop_id->prop_id, IPP_STOP);
+ }
+
LIST_FOR_EACH_ENTRY_SAFE(b, bb, &pp_data->pending_buffer_list, link) {
LIST_DEL(&b->link);
free(b);
}
- if (pp_data->current_task_p && pp_data->current_task_p->status == TASK_CONVERTING) {
- _tdm_sprd_pp_queue(pp_data, pp_data->current_task_p->prop_id[pp_data->current_task_p->current_step],
- pp_data->current_task_p->buffers[pp_data->current_task_p->current_step].src,
- pp_data->current_task_p->buffers[pp_data->current_task_p->current_step].dst, IPP_BUF_DEQUEUE);
- _tdm_sprd_pp_destroy_task(pp_data, pp_data->current_task_p);
- }
+
LIST_FOR_EACH_ENTRY_SAFE(task, next_task, &pp_data->pending_tasks_list, link) {
LIST_DEL(&task->link);
_tdm_sprd_pp_destroy_task(pp_data, task);
}
- LIST_FOR_EACH_ENTRY_SAFE (prop_id, next_prop_id, &pp_data->prop_id_list, link) {
- _tdm_sprd_pp_cmd(pp_data, prop_id->prop_id, IPP_STOP);
+
+ if (pp_data->current_task_p && pp_data->current_task_p->status == TASK_CONVERTING) {
+ TDM_DBG("pp %p(%d) Still converting. Should Remove after callback", pp_data, pp_data->stamp);
+ pp_data->pp_need_destroy = 1;
+ _tdm_sprd_pp_destroy_task(pp_data, pp_data->current_task_p);
+ pp_data->current_task_p = NULL;
}
+
+ if (pp_data->pp_need_destroy)
+ return;
+
LIST_DEL(&pp_data->link);
free(pp_data);
+
}
static tdm_error
RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER);
RETURN_VAL_IF_FAIL(_tdm_sprd_pp_check_struct(pp_data), TDM_ERROR_INVALID_PARAMETER);
TDM_DBG("pp %p(%d). Set new info.", pp_data, pp_data->stamp);
+ if (pp_data->pp_need_destroy) {
+ TDM_WRN("pp %p(%d) Will remove. Ignoring request.", pp_data, pp_data->stamp);
+ return TDM_ERROR_BAD_REQUEST;
+ }
if (info->sync) {
TDM_ERR("pp %p(%d). not support sync mode currently", pp_data, pp_data->stamp);
return TDM_ERROR_INVALID_PARAMETER;
RETURN_VAL_IF_FAIL(src, TDM_ERROR_INVALID_PARAMETER);
RETURN_VAL_IF_FAIL(dst, TDM_ERROR_INVALID_PARAMETER);
RETURN_VAL_IF_FAIL(_tdm_sprd_pp_check_struct(pp_data), TDM_ERROR_INVALID_PARAMETER);
+ if (pp_data->pp_need_destroy) {
+ TDM_WRN("pp %p(%d) Will remove. Ignoring request.", pp_data, pp_data->stamp);
+ return TDM_ERROR_BAD_REQUEST;
+ }
buffer = calloc(1, sizeof(tdm_sprd_pp_buffer));
if (!buffer) {
TDM_ERR("pp %p(%d). Alloc failed", pp_data, pp_data->stamp);
{
tdm_sprd_pp_data *pp_data = (tdm_sprd_pp_data *) pp;
RETURN_VAL_IF_FAIL(_tdm_sprd_pp_check_struct(pp_data), TDM_ERROR_INVALID_PARAMETER);
+ if (pp_data->pp_need_destroy) {
+ TDM_WRN("pp %p(%d) Will remove. Ignoring request.", pp_data, pp_data->stamp);
+ return TDM_ERROR_BAD_REQUEST;
+ }
if (pp_data->roadmap_changed) {
unsigned int i, need_postpond = 0;
for (i = 0; i < pp_data->roadmap.max_step; i++) {