Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fe153610 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: vidc: replace resurrect_fw with unload_fw"

parents 0c6db951 845e9210
Loading
Loading
Loading
Loading
+21 −61
Original line number Diff line number Diff line
@@ -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) {
@@ -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)
@@ -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;
	}
@@ -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);
+23 −60
Original line number Diff line number Diff line
@@ -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:
@@ -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);
@@ -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;
	}

@@ -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);
@@ -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;
@@ -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;
+0 −1
Original line number Diff line number Diff line
@@ -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);