[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260104164037.18176-1-karthikey3608@gmail.com>
Date: Sun, 4 Jan 2026 22:10:37 +0530
From: Karthikey D Kadati <karthikey3608@...il.com>
To: hansg@...nel.org,
mchehab@...nel.org
Cc: sakari.ailus@...ux.intel.com,
linux-media@...r.kernel.org,
linux-staging@...ts.linux.dev,
linux-kernel@...r.kernel.org,
Karthikey D Kadati <karthikey3608@...il.com>
Subject: [PATCH] media: atomisp: replace shadow zoom structs with v4l2_rect and fix error paths
This patch addresses a TODO graduation blocker by removing private zoom
structures (`atomisp_zoom_point` and `atomisp_zoom_region`) in favor of
standard V4L2 types (`v4l2_rect`).
It also improves error propagation for IRQs and XNR configuration, ensuring
that failures are detected and reported. Additionally, it consolidates
memory allocation boilerplate into a safer helper function
(`atomisp_alloc_stat_bufs_list`) that includes a proper error-unwind path
to prevent memory leaks during partial allocation failures.
Signed-off-by: Karthikey D Kadati <karthikey3608@...il.com>
---
.../media/atomisp/include/linux/atomisp.h | 19 +--
.../staging/media/atomisp/pci/atomisp_cmd.c | 144 ++++++++---------
.../staging/media/atomisp/pci/atomisp_ioctl.c | 147 +++++++++++++-----
3 files changed, 183 insertions(+), 127 deletions(-)
diff --git a/drivers/staging/media/atomisp/include/linux/atomisp.h b/drivers/staging/media/atomisp/include/linux/atomisp.h
index fcf116cc4..e86f636d2 100644
--- a/drivers/staging/media/atomisp/include/linux/atomisp.h
+++ b/drivers/staging/media/atomisp/include/linux/atomisp.h
@@ -326,27 +326,14 @@ struct atomisp_resolution {
u32 height; /** Height */
};
-/*
- * This specifies the coordinates (x,y)
- */
-struct atomisp_zoom_point {
- s32 x; /** x coordinate */
- s32 y; /** y coordinate */
-};
+#include <linux/videodev2.h>
-/*
- * This specifies the region
- */
-struct atomisp_zoom_region {
- struct atomisp_zoom_point
- origin; /* Starting point coordinates for the region */
- struct atomisp_resolution resolution; /* Region resolution */
-};
+/* Use v4l2_rect instead of shadow structures */
struct atomisp_dz_config {
u32 dx; /** Horizontal zoom factor */
u32 dy; /** Vertical zoom factor */
- struct atomisp_zoom_region zoom_region; /** region for zoom */
+ struct v4l2_rect zoom_region; /** region for zoom */
};
struct atomisp_parm {
diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
index 327836372..76a65f379 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
@@ -874,7 +874,9 @@ void atomisp_assert_recovery_work(struct work_struct *work)
if (!isp->asd.streaming)
goto out_unlock;
- atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF, false);
+ if (atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF,
+ false))
+ dev_err_once(isp->dev, "atomisp_css_irq_enable failed\n");
spin_lock_irqsave(&isp->lock, flags);
isp->asd.streaming = false;
@@ -925,8 +927,9 @@ void atomisp_assert_recovery_work(struct work_struct *work)
atomisp_csi2_configure(&isp->asd);
- atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF,
- atomisp_css_valid_sof(isp));
+ if (atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF,
+ atomisp_css_valid_sof(isp)))
+ dev_err_once(isp->dev, "atomisp_css_irq_enable failed\n");
if (atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_AUTO, true) < 0)
dev_dbg(isp->dev, "DFS auto failed while recovering!\n");
@@ -1196,9 +1199,7 @@ int atomisp_xnr(struct atomisp_sub_device *asd, int flag,
return 0;
}
- atomisp_css_capture_enable_xnr(asd, !!*xnr_enable);
-
- return 0;
+ return atomisp_css_capture_enable_xnr(asd, !!*xnr_enable);
}
/*
@@ -1764,15 +1765,13 @@ int atomisp_calculate_real_zoom_region(struct atomisp_sub_device *asd,
return -EINVAL;
}
- if (dz_config->zoom_region.resolution.width
- == asd->sensor_array_res.width
- || dz_config->zoom_region.resolution.height
- == asd->sensor_array_res.height) {
+ if (dz_config->zoom_region.width == asd->sensor_array_res.width ||
+ dz_config->zoom_region.height == asd->sensor_array_res.height) {
/*no need crop region*/
- dz_config->zoom_region.origin.x = 0;
- dz_config->zoom_region.origin.y = 0;
- dz_config->zoom_region.resolution.width = eff_res.width;
- dz_config->zoom_region.resolution.height = eff_res.height;
+ dz_config->zoom_region.left = 0;
+ dz_config->zoom_region.top = 0;
+ dz_config->zoom_region.width = eff_res.width;
+ dz_config->zoom_region.height = eff_res.height;
return 0;
}
@@ -1783,18 +1782,18 @@ int atomisp_calculate_real_zoom_region(struct atomisp_sub_device *asd,
*/
if (!IS_ISP2401) {
- dz_config->zoom_region.origin.x = dz_config->zoom_region.origin.x
- * eff_res.width
- / asd->sensor_array_res.width;
- dz_config->zoom_region.origin.y = dz_config->zoom_region.origin.y
- * eff_res.height
- / asd->sensor_array_res.height;
- dz_config->zoom_region.resolution.width = dz_config->zoom_region.resolution.width
- * eff_res.width
- / asd->sensor_array_res.width;
- dz_config->zoom_region.resolution.height = dz_config->zoom_region.resolution.height
- * eff_res.height
- / asd->sensor_array_res.height;
+ dz_config->zoom_region.left =
+ (s32)((long long)dz_config->zoom_region.left *
+ eff_res.width / asd->sensor_array_res.width);
+ dz_config->zoom_region.top =
+ (s32)((long long)dz_config->zoom_region.top *
+ eff_res.height / asd->sensor_array_res.height);
+ dz_config->zoom_region.width =
+ (u32)((long long)dz_config->zoom_region.width *
+ eff_res.width / asd->sensor_array_res.width);
+ dz_config->zoom_region.height =
+ (u32)((long long)dz_config->zoom_region.height *
+ eff_res.height / asd->sensor_array_res.height);
/*
* Set same ratio of crop region resolution and current pipe output
* resolution
@@ -1821,62 +1820,67 @@ int atomisp_calculate_real_zoom_region(struct atomisp_sub_device *asd,
- asd->sensor_array_res.width
* out_res.height / out_res.width;
h_offset = h_offset / 2;
- if (dz_config->zoom_region.origin.y < h_offset)
- dz_config->zoom_region.origin.y = 0;
+ if (dz_config->zoom_region.top < h_offset)
+ dz_config->zoom_region.top = 0;
else
- dz_config->zoom_region.origin.y = dz_config->zoom_region.origin.y - h_offset;
+ dz_config->zoom_region.top = dz_config->zoom_region.top - h_offset;
w_offset = 0;
} else {
w_offset = asd->sensor_array_res.width
- asd->sensor_array_res.height
* out_res.width / out_res.height;
w_offset = w_offset / 2;
- if (dz_config->zoom_region.origin.x < w_offset)
- dz_config->zoom_region.origin.x = 0;
+ if (dz_config->zoom_region.left < w_offset)
+ dz_config->zoom_region.left = 0;
else
- dz_config->zoom_region.origin.x = dz_config->zoom_region.origin.x - w_offset;
+ dz_config->zoom_region.left =
+ dz_config->zoom_region.left - w_offset;
h_offset = 0;
}
- dz_config->zoom_region.origin.x = dz_config->zoom_region.origin.x
- * eff_res.width
- / (asd->sensor_array_res.width - 2 * w_offset);
- dz_config->zoom_region.origin.y = dz_config->zoom_region.origin.y
- * eff_res.height
- / (asd->sensor_array_res.height - 2 * h_offset);
- dz_config->zoom_region.resolution.width = dz_config->zoom_region.resolution.width
- * eff_res.width
- / (asd->sensor_array_res.width - 2 * w_offset);
- dz_config->zoom_region.resolution.height = dz_config->zoom_region.resolution.height
- * eff_res.height
- / (asd->sensor_array_res.height - 2 * h_offset);
- }
-
- if (out_res.width * dz_config->zoom_region.resolution.height
- > dz_config->zoom_region.resolution.width * out_res.height) {
- dz_config->zoom_region.resolution.height =
- dz_config->zoom_region.resolution.width
- * out_res.height / out_res.width;
+ dz_config->zoom_region.left =
+ (s32)((long long)dz_config->zoom_region.left *
+ eff_res.width /
+ (asd->sensor_array_res.width - 2 * w_offset));
+ dz_config->zoom_region.top =
+ (s32)((long long)dz_config->zoom_region.top *
+ eff_res.height /
+ (asd->sensor_array_res.height - 2 * h_offset));
+ dz_config->zoom_region.width =
+ (u32)((long long)dz_config->zoom_region.width *
+ eff_res.width /
+ (asd->sensor_array_res.width - 2 * w_offset));
+ dz_config->zoom_region.height =
+ (u32)((long long)dz_config->zoom_region.height *
+ eff_res.height /
+ (asd->sensor_array_res.height - 2 * h_offset));
+ }
+
+ if ((long long)out_res.width * dz_config->zoom_region.height >
+ (long long)dz_config->zoom_region.width * out_res.height) {
+ dz_config->zoom_region.height =
+ (u32)((long long)dz_config->zoom_region.width *
+ out_res.height / out_res.width);
} else {
- dz_config->zoom_region.resolution.width =
- dz_config->zoom_region.resolution.height
- * out_res.width / out_res.height;
+ dz_config->zoom_region.width =
+ (u32)((long long)dz_config->zoom_region.height *
+ out_res.width / out_res.height);
}
dev_dbg(asd->isp->dev,
"%s crop region:(%d,%d),(%d,%d) eff_res(%d, %d) array_size(%d,%d) out_res(%d, %d)\n",
- __func__, dz_config->zoom_region.origin.x,
- dz_config->zoom_region.origin.y,
- dz_config->zoom_region.resolution.width,
- dz_config->zoom_region.resolution.height,
+ __func__, dz_config->zoom_region.left,
+ dz_config->zoom_region.top,
+ dz_config->zoom_region.width,
+ dz_config->zoom_region.height,
eff_res.width, eff_res.height,
asd->sensor_array_res.width,
asd->sensor_array_res.height,
out_res.width, out_res.height);
- if ((dz_config->zoom_region.origin.x +
- dz_config->zoom_region.resolution.width
+ if ((dz_config->zoom_region.left +
+ dz_config->zoom_region.width
> eff_res.width) ||
- (dz_config->zoom_region.origin.y +
- dz_config->zoom_region.resolution.height
+ (dz_config->zoom_region.top +
+ dz_config->zoom_region.height
> eff_res.height))
return -EINVAL;
@@ -1901,10 +1905,10 @@ static bool atomisp_check_zoom_region(
config.width = asd->sensor_array_res.width;
config.height = asd->sensor_array_res.height;
- w = dz_config->zoom_region.origin.x +
- dz_config->zoom_region.resolution.width;
- h = dz_config->zoom_region.origin.y +
- dz_config->zoom_region.resolution.height;
+ w = dz_config->zoom_region.left +
+ dz_config->zoom_region.width;
+ h = dz_config->zoom_region.top +
+ dz_config->zoom_region.height;
if ((w <= config.width) && (h <= config.height) && w > 0 && h > 0)
flag = true;
@@ -1912,10 +1916,10 @@ static bool atomisp_check_zoom_region(
/* setting error zoom region */
dev_err(asd->isp->dev,
"%s zoom region ERROR:dz_config:(%d,%d),(%d,%d)array_res(%d, %d)\n",
- __func__, dz_config->zoom_region.origin.x,
- dz_config->zoom_region.origin.y,
- dz_config->zoom_region.resolution.width,
- dz_config->zoom_region.resolution.height,
+ __func__, dz_config->zoom_region.left,
+ dz_config->zoom_region.top,
+ dz_config->zoom_region.width,
+ dz_config->zoom_region.height,
config.width, config.height);
return flag;
diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
index 5c0a1d92b..bb277f5a3 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
@@ -678,13 +678,104 @@ static int atomisp_g_fmt_cap(struct file *file, void *fh,
return atomisp_try_fmt_cap(file, fh, f);
}
+static int atomisp_alloc_stat_bufs_list(struct atomisp_sub_device *asd,
+ u16 stream_id,
+ struct list_head *head,
+ int count,
+ int type)
+{
+ struct atomisp_s3a_buf *s3a_buf;
+ struct atomisp_dis_buf *dis_buf;
+ struct atomisp_metadata_buf *md_buf;
+ int ret;
+
+ while (count--) {
+ switch (type) {
+ case IA_CSS_BUFFER_TYPE_3A_STATISTICS:
+ s3a_buf = kzalloc(sizeof(*s3a_buf), GFP_KERNEL);
+ if (!s3a_buf)
+ goto error;
+
+ ret = atomisp_css_allocate_stat_buffers(asd, stream_id,
+ s3a_buf, NULL,
+ NULL);
+ if (ret) {
+ kfree(s3a_buf);
+ goto error;
+ }
+ list_add_tail(&s3a_buf->list, head);
+ break;
+ case IA_CSS_BUFFER_TYPE_DIS_STATISTICS:
+ dis_buf = kzalloc(sizeof(*dis_buf), GFP_KERNEL);
+ if (!dis_buf)
+ goto error;
+
+ ret = atomisp_css_allocate_stat_buffers(asd, stream_id,
+ NULL, dis_buf,
+ NULL);
+ if (ret) {
+ kfree(dis_buf);
+ goto error;
+ }
+ list_add_tail(&dis_buf->list, head);
+ break;
+ case IA_CSS_BUFFER_TYPE_METADATA:
+ md_buf = kzalloc(sizeof(*md_buf), GFP_KERNEL);
+ if (!md_buf)
+ goto error;
+
+ ret = atomisp_css_allocate_stat_buffers(asd, stream_id,
+ NULL, NULL,
+ md_buf);
+ if (ret) {
+ kfree(md_buf);
+ goto error;
+ }
+ list_add_tail(&md_buf->list, head);
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+
+error:
+ while (!list_empty(head)) {
+ switch (type) {
+ case IA_CSS_BUFFER_TYPE_3A_STATISTICS:
+ s3a_buf = list_entry(head->next,
+ struct atomisp_s3a_buf, list);
+ atomisp_css_free_3a_buffer(s3a_buf);
+ list_del(&s3a_buf->list);
+ kfree(s3a_buf);
+ break;
+ case IA_CSS_BUFFER_TYPE_DIS_STATISTICS:
+ dis_buf = list_entry(head->next,
+ struct atomisp_dis_buf, list);
+ atomisp_css_free_dis_buffer(dis_buf);
+ list_del(&dis_buf->list);
+ kfree(dis_buf);
+ break;
+ case IA_CSS_BUFFER_TYPE_METADATA:
+ md_buf = list_entry(head->next,
+ struct atomisp_metadata_buf, list);
+ atomisp_css_free_metadata_buffer(md_buf);
+ list_del(&md_buf->list);
+ kfree(md_buf);
+ break;
+ }
+ }
+ return -ENOMEM;
+}
+
int atomisp_alloc_css_stat_bufs(struct atomisp_sub_device *asd,
uint16_t stream_id)
{
struct atomisp_device *isp = asd->isp;
- struct atomisp_s3a_buf *s3a_buf = NULL, *_s3a_buf;
- struct atomisp_dis_buf *dis_buf = NULL, *_dis_buf;
- struct atomisp_metadata_buf *md_buf = NULL, *_md_buf;
+ struct atomisp_dis_buf *dis_buf, *_dis_buf;
+ struct atomisp_s3a_buf *s3a_buf, *_s3a_buf;
+ struct atomisp_metadata_buf *md_buf, *_md_buf;
int count;
struct ia_css_dvs_grid_info *dvs_grid_info =
atomisp_css_get_dvs_grid_info(&asd->params.curr_grid_info);
@@ -695,37 +786,20 @@ int atomisp_alloc_css_stat_bufs(struct atomisp_sub_device *asd,
count = ATOMISP_CSS_Q_DEPTH +
ATOMISP_S3A_BUF_QUEUE_DEPTH_FOR_HAL;
dev_dbg(isp->dev, "allocating %d 3a buffers\n", count);
- while (count--) {
- s3a_buf = kzalloc(sizeof(struct atomisp_s3a_buf), GFP_KERNEL);
- if (!s3a_buf)
- goto error;
-
- if (atomisp_css_allocate_stat_buffers(
- asd, stream_id, s3a_buf, NULL, NULL)) {
- kfree(s3a_buf);
- goto error;
- }
-
- list_add_tail(&s3a_buf->list, &asd->s3a_stats);
- }
+ if (atomisp_alloc_stat_bufs_list(asd, stream_id,
+ &asd->s3a_stats, count,
+ IA_CSS_BUFFER_TYPE_3A_STATISTICS))
+ goto error;
}
if (list_empty(&asd->dis_stats) && dvs_grid_info &&
dvs_grid_info->enable) {
count = ATOMISP_CSS_Q_DEPTH + 1;
dev_dbg(isp->dev, "allocating %d dis buffers\n", count);
- while (count--) {
- dis_buf = kzalloc(sizeof(struct atomisp_dis_buf), GFP_KERNEL);
- if (!dis_buf)
- goto error;
- if (atomisp_css_allocate_stat_buffers(
- asd, stream_id, NULL, dis_buf, NULL)) {
- kfree(dis_buf);
- goto error;
- }
-
- list_add_tail(&dis_buf->list, &asd->dis_stats);
- }
+ if (atomisp_alloc_stat_bufs_list(asd, stream_id,
+ &asd->dis_stats, count,
+ IA_CSS_BUFFER_TYPE_DIS_STATISTICS))
+ goto error;
}
for (i = 0; i < ATOMISP_METADATA_TYPE_NUM; i++) {
@@ -736,19 +810,10 @@ int atomisp_alloc_css_stat_bufs(struct atomisp_sub_device *asd,
ATOMISP_METADATA_QUEUE_DEPTH_FOR_HAL;
dev_dbg(isp->dev, "allocating %d metadata buffers for type %d\n",
count, i);
- while (count--) {
- md_buf = kzalloc(sizeof(struct atomisp_metadata_buf),
- GFP_KERNEL);
- if (!md_buf)
- goto error;
-
- if (atomisp_css_allocate_stat_buffers(
- asd, stream_id, NULL, NULL, md_buf)) {
- kfree(md_buf);
- goto error;
- }
- list_add_tail(&md_buf->list, &asd->metadata[i]);
- }
+ if (atomisp_alloc_stat_bufs_list(asd, stream_id,
+ &asd->metadata[i], count,
+ IA_CSS_BUFFER_TYPE_METADATA))
+ goto error;
}
}
return 0;
--
2.43.0
Powered by blists - more mailing lists