summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Kocialkowski <paul.kocialkowski@bootlin.com>2022-11-03 16:30:53 +0000
committerMauro Carvalho Chehab <mchehab@kernel.org>2022-11-25 07:06:09 +0000
commitd0895e0f81731cc781a25e4f298c2af07f16e4cf (patch)
tree5a485e992e6e60bc5d09b25e9625b5b02343484b
parent85469b9e6634cf64836568587c82ecba330bb38f (diff)
downloadlinux-stable-d0895e0f81731cc781a25e4f298c2af07f16e4cf.tar.gz
linux-stable-d0895e0f81731cc781a25e4f298c2af07f16e4cf.tar.bz2
linux-stable-d0895e0f81731cc781a25e4f298c2af07f16e4cf.zip
media: sun6i-csi: Move power management to runtime pm in capture
Let's just enable the module when we start using it (at stream on) and benefit from runtime pm instead of enabling it at first open. Also reorder the call to v4l2_pipeline_pm_get. Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com> Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
-rw-r--r--drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c24
-rw-r--r--drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h9
-rw-r--r--drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c41
3 files changed, 22 insertions, 52 deletions
diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c
index 7944736d27e1..26d8f5eb11ce 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c
@@ -148,30 +148,6 @@ bool sun6i_csi_is_format_supported(struct sun6i_csi_device *csi_dev,
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)
{
diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h
index 6fe40a56d6df..83180475e55b 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h
@@ -78,15 +78,6 @@ bool sun6i_csi_is_format_supported(struct sun6i_csi_device *csi_dev,
u32 pixformat, u32 mbus_code);
/**
- * sun6i_csi_set_power() - power on/off the csi
- * @csi_dev: pointer to the csi device
- * @enable: on/off
- *
- * Return: 0 if successful, error code otherwise.
- */
-int sun6i_csi_set_power(struct sun6i_csi_device *csi_dev, bool enable);
-
-/**
* sun6i_csi_update_config() - update the csi register settings
* @csi_dev: pointer to the csi device
* @config: see struct sun6i_csi_config
diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
index 3ea443aa6fde..638d4ab33acd 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
@@ -6,6 +6,7 @@
*/
#include <linux/of.h>
+#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <media/v4l2-device.h>
@@ -141,6 +142,9 @@ static void sun6i_csi_capture_enable(struct sun6i_csi_device *csi_dev)
{
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);
}
@@ -150,6 +154,7 @@ static void sun6i_csi_capture_disable(struct sun6i_csi_device *csi_dev)
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
@@ -382,6 +387,7 @@ static int sun6i_csi_capture_start_streaming(struct vb2_queue *queue,
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;
@@ -402,6 +408,12 @@ static int sun6i_csi_capture_start_streaming(struct vb2_queue *queue,
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);
@@ -429,6 +441,8 @@ error_stream:
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);
@@ -442,6 +456,7 @@ static void sun6i_csi_capture_stop_streaming(struct vb2_queue *queue)
{
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);
@@ -451,6 +466,8 @@ static void sun6i_csi_capture_stop_streaming(struct vb2_queue *queue)
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);
@@ -635,27 +652,20 @@ static int sun6i_csi_capture_open(struct file *file)
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);
@@ -667,19 +677,12 @@ static int sun6i_csi_capture_close(struct file *file)
{
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;