]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
staging: sm750fb: add missing pci_release_region on error and removal
authorArtem Lytkin <iprintercanon@gmail.com>
Mon, 16 Feb 2026 20:20:38 +0000 (20:20 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 23 Feb 2026 15:32:56 +0000 (16:32 +0100)
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
drivers/staging/sm750fb/sm750_hw.c

index dec1f6b88a7dff133bb1ff4b42e08f14fde19df0..62f6e0cdff4d48f46be2a4443ddfd0c9a74a18cc 100644 (file)
@@ -1123,6 +1123,7 @@ static void lynxfb_pci_remove(struct pci_dev *pdev)
 
        iounmap(sm750_dev->pvReg);
        iounmap(sm750_dev->pvMem);
+       pci_release_region(pdev, 1);
        kfree(g_settings);
 }
 
index a29faee91c784fbd76a74831c1ccc8bb7121ae54..f60b152a647d3f18ff1ba586cf911822f7ece3ee 100644 (file)
@@ -36,16 +36,11 @@ int hw_sm750_map(struct sm750_dev *sm750_dev, struct pci_dev *pdev)
 
        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_dev, struct pci_dev *pdev)
        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_dev, struct pci_dev *pdev)
        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;
 }