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

Commit 7705b6d8 authored by Guennadi Liakhovetski's avatar Guennadi Liakhovetski Committed by Mauro Carvalho Chehab
Browse files

[media] V4L: soc-camera: call soc_camera_power_on() after adding the client to the host



soc_camera_power_on() calls client's .s_power(1) method, which can try to
access the client hardware. This, however, is typically only possible,
after calling host's .add() method, because that's where the host driver
usually turns the master clock on.

Signed-off-by: default avatarGuennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 5da6e984
Loading
Loading
Loading
Loading
+16 −16
Original line number Original line Diff line number Diff line
@@ -526,10 +526,6 @@ static int soc_camera_open(struct file *file)
			},
			},
		};
		};


		ret = soc_camera_power_on(icd, icl);
		if (ret < 0)
			goto epower;

		/* The camera could have been already on, try to reset */
		/* The camera could have been already on, try to reset */
		if (icl->reset)
		if (icl->reset)
			icl->reset(icd->pdev);
			icl->reset(icd->pdev);
@@ -540,6 +536,10 @@ static int soc_camera_open(struct file *file)
			goto eiciadd;
			goto eiciadd;
		}
		}


		ret = soc_camera_power_on(icd, icl);
		if (ret < 0)
			goto epower;

		pm_runtime_enable(&icd->vdev->dev);
		pm_runtime_enable(&icd->vdev->dev);
		ret = pm_runtime_resume(&icd->vdev->dev);
		ret = pm_runtime_resume(&icd->vdev->dev);
		if (ret < 0 && ret != -ENOSYS)
		if (ret < 0 && ret != -ENOSYS)
@@ -578,10 +578,10 @@ static int soc_camera_open(struct file *file)
esfmt:
esfmt:
	pm_runtime_disable(&icd->vdev->dev);
	pm_runtime_disable(&icd->vdev->dev);
eresume:
eresume:
	ici->ops->remove(icd);
eiciadd:
	soc_camera_power_off(icd, icl);
	soc_camera_power_off(icd, icl);
epower:
epower:
	ici->ops->remove(icd);
eiciadd:
	icd->use_count--;
	icd->use_count--;
	module_put(ici->ops->owner);
	module_put(ici->ops->owner);


@@ -1050,6 +1050,14 @@ static int soc_camera_probe(struct soc_camera_device *icd)
	if (ret < 0)
	if (ret < 0)
		goto ereg;
		goto ereg;


	/* The camera could have been already on, try to reset */
	if (icl->reset)
		icl->reset(icd->pdev);

	ret = ici->ops->add(icd);
	if (ret < 0)
		goto eadd;

	/*
	/*
	 * This will not yet call v4l2_subdev_core_ops::s_power(1), because the
	 * This will not yet call v4l2_subdev_core_ops::s_power(1), because the
	 * subdevice has not been initialised yet. We'll have to call it once
	 * subdevice has not been initialised yet. We'll have to call it once
@@ -1060,14 +1068,6 @@ static int soc_camera_probe(struct soc_camera_device *icd)
	if (ret < 0)
	if (ret < 0)
		goto epower;
		goto epower;


	/* The camera could have been already on, try to reset */
	if (icl->reset)
		icl->reset(icd->pdev);

	ret = ici->ops->add(icd);
	if (ret < 0)
		goto eadd;

	/* Must have icd->vdev before registering the device */
	/* Must have icd->vdev before registering the device */
	ret = video_dev_create(icd);
	ret = video_dev_create(icd);
	if (ret < 0)
	if (ret < 0)
@@ -1165,10 +1165,10 @@ static int soc_camera_probe(struct soc_camera_device *icd)
	video_device_release(icd->vdev);
	video_device_release(icd->vdev);
	icd->vdev = NULL;
	icd->vdev = NULL;
evdc:
evdc:
	ici->ops->remove(icd);
eadd:
	soc_camera_power_off(icd, icl);
	soc_camera_power_off(icd, icl);
epower:
epower:
	ici->ops->remove(icd);
eadd:
	regulator_bulk_free(icl->num_regulators, icl->regulators);
	regulator_bulk_free(icl->num_regulators, icl->regulators);
ereg:
ereg:
	v4l2_ctrl_handler_free(&icd->ctrl_handler);
	v4l2_ctrl_handler_free(&icd->ctrl_handler);