]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
media: tunner: xc5000: Refactor firmware load
authorRicardo Ribalda <ribalda@chromium.org>
Thu, 11 Apr 2024 21:17:54 +0000 (21:17 +0000)
committerHans Verkuil <hverkuil-cisco@xs4all.nl>
Mon, 15 Apr 2024 11:42:38 +0000 (13:42 +0200)
Make sure the firmware is released when we leave
xc_load_fw_and_init_tuner()

This change makes smatch happy:
drivers/media/tuners/xc5000.c:1213 xc_load_fw_and_init_tuner() warn: 'fw' from request_firmware() not released on lines: 1213.

Cc: Shuah Khan <shuah.kh@samsung.com>
Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
drivers/media/tuners/xc5000.c

index 2182e5b7b6064c2f129e06d73ad7aca6ab603e6a..30aa4ee958bdeabf45a16af9c42d7762bb395895 100644 (file)
@@ -58,7 +58,7 @@ struct xc5000_priv {
        struct dvb_frontend *fe;
        struct delayed_work timer_sleep;
 
-       const struct firmware   *firmware;
+       bool inited;
 };
 
 /* Misc Defines */
@@ -1110,23 +1110,19 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force)
        if (!force && xc5000_is_firmware_loaded(fe) == 0)
                return 0;
 
-       if (!priv->firmware) {
-               ret = request_firmware(&fw, desired_fw->name,
-                                       priv->i2c_props.adap->dev.parent);
-               if (ret) {
-                       pr_err("xc5000: Upload failed. rc %d\n", ret);
-                       return ret;
-               }
-               dprintk(1, "firmware read %zu bytes.\n", fw->size);
+       ret = request_firmware(&fw, desired_fw->name,
+                              priv->i2c_props.adap->dev.parent);
+       if (ret) {
+               pr_err("xc5000: Upload failed. rc %d\n", ret);
+               return ret;
+       }
+       dprintk(1, "firmware read %zu bytes.\n", fw->size);
 
-               if (fw->size != desired_fw->size) {
-                       pr_err("xc5000: Firmware file with incorrect size\n");
-                       release_firmware(fw);
-                       return -EINVAL;
-               }
-               priv->firmware = fw;
-       } else
-               fw = priv->firmware;
+       if (fw->size != desired_fw->size) {
+               pr_err("xc5000: Firmware file with incorrect size\n");
+               release_firmware(fw);
+               return -EINVAL;
+       }
 
        /* Try up to 5 times to load firmware */
        for (i = 0; i < 5; i++) {
@@ -1204,6 +1200,7 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force)
        }
 
 err:
+       release_firmware(fw);
        if (!ret)
                printk(KERN_INFO "xc5000: Firmware %s loaded and running.\n",
                       desired_fw->name);
@@ -1274,7 +1271,7 @@ static int xc5000_resume(struct dvb_frontend *fe)
 
        /* suspended before firmware is loaded.
           Avoid firmware load in resume path. */
-       if (!priv->firmware)
+       if (!priv->inited)
                return 0;
 
        return xc5000_set_params(fe);
@@ -1293,6 +1290,8 @@ static int xc5000_init(struct dvb_frontend *fe)
        if (debug)
                xc_debug_dump(priv);
 
+       priv->inited = true;
+
        return 0;
 }
 
@@ -1306,10 +1305,6 @@ static void xc5000_release(struct dvb_frontend *fe)
 
        if (priv) {
                cancel_delayed_work(&priv->timer_sleep);
-               if (priv->firmware) {
-                       release_firmware(priv->firmware);
-                       priv->firmware = NULL;
-               }
                hybrid_tuner_release_state(priv);
        }