[PATCH 6.18 210/333] staging: sm750fb: add missing pci_release_region on error and removal

Greg Kroah-Hartman
2026-03-17T17:21:25Z

From: Artem Lytkin <iprintercanon@gmail.com>

commit 8225489ddb900656cc21573b4e1b00c9181fd777 upstream.

hw_sm750_map() calls pci_request_region() but never releases the
region on error paths or in lynxfb_pci_remove(). This causes a
resource leak that prevents the PCI region from being mapped again
after driver removal or a failed probe. A TODO comment in the code
acknowledges this missing cleanup.

Restructure the error handling in hw_sm750_map() to properly release
the PCI region on ioremap failures, and add pci_release_region() to
lynxfb_pci_remove().

Signed-off-by: Artem Lytkin <iprintercanon@gmail.com>
Cc: stable <stable@kernel.org>
Link: https://patch.msgid.link/20260216202038.1828-1-iprintercanon@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/staging/sm750fb/sm750.c | 1 +
drivers/staging/sm750fb/sm750_hw.c | 22 +++++++++++-----------
2 files changed, 12 insertions(+), 11 deletions(-)

--- a/drivers/staging/sm750fb/sm750.c
+++ b/drivers/staging/sm750fb/sm750.c
@@ -1118,6 +1118,7 @@ static void lynxfb_pci_remove(struct pci

iounmap(sm750_dev->pvReg);
iounmap(sm750_dev->pvMem);
+ pci_release_region(pdev, 1);
kfree(g_settings);
}

--- a/drivers/staging/sm750fb/sm750_hw.c
+++ b/drivers/staging/sm750fb/sm750_hw.c
@@ -36,16 +36,11 @@ int hw_sm750_map(struct sm750_dev *sm750

pr_info("mmio phyAddr = %lx\n", sm750_dev->vidreg_start);

- /*
- * reserve the vidreg space of smi adaptor
- * if you do this, you need to add release region code
- * in lynxfb_remove, or memory will not be mapped again
- * successfully
- */
+ /* reserve the vidreg space of smi adaptor */
ret = pci_request_region(pdev, 1, "sm750fb");
if (ret) {
pr_err("Can not request PCI regions.\n");
- goto exit;
+ return ret;
}

/* now map mmio and vidmem */
@@ -54,7 +49,7 @@ int hw_sm750_map(struct sm750_dev *sm750
if (!sm750_dev->pvReg) {
pr_err("mmio failed\n");
ret = -EFAULT;
- goto exit;
+ goto err_release_region;
}
pr_info("mmio virtual addr = %p\n", sm750_dev->pvReg);

@@ -79,13 +74,18 @@ int hw_sm750_map(struct sm750_dev *sm750
sm750_dev->pvMem =
ioremap_wc(sm750_dev->vidmem_start, sm750_dev->vidmem_size);
if (!sm750_dev->pvMem) {
- iounmap(sm750_dev->pvReg);
pr_err("Map video memory failed\n");
ret = -EFAULT;
- goto exit;
+ goto err_unmap_reg;
}
pr_info("video memory vaddr = %p\n", sm750_dev->pvMem);
-exit:
+
+ return 0;
+
+err_unmap_reg:
+ iounmap(sm750_dev->pvReg);
+err_release_region:
+ pci_release_region(pdev, 1);
return ret;
}