mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: shayderrr <darknessshayder@gmail.com>
To: sakari.ailus@linux.intel.com, bingbu.cao@intel.com,
	mchehab@kernel.org, gregkh@linuxfoundation.org
Cc: linux-media@vger.kernel.org, linux-staging@lists.linux.dev,
	linux-kernel@vger.kernel.org,
	Pranav Bajjuri <darknessshayder@gmail.com>
Subject: [PATCH] media: ipu7: fix boot config memory leak and replace polling loops
Date: Sun, 17 May 2026 09:34:56 -0500	[thread overview]
Message-ID: <20260517143456.81109-1-darknessshayder@gmail.com> (raw)

From: Pranav Bajjuri <darknessshayder@gmail.com>

Free boot_config DMA allocation if queue memory alloc fails in
ipu7_boot_init_boot_config(). Replace hand-rolled timeout loops in
ipu7_boot_start_fw() and ipu7_boot_stop_fw() with read_poll_timeout().
Fix variable declaration order in cell reset, start, and stop to follow
reverse Christmas tree convention.

Signed-off-by: Pranav Bajjuri <darknessshayder@gmail.com>
---
 drivers/staging/media/ipu7/ipu7-boot.c | 88 +++++++++++---------------
 1 file changed, 36 insertions(+), 52 deletions(-)

diff --git a/drivers/staging/media/ipu7/ipu7-boot.c b/drivers/staging/media/ipu7/ipu7-boot.c
index d7901ff78b38..f081c39604a7 100644
--- a/drivers/staging/media/ipu7/ipu7-boot.c
+++ b/drivers/staging/media/ipu7/ipu7-boot.c
@@ -22,8 +22,8 @@
 #include "ipu7-platform-regs.h"
 #include "ipu7-syscom.h"
 
-#define IPU_FW_START_STOP_TIMEOUT		2000
-#define IPU_BOOT_CELL_RESET_TIMEOUT		(2 * USEC_PER_SEC)
+#define IPU_FW_START_STOP_TIMEOUT	2000
+#define IPU_BOOT_CELL_RESET_TIMEOUT	(2 * USEC_PER_SEC)
 #define BOOT_STATE_IS_CRITICAL(s)	IA_GOFO_FW_BOOT_STATE_IS_CRITICAL(s)
 #define BOOT_STATE_IS_READY(s)		((s) == IA_GOFO_FW_BOOT_STATE_READY)
 #define BOOT_STATE_IS_INACTIVE(s)	((s) == IA_GOFO_FW_BOOT_STATE_INACTIVE)
@@ -39,17 +39,17 @@ struct ipu7_boot_context {
 static const struct ipu7_boot_context contexts[IPU_SUBSYS_NUM] = {
 	{
 		/* ISYS */
-		.dmem_address = IPU_ISYS_DMEM_OFFSET,
-		.status_ctrl_reg = BUTTRESS_REG_DRV_IS_UCX_CONTROL_STATUS,
-		.fw_start_address_reg = BUTTRESS_REG_DRV_IS_UCX_START_ADDR,
-		.fw_code_base_reg = IS_UC_CTRL_BASE
+		.dmem_address		= IPU_ISYS_DMEM_OFFSET,
+		.status_ctrl_reg	= BUTTRESS_REG_DRV_IS_UCX_CONTROL_STATUS,
+		.fw_start_address_reg	= BUTTRESS_REG_DRV_IS_UCX_START_ADDR,
+		.fw_code_base_reg	= IS_UC_CTRL_BASE
 	},
 	{
 		/* PSYS */
-		.dmem_address = IPU_PSYS_DMEM_OFFSET,
-		.status_ctrl_reg = BUTTRESS_REG_DRV_PS_UCX_CONTROL_STATUS,
-		.fw_start_address_reg = BUTTRESS_REG_DRV_PS_UCX_START_ADDR,
-		.fw_code_base_reg = PS_UC_CTRL_BASE
+		.dmem_address		= IPU_PSYS_DMEM_OFFSET,
+		.status_ctrl_reg	= BUTTRESS_REG_DRV_PS_UCX_CONTROL_STATUS,
+		.fw_start_address_reg	= BUTTRESS_REG_DRV_PS_UCX_START_ADDR,
+		.fw_code_base_reg	= PS_UC_CTRL_BASE
 	}
 };
 
@@ -85,9 +85,9 @@ static int ipu7_boot_cell_reset(const struct ipu7_bus_device *adev)
 {
 	const struct ipu7_boot_context *ctx = &contexts[adev->subsys];
 	const struct device *dev = &adev->auxdev.dev;
+	void __iomem *base = adev->isp->base;
 	u32 ucx_ctrl_status = ctx->status_ctrl_reg;
 	u32 timeout = IPU_BOOT_CELL_RESET_TIMEOUT;
-	void __iomem *base = adev->isp->base;
 	u32 val, val2;
 	int ret;
 
@@ -134,8 +134,8 @@ static int ipu7_boot_cell_reset(const struct ipu7_bus_device *adev)
 static void ipu7_boot_cell_start(const struct ipu7_bus_device *adev)
 {
 	const struct ipu7_boot_context *ctx = &contexts[adev->subsys];
-	void __iomem *base = adev->isp->base;
 	const struct device *dev = &adev->auxdev.dev;
+	void __iomem *base = adev->isp->base;
 	u32 val;
 
 	dev_dbg(dev, "starting cell...\n");
@@ -152,8 +152,8 @@ static void ipu7_boot_cell_start(const struct ipu7_bus_device *adev)
 static void ipu7_boot_cell_stop(const struct ipu7_bus_device *adev)
 {
 	const struct ipu7_boot_context *ctx = &contexts[adev->subsys];
-	void __iomem *base = adev->isp->base;
 	const struct device *dev = &adev->auxdev.dev;
+	void __iomem *base = adev->isp->base;
 	u32 val;
 
 	dev_dbg(dev, "stopping cell...\n");
@@ -187,16 +187,14 @@ static int ipu7_boot_cell_init(const struct ipu7_bus_device *adev)
 }
 
 static void init_boot_config(struct ia_gofo_boot_config *boot_config,
-			     u32 length, u8 major)
+			     u32 config_size, u8 major)
 {
-	/* syscom version, new syscom2 version */
-	boot_config->length = length;
+	boot_config->length = config_size;
 	boot_config->config_version.major = 1U;
 	boot_config->config_version.minor = 0U;
 	boot_config->config_version.subminor = 0U;
 	boot_config->config_version.patch = 0U;
 
-	/* msg version for task interface */
 	boot_config->client_version_support.num_versions = 1U;
 	boot_config->client_version_support.versions[0].major = major;
 	boot_config->client_version_support.versions[0].minor = 0U;
@@ -221,7 +219,7 @@ int ipu7_boot_init_boot_config(struct ipu7_bus_device *adev,
 
 	dev_dbg(dev, "boot config queues_nr: %d freq: %u sys_conf: 0x%pad\n",
 		num_queues, uc_freq, &subsys_config);
-	/* Allocate boot config. */
+
 	adev->boot_config_size =
 		sizeof(*cfgs) * num_queues + sizeof(*boot_config);
 	adev->boot_config = ipu7_dma_alloc(adev, adev->boot_config_size,
@@ -257,12 +255,15 @@ int ipu7_boot_init_boot_config(struct ipu7_bus_device *adev,
 		qconfigs[i].queue_size = queue_size;
 	}
 
-	/* Allocate queue memory */
 	syscom->queue_mem = ipu7_dma_alloc(adev, total_queue_size_aligned,
 					   &syscom->queue_mem_dma_addr,
 					   GFP_KERNEL, 0);
 	if (!syscom->queue_mem) {
 		dev_err(dev, "Failed to allocate queue memory.\n");
+		ipu7_dma_free(adev, adev->boot_config_size,
+			      adev->boot_config,
+			      adev->boot_config_dma_addr, 0);
+		adev->boot_config = NULL;
 		return -ENOMEM;
 	}
 	syscom->queue_mem_size = total_queue_size_aligned;
@@ -312,7 +313,6 @@ EXPORT_SYMBOL_NS_GPL(ipu7_boot_release_boot_config, "INTEL_IPU7");
 int ipu7_boot_start_fw(const struct ipu7_bus_device *adev)
 {
 	const struct device *dev = &adev->auxdev.dev;
-	u32 timeout = IPU_FW_START_STOP_TIMEOUT;
 	void __iomem *base = adev->isp->base;
 	u32 boot_state, last_boot_state;
 	u32 indices_addr, msg_ver, id;
@@ -323,37 +323,26 @@ int ipu7_boot_start_fw(const struct ipu7_bus_device *adev)
 		return ret;
 
 	dev_dbg(dev, "start booting fw...\n");
-	/* store "uninit" state to syscom/boot state reg */
 	write_fw_boot_param(adev, IA_GOFO_FW_BOOT_STATE_ID,
 			    IA_GOFO_FW_BOOT_STATE_UNINIT);
-	/*
-	 * Set registers to zero
-	 * (not strictly required, but recommended for diagnostics)
-	 */
 	write_fw_boot_param(adev,
 			    IA_GOFO_FW_BOOT_SYSCOM_QUEUE_INDICES_BASE_ID, 0);
 	write_fw_boot_param(adev, IA_GOFO_FW_BOOT_MESSAGING_VERSION_ID, 0);
-	/* store firmware configuration address */
 	write_fw_boot_param(adev, IA_GOFO_FW_BOOT_CONFIG_ID,
 			    adev->boot_config_dma_addr);
 
-	/* Kick uC, then wait for boot complete */
 	ipu7_boot_cell_start(adev);
 
 	last_boot_state = IA_GOFO_FW_BOOT_STATE_UNINIT;
-	while (timeout--) {
-		boot_state = read_fw_boot_param(adev,
-						IA_GOFO_FW_BOOT_STATE_ID);
-		if (boot_state != last_boot_state) {
-			dev_dbg(dev, "boot state changed from 0x%x to 0x%x\n",
-				last_boot_state, boot_state);
-			last_boot_state = boot_state;
-		}
-		if (BOOT_STATE_IS_CRITICAL(boot_state) ||
-		    BOOT_STATE_IS_READY(boot_state))
-			break;
-		usleep_range(1000, 1200);
-	}
+	ret = read_poll_timeout(read_fw_boot_param, boot_state,
+				BOOT_STATE_IS_CRITICAL(boot_state) ||
+				BOOT_STATE_IS_READY(boot_state),
+				1000, IPU_FW_START_STOP_TIMEOUT * 1000ULL,
+				false, adev, IA_GOFO_FW_BOOT_STATE_ID);
+
+	if (boot_state != last_boot_state)
+		dev_dbg(dev, "boot state changed from 0x%x to 0x%x\n",
+			last_boot_state, boot_state);
 
 	if (BOOT_STATE_IS_CRITICAL(boot_state)) {
 		ipu7_dump_fw_error_log(adev);
@@ -365,13 +354,11 @@ int ipu7_boot_start_fw(const struct ipu7_bus_device *adev)
 	}
 	dev_dbg(dev, "fw boot done.\n");
 
-	/* Get FW syscom queue indices addr */
 	id = IA_GOFO_FW_BOOT_SYSCOM_QUEUE_INDICES_BASE_ID;
 	indices_addr = read_fw_boot_param(adev, id);
 	adev->syscom->queue_indices = base + indices_addr;
 	dev_dbg(dev, "fw queue indices offset is 0x%x\n", indices_addr);
 
-	/* Get message version. */
 	msg_ver = read_fw_boot_param(adev,
 				     IA_GOFO_FW_BOOT_MESSAGING_VERSION_ID);
 	dev_dbg(dev, "ipu message version is 0x%08x\n", msg_ver);
@@ -383,8 +370,8 @@ EXPORT_SYMBOL_NS_GPL(ipu7_boot_start_fw, "INTEL_IPU7");
 int ipu7_boot_stop_fw(const struct ipu7_bus_device *adev)
 {
 	const struct device *dev = &adev->auxdev.dev;
-	u32 timeout = IPU_FW_START_STOP_TIMEOUT;
 	u32 boot_state;
+	int ret;
 
 	boot_state = read_fw_boot_param(adev, IA_GOFO_FW_BOOT_STATE_ID);
 	if (BOOT_STATE_IS_CRITICAL(boot_state) ||
@@ -394,18 +381,15 @@ int ipu7_boot_stop_fw(const struct ipu7_bus_device *adev)
 		return -EBUSY;
 	}
 
-	/* Issue shutdown to start shutdown process */
 	dev_dbg(dev, "stopping fw...\n");
 	write_fw_boot_param(adev, IA_GOFO_FW_BOOT_STATE_ID,
 			    IA_GOFO_FW_BOOT_STATE_SHUTDOWN_CMD);
-	while (timeout--) {
-		boot_state = read_fw_boot_param(adev,
-						IA_GOFO_FW_BOOT_STATE_ID);
-		if (BOOT_STATE_IS_CRITICAL(boot_state) ||
-		    BOOT_STATE_IS_INACTIVE(boot_state))
-			break;
-		usleep_range(1000, 1200);
-	}
+
+	ret = read_poll_timeout(read_fw_boot_param, boot_state,
+				BOOT_STATE_IS_CRITICAL(boot_state) ||
+				BOOT_STATE_IS_INACTIVE(boot_state),
+				1000, IPU_FW_START_STOP_TIMEOUT * 1000ULL,
+				false, adev, IA_GOFO_FW_BOOT_STATE_ID);
 
 	if (BOOT_STATE_IS_CRITICAL(boot_state)) {
 		ipu7_dump_fw_error_log(adev);
-- 
2.50.1 (Apple Git-155)


             reply	other threads:[~2026-05-17 14:35 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-17 14:34 shayderrr [this message]
2026-05-17 23:33 ` kernel test robot

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=20260517143456.81109-1-darknessshayder@gmail.com \
    --to=darknessshayder@gmail.com \
    --cc=bingbu.cao@intel.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=linux-staging@lists.linux.dev \
    --cc=mchehab@kernel.org \
    --cc=sakari.ailus@linux.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®