From: Sakari Ailus <sakari.ailus@linux.intel.com>
To: linux-media@vger.kernel.org
Cc: "Yan, Dongcheng" <dongcheng.yan@intel.com>,
Mehdi Djait <mehdi.djait@linux.intel.com>,
"Yu, Ong Hock" <ong.hock.yu@intel.com>,
"Ng, Khai Wen" <khai.wen.ng@intel.com>,
Antti Laakso <antti.laakso@linux.intel.com>,
"Bajpai, Manik" <manik.bajpai@intel.com>,
Divyamani Tripathi <divyamani.tripathi@intel.com>,
"Sapre, Sarang" <sarang.sapre@intel.com>,
"Yao, Hao" <hao.yao@intel.com>
Subject: [PATCH 5/5] media: ipu6: Return errors from stream stop and close
Date: Thu, 8 Oct 2026 11:52:47 +0300 [thread overview]
Message-ID: <20261008085247.798156-6-sakari.ailus@linux.intel.com> (raw)
In-Reply-To: <20261008085247.798156-1-sakari.ailus@linux.intel.com>
If the firmware fails to start, stop or close a stream, either by telling
about it with an error or due to a timeout, it probably requires a reset
before being operational again. Mark isys needing a reset in such cases.
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
.../media/pci/intel/ipu6/ipu6-isys-video.c | 55 ++++++++++++++-----
.../media/pci/intel/ipu6/ipu6-isys-video.h | 4 +-
2 files changed, 43 insertions(+), 16 deletions(-)
diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-video.c b/drivers/media/pci/intel/ipu6/ipu6-isys-video.c
index 44541aff79b3..799a4be3160b 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-isys-video.c
+++ b/drivers/media/pci/intel/ipu6/ipu6-isys-video.c
@@ -543,25 +543,31 @@ int ipu6_isys_start_stream_firmware(struct ipu6_isys_stream *stream,
out_stream_close:
reinit_completion(&stream->stream_close_completion);
+ scoped_guard(mutex, &stream->isys->mutex)
+ stream->isys->need_reset = true;
+
retout = fw_ops->stream_close(stream->isys, stream->stream_handle);
if (retout < 0) {
dev_dbg(dev, "can't close stream (%d)\n", retout);
- return retout;
+ return ret;
}
tout = wait_for_completion_timeout(&stream->stream_close_completion,
IPU6_FW_CALL_TIMEOUT_JIFFIES);
- if (!tout)
+ if (!tout) {
dev_err(dev, "stream close time out\n");
- else if (stream->error)
+ ret = -ETIMEDOUT;
+ } else if (stream->error) {
dev_err(dev, "stream close error: %d\n", stream->error);
- else
+ ret = -EINVAL;
+ } else {
dev_dbg(dev, "stream close complete\n");
+ }
return ret;
}
-void ipu6_isys_stop_stream_firmware(struct ipu6_isys_stream *stream)
+int ipu6_isys_stop_stream_firmware(struct ipu6_isys_stream *stream)
{
struct ipu6_bus_device *adev = stream->asd->isys->adev;
const struct ipu6_fw_isys_ops *fw_ops = adev->auxdrv_data->fw_ops;
@@ -573,20 +579,30 @@ void ipu6_isys_stop_stream_firmware(struct ipu6_isys_stream *stream)
ret = fw_ops->stream_flush(stream->isys, stream->stream_handle);
if (ret < 0) {
dev_err(dev, "can't stop stream (%d)\n", ret);
- return;
+ return -EBUSY;
}
tout = wait_for_completion_timeout(&stream->stream_stop_completion,
IPU6_FW_CALL_TIMEOUT_JIFFIES);
- if (!tout)
+ if (!tout) {
dev_warn(dev, "stream stop time out\n");
- else if (stream->error)
+ ret = -ETIMEDOUT;
+ } else if (stream->error) {
dev_warn(dev, "stream stop error: %d\n", stream->error);
- else
+ ret = -EINVAL;
+ } else{
dev_dbg(dev, "stop stream: complete\n");
+ }
+
+ if (ret) {
+ scoped_guard(mutex, &stream->isys->mutex)
+ stream->isys->need_reset = true;
+ }
+
+ return ret;
}
-void ipu6_isys_close_stream_firmware(struct ipu6_isys_stream *stream)
+int ipu6_isys_close_stream_firmware(struct ipu6_isys_stream *stream)
{
struct ipu6_bus_device *adev = stream->asd->isys->adev;
const struct ipu6_fw_isys_ops *fw_ops = adev->auxdrv_data->fw_ops;
@@ -599,22 +615,33 @@ void ipu6_isys_close_stream_firmware(struct ipu6_isys_stream *stream)
ret = fw_ops->stream_close(stream->isys, stream->stream_handle);
if (ret < 0) {
dev_err(dev, "can't close stream (%d)\n", ret);
- return;
+ goto out_cleanup;
}
tout = wait_for_completion_timeout(&stream->stream_close_completion,
IPU6_FW_CALL_TIMEOUT_JIFFIES);
- if (!tout)
+ if (!tout) {
dev_warn(dev, "stream close time out\n");
- else if (stream->error)
+ ret = -ETIMEDOUT;
+ } else if (stream->error) {
dev_warn(dev, "stream close error: %d\n", stream->error);
- else
+ ret = -EINVAL;
+ } else {
dev_dbg(dev, "close stream: complete\n");
+ }
+out_cleanup:
scoped_guard(spinlock_irqsave, &stream->isys->streams_lock) {
stream->isys->streams_by_handle[stream->stream_handle] = NULL;
csi2->streams_by_vc[stream->vc] = NULL;
}
+
+ if (ret) {
+ scoped_guard(mutex, &stream->isys->mutex)
+ stream->isys->need_reset = true;
+ }
+
+ return ret;
}
struct ipu6_isys_stream *
diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-video.h b/drivers/media/pci/intel/ipu6/ipu6-isys-video.h
index 2821b9b1b943..2ab6f32716ad 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-isys-video.h
+++ b/drivers/media/pci/intel/ipu6/ipu6-isys-video.h
@@ -99,8 +99,8 @@ int ipu6_isys_fw_pins_prepare(struct ipu6_isys_stream *stream,
int ipu6_isys_start_stream_firmware(struct ipu6_isys_stream *stream,
struct ipu6_isys_buffer_list *bl,
struct v4l2_mbus_frame_desc *desc);
-void ipu6_isys_stop_stream_firmware(struct ipu6_isys_stream *stream);
-void ipu6_isys_close_stream_firmware(struct ipu6_isys_stream *stream);
+int ipu6_isys_stop_stream_firmware(struct ipu6_isys_stream *stream);
+int ipu6_isys_close_stream_firmware(struct ipu6_isys_stream *stream);
struct ipu6_isys_stream *
ipu6_isys_find_stream_firmware(struct ipu6_isys_csi2 *csi2, u8 vc);
void ipu6_isys_free_stream_firmware(struct ipu6_isys_stream *stream);
--
2.47.3
prev parent reply other threads:[~2026-10-08 8:55 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-08 8:52 [PATCH 0/5] IPU reset workaround changes Sakari Ailus
2026-10-08 8:52 ` [PATCH 1/5] media: ipu6: Don't mark need_reset based on returned buffers Sakari Ailus
2026-10-08 8:52 ` [PATCH 2/5] media: ipu6: Tell about not being able to obtain frame descriptor Sakari Ailus
2026-10-09 11:11 ` Antti Laakso
2026-10-09 11:20 ` Sakari Ailus
2026-10-08 8:52 ` [PATCH 3/5] media: ipu6: Prevent starting streaming if ISYS needs reset Sakari Ailus
2026-10-09 10:59 ` Antti Laakso
2026-10-09 11:16 ` Sakari Ailus
2026-10-08 8:52 ` [PATCH 4/5] media: ipu6: Remove need_reset check from video device open Sakari Ailus
2026-10-08 8:52 ` Sakari Ailus [this message]
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=20261008085247.798156-6-sakari.ailus@linux.intel.com \
--to=sakari.ailus@linux.intel.com \
--cc=antti.laakso@linux.intel.com \
--cc=divyamani.tripathi@intel.com \
--cc=dongcheng.yan@intel.com \
--cc=hao.yao@intel.com \
--cc=khai.wen.ng@intel.com \
--cc=linux-media@vger.kernel.org \
--cc=manik.bajpai@intel.com \
--cc=mehdi.djait@linux.intel.com \
--cc=ong.hock.yu@intel.com \
--cc=sarang.sapre@intel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.