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

Commit 0ab1e80f authored by Karthikeyan Periasamy's avatar Karthikeyan Periasamy
Browse files

msm: vidc: fix the interrupt miss issue from video hardware



enable_irq() called before processing responses in work handler
which would lead to miss interrupt from video hardware sometimes.
An interrupt from video h/w will queue the work to work handler
but if work is already running the new work is not posted.
work handler has two parts, one, read all the messages from video h/w,
two, process the messages. queue work while processing messages
will miss reading the new messages from video h/w because
the queue work (as a result of interrupt from video h/w) will not
actually queue the work as work handler already running. Fix the
issue by enabling irq after processing all the responses to
makesure interrupt coming from video h/w after work handler
completed processing the messages.

CRs-Fixed: 1086284
Change-Id: Id158e5c6d89fc8b761d8cfe92afbf3592877c556
Signed-off-by: default avatarKarthikeyan Periasamy <kperiasa@codeaurora.org>
parent 61f26e3a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -5359,10 +5359,10 @@ static void msm_comm_print_debug_info(struct msm_vidc_inst *inst)

	dprintk(VIDC_ERR, "Venus core frequency = %lu",
		msm_comm_get_clock_rate(core));
	mutex_lock(&core->lock);
	dprintk(VIDC_ERR, "Printing instance info that caused Error\n");
	msm_comm_print_inst_info(inst);
	dprintk(VIDC_ERR, "Printing remaining instances info\n");
	mutex_lock(&core->lock);
	list_for_each_entry(temp, &core->instances, list) {
		/* inst already printed above. Hence don't repeat.*/
		if (temp == inst)
+9 −5
Original line number Diff line number Diff line
@@ -75,7 +75,7 @@ const struct msm_vidc_gov_data DEFAULT_BUS_VOTE = {
	.imem_size = 0,
};

const int max_packets = 250;
const int max_packets = 1000;

static void venus_hfi_pm_handler(struct work_struct *work);
static DECLARE_DELAYED_WORK(venus_hfi_pm_work, venus_hfi_pm_handler);
@@ -3576,6 +3576,7 @@ static void venus_hfi_core_work_handler(struct work_struct *work)
	struct venus_hfi_device *device = list_first_entry(
		&hal_ctxt.dev_head, struct venus_hfi_device, list);
	int num_responses = 0, i = 0;
	u32 intr_status;

	mutex_lock(&device->lock);

@@ -3601,10 +3602,9 @@ static void venus_hfi_core_work_handler(struct work_struct *work)
	num_responses = __response_handler(device);

err_no_work:
	/* We need re-enable the irq which was disabled in ISR handler */
	if (!(device->intr_status & VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK))
		enable_irq(device->hal_data->irq);

	/* Keep the interrupt status before releasing device lock */
	intr_status = device->intr_status;
	mutex_unlock(&device->lock);

	/*
@@ -3619,6 +3619,10 @@ err_no_work:
		device->callback(r->response_type, &r->response);
	}

	/* We need re-enable the irq which was disabled in ISR handler */
	if (!(intr_status & VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK))
		enable_irq(device->hal_data->irq);

	/*
	 * XXX: Don't add any code beyond here.  Reacquiring locks after release
	 * it above doesn't guarantee the atomicity that we're aiming for.
@@ -4548,7 +4552,7 @@ static struct venus_hfi_device *__add_device(u32 device_id,
	}

	hdevice->response_pkt = kmalloc_array(max_packets,
				sizeof(*hdevice->response_pkt), GFP_TEMPORARY);
				sizeof(*hdevice->response_pkt), GFP_KERNEL);
	if (!hdevice->response_pkt) {
		dprintk(VIDC_ERR, "failed to allocate response_pkt\n");
		goto err_cleanup;