From: Brandon Brnich <b-brnich@ti.com>
To: <devarsht@ti.com>, <mchehab@kernel.org>, <hverkuil@kernel.org>,
<benjamin.gaignard@collabora.com>,
<sebastian.fricke@collabora.com>
Cc: <linux-media@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
<b-brnich@ti.com>, <k-willis@ti.com>
Subject: [PATCH] media: imagination: e5010: Enable autosuspend for runtime PM
Date: Wed, 22 Jul 2026 16:08:45 -0500 [thread overview]
Message-ID: <20260722210845.723864-1-b-brnich@ti.com> (raw)
Current implementation only has one call to turn the device on -
start_streaming. This can waste power of device as the device can be in
STREAM_ON state, but no buffers are actually being submitted.
e5010_init_device needs to be moved to the resume hook to ensure
register state is correct during any power on. This also fixes an issue
when device was never powered on, but system resumes from deep sleep.
The PM framework skips the runtime resume hook since device was never on
in the first place. This causes e5010_init_device to be called for a
powered off device leading to invalid write and system crash.
Fixes: a1e2940458853 ("media: imagination: Add E5010 JPEG Encoder driver")
Signed-off-by: Brandon Brnich <b-brnich@ti.com>
---
.../platform/imagination/e5010-jpeg-enc.c | 47 +++++++++----------
1 file changed, 21 insertions(+), 26 deletions(-)
diff --git a/drivers/media/platform/imagination/e5010-jpeg-enc.c b/drivers/media/platform/imagination/e5010-jpeg-enc.c
index 42ad9ee3993b4..189c147cb9705 100644
--- a/drivers/media/platform/imagination/e5010-jpeg-enc.c
+++ b/drivers/media/platform/imagination/e5010-jpeg-enc.c
@@ -976,6 +976,8 @@ static irqreturn_t e5010_irq(int irq, void *data)
v4l2_m2m_job_finish(e5010->m2m_dev, ctx->fh.m2m_ctx);
dprintk(e5010, 3, "ctx: 0x%p Finish job\n", ctx);
+ pm_runtime_mark_last_busy(e5010->dev);
+ pm_runtime_put_autosuspend(e5010->dev);
job_unlock:
spin_unlock(&e5010->hw_lock);
@@ -1099,6 +1101,8 @@ static int e5010_probe(struct platform_device *pdev)
goto fail_after_v4l2_register;
}
+ pm_runtime_set_autosuspend_delay(dev, 100);
+ pm_runtime_use_autosuspend(dev);
pm_runtime_enable(dev);
ret = video_register_device(e5010->vdev, VFL_TYPE_VIDEO, 0);
@@ -1289,31 +1293,13 @@ static int e5010_encoder_cmd(struct file *file, void *priv,
static int e5010_start_streaming(struct vb2_queue *q, unsigned int count)
{
struct e5010_context *ctx = vb2_get_drv_priv(q);
- int ret;
struct e5010_q_data *queue = get_queue(ctx, q->type);
v4l2_m2m_update_start_streaming_state(ctx->fh.m2m_ctx, q);
queue->sequence = 0;
- ret = pm_runtime_resume_and_get(ctx->e5010->dev);
- if (ret < 0) {
- v4l2_err(&ctx->e5010->v4l2_dev, "failed to power up jpeg\n");
- goto fail;
- }
-
- ret = e5010_init_device(ctx->e5010);
- if (ret) {
- v4l2_err(&ctx->e5010->v4l2_dev, "failed to Enable e5010 device\n");
- goto fail;
- }
-
return 0;
-
-fail:
- e5010_vb2_buffers_return(q, VB2_BUF_STATE_QUEUED);
-
- return ret;
}
static void e5010_stop_streaming(struct vb2_queue *q)
@@ -1329,8 +1315,6 @@ static void e5010_stop_streaming(struct vb2_queue *q)
v4l2_m2m_has_stopped(ctx->fh.m2m_ctx)) {
v4l2_event_queue_fh(&ctx->fh, &e5010_eos_event);
}
-
- pm_runtime_put_sync(ctx->e5010->dev);
}
static void e5010_device_run(void *priv)
@@ -1343,7 +1327,15 @@ static void e5010_device_run(void *priv)
unsigned long flags;
int num_planes = ctx->out_queue.fmt->num_planes;
+ ret = pm_runtime_resume_and_get(e5010->dev);
+ if (ret < 0) {
+ dev_err(e5010->dev, "Device failed to turn on\n");
+ v4l2_m2m_job_finish(e5010->m2m_dev, ctx->fh.m2m_ctx);
+ return;
+ }
+
spin_lock_irqsave(&e5010->hw_lock, flags);
+
s_vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
WARN_ON(!s_vb);
d_vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
@@ -1474,6 +1466,8 @@ static void e5010_device_run(void *priv)
e5010_reset(e5010->dev, e5010->core_base, e5010->mmu_base);
no_ready_buf_err:
+ pm_runtime_mark_last_busy(e5010->dev);
+ pm_runtime_put_autosuspend(e5010->dev);
if (s_vb) {
v4l2_m2m_src_buf_remove_by_buf(ctx->fh.m2m_ctx, s_vb);
v4l2_m2m_buf_done(s_vb, VB2_BUF_STATE_ERROR);
@@ -1501,6 +1495,13 @@ static int e5010_runtime_resume(struct device *dev)
return ret;
}
+ ret = e5010_init_device(e5010);
+ if (ret) {
+ dev_err(dev, "Failed to re-enable e5010 device\n");
+ clk_disable_unprepare(e5010->clk);
+ return ret;
+ }
+
return 0;
}
@@ -1533,12 +1534,6 @@ static int e5010_resume(struct device *dev)
if (ret < 0)
return ret;
- ret = e5010_init_device(e5010);
- if (ret) {
- dev_err(dev, "Failed to re-enable e5010 device\n");
- return ret;
- }
-
v4l2_m2m_resume(e5010->m2m_dev);
return ret;
--
2.43.0
reply other threads:[~2026-07-22 21:09 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260722210845.723864-1-b-brnich@ti.com \
--to=b-brnich@ti.com \
--cc=benjamin.gaignard@collabora.com \
--cc=devarsht@ti.com \
--cc=hverkuil@kernel.org \
--cc=k-willis@ti.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=mchehab@kernel.org \
--cc=sebastian.fricke@collabora.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox