Loading drivers/media/platform/msm/vidc/msm_vidc_common.c +21 −61 Original line number Diff line number Diff line Loading @@ -1248,53 +1248,12 @@ struct sys_err_handler_data { struct delayed_work work; }; void hw_sys_error_handler(struct work_struct *work) { struct msm_vidc_core *core = NULL; struct hfi_device *hdev = NULL; struct sys_err_handler_data *handler = NULL; int rc = 0; handler = container_of(work, struct sys_err_handler_data, work.work); if (!handler || !handler->core || !handler->core->device) { dprintk(VIDC_ERR, "%s - invalid work or core handle\n", __func__); goto exit; } core = handler->core; hdev = core->device; mutex_lock(&core->lock); /* * Restart the firmware to bring out of bad state. */ if (core->state == VIDC_CORE_INVALID && hdev->resurrect_fw) { rc = call_hfi_op(hdev, resurrect_fw, hdev->hfi_device_data); if (rc) { dprintk(VIDC_ERR, "%s - resurrect_fw failed: %d\n", __func__, rc); } core->state = VIDC_CORE_LOADED; } else { dprintk(VIDC_DBG, "fw unloaded after sys error, no need to resurrect\n"); } mutex_unlock(&core->lock); exit: /* free sys error handler, allocated in handle_sys_err */ kfree(handler); } static void handle_sys_error(enum hal_command_response cmd, void *data) { struct msm_vidc_cb_cmd_done *response = data; struct msm_vidc_core *core = NULL; struct sys_err_handler_data *handler = NULL; struct hfi_device *hdev = NULL; int rc = 0; subsystem_crashed("venus"); if (!response) { Loading @@ -1313,23 +1272,22 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) dprintk(VIDC_WARN, "SYS_ERROR %d received for core %p\n", cmd, core); msm_comm_clean_notify_client(core); handler = kzalloc(sizeof(*handler), GFP_KERNEL); if (!handler) { dprintk(VIDC_ERR, "%s - failed to allocate sys error handler\n", __func__); hdev = core->device; mutex_lock(&core->lock); if (core->state == VIDC_CORE_INVALID) { dprintk(VIDC_DBG, "Calling core_release\n"); rc = call_hfi_op(hdev, core_release, hdev->hfi_device_data); if (rc) { dprintk(VIDC_ERR, "core_release failed\n"); mutex_unlock(&core->lock); return; } handler->core = core; INIT_DELAYED_WORK(&handler->work, hw_sys_error_handler); /* * Sleep for 5 sec to ensure venus has completed any * pending cache operations. Without this sleep, we see * device reset when firmware is unloaded after a sys * error. */ schedule_delayed_work(&handler->work, msecs_to_jiffies(5000)); core->state = VIDC_CORE_UNINIT; call_hfi_op(hdev, unload_fw, hdev->hfi_device_data); dprintk(VIDC_DBG, "Firmware unloaded\n"); } mutex_unlock(&core->lock); } void msm_comm_session_clean(struct msm_vidc_inst *inst) Loading Loading @@ -3356,7 +3314,8 @@ int msm_comm_qbuf(struct msm_vidc_inst *inst, struct vb2_buffer *vb) hdev = core->device; if (inst->state == MSM_VIDC_CORE_INVALID || core->state == VIDC_CORE_INVALID) { core->state == VIDC_CORE_INVALID || core->state == VIDC_CORE_UNINIT) { dprintk(VIDC_ERR, "Core is in bad state. Can't Queue\n"); return -EINVAL; } Loading Loading @@ -4202,7 +4161,8 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) msm_comm_flush_dynamic_buffers(inst); if (inst->state == MSM_VIDC_CORE_INVALID || core->state == VIDC_CORE_INVALID) { core->state == VIDC_CORE_INVALID || core->state == VIDC_CORE_UNINIT) { dprintk(VIDC_ERR, "Core %p and inst %p are in bad state\n", core, inst); Loading drivers/media/platform/msm/vidc/venus_hfi.c +23 −60 Original line number Diff line number Diff line Loading @@ -900,13 +900,16 @@ static int __vote_buses(struct venus_hfi_device *device, device->bus_vote.imem_size = device->res->imem_size; venus_hfi_for_each_bus(device, bus) { if (bus && bus->devfreq) { /* NOP if already resume */ rc = devfreq_resume_device(bus->devfreq); if (rc) goto err_no_mem; /* Kick devfreq awake incase _resume() didn't do it */ bus->devfreq->nb.notifier_call(&bus->devfreq->nb, 0, NULL); bus->devfreq->nb.notifier_call( &bus->devfreq->nb, 0, NULL); } } err_no_mem: Loading Loading @@ -2349,11 +2352,13 @@ static int __core_release(struct venus_hfi_device *device) return -EIO; } if (device->state != VENUS_STATE_DEINIT) { rc = __unset_free_imem(device); if (rc) dprintk(VIDC_ERR, "Failed to unset and free imem in core release: %d\n", rc); } if (!(device->intr_status & VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK)) disable_irq_nosync(device->hal_data->irq); Loading Loading @@ -3496,16 +3501,19 @@ static struct hal_session *__get_session(struct venus_hfi_device *device, static int __response_handler(struct venus_hfi_device *device) { struct msm_vidc_cb_info *packets = device->response_pkt; struct msm_vidc_cb_info *packets; int packet_count = 0; u8 *raw_packet = NULL; if (!device || device->state != VENUS_STATE_INIT) return 0; packets = device->response_pkt; raw_packet = kzalloc(VIDC_IFACEQ_VAR_HUGE_PKT_SIZE, GFP_TEMPORARY); if (!raw_packet || !packets) { dprintk(VIDC_ERR, "%s: Failed to allocate memory\n", __func__); kfree(raw_packet); kfree(packets); return 0; } Loading Loading @@ -4378,7 +4386,6 @@ static void __unload_fw(struct venus_hfi_device *device) if (!device->resources.fw.cookie) return; flush_workqueue(device->vidc_workq); cancel_delayed_work(&venus_hfi_pm_work); if (device->state != VENUS_STATE_DEINIT) flush_workqueue(device->venus_pm_workq); Loading Loading @@ -4412,49 +4419,6 @@ static void venus_hfi_unload_fw(void *dev) mutex_unlock(&device->lock); } static int venus_hfi_resurrect_fw(void *dev) { struct venus_hfi_device *device = dev; int rc = 0; if (!device) { dprintk(VIDC_ERR, "%s Invalid paramter: %p\n", __func__, device); return -EINVAL; } mutex_lock(&device->lock); rc = __core_release(device); if (rc) { dprintk(VIDC_ERR, "%s - failed to release venus core rc = %d\n", __func__, rc); goto exit; } dprintk(VIDC_ERR, "praying for firmware resurrection\n"); __unload_fw(device); rc = __vote_buses(device, device->bus_vote.data, device->bus_vote.data_count); if (rc) { dprintk(VIDC_ERR, "Failed to scale buses\n"); goto exit; } rc = __load_fw(device); if (rc) { dprintk(VIDC_ERR, "%s - failed to load venus fw rc = %d\n", __func__, rc); goto exit; } dprintk(VIDC_ERR, "Hurray!! firmware has restarted\n"); exit: mutex_unlock(&device->lock); return rc; } static int venus_hfi_get_fw_info(void *dev, enum fw_info info) { int rc = 0; Loading Loading @@ -4687,7 +4651,6 @@ static void venus_init_hfi_callbacks(struct hfi_device *hdev) hdev->unvote_bus = venus_hfi_unvote_buses; hdev->load_fw = venus_hfi_load_fw; hdev->unload_fw = venus_hfi_unload_fw; hdev->resurrect_fw = venus_hfi_resurrect_fw; hdev->get_fw_info = venus_hfi_get_fw_info; hdev->get_core_capabilities = venus_hfi_get_core_capabilities; hdev->resume = venus_hfi_resume; Loading drivers/media/platform/msm/vidc/vidc_hfi_api.h +0 −1 Original line number Diff line number Diff line Loading @@ -1440,7 +1440,6 @@ struct hfi_device { int (*unvote_bus)(void *dev); int (*load_fw)(void *dev); void (*unload_fw)(void *dev); int (*resurrect_fw)(void *dev); int (*get_fw_info)(void *dev, enum fw_info info); int (*session_clean)(void *sess); int (*get_core_capabilities)(void *dev); Loading Loading
drivers/media/platform/msm/vidc/msm_vidc_common.c +21 −61 Original line number Diff line number Diff line Loading @@ -1248,53 +1248,12 @@ struct sys_err_handler_data { struct delayed_work work; }; void hw_sys_error_handler(struct work_struct *work) { struct msm_vidc_core *core = NULL; struct hfi_device *hdev = NULL; struct sys_err_handler_data *handler = NULL; int rc = 0; handler = container_of(work, struct sys_err_handler_data, work.work); if (!handler || !handler->core || !handler->core->device) { dprintk(VIDC_ERR, "%s - invalid work or core handle\n", __func__); goto exit; } core = handler->core; hdev = core->device; mutex_lock(&core->lock); /* * Restart the firmware to bring out of bad state. */ if (core->state == VIDC_CORE_INVALID && hdev->resurrect_fw) { rc = call_hfi_op(hdev, resurrect_fw, hdev->hfi_device_data); if (rc) { dprintk(VIDC_ERR, "%s - resurrect_fw failed: %d\n", __func__, rc); } core->state = VIDC_CORE_LOADED; } else { dprintk(VIDC_DBG, "fw unloaded after sys error, no need to resurrect\n"); } mutex_unlock(&core->lock); exit: /* free sys error handler, allocated in handle_sys_err */ kfree(handler); } static void handle_sys_error(enum hal_command_response cmd, void *data) { struct msm_vidc_cb_cmd_done *response = data; struct msm_vidc_core *core = NULL; struct sys_err_handler_data *handler = NULL; struct hfi_device *hdev = NULL; int rc = 0; subsystem_crashed("venus"); if (!response) { Loading @@ -1313,23 +1272,22 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) dprintk(VIDC_WARN, "SYS_ERROR %d received for core %p\n", cmd, core); msm_comm_clean_notify_client(core); handler = kzalloc(sizeof(*handler), GFP_KERNEL); if (!handler) { dprintk(VIDC_ERR, "%s - failed to allocate sys error handler\n", __func__); hdev = core->device; mutex_lock(&core->lock); if (core->state == VIDC_CORE_INVALID) { dprintk(VIDC_DBG, "Calling core_release\n"); rc = call_hfi_op(hdev, core_release, hdev->hfi_device_data); if (rc) { dprintk(VIDC_ERR, "core_release failed\n"); mutex_unlock(&core->lock); return; } handler->core = core; INIT_DELAYED_WORK(&handler->work, hw_sys_error_handler); /* * Sleep for 5 sec to ensure venus has completed any * pending cache operations. Without this sleep, we see * device reset when firmware is unloaded after a sys * error. */ schedule_delayed_work(&handler->work, msecs_to_jiffies(5000)); core->state = VIDC_CORE_UNINIT; call_hfi_op(hdev, unload_fw, hdev->hfi_device_data); dprintk(VIDC_DBG, "Firmware unloaded\n"); } mutex_unlock(&core->lock); } void msm_comm_session_clean(struct msm_vidc_inst *inst) Loading Loading @@ -3356,7 +3314,8 @@ int msm_comm_qbuf(struct msm_vidc_inst *inst, struct vb2_buffer *vb) hdev = core->device; if (inst->state == MSM_VIDC_CORE_INVALID || core->state == VIDC_CORE_INVALID) { core->state == VIDC_CORE_INVALID || core->state == VIDC_CORE_UNINIT) { dprintk(VIDC_ERR, "Core is in bad state. Can't Queue\n"); return -EINVAL; } Loading Loading @@ -4202,7 +4161,8 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) msm_comm_flush_dynamic_buffers(inst); if (inst->state == MSM_VIDC_CORE_INVALID || core->state == VIDC_CORE_INVALID) { core->state == VIDC_CORE_INVALID || core->state == VIDC_CORE_UNINIT) { dprintk(VIDC_ERR, "Core %p and inst %p are in bad state\n", core, inst); Loading
drivers/media/platform/msm/vidc/venus_hfi.c +23 −60 Original line number Diff line number Diff line Loading @@ -900,13 +900,16 @@ static int __vote_buses(struct venus_hfi_device *device, device->bus_vote.imem_size = device->res->imem_size; venus_hfi_for_each_bus(device, bus) { if (bus && bus->devfreq) { /* NOP if already resume */ rc = devfreq_resume_device(bus->devfreq); if (rc) goto err_no_mem; /* Kick devfreq awake incase _resume() didn't do it */ bus->devfreq->nb.notifier_call(&bus->devfreq->nb, 0, NULL); bus->devfreq->nb.notifier_call( &bus->devfreq->nb, 0, NULL); } } err_no_mem: Loading Loading @@ -2349,11 +2352,13 @@ static int __core_release(struct venus_hfi_device *device) return -EIO; } if (device->state != VENUS_STATE_DEINIT) { rc = __unset_free_imem(device); if (rc) dprintk(VIDC_ERR, "Failed to unset and free imem in core release: %d\n", rc); } if (!(device->intr_status & VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK)) disable_irq_nosync(device->hal_data->irq); Loading Loading @@ -3496,16 +3501,19 @@ static struct hal_session *__get_session(struct venus_hfi_device *device, static int __response_handler(struct venus_hfi_device *device) { struct msm_vidc_cb_info *packets = device->response_pkt; struct msm_vidc_cb_info *packets; int packet_count = 0; u8 *raw_packet = NULL; if (!device || device->state != VENUS_STATE_INIT) return 0; packets = device->response_pkt; raw_packet = kzalloc(VIDC_IFACEQ_VAR_HUGE_PKT_SIZE, GFP_TEMPORARY); if (!raw_packet || !packets) { dprintk(VIDC_ERR, "%s: Failed to allocate memory\n", __func__); kfree(raw_packet); kfree(packets); return 0; } Loading Loading @@ -4378,7 +4386,6 @@ static void __unload_fw(struct venus_hfi_device *device) if (!device->resources.fw.cookie) return; flush_workqueue(device->vidc_workq); cancel_delayed_work(&venus_hfi_pm_work); if (device->state != VENUS_STATE_DEINIT) flush_workqueue(device->venus_pm_workq); Loading Loading @@ -4412,49 +4419,6 @@ static void venus_hfi_unload_fw(void *dev) mutex_unlock(&device->lock); } static int venus_hfi_resurrect_fw(void *dev) { struct venus_hfi_device *device = dev; int rc = 0; if (!device) { dprintk(VIDC_ERR, "%s Invalid paramter: %p\n", __func__, device); return -EINVAL; } mutex_lock(&device->lock); rc = __core_release(device); if (rc) { dprintk(VIDC_ERR, "%s - failed to release venus core rc = %d\n", __func__, rc); goto exit; } dprintk(VIDC_ERR, "praying for firmware resurrection\n"); __unload_fw(device); rc = __vote_buses(device, device->bus_vote.data, device->bus_vote.data_count); if (rc) { dprintk(VIDC_ERR, "Failed to scale buses\n"); goto exit; } rc = __load_fw(device); if (rc) { dprintk(VIDC_ERR, "%s - failed to load venus fw rc = %d\n", __func__, rc); goto exit; } dprintk(VIDC_ERR, "Hurray!! firmware has restarted\n"); exit: mutex_unlock(&device->lock); return rc; } static int venus_hfi_get_fw_info(void *dev, enum fw_info info) { int rc = 0; Loading Loading @@ -4687,7 +4651,6 @@ static void venus_init_hfi_callbacks(struct hfi_device *hdev) hdev->unvote_bus = venus_hfi_unvote_buses; hdev->load_fw = venus_hfi_load_fw; hdev->unload_fw = venus_hfi_unload_fw; hdev->resurrect_fw = venus_hfi_resurrect_fw; hdev->get_fw_info = venus_hfi_get_fw_info; hdev->get_core_capabilities = venus_hfi_get_core_capabilities; hdev->resume = venus_hfi_resume; Loading
drivers/media/platform/msm/vidc/vidc_hfi_api.h +0 −1 Original line number Diff line number Diff line Loading @@ -1440,7 +1440,6 @@ struct hfi_device { int (*unvote_bus)(void *dev); int (*load_fw)(void *dev); void (*unload_fw)(void *dev); int (*resurrect_fw)(void *dev); int (*get_fw_info)(void *dev, enum fw_info info); int (*session_clean)(void *sess); int (*get_core_capabilities)(void *dev); Loading