return false;
}
-int sun6i_csi_set_power(struct sun6i_csi_device *csi_dev, bool enable)
-{
- struct device *dev = csi_dev->dev;
- struct regmap *regmap = csi_dev->regmap;
- int ret;
-
- if (!enable) {
- regmap_update_bits(regmap, SUN6I_CSI_EN_REG,
- SUN6I_CSI_EN_CSI_EN, 0);
- pm_runtime_put(dev);
-
- return 0;
- }
-
- ret = pm_runtime_resume_and_get(dev);
- if (ret < 0)
- return ret;
-
- regmap_update_bits(regmap, SUN6I_CSI_EN_REG, SUN6I_CSI_EN_CSI_EN,
- SUN6I_CSI_EN_CSI_EN);
-
- return 0;
-}
-
static enum csi_input_fmt get_csi_input_format(struct sun6i_csi_device *csi_dev,
u32 mbus_code, u32 pixformat)
{
*/
#include <linux/of.h>
+#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <media/v4l2-device.h>
{
struct regmap *regmap = csi_dev->regmap;
+ regmap_update_bits(regmap, SUN6I_CSI_EN_REG, SUN6I_CSI_EN_CSI_EN,
+ SUN6I_CSI_EN_CSI_EN);
+
regmap_update_bits(regmap, SUN6I_CSI_CAP_REG, SUN6I_CSI_CAP_VCAP_ON,
SUN6I_CSI_CAP_VCAP_ON);
}
struct regmap *regmap = csi_dev->regmap;
regmap_update_bits(regmap, SUN6I_CSI_CAP_REG, SUN6I_CSI_CAP_VCAP_ON, 0);
+ regmap_update_bits(regmap, SUN6I_CSI_EN_REG, SUN6I_CSI_EN_CSI_EN, 0);
}
static void
struct sun6i_csi_capture *capture = &csi_dev->capture;
struct sun6i_csi_capture_state *state = &capture->state;
struct video_device *video_dev = &capture->video_dev;
+ struct device *dev = csi_dev->dev;
struct v4l2_subdev *subdev;
int ret;
goto error_media_pipeline;
}
+ /* PM */
+
+ ret = pm_runtime_resume_and_get(dev);
+ if (ret < 0)
+ goto error_media_pipeline;
+
/* Clear */
sun6i_csi_capture_irq_clear(csi_dev);
sun6i_csi_capture_disable(csi_dev);
sun6i_csi_capture_irq_disable(csi_dev);
+ pm_runtime_put(dev);
+
error_media_pipeline:
video_device_pipeline_stop(video_dev);
{
struct sun6i_csi_device *csi_dev = vb2_get_drv_priv(queue);
struct sun6i_csi_capture *capture = &csi_dev->capture;
+ struct device *dev = csi_dev->dev;
struct v4l2_subdev *subdev;
subdev = sun6i_csi_capture_remote_subdev(capture, NULL);
sun6i_csi_capture_disable(csi_dev);
sun6i_csi_capture_irq_disable(csi_dev);
+ pm_runtime_put(dev);
+
video_device_pipeline_stop(&capture->video_dev);
sun6i_csi_capture_state_cleanup(csi_dev, true);
if (mutex_lock_interruptible(&capture->lock))
return -ERESTARTSYS;
- ret = v4l2_fh_open(file);
+ ret = v4l2_pipeline_pm_get(&capture->video_dev.entity);
if (ret < 0)
goto error_lock;
- ret = v4l2_pipeline_pm_get(&capture->video_dev.entity);
+ ret = v4l2_fh_open(file);
if (ret < 0)
- goto error_v4l2_fh;
-
- /* Power on at first open. */
- if (v4l2_fh_is_singular_file(file)) {
- ret = sun6i_csi_set_power(csi_dev, true);
- if (ret < 0)
- goto error_v4l2_fh;
- }
+ goto error_pipeline;
mutex_unlock(&capture->lock);
return 0;
-error_v4l2_fh:
- v4l2_fh_release(file);
+error_pipeline:
+ v4l2_pipeline_pm_put(&capture->video_dev.entity);
error_lock:
mutex_unlock(&capture->lock);
{
struct sun6i_csi_device *csi_dev = video_drvdata(file);
struct sun6i_csi_capture *capture = &csi_dev->capture;
- bool last_close;
mutex_lock(&capture->lock);
- last_close = v4l2_fh_is_singular_file(file);
-
_vb2_fop_release(file, NULL);
v4l2_pipeline_pm_put(&capture->video_dev.entity);
- /* Power off at last close. */
- if (last_close)
- sun6i_csi_set_power(csi_dev, false);
-
mutex_unlock(&capture->lock);
return 0;