aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <m.chehab@samsung.com>2014-07-30 10:09:15 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-07-30 14:55:26 -0400
commit8604f3552b1c995186acc8306acf25ee73fd9d5e (patch)
tree30eef24b2a58be9ebc3f530080cd4c1f20017706 /drivers/media
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>
Diffstat (limited to 'drivers/media')
-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 460df44aa1ad..39f9fb1001d8 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)
625 return ret; 625 return ret;
626} 626}
627 627
628static int xc5000_fwupload(struct dvb_frontend *fe) 628static int xc5000_fwupload(struct dvb_frontend *fe,
629 const struct xc5000_fw_cfg *desired_fw,
630 const struct firmware *fw)
629{ 631{
630 struct xc5000_priv *priv = fe->tuner_priv; 632 struct xc5000_priv *priv = fe->tuner_priv;
631 const struct firmware *fw;
632 int ret; 633 int ret;
633 const struct xc5000_fw_cfg *desired_fw =
634 xc5000_assign_firmware(priv->chip_id);
635 priv->pll_register_no = desired_fw->pll_reg;
636 priv->init_status_supported = desired_fw->init_status_supported;
637 priv->fw_checksum_supported = desired_fw->fw_checksum_supported;
638 634
639 /* request the firmware, this will block and timeout */ 635 /* request the firmware, this will block and timeout */
640 printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n", 636 dprintk(1, "waiting for firmware upload (%s)...\n",
641 desired_fw->name); 637 desired_fw->name);
642 638
643 ret = request_firmware(&fw, desired_fw->name, 639 priv->pll_register_no = desired_fw->pll_reg;
644 priv->i2c_props.adap->dev.parent); 640 priv->init_status_supported = desired_fw->init_status_supported;
645 if (ret) { 641 priv->fw_checksum_supported = desired_fw->fw_checksum_supported;
646 printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n");
647 goto out;
648 } else {
649 printk(KERN_DEBUG "xc5000: firmware read %Zu bytes.\n",
650 fw->size);
651 ret = 0;
652 }
653 642
654 if (fw->size != desired_fw->size) {
655 printk(KERN_ERR "xc5000: firmware incorrect size\n");
656 ret = -EINVAL;
657 } else {
658 printk(KERN_INFO "xc5000: firmware uploading...\n");
659 ret = xc_load_i2c_sequence(fe, fw->data);
660 if (0 == ret)
661 ret = xc_set_xtal(fe);
662 if (0 == ret)
663 printk(KERN_INFO "xc5000: firmware upload complete...\n");
664 else
665 printk(KERN_ERR "xc5000: firmware upload failed...\n");
666 }
667 643
668out: 644 dprintk(1, "firmware uploading...\n");
669 release_firmware(fw); 645 ret = xc_load_i2c_sequence(fe, fw->data);
646 if (!ret) {
647 ret = xc_set_xtal(fe);
648 dprintk(1, "Firmware upload complete...\n");
649 } else
650 printk(KERN_ERR "xc5000: firmware upload failed...\n");
651
670 return ret; 652 return ret;
671} 653}
672 654
@@ -1101,6 +1083,8 @@ static int xc5000_get_status(struct dvb_frontend *fe, u32 *status)
1101static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force) 1083static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force)
1102{ 1084{
1103 struct xc5000_priv *priv = fe->tuner_priv; 1085 struct xc5000_priv *priv = fe->tuner_priv;
1086 const struct xc5000_fw_cfg *desired_fw = xc5000_assign_firmware(priv->chip_id);
1087 const struct firmware *fw;
1104 int ret, i; 1088 int ret, i;
1105 u16 pll_lock_status; 1089 u16 pll_lock_status;
1106 u16 fw_ck; 1090 u16 fw_ck;
@@ -1110,11 +1094,26 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force)
1110 if (!force && xc5000_is_firmware_loaded(fe) == 0) 1094 if (!force && xc5000_is_firmware_loaded(fe) == 0)
1111 return 0; 1095 return 0;
1112 1096
1097 ret = request_firmware(&fw, desired_fw->name,
1098 priv->i2c_props.adap->dev.parent);
1099 if (ret) {
1100 printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n");
1101 return ret;
1102 }
1103
1104 dprintk(1, "firmware read %Zu bytes.\n", fw->size);
1105
1106 if (fw->size != desired_fw->size) {
1107 printk(KERN_ERR "xc5000: firmware file with incorrect size\n");
1108 ret = -EINVAL;
1109 goto err;
1110 }
1111
1113 /* Try up to 5 times to load firmware */ 1112 /* Try up to 5 times to load firmware */
1114 for (i = 0; i < 5; i++) { 1113 for (i = 0; i < 5; i++) {
1115 ret = xc5000_fwupload(fe); 1114 ret = xc5000_fwupload(fe, desired_fw, fw);
1116 if (ret != 0) 1115 if (ret != 0)
1117 return ret; 1116 goto err;
1118 1117
1119 msleep(20); 1118 msleep(20);
1120 1119
@@ -1171,9 +1170,13 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force)
1171 1170
1172 /* Default to "CABLE" mode */ 1171 /* Default to "CABLE" mode */
1173 ret = xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE); 1172 ret = xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE);
1173 printk(KERN_INFO "xc5000: Firmware %s loaded and running.\n",
1174 desired_fw->name);
1174 break; 1175 break;
1175 } 1176 }
1176 1177
1178err:
1179 release_firmware(fw);
1177 return ret; 1180 return ret;
1178} 1181}
1179 1182