diff options
author | Shuah Khan <shuahkh@osg.samsung.com> | 2014-09-22 20:30:46 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2014-09-23 15:13:48 -0400 |
commit | 5264a522a597032c009f9143686ebf0fa4e244fb (patch) | |
tree | 101ba095de6e94cbf6e9c8f9f210bd493268bd77 /drivers/media | |
parent | 8eb988f1be98e13d33c786ad1511f9870d3038fb (diff) |
[media] media: tuner xc5000 - release firmwware from xc5000_release()
xc5000 releases firmware right after loading it. Change it to
save the firmware and release it from xc5000_release(). This
helps avoid fecthing firmware when forced firmware load requests
come in to change analog tv frequence and when firmware needs to
be reloaded after suspend and resume.
Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/tuners/xc5000.c | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c index 512fe508bcd2..b72ec64b758c 100644 --- a/drivers/media/tuners/xc5000.c +++ b/drivers/media/tuners/xc5000.c | |||
@@ -70,6 +70,8 @@ struct xc5000_priv { | |||
70 | 70 | ||
71 | struct dvb_frontend *fe; | 71 | struct dvb_frontend *fe; |
72 | struct delayed_work timer_sleep; | 72 | struct delayed_work timer_sleep; |
73 | |||
74 | const struct firmware *firmware; | ||
73 | }; | 75 | }; |
74 | 76 | ||
75 | /* Misc Defines */ | 77 | /* Misc Defines */ |
@@ -1136,20 +1138,23 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force) | |||
1136 | if (!force && xc5000_is_firmware_loaded(fe) == 0) | 1138 | if (!force && xc5000_is_firmware_loaded(fe) == 0) |
1137 | return 0; | 1139 | return 0; |
1138 | 1140 | ||
1139 | ret = request_firmware(&fw, desired_fw->name, | 1141 | if (!priv->firmware) { |
1140 | priv->i2c_props.adap->dev.parent); | 1142 | ret = request_firmware(&fw, desired_fw->name, |
1141 | if (ret) { | 1143 | priv->i2c_props.adap->dev.parent); |
1142 | printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n"); | 1144 | if (ret) { |
1143 | return ret; | 1145 | pr_err("xc5000: Upload failed. rc %d\n", ret); |
1144 | } | 1146 | return ret; |
1145 | 1147 | } | |
1146 | dprintk(1, "firmware read %Zu bytes.\n", fw->size); | 1148 | dprintk(1, "firmware read %Zu bytes.\n", fw->size); |
1147 | 1149 | ||
1148 | if (fw->size != desired_fw->size) { | 1150 | if (fw->size != desired_fw->size) { |
1149 | printk(KERN_ERR "xc5000: Firmware file with incorrect size\n"); | 1151 | pr_err("xc5000: Firmware file with incorrect size\n"); |
1150 | ret = -EINVAL; | 1152 | release_firmware(fw); |
1151 | goto err; | 1153 | return -EINVAL; |
1152 | } | 1154 | } |
1155 | priv->firmware = fw; | ||
1156 | } else | ||
1157 | fw = priv->firmware; | ||
1153 | 1158 | ||
1154 | /* Try up to 5 times to load firmware */ | 1159 | /* Try up to 5 times to load firmware */ |
1155 | for (i = 0; i < 5; i++) { | 1160 | for (i = 0; i < 5; i++) { |
@@ -1232,7 +1237,6 @@ err: | |||
1232 | else | 1237 | else |
1233 | printk(KERN_CONT " - too many retries. Giving up\n"); | 1238 | printk(KERN_CONT " - too many retries. Giving up\n"); |
1234 | 1239 | ||
1235 | release_firmware(fw); | ||
1236 | return ret; | 1240 | return ret; |
1237 | } | 1241 | } |
1238 | 1242 | ||
@@ -1316,6 +1320,8 @@ static int xc5000_release(struct dvb_frontend *fe) | |||
1316 | if (priv) { | 1320 | if (priv) { |
1317 | cancel_delayed_work(&priv->timer_sleep); | 1321 | cancel_delayed_work(&priv->timer_sleep); |
1318 | hybrid_tuner_release_state(priv); | 1322 | hybrid_tuner_release_state(priv); |
1323 | if (priv->firmware) | ||
1324 | release_firmware(priv->firmware); | ||
1319 | } | 1325 | } |
1320 | 1326 | ||
1321 | mutex_unlock(&xc5000_list_mutex); | 1327 | mutex_unlock(&xc5000_list_mutex); |