aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/tuners/tuner-xc2028.c')
-rw-r--r--drivers/media/tuners/tuner-xc2028.c37
1 files changed, 16 insertions, 21 deletions
diff --git a/drivers/media/tuners/tuner-xc2028.c b/drivers/media/tuners/tuner-xc2028.c
index 317ef63ee789..8d96a22647b3 100644
--- a/drivers/media/tuners/tuner-xc2028.c
+++ b/drivers/media/tuners/tuner-xc2028.c
@@ -281,6 +281,14 @@ static void free_firmware(struct xc2028_data *priv)
281 int i; 281 int i;
282 tuner_dbg("%s called\n", __func__); 282 tuner_dbg("%s called\n", __func__);
283 283
284 /* free allocated f/w string */
285 if (priv->fname != firmware_name)
286 kfree(priv->fname);
287 priv->fname = NULL;
288
289 priv->state = XC2028_NO_FIRMWARE;
290 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
291
284 if (!priv->firm) 292 if (!priv->firm)
285 return; 293 return;
286 294
@@ -291,9 +299,6 @@ static void free_firmware(struct xc2028_data *priv)
291 299
292 priv->firm = NULL; 300 priv->firm = NULL;
293 priv->firm_size = 0; 301 priv->firm_size = 0;
294 priv->state = XC2028_NO_FIRMWARE;
295
296 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
297} 302}
298 303
299static int load_all_firmwares(struct dvb_frontend *fe, 304static int load_all_firmwares(struct dvb_frontend *fe,
@@ -884,9 +889,8 @@ read_not_reliable:
884 return 0; 889 return 0;
885 890
886fail: 891fail:
887 priv->state = XC2028_NO_FIRMWARE; 892 free_firmware(priv);
888 893
889 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
890 if (retry_count < 8) { 894 if (retry_count < 8) {
891 msleep(50); 895 msleep(50);
892 retry_count++; 896 retry_count++;
@@ -1332,11 +1336,8 @@ static int xc2028_dvb_release(struct dvb_frontend *fe)
1332 mutex_lock(&xc2028_list_mutex); 1336 mutex_lock(&xc2028_list_mutex);
1333 1337
1334 /* only perform final cleanup if this is the last instance */ 1338 /* only perform final cleanup if this is the last instance */
1335 if (hybrid_tuner_report_instance_count(priv) == 1) { 1339 if (hybrid_tuner_report_instance_count(priv) == 1)
1336 free_firmware(priv); 1340 free_firmware(priv);
1337 kfree(priv->ctrl.fname);
1338 priv->ctrl.fname = NULL;
1339 }
1340 1341
1341 if (priv) 1342 if (priv)
1342 hybrid_tuner_release_state(priv); 1343 hybrid_tuner_release_state(priv);
@@ -1399,19 +1400,8 @@ static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg)
1399 1400
1400 /* 1401 /*
1401 * Copy the config data. 1402 * Copy the config data.
1402 * For the firmware name, keep a local copy of the string,
1403 * in order to avoid troubles during device release.
1404 */ 1403 */
1405 kfree(priv->ctrl.fname);
1406 priv->ctrl.fname = NULL;
1407 memcpy(&priv->ctrl, p, sizeof(priv->ctrl)); 1404 memcpy(&priv->ctrl, p, sizeof(priv->ctrl));
1408 if (p->fname) {
1409 priv->ctrl.fname = kstrdup(p->fname, GFP_KERNEL);
1410 if (priv->ctrl.fname == NULL) {
1411 rc = -ENOMEM;
1412 goto unlock;
1413 }
1414 }
1415 1405
1416 /* 1406 /*
1417 * If firmware name changed, frees firmware. As free_firmware will 1407 * If firmware name changed, frees firmware. As free_firmware will
@@ -1426,10 +1416,15 @@ static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg)
1426 1416
1427 if (priv->state == XC2028_NO_FIRMWARE) { 1417 if (priv->state == XC2028_NO_FIRMWARE) {
1428 if (!firmware_name[0]) 1418 if (!firmware_name[0])
1429 priv->fname = priv->ctrl.fname; 1419 priv->fname = kstrdup(p->fname, GFP_KERNEL);
1430 else 1420 else
1431 priv->fname = firmware_name; 1421 priv->fname = firmware_name;
1432 1422
1423 if (!priv->fname) {
1424 rc = -ENOMEM;
1425 goto unlock;
1426 }
1427
1433 rc = request_firmware_nowait(THIS_MODULE, 1, 1428 rc = request_firmware_nowait(THIS_MODULE, 1,
1434 priv->fname, 1429 priv->fname,
1435 priv->i2c_props.adap->dev.parent, 1430 priv->i2c_props.adap->dev.parent,