aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <m.chehab@samsung.com>2014-07-30 14:09:15 (GMT)
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-07-30 18:55:26 (GMT)
commit8604f3552b1c995186acc8306acf25ee73fd9d5e (patch)
tree30eef24b2a58be9ebc3f530080cd4c1f20017706
parent2621c0b3224633393ef9e24c3ac9de2770b3750c (diff)
[media] xc5000: optimize firmware retry logic
Currently, firmware retry logic keeps reading from FS every time during the retry logic. This is not needed. Instead, only release the firmware read after success. While here, make the non-debug messages less verbose, as it only matters to the user if the firmware was successfully loaded, or if some error happened. Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r--drivers/media/tuners/xc5000.c73
1 files changed, 38 insertions, 35 deletions
diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c
index 460df44..39f9fb1 100644
--- a/drivers/media/tuners/xc5000.c
+++ b/drivers/media/tuners/xc5000.c
@@ -625,48 +625,30 @@ static int xc_set_xtal(struct dvb_frontend *fe)
return ret;
}
-static int xc5000_fwupload(struct dvb_frontend *fe)
+static int xc5000_fwupload(struct dvb_frontend *fe,
+ const struct xc5000_fw_cfg *desired_fw,
+ const struct firmware *fw)
{
struct xc5000_priv *priv = fe->tuner_priv;
- const struct firmware *fw;
int ret;
- const struct xc5000_fw_cfg *desired_fw =
- xc5000_assign_firmware(priv->chip_id);
- priv->pll_register_no = desired_fw->pll_reg;
- priv->init_status_supported = desired_fw->init_status_supported;
- priv->fw_checksum_supported = desired_fw->fw_checksum_supported;
/* request the firmware, this will block and timeout */
- printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n",
+ dprintk(1, "waiting for firmware upload (%s)...\n",
desired_fw->name);
- ret = request_firmware(&fw, desired_fw->name,
- priv->i2c_props.adap->dev.parent);
- if (ret) {
- printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n");
- goto out;
- } else {
- printk(KERN_DEBUG "xc5000: firmware read %Zu bytes.\n",
- fw->size);
- ret = 0;
- }
+ priv->pll_register_no = desired_fw->pll_reg;
+ priv->init_status_supported = desired_fw->init_status_supported;
+ priv->fw_checksum_supported = desired_fw->fw_checksum_supported;
- if (fw->size != desired_fw->size) {
- printk(KERN_ERR "xc5000: firmware incorrect size\n");
- ret = -EINVAL;
- } else {
- printk(KERN_INFO "xc5000: firmware uploading...\n");
- ret = xc_load_i2c_sequence(fe, fw->data);
- if (0 == ret)
- ret = xc_set_xtal(fe);
- if (0 == ret)
- printk(KERN_INFO "xc5000: firmware upload complete...\n");
- else
- printk(KERN_ERR "xc5000: firmware upload failed...\n");
- }
-out:
- release_firmware(fw);
+ dprintk(1, "firmware uploading...\n");
+ ret = xc_load_i2c_sequence(fe, fw->data);
+ if (!ret) {
+ ret = xc_set_xtal(fe);
+ dprintk(1, "Firmware upload complete...\n");
+ } else
+ printk(KERN_ERR "xc5000: firmware upload failed...\n");
+
return ret;
}
@@ -1101,6 +1083,8 @@ static int xc5000_get_status(struct dvb_frontend *fe, u32 *status)
static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force)
{
struct xc5000_priv *priv = fe->tuner_priv;
+ const struct xc5000_fw_cfg *desired_fw = xc5000_assign_firmware(priv->chip_id);
+ const struct firmware *fw;
int ret, i;
u16 pll_lock_status;
u16 fw_ck;
@@ -1110,11 +1094,26 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force)
if (!force && xc5000_is_firmware_loaded(fe) == 0)
return 0;
+ ret = request_firmware(&fw, desired_fw->name,
+ priv->i2c_props.adap->dev.parent);
+ if (ret) {
+ printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n");
+ return ret;
+ }
+
+ dprintk(1, "firmware read %Zu bytes.\n", fw->size);
+
+ if (fw->size != desired_fw->size) {
+ printk(KERN_ERR "xc5000: firmware file with incorrect size\n");
+ ret = -EINVAL;
+ goto err;
+ }
+
/* Try up to 5 times to load firmware */
for (i = 0; i < 5; i++) {
- ret = xc5000_fwupload(fe);
+ ret = xc5000_fwupload(fe, desired_fw, fw);
if (ret != 0)
- return ret;
+ goto err;
msleep(20);
@@ -1171,9 +1170,13 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force)
/* Default to "CABLE" mode */
ret = xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE);
+ printk(KERN_INFO "xc5000: Firmware %s loaded and running.\n",
+ desired_fw->name);
break;
}
+err:
+ release_firmware(fw);
return ret;
}

Privacy Policy