Loading drivers/media/platform/msm/vidc/msm_vdec.c +2 −2 Original line number Original line Diff line number Diff line Loading @@ -1657,7 +1657,7 @@ int msm_vdec_cmd(struct msm_vidc_inst *inst, struct v4l2_decoder_cmd *dec) case V4L2_DEC_QCOM_CMD_FLUSH: case V4L2_DEC_QCOM_CMD_FLUSH: if (core->state != VIDC_CORE_INVALID && if (core->state != VIDC_CORE_INVALID && inst->state == MSM_VIDC_CORE_INVALID) { inst->state == MSM_VIDC_CORE_INVALID) { rc = msm_comm_recover_from_session_error(inst); rc = msm_comm_kill_session(inst); if (rc) if (rc) dprintk(VIDC_ERR, dprintk(VIDC_ERR, "Failed to recover from session_error: %d\n", "Failed to recover from session_error: %d\n", Loading @@ -1672,7 +1672,7 @@ int msm_vdec_cmd(struct msm_vidc_inst *inst, struct v4l2_decoder_cmd *dec) case V4L2_DEC_CMD_STOP: case V4L2_DEC_CMD_STOP: if (core->state != VIDC_CORE_INVALID && if (core->state != VIDC_CORE_INVALID && inst->state == MSM_VIDC_CORE_INVALID) { inst->state == MSM_VIDC_CORE_INVALID) { rc = msm_comm_recover_from_session_error(inst); rc = msm_comm_kill_session(inst); if (rc) if (rc) dprintk(VIDC_ERR, dprintk(VIDC_ERR, "Failed to recover from session_error: %d\n", "Failed to recover from session_error: %d\n", Loading drivers/media/platform/msm/vidc/msm_vidc_common.c +93 −60 Original line number Original line Diff line number Diff line Loading @@ -42,6 +42,9 @@ struct getprop_buf { void *data; void *data; }; }; static void msm_comm_generate_session_error(struct msm_vidc_inst *inst); static void msm_comm_generate_sys_error(struct msm_vidc_inst *inst); static inline bool is_turbo_session(struct msm_vidc_inst *inst) static inline bool is_turbo_session(struct msm_vidc_inst *inst) { { return !!(inst->flags & VIDC_TURBO); return !!(inst->flags & VIDC_TURBO); Loading Loading @@ -494,7 +497,7 @@ static int wait_for_sess_signal_receipt(struct msm_vidc_inst *inst, dprintk(VIDC_ERR, dprintk(VIDC_ERR, "%s: Wait interrupted or timed out [%p]: %d\n", "%s: Wait interrupted or timed out [%p]: %d\n", __func__, inst, SESSION_MSG_INDEX(cmd)); __func__, inst, SESSION_MSG_INDEX(cmd)); msm_comm_recover_from_session_error(inst); msm_comm_kill_session(inst); rc = -EIO; rc = -EIO; } else { } else { rc = 0; rc = 0; Loading Loading @@ -528,19 +531,6 @@ void msm_vidc_queue_v4l2_event(struct msm_vidc_inst *inst, int event_type) wake_up(&inst->kernel_event_queue); wake_up(&inst->kernel_event_queue); } } static void msm_comm_generate_session_error(struct msm_vidc_inst *inst) { if (!inst) { dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__); return; } mutex_lock(&inst->lock); inst->session = NULL; inst->state = MSM_VIDC_CORE_INVALID; msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); mutex_unlock(&inst->lock); } static void msm_comm_generate_max_clients_error(struct msm_vidc_inst *inst) static void msm_comm_generate_max_clients_error(struct msm_vidc_inst *inst) { { if (!inst) { if (!inst) { Loading Loading @@ -865,22 +855,40 @@ static void handle_session_flush(enum command_response cmd, void *data) static void handle_session_error(enum command_response cmd, void *data) static void handle_session_error(enum command_response cmd, void *data) { { struct msm_vidc_cb_cmd_done *response = data; struct msm_vidc_cb_cmd_done *response = data; int rc; struct hfi_device *hdev = NULL; struct msm_vidc_inst *inst = NULL; struct msm_vidc_inst *inst = NULL; if (response) { if (!response) { dprintk(VIDC_ERR, "Failed to get valid response for session error\n"); return; } inst = (struct msm_vidc_inst *)response->session_id; inst = (struct msm_vidc_inst *)response->session_id; if (inst) { dprintk(VIDC_WARN, if (!inst || !inst->session || !inst->core->device) { "Session error receivd for session %p\n", inst); dprintk(VIDC_ERR, "Session (%p) not in a stable enough state to handle session error\n", inst); return; } hdev = inst->core->device; dprintk(VIDC_WARN, "Session error received for session %p\n", inst); mutex_lock(&inst->sync_lock); mutex_lock(&inst->sync_lock); inst->state = MSM_VIDC_CORE_INVALID; inst->state = MSM_VIDC_CORE_INVALID; dprintk(VIDC_DBG, "cleaning up inst: %p\n", inst); rc = call_hfi_op(hdev, session_clean, inst->session); if (rc) dprintk(VIDC_ERR, "Session (%p) clean failed: %d\n", inst, rc); inst->session = NULL; mutex_unlock(&inst->sync_lock); mutex_unlock(&inst->sync_lock); msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); } } else { dprintk(VIDC_ERR, "Failed to get valid response for session error\n"); } } } static void handle_sys_error(enum command_response cmd, void *data) static void handle_sys_error(enum command_response cmd, void *data) { { Loading Loading @@ -1259,10 +1267,10 @@ static void handle_fbd(enum command_response cmd, void *data) inst = (struct msm_vidc_inst *)response->session_id; inst = (struct msm_vidc_inst *)response->session_id; fill_buf_done = (struct vidc_hal_fbd *)&response->output_done; fill_buf_done = (struct vidc_hal_fbd *)&response->output_done; buffer_type = msm_comm_get_hal_output_buffer(inst); buffer_type = msm_comm_get_hal_output_buffer(inst); if (fill_buf_done->buffer_type == buffer_type) if (fill_buf_done->buffer_type == buffer_type) { vb = get_vb_from_device_addr(&inst->bufq[CAPTURE_PORT], vb = get_vb_from_device_addr(&inst->bufq[CAPTURE_PORT], fill_buf_done->packet_buffer1); fill_buf_done->packet_buffer1); else { } else { if (handle_multi_stream_buffers(inst, if (handle_multi_stream_buffers(inst, fill_buf_done->packet_buffer1)) fill_buf_done->packet_buffer1)) dprintk(VIDC_ERR, dprintk(VIDC_ERR, Loading Loading @@ -1825,7 +1833,7 @@ static int msm_vidc_load_resources(int flipped_state, inst->state = MSM_VIDC_CORE_INVALID; inst->state = MSM_VIDC_CORE_INVALID; msm_vidc_queue_v4l2_event(inst, msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_HW_OVERLOAD); V4L2_EVENT_MSM_VIDC_HW_OVERLOAD); msm_comm_recover_from_session_error(inst); msm_comm_kill_session(inst); return -ENOMEM; return -ENOMEM; } } Loading Loading @@ -2696,7 +2704,7 @@ int msm_comm_try_get_prop(struct msm_vidc_inst *inst, enum hal_property ptype, __func__, inst, __func__, inst, SESSION_MSG_INDEX(SESSION_PROPERTY_INFO)); SESSION_MSG_INDEX(SESSION_PROPERTY_INFO)); inst->state = MSM_VIDC_CORE_INVALID; inst->state = MSM_VIDC_CORE_INVALID; msm_comm_recover_from_session_error(inst); msm_comm_kill_session(inst); rc = -EIO; rc = -EIO; goto exit; goto exit; } } Loading Loading @@ -2830,8 +2838,7 @@ int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst) mutex_lock(&inst->sync_lock); mutex_lock(&inst->sync_lock); inst->state = MSM_VIDC_CORE_INVALID; inst->state = MSM_VIDC_CORE_INVALID; mutex_unlock(&inst->sync_lock); mutex_unlock(&inst->sync_lock); msm_comm_recover_from_session_error( msm_comm_kill_session(inst); inst); } } mutex_lock(&inst->lock); mutex_lock(&inst->lock); } } Loading Loading @@ -2901,8 +2908,7 @@ int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst) mutex_lock(&inst->sync_lock); mutex_lock(&inst->sync_lock); inst->state = MSM_VIDC_CORE_INVALID; inst->state = MSM_VIDC_CORE_INVALID; mutex_unlock(&inst->sync_lock); mutex_unlock(&inst->sync_lock); msm_comm_recover_from_session_error( msm_comm_kill_session(inst); inst); } } mutex_lock(&inst->lock); mutex_lock(&inst->lock); } } Loading Loading @@ -3511,6 +3517,20 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) return rc; return rc; } } static void msm_comm_generate_session_error(struct msm_vidc_inst *inst) { enum command_response cmd = SESSION_ERROR; struct msm_vidc_cb_cmd_done response = {0}; if (!inst || !inst->core) { dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__); return; } response.session_id = inst; handle_session_error(cmd, (void *)&response); } static void msm_comm_generate_sys_error(struct msm_vidc_inst *inst) static void msm_comm_generate_sys_error(struct msm_vidc_inst *inst) { { struct msm_vidc_core *core; struct msm_vidc_core *core; Loading @@ -3525,42 +3545,55 @@ static void msm_comm_generate_sys_error(struct msm_vidc_inst *inst) handle_sys_error(cmd, (void *) &response); handle_sys_error(cmd, (void *) &response); } } int msm_comm_recover_from_session_error(struct msm_vidc_inst *inst) int msm_comm_kill_session(struct msm_vidc_inst *inst) { { struct hfi_device *hdev; int rc = 0; int rc = 0; if (!inst || !inst->core || !inst->core->device) { if (!inst || !inst->core || !inst->core->device) { dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__); dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__); return -EINVAL; return -EINVAL; } else if (!inst->session) { /* There's no hfi session to kill */ return 0; } } if (!inst->session || inst->state < MSM_VIDC_OPEN_DONE) { dprintk(VIDC_WARN, "No corresponding FW session. No need to send Abort\n"); return rc; } hdev = inst->core->device; init_completion(&inst->completions[SESSION_MSG_INDEX /* (SESSION_ABORT_DONE)]); * We're internally forcibly killing the session, if fw is aware of * the session send session_abort to firmware to clean up and release /* We have received session_error. Send session_abort to firmware * the session, else just kill the session inside the driver. * to clean up and release the session */ */ if (inst->state >= MSM_VIDC_OPEN_DONE || inst->state < MSM_VIDC_CLOSE_DONE) { struct hfi_device *hdev = inst->core->device; int abort_completion = SESSION_MSG_INDEX(SESSION_ABORT_DONE); rc = call_hfi_op(hdev, session_abort, (void *) inst->session); rc = call_hfi_op(hdev, session_abort, (void *) inst->session); if (rc) { if (rc) { dprintk(VIDC_ERR, "session_abort failed rc: %d\n", rc); dprintk(VIDC_ERR, "session_abort failed rc: %d\n", rc); return rc; return rc; } } init_completion(&inst->completions[abort_completion]); rc = wait_for_completion_timeout( rc = wait_for_completion_timeout( &inst->completions[SESSION_MSG_INDEX(SESSION_ABORT_DONE)], &inst->completions[abort_completion], msecs_to_jiffies(msm_vidc_hw_rsp_timeout)); msecs_to_jiffies(msm_vidc_hw_rsp_timeout)); if (!rc) { if (!rc) { dprintk(VIDC_ERR, "%s: Wait interrupted or timed out [%p]:%d\n", dprintk(VIDC_ERR, __func__, inst, SESSION_MSG_INDEX(SESSION_ABORT_DONE)); "%s: Wait interrupted or timed out [%p]: %d\n", __func__, inst, abort_completion); msm_comm_generate_sys_error(inst); msm_comm_generate_sys_error(inst); } else } else { change_inst_state(inst, MSM_VIDC_CLOSE_DONE); change_inst_state(inst, MSM_VIDC_CLOSE_DONE); } } else { dprintk(VIDC_WARN, "Inactive session %p, triggering an internal session error\n", inst); msm_comm_generate_session_error(inst); } return rc; return rc; } } Loading drivers/media/platform/msm/vidc/msm_vidc_common.h +2 −2 Original line number Original line Diff line number Diff line /* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -52,7 +52,7 @@ struct hal_buffer_requirements *get_buff_req_buffer( (V4L2_CTRL_ID2CLASS(idx) == V4L2_CTRL_CLASS_MPEG) && \ (V4L2_CTRL_ID2CLASS(idx) == V4L2_CTRL_CLASS_MPEG) && \ V4L2_CTRL_DRIVER_PRIV(idx)) V4L2_CTRL_DRIVER_PRIV(idx)) int msm_comm_recover_from_session_error(struct msm_vidc_inst *inst); int msm_comm_kill_session(struct msm_vidc_inst *inst); enum multi_stream msm_comm_get_stream_output_mode(struct msm_vidc_inst *inst); enum multi_stream msm_comm_get_stream_output_mode(struct msm_vidc_inst *inst); enum hal_buffer msm_comm_get_hal_output_buffer(struct msm_vidc_inst *inst); enum hal_buffer msm_comm_get_hal_output_buffer(struct msm_vidc_inst *inst); struct msm_smem *msm_comm_smem_alloc(struct msm_vidc_inst *inst, struct msm_smem *msm_comm_smem_alloc(struct msm_vidc_inst *inst, Loading Loading
drivers/media/platform/msm/vidc/msm_vdec.c +2 −2 Original line number Original line Diff line number Diff line Loading @@ -1657,7 +1657,7 @@ int msm_vdec_cmd(struct msm_vidc_inst *inst, struct v4l2_decoder_cmd *dec) case V4L2_DEC_QCOM_CMD_FLUSH: case V4L2_DEC_QCOM_CMD_FLUSH: if (core->state != VIDC_CORE_INVALID && if (core->state != VIDC_CORE_INVALID && inst->state == MSM_VIDC_CORE_INVALID) { inst->state == MSM_VIDC_CORE_INVALID) { rc = msm_comm_recover_from_session_error(inst); rc = msm_comm_kill_session(inst); if (rc) if (rc) dprintk(VIDC_ERR, dprintk(VIDC_ERR, "Failed to recover from session_error: %d\n", "Failed to recover from session_error: %d\n", Loading @@ -1672,7 +1672,7 @@ int msm_vdec_cmd(struct msm_vidc_inst *inst, struct v4l2_decoder_cmd *dec) case V4L2_DEC_CMD_STOP: case V4L2_DEC_CMD_STOP: if (core->state != VIDC_CORE_INVALID && if (core->state != VIDC_CORE_INVALID && inst->state == MSM_VIDC_CORE_INVALID) { inst->state == MSM_VIDC_CORE_INVALID) { rc = msm_comm_recover_from_session_error(inst); rc = msm_comm_kill_session(inst); if (rc) if (rc) dprintk(VIDC_ERR, dprintk(VIDC_ERR, "Failed to recover from session_error: %d\n", "Failed to recover from session_error: %d\n", Loading
drivers/media/platform/msm/vidc/msm_vidc_common.c +93 −60 Original line number Original line Diff line number Diff line Loading @@ -42,6 +42,9 @@ struct getprop_buf { void *data; void *data; }; }; static void msm_comm_generate_session_error(struct msm_vidc_inst *inst); static void msm_comm_generate_sys_error(struct msm_vidc_inst *inst); static inline bool is_turbo_session(struct msm_vidc_inst *inst) static inline bool is_turbo_session(struct msm_vidc_inst *inst) { { return !!(inst->flags & VIDC_TURBO); return !!(inst->flags & VIDC_TURBO); Loading Loading @@ -494,7 +497,7 @@ static int wait_for_sess_signal_receipt(struct msm_vidc_inst *inst, dprintk(VIDC_ERR, dprintk(VIDC_ERR, "%s: Wait interrupted or timed out [%p]: %d\n", "%s: Wait interrupted or timed out [%p]: %d\n", __func__, inst, SESSION_MSG_INDEX(cmd)); __func__, inst, SESSION_MSG_INDEX(cmd)); msm_comm_recover_from_session_error(inst); msm_comm_kill_session(inst); rc = -EIO; rc = -EIO; } else { } else { rc = 0; rc = 0; Loading Loading @@ -528,19 +531,6 @@ void msm_vidc_queue_v4l2_event(struct msm_vidc_inst *inst, int event_type) wake_up(&inst->kernel_event_queue); wake_up(&inst->kernel_event_queue); } } static void msm_comm_generate_session_error(struct msm_vidc_inst *inst) { if (!inst) { dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__); return; } mutex_lock(&inst->lock); inst->session = NULL; inst->state = MSM_VIDC_CORE_INVALID; msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); mutex_unlock(&inst->lock); } static void msm_comm_generate_max_clients_error(struct msm_vidc_inst *inst) static void msm_comm_generate_max_clients_error(struct msm_vidc_inst *inst) { { if (!inst) { if (!inst) { Loading Loading @@ -865,22 +855,40 @@ static void handle_session_flush(enum command_response cmd, void *data) static void handle_session_error(enum command_response cmd, void *data) static void handle_session_error(enum command_response cmd, void *data) { { struct msm_vidc_cb_cmd_done *response = data; struct msm_vidc_cb_cmd_done *response = data; int rc; struct hfi_device *hdev = NULL; struct msm_vidc_inst *inst = NULL; struct msm_vidc_inst *inst = NULL; if (response) { if (!response) { dprintk(VIDC_ERR, "Failed to get valid response for session error\n"); return; } inst = (struct msm_vidc_inst *)response->session_id; inst = (struct msm_vidc_inst *)response->session_id; if (inst) { dprintk(VIDC_WARN, if (!inst || !inst->session || !inst->core->device) { "Session error receivd for session %p\n", inst); dprintk(VIDC_ERR, "Session (%p) not in a stable enough state to handle session error\n", inst); return; } hdev = inst->core->device; dprintk(VIDC_WARN, "Session error received for session %p\n", inst); mutex_lock(&inst->sync_lock); mutex_lock(&inst->sync_lock); inst->state = MSM_VIDC_CORE_INVALID; inst->state = MSM_VIDC_CORE_INVALID; dprintk(VIDC_DBG, "cleaning up inst: %p\n", inst); rc = call_hfi_op(hdev, session_clean, inst->session); if (rc) dprintk(VIDC_ERR, "Session (%p) clean failed: %d\n", inst, rc); inst->session = NULL; mutex_unlock(&inst->sync_lock); mutex_unlock(&inst->sync_lock); msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); } } else { dprintk(VIDC_ERR, "Failed to get valid response for session error\n"); } } } static void handle_sys_error(enum command_response cmd, void *data) static void handle_sys_error(enum command_response cmd, void *data) { { Loading Loading @@ -1259,10 +1267,10 @@ static void handle_fbd(enum command_response cmd, void *data) inst = (struct msm_vidc_inst *)response->session_id; inst = (struct msm_vidc_inst *)response->session_id; fill_buf_done = (struct vidc_hal_fbd *)&response->output_done; fill_buf_done = (struct vidc_hal_fbd *)&response->output_done; buffer_type = msm_comm_get_hal_output_buffer(inst); buffer_type = msm_comm_get_hal_output_buffer(inst); if (fill_buf_done->buffer_type == buffer_type) if (fill_buf_done->buffer_type == buffer_type) { vb = get_vb_from_device_addr(&inst->bufq[CAPTURE_PORT], vb = get_vb_from_device_addr(&inst->bufq[CAPTURE_PORT], fill_buf_done->packet_buffer1); fill_buf_done->packet_buffer1); else { } else { if (handle_multi_stream_buffers(inst, if (handle_multi_stream_buffers(inst, fill_buf_done->packet_buffer1)) fill_buf_done->packet_buffer1)) dprintk(VIDC_ERR, dprintk(VIDC_ERR, Loading Loading @@ -1825,7 +1833,7 @@ static int msm_vidc_load_resources(int flipped_state, inst->state = MSM_VIDC_CORE_INVALID; inst->state = MSM_VIDC_CORE_INVALID; msm_vidc_queue_v4l2_event(inst, msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_HW_OVERLOAD); V4L2_EVENT_MSM_VIDC_HW_OVERLOAD); msm_comm_recover_from_session_error(inst); msm_comm_kill_session(inst); return -ENOMEM; return -ENOMEM; } } Loading Loading @@ -2696,7 +2704,7 @@ int msm_comm_try_get_prop(struct msm_vidc_inst *inst, enum hal_property ptype, __func__, inst, __func__, inst, SESSION_MSG_INDEX(SESSION_PROPERTY_INFO)); SESSION_MSG_INDEX(SESSION_PROPERTY_INFO)); inst->state = MSM_VIDC_CORE_INVALID; inst->state = MSM_VIDC_CORE_INVALID; msm_comm_recover_from_session_error(inst); msm_comm_kill_session(inst); rc = -EIO; rc = -EIO; goto exit; goto exit; } } Loading Loading @@ -2830,8 +2838,7 @@ int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst) mutex_lock(&inst->sync_lock); mutex_lock(&inst->sync_lock); inst->state = MSM_VIDC_CORE_INVALID; inst->state = MSM_VIDC_CORE_INVALID; mutex_unlock(&inst->sync_lock); mutex_unlock(&inst->sync_lock); msm_comm_recover_from_session_error( msm_comm_kill_session(inst); inst); } } mutex_lock(&inst->lock); mutex_lock(&inst->lock); } } Loading Loading @@ -2901,8 +2908,7 @@ int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst) mutex_lock(&inst->sync_lock); mutex_lock(&inst->sync_lock); inst->state = MSM_VIDC_CORE_INVALID; inst->state = MSM_VIDC_CORE_INVALID; mutex_unlock(&inst->sync_lock); mutex_unlock(&inst->sync_lock); msm_comm_recover_from_session_error( msm_comm_kill_session(inst); inst); } } mutex_lock(&inst->lock); mutex_lock(&inst->lock); } } Loading Loading @@ -3511,6 +3517,20 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) return rc; return rc; } } static void msm_comm_generate_session_error(struct msm_vidc_inst *inst) { enum command_response cmd = SESSION_ERROR; struct msm_vidc_cb_cmd_done response = {0}; if (!inst || !inst->core) { dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__); return; } response.session_id = inst; handle_session_error(cmd, (void *)&response); } static void msm_comm_generate_sys_error(struct msm_vidc_inst *inst) static void msm_comm_generate_sys_error(struct msm_vidc_inst *inst) { { struct msm_vidc_core *core; struct msm_vidc_core *core; Loading @@ -3525,42 +3545,55 @@ static void msm_comm_generate_sys_error(struct msm_vidc_inst *inst) handle_sys_error(cmd, (void *) &response); handle_sys_error(cmd, (void *) &response); } } int msm_comm_recover_from_session_error(struct msm_vidc_inst *inst) int msm_comm_kill_session(struct msm_vidc_inst *inst) { { struct hfi_device *hdev; int rc = 0; int rc = 0; if (!inst || !inst->core || !inst->core->device) { if (!inst || !inst->core || !inst->core->device) { dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__); dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__); return -EINVAL; return -EINVAL; } else if (!inst->session) { /* There's no hfi session to kill */ return 0; } } if (!inst->session || inst->state < MSM_VIDC_OPEN_DONE) { dprintk(VIDC_WARN, "No corresponding FW session. No need to send Abort\n"); return rc; } hdev = inst->core->device; init_completion(&inst->completions[SESSION_MSG_INDEX /* (SESSION_ABORT_DONE)]); * We're internally forcibly killing the session, if fw is aware of * the session send session_abort to firmware to clean up and release /* We have received session_error. Send session_abort to firmware * the session, else just kill the session inside the driver. * to clean up and release the session */ */ if (inst->state >= MSM_VIDC_OPEN_DONE || inst->state < MSM_VIDC_CLOSE_DONE) { struct hfi_device *hdev = inst->core->device; int abort_completion = SESSION_MSG_INDEX(SESSION_ABORT_DONE); rc = call_hfi_op(hdev, session_abort, (void *) inst->session); rc = call_hfi_op(hdev, session_abort, (void *) inst->session); if (rc) { if (rc) { dprintk(VIDC_ERR, "session_abort failed rc: %d\n", rc); dprintk(VIDC_ERR, "session_abort failed rc: %d\n", rc); return rc; return rc; } } init_completion(&inst->completions[abort_completion]); rc = wait_for_completion_timeout( rc = wait_for_completion_timeout( &inst->completions[SESSION_MSG_INDEX(SESSION_ABORT_DONE)], &inst->completions[abort_completion], msecs_to_jiffies(msm_vidc_hw_rsp_timeout)); msecs_to_jiffies(msm_vidc_hw_rsp_timeout)); if (!rc) { if (!rc) { dprintk(VIDC_ERR, "%s: Wait interrupted or timed out [%p]:%d\n", dprintk(VIDC_ERR, __func__, inst, SESSION_MSG_INDEX(SESSION_ABORT_DONE)); "%s: Wait interrupted or timed out [%p]: %d\n", __func__, inst, abort_completion); msm_comm_generate_sys_error(inst); msm_comm_generate_sys_error(inst); } else } else { change_inst_state(inst, MSM_VIDC_CLOSE_DONE); change_inst_state(inst, MSM_VIDC_CLOSE_DONE); } } else { dprintk(VIDC_WARN, "Inactive session %p, triggering an internal session error\n", inst); msm_comm_generate_session_error(inst); } return rc; return rc; } } Loading
drivers/media/platform/msm/vidc/msm_vidc_common.h +2 −2 Original line number Original line Diff line number Diff line /* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -52,7 +52,7 @@ struct hal_buffer_requirements *get_buff_req_buffer( (V4L2_CTRL_ID2CLASS(idx) == V4L2_CTRL_CLASS_MPEG) && \ (V4L2_CTRL_ID2CLASS(idx) == V4L2_CTRL_CLASS_MPEG) && \ V4L2_CTRL_DRIVER_PRIV(idx)) V4L2_CTRL_DRIVER_PRIV(idx)) int msm_comm_recover_from_session_error(struct msm_vidc_inst *inst); int msm_comm_kill_session(struct msm_vidc_inst *inst); enum multi_stream msm_comm_get_stream_output_mode(struct msm_vidc_inst *inst); enum multi_stream msm_comm_get_stream_output_mode(struct msm_vidc_inst *inst); enum hal_buffer msm_comm_get_hal_output_buffer(struct msm_vidc_inst *inst); enum hal_buffer msm_comm_get_hal_output_buffer(struct msm_vidc_inst *inst); struct msm_smem *msm_comm_smem_alloc(struct msm_vidc_inst *inst, struct msm_smem *msm_comm_smem_alloc(struct msm_vidc_inst *inst, Loading