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

Commit aae6c43c authored by Peter Liu's avatar Peter Liu Committed by Gerrit - the friendly Code Review server
Browse files

msm: camera: isp: Fix tasklet and irq handling



Use tasklet kill instead of tasklet disable
to avoid CPU busy waiting.

Besides, mask out all irq mask and do irq disable
to make sure tasklet will not reschedule itself.

Change-Id: Ie980ef0cb183215ccd4f7c7788c6cab083929250
Signed-off-by: default avatarPeter Liu <pingchie@codeaurora.org>
parent 3380d16c
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -497,8 +497,6 @@ static int vfe_probe(struct platform_device *pdev)
	tasklet_init(&vfe_dev->vfe_tasklet,
		msm_isp_do_tasklet, (unsigned long)vfe_dev);

	/* init hardware will enable it back */
	tasklet_disable(&vfe_dev->vfe_tasklet);
	v4l2_subdev_init(&vfe_dev->subdev.sd, vfe_dev->hw_info->subdev_ops);
	vfe_dev->subdev.sd.internal_ops =
		vfe_dev->hw_info->subdev_internal_ops;
+4 −3
Original line number Diff line number Diff line
@@ -285,7 +285,6 @@ static int msm_vfe32_init_hardware(struct vfe_device *vfe_dev)
		goto vbif_remap_failed;
	}

	tasklet_enable(&vfe_dev->vfe_tasklet);
	rc = request_irq(vfe_dev->vfe_irq->start, msm_isp_process_irq,
					 IRQF_TRIGGER_RISING, "vfe", vfe_dev);
	if (rc < 0) {
@@ -295,7 +294,6 @@ static int msm_vfe32_init_hardware(struct vfe_device *vfe_dev)

	return rc;
irq_req_failed:
	tasklet_disable(&vfe_dev->vfe_tasklet);
	iounmap(vfe_dev->vfe_vbif_base);
	vfe_dev->vfe_vbif_base = NULL;
vbif_remap_failed:
@@ -322,8 +320,11 @@ bus_scale_register_failed:

static void msm_vfe32_release_hardware(struct vfe_device *vfe_dev)
{
	msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x1C);
	msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x20);
	disable_irq(vfe_dev->vfe_irq->start);
	free_irq(vfe_dev->vfe_irq->start, vfe_dev);
	tasklet_disable(&vfe_dev->vfe_tasklet);
	tasklet_kill(&vfe_dev->vfe_tasklet);
	msm_isp_flush_tasklet(vfe_dev);
	iounmap(vfe_dev->vfe_vbif_base);
	vfe_dev->vfe_vbif_base = NULL;
+6 −3
Original line number Diff line number Diff line
@@ -316,7 +316,6 @@ static int msm_vfe40_init_hardware(struct vfe_device *vfe_dev)
		goto vbif_remap_failed;
	}

	tasklet_enable(&vfe_dev->vfe_tasklet);
	rc = request_irq(vfe_dev->vfe_irq->start, msm_isp_process_irq,
		IRQF_TRIGGER_RISING, "vfe", vfe_dev);
	if (rc < 0) {
@@ -325,7 +324,6 @@ static int msm_vfe40_init_hardware(struct vfe_device *vfe_dev)
	}
	return rc;
irq_req_failed:
	tasklet_disable(&vfe_dev->vfe_tasklet);
	iounmap(vfe_dev->vfe_vbif_base);
	vfe_dev->vfe_vbif_base = NULL;
vbif_remap_failed:
@@ -346,8 +344,13 @@ bus_scale_register_failed:

static void msm_vfe40_release_hardware(struct vfe_device *vfe_dev)
{
	/* disable all mask before tasklet kill */
	msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x28);
	msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x2C);

	disable_irq(vfe_dev->vfe_irq->start);
	free_irq(vfe_dev->vfe_irq->start, vfe_dev);
	tasklet_disable(&vfe_dev->vfe_tasklet);
	tasklet_kill(&vfe_dev->vfe_tasklet);
	msm_isp_flush_tasklet(vfe_dev);
	iounmap(vfe_dev->vfe_vbif_base);
	vfe_dev->vfe_vbif_base = NULL;
+4 −3
Original line number Diff line number Diff line
@@ -184,7 +184,6 @@ static int msm_vfe44_init_hardware(struct vfe_device *vfe_dev)
		goto vbif_remap_failed;
	}

	tasklet_enable(&vfe_dev->vfe_tasklet);
	rc = request_irq(vfe_dev->vfe_irq->start, msm_isp_process_irq,
		IRQF_TRIGGER_RISING, "vfe", vfe_dev);
	if (rc < 0) {
@@ -193,7 +192,6 @@ static int msm_vfe44_init_hardware(struct vfe_device *vfe_dev)
	}
	return rc;
irq_req_failed:
	tasklet_disable(&vfe_dev->vfe_tasklet);
	iounmap(vfe_dev->vfe_vbif_base);
	vfe_dev->vfe_vbif_base = NULL;
vbif_remap_failed:
@@ -214,8 +212,11 @@ bus_scale_register_failed:

static void msm_vfe44_release_hardware(struct vfe_device *vfe_dev)
{
	msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x28);
	msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x2C);
	disable_irq(vfe_dev->vfe_irq->start);
	free_irq(vfe_dev->vfe_irq->start, vfe_dev);
	tasklet_disable(&vfe_dev->vfe_tasklet);
	tasklet_kill(&vfe_dev->vfe_tasklet);
	msm_isp_flush_tasklet(vfe_dev);
	iounmap(vfe_dev->vfe_vbif_base);
	vfe_dev->vfe_vbif_base = NULL;
+6 −3
Original line number Diff line number Diff line
@@ -206,7 +206,6 @@ static int msm_vfe46_init_hardware(struct vfe_device *vfe_dev)
		goto vbif_remap_failed;
	}

	tasklet_enable(&vfe_dev->vfe_tasklet);
	rc = request_irq(vfe_dev->vfe_irq->start, msm_isp_process_irq,
		IRQF_TRIGGER_RISING, "vfe", vfe_dev);
	if (rc < 0) {
@@ -215,7 +214,6 @@ static int msm_vfe46_init_hardware(struct vfe_device *vfe_dev)
	}
	return rc;
irq_req_failed:
	tasklet_disable(&vfe_dev->vfe_tasklet);
	iounmap(vfe_dev->vfe_vbif_base);
	vfe_dev->vfe_vbif_base = NULL;
vbif_remap_failed:
@@ -236,8 +234,13 @@ bus_scale_register_failed:

static void msm_vfe46_release_hardware(struct vfe_device *vfe_dev)
{
	/* when closing node, disable all irq */
	msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x5C);
	msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x60);

	disable_irq(vfe_dev->vfe_irq->start);
	free_irq(vfe_dev->vfe_irq->start, vfe_dev);
	tasklet_disable(&vfe_dev->vfe_tasklet);
	tasklet_kill(&vfe_dev->vfe_tasklet);
	msm_isp_flush_tasklet(vfe_dev);
	iounmap(vfe_dev->vfe_vbif_base);
	vfe_dev->vfe_vbif_base = NULL;
Loading