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

Commit 27cb30fa 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 334902b8 0173bd6e
Loading
Loading
Loading
Loading
+34 −65
Original line number Diff line number Diff line
@@ -1084,54 +1084,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 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) {
@@ -1149,24 +1107,25 @@ static void handle_sys_error(enum 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");
		msm_comm_unvote_buses(core);
	}
	mutex_unlock(&core->lock);

}

void msm_comm_session_clean(struct msm_vidc_inst *inst)
@@ -3031,7 +2990,8 @@ int msm_comm_qbuf(struct vb2_buffer *vb)
	}

	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;
	}
@@ -3836,8 +3796,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_UNINIT ||
		core->state == VIDC_CORE_INVALID) {
		dprintk(VIDC_ERR,
				"Core %p and inst %p are in bad state\n",
@@ -4330,10 +4290,12 @@ void msm_comm_smem_free(struct msm_vidc_inst *inst, struct msm_smem *mem)
			"%s: invalid params: %p %p\n", __func__, inst, mem);
		return;
	}

	mutex_lock(&inst->core->lock);
	if (inst->state != MSM_VIDC_CORE_INVALID) {
		if (power_on_for_smem(inst))
			goto err_power_on;

	}
	msm_smem_free(inst->mem_client, mem);
err_power_on:
	mutex_unlock(&inst->core->lock);
@@ -4359,6 +4321,13 @@ struct msm_smem *msm_comm_smem_user_to_kernel(struct msm_vidc_inst *inst,
		dprintk(VIDC_ERR, "%s: invalid inst: %p\n", __func__, inst);
		return NULL;
	}

	if (inst->state == MSM_VIDC_CORE_INVALID) {
		dprintk(VIDC_ERR, "Core in Invalid state, returning from %s\n",
			__func__);
		return NULL;
	}

	mutex_lock(&inst->core->lock);
	if (power_on_for_smem(inst))
		goto err_power_on;
+23 −51
Original line number Diff line number Diff line
@@ -2412,13 +2412,16 @@ static int venus_hfi_core_release(void *device)
					"%s: Power enable failed\n", __func__);
			return -EIO;
		}
		if (dev->state != VENUS_STATE_DEINIT) {
			mutex_lock(&dev->resource_lock);
			rc = __unset_free_ocmem(dev);
			mutex_unlock(&dev->resource_lock);

			if (rc)
				dprintk(VIDC_ERR,
					"Failed to unset and free OCMEM in core release, rc : %d\n",
					rc);
					"Failed in unset_free_ocmem() in %s, rc : %d\n",
					__func__, rc);
		}
		venus_hfi_write_register(dev, VIDC_CPU_CS_SCIACMDARG3, 0);
		if (!(dev->intr_status & VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK))
			disable_irq_nosync(dev->hal_data->irq);
@@ -3325,7 +3328,8 @@ static void venus_hfi_response_handler(struct venus_hfi_device *device)
		return;
	}
	dprintk(VIDC_INFO, "#####venus_hfi_response_handler#####\n");
	if (device) {
	/* Process messages only if device is in valid state*/
	if (device && device->state != VENUS_STATE_DEINIT) {
		if ((device->intr_status &
			VIDC_WRAPPER_INTR_CLEAR_A2HWD_BMSK)) {
			dprintk(VIDC_ERR, "Received: Watchdog timeout %s\n",
@@ -3340,6 +3344,16 @@ static void venus_hfi_response_handler(struct venus_hfi_device *device)
		}

		while (!venus_hfi_iface_msgq_read(device, packet)) {
			/* During SYS_ERROR processing the device state
			*  will be changed to DEINIT. Below check will
			*  make sure no messages messages are read or
			*  processed after processing SYS_ERROR
			*/
			if (device->state == VENUS_STATE_DEINIT) {
				dprintk(VIDC_ERR,
					"core DEINIT'd, stopping q reads\n");
				break;
			}
			rc = hfi_process_msg_packet(device->callback,
				device->device_id,
				(struct vidc_hal_msg_pkt_hdr *) packet,
@@ -4128,7 +4142,6 @@ static void venus_hfi_unload_fw(void *dev)
		return;
	}
	if (device->resources.fw.cookie) {
		flush_workqueue(device->vidc_workq);
		cancel_delayed_work(&venus_hfi_pm_work);
		flush_workqueue(device->venus_pm_workq);
		subsystem_put(device->resources.fw.cookie);
@@ -4148,46 +4161,6 @@ static void venus_hfi_unload_fw(void *dev)
	}
}

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;
	}

	rc = venus_hfi_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");
	venus_hfi_unload_fw(device);

	rc = venus_hfi_vote_buses(device, device->bus_load.vote_data,
			device->bus_load.vote_data_count);
	if (rc) {
		dprintk(VIDC_ERR, "Failed to scale buses\n");
		goto exit;
	}

	rc = venus_hfi_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:
	return rc;
}

static int venus_hfi_get_fw_info(void *dev, enum fw_info info)
{
	int rc = 0;
@@ -4460,7 +4433,6 @@ static void venus_init_hfi_callbacks(struct hfi_device *hdev)
	hdev->iommu_get_domain_partition = venus_hfi_iommu_get_domain_partition;
	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_stride_scanline = venus_hfi_get_stride_scanline;
	hdev->get_core_capabilities = venus_hfi_get_core_capabilities;
+0 −1
Original line number Diff line number Diff line
@@ -1348,7 +1348,6 @@ struct hfi_device {
			int *domain_num, int *partition_num);
	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 (*get_stride_scanline)(int color_fmt, int width,
		int height,	int *stride, int *scanlines);