Skip to content

Commit

Permalink
[media] V4L: soc-camera: call soc_camera_power_on() after adding the …
Browse files Browse the repository at this point in the history
…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: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Guennadi Liakhovetski authored and Mauro Carvalho Chehab committed Mar 20, 2012
1 parent 5da6e98 commit 7705b6d
Showing 1 changed file with 16 additions and 16 deletions.
32 changes: 16 additions & 16 deletions drivers/media/video/soc_camera.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
if (icl->reset)
icl->reset(icd->pdev);
Expand All @@ -540,6 +536,10 @@ static int soc_camera_open(struct file *file)
goto eiciadd;
}

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

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

Expand Down Expand Up @@ -1050,6 +1050,14 @@ static int soc_camera_probe(struct soc_camera_device *icd)
if (ret < 0)
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
* subdevice has not been initialised yet. We'll have to call it once
Expand All @@ -1060,14 +1068,6 @@ static int soc_camera_probe(struct soc_camera_device *icd)
if (ret < 0)
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 */
ret = video_dev_create(icd);
if (ret < 0)
Expand Down Expand Up @@ -1165,10 +1165,10 @@ static int soc_camera_probe(struct soc_camera_device *icd)
video_device_release(icd->vdev);
icd->vdev = NULL;
evdc:
ici->ops->remove(icd);
eadd:
soc_camera_power_off(icd, icl);
epower:
ici->ops->remove(icd);
eadd:
regulator_bulk_free(icl->num_regulators, icl->regulators);
ereg:
v4l2_ctrl_handler_free(&icd->ctrl_handler);
Expand Down

0 comments on commit 7705b6d

Please sign in to comment.