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

Commit eeb36604 authored by Sagar Gore's avatar Sagar Gore Committed by Matt Wagantall
Browse files

msm: camera: isp: Use disable tasklet instead of kill



Apart from ISR, page faults handler for iommu can schedule
isp subdev tasklet. During camera exit, there is concurrency
with page fault handler that reschedules tasklet after tasklet
kill in close node, resulting in an invalid access to data struct.
To prevent self rescheudling add tasklet disable and tasklet
queue flush. Add counterpart, tasklet enable in init hardware
to complete pair.

Change-Id: I0a70d4563ea03127f93ab3524ab127dda61778be
Signed-off-by: default avatarSagar Gore <sgore@codeaurora.org>
parent 4b246eb6
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -490,6 +490,8 @@ 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 −1
Original line number Diff line number Diff line
@@ -284,6 +284,7 @@ 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) {
@@ -293,6 +294,7 @@ 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:
@@ -320,7 +322,8 @@ bus_scale_register_failed:
static void msm_vfe32_release_hardware(struct vfe_device *vfe_dev)
{
	free_irq(vfe_dev->vfe_irq->start, vfe_dev);
	tasklet_kill(&vfe_dev->vfe_tasklet);
	tasklet_disable(&vfe_dev->vfe_tasklet);
	msm_isp_flush_tasklet(vfe_dev);
	iounmap(vfe_dev->vfe_vbif_base);
	vfe_dev->vfe_vbif_base = NULL;
	if (vfe_dev->vfe_clk_idx == 1)
+4 −1
Original line number Diff line number Diff line
@@ -313,6 +313,7 @@ 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) {
@@ -321,6 +322,7 @@ 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:
@@ -342,7 +344,8 @@ bus_scale_register_failed:
static void msm_vfe40_release_hardware(struct vfe_device *vfe_dev)
{
	free_irq(vfe_dev->vfe_irq->start, vfe_dev);
	tasklet_kill(&vfe_dev->vfe_tasklet);
	tasklet_disable(&vfe_dev->vfe_tasklet);
	msm_isp_flush_tasklet(vfe_dev);
	iounmap(vfe_dev->vfe_vbif_base);
	vfe_dev->vfe_vbif_base = NULL;
	msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe40_clk_info,
+4 −1
Original line number Diff line number Diff line
@@ -183,6 +183,7 @@ 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) {
@@ -191,6 +192,7 @@ 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:
@@ -212,7 +214,8 @@ bus_scale_register_failed:
static void msm_vfe44_release_hardware(struct vfe_device *vfe_dev)
{
	free_irq(vfe_dev->vfe_irq->start, vfe_dev);
	tasklet_kill(&vfe_dev->vfe_tasklet);
	tasklet_disable(&vfe_dev->vfe_tasklet);
	msm_isp_flush_tasklet(vfe_dev);
	iounmap(vfe_dev->vfe_vbif_base);
	vfe_dev->vfe_vbif_base = NULL;
	msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe44_clk_info,
+4 −1
Original line number Diff line number Diff line
@@ -205,6 +205,7 @@ 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) {
@@ -213,6 +214,7 @@ 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:
@@ -234,7 +236,8 @@ bus_scale_register_failed:
static void msm_vfe46_release_hardware(struct vfe_device *vfe_dev)
{
	free_irq(vfe_dev->vfe_irq->start, vfe_dev);
	tasklet_kill(&vfe_dev->vfe_tasklet);
	tasklet_disable(&vfe_dev->vfe_tasklet);
	msm_isp_flush_tasklet(vfe_dev);
	iounmap(vfe_dev->vfe_vbif_base);
	vfe_dev->vfe_vbif_base = NULL;
	msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe46_clk_info,
Loading