u8  radio_input;
 
        int chip_id;
+       u16 pll_register_no;
 };
 
 /* Misc Defines */
 struct xc5000_fw_cfg {
        char *name;
        u16 size;
+       u16 pll_reg;
 };
 
 #define XC5000A_FIRMWARE "dvb-fe-xc5000-1.6.114.fw"
 static const struct xc5000_fw_cfg xc5000a_1_6_114 = {
        .name = XC5000A_FIRMWARE,
        .size = 12401,
+       .pll_reg = 0x806c,
 };
 
 #define XC5000C_FIRMWARE "dvb-fe-xc5000c-41.024.5.fw"
 static const struct xc5000_fw_cfg xc5000c_41_024_5 = {
        .name = XC5000C_FIRMWARE,
        .size = 16497,
+       .pll_reg = 0x13,
 };
 
 static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id)
        }
 }
 
-static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe);
+static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force);
 static int xc5000_is_firmware_loaded(struct dvb_frontend *fe);
 static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val);
 static int xc5000_TunerReset(struct dvb_frontend *fe);
        int ret;
        const struct xc5000_fw_cfg *desired_fw =
                xc5000_assign_firmware(priv->chip_id);
+       priv->pll_register_no = desired_fw->pll_reg;
 
        /* request the firmware, this will block and timeout */
        printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n",
        u8 hw_majorversion = 0, hw_minorversion = 0;
        u8 fw_majorversion = 0, fw_minorversion = 0;
        u16 fw_buildversion = 0;
+       u16 regval;
 
        /* Wait for stats to stabilize.
         * Frame Lines needs two frame times after initial lock
        xc_get_totalgain(priv,  &totalgain);
        dprintk(1, "*** Total gain = %d.%d dB\n", totalgain / 256,
                (totalgain % 256) * 100 / 256);
+
+       if (priv->pll_register_no) {
+               xc5000_readreg(priv, priv->pll_register_no, ®val);
+               dprintk(1, "*** PLL lock status = 0x%04x\n", regval);
+       }
 }
 
 static int xc5000_set_params(struct dvb_frontend *fe)
        u32 freq = fe->dtv_property_cache.frequency;
        u32 delsys  = fe->dtv_property_cache.delivery_system;
 
-       if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) {
+       if (xc_load_fw_and_init_tuner(fe, 0) != XC_RESULT_SUCCESS) {
                dprintk(1, "Unable to load firmware and init tuner\n");
                return -EINVAL;
        }
        struct analog_parameters *params)
 {
        struct xc5000_priv *priv = fe->tuner_priv;
+       u16 pll_lock_status;
        int ret;
 
        dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
        if (debug)
                xc_debug_dump(priv);
 
+       if (priv->pll_register_no != 0) {
+               msleep(20);
+               xc5000_readreg(priv, priv->pll_register_no, &pll_lock_status);
+               if (pll_lock_status > 63) {
+                       /* PLL is unlocked, force reload of the firmware */
+                       dprintk(1, "xc5000: PLL not locked (0x%x).  Reloading...\n",
+                               pll_lock_status);
+                       if (xc_load_fw_and_init_tuner(fe, 1) != XC_RESULT_SUCCESS) {
+                               printk(KERN_ERR "xc5000: Unable to reload fw\n");
+                               return -EREMOTEIO;
+                       }
+                       goto tune_channel;
+               }
+       }
+
        return 0;
 }
 
        if (priv->i2c_props.adap == NULL)
                return -EINVAL;
 
-       if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) {
+       if (xc_load_fw_and_init_tuner(fe, 0) != XC_RESULT_SUCCESS) {
                dprintk(1, "Unable to load firmware and init tuner\n");
                return -EINVAL;
        }
        return 0;
 }
 
-static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe)
+static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force)
 {
        struct xc5000_priv *priv = fe->tuner_priv;
        int ret = XC_RESULT_SUCCESS;
+       u16 pll_lock_status;
+
+       if (force || xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
+
+fw_retry:
 
-       if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
                ret = xc5000_fwupload(fe);
                if (ret != XC_RESULT_SUCCESS)
                        return ret;
 
+               msleep(20);
+
                /* Start the tuner self-calibration process */
                ret |= xc_initialize(priv);
 
+               if (ret != XC_RESULT_SUCCESS)
+                       goto fw_retry;
+
                /* Wait for calibration to complete.
                 * We could continue but XC5000 will clock stretch subsequent
                 * I2C transactions until calibration is complete.  This way we
                 */
                xc_wait(100);
 
+               if (priv->pll_register_no) {
+                       xc5000_readreg(priv, priv->pll_register_no,
+                                      &pll_lock_status);
+                       if (pll_lock_status > 63) {
+                               /* PLL is unlocked, force reload of the firmware */
+                               printk(KERN_ERR "xc5000: PLL not running after fwload.\n");
+                               goto fw_retry;
+                       }
+               }
+
                /* Default to "CABLE" mode */
                ret |= xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE);
        }
        struct xc5000_priv *priv = fe->tuner_priv;
        dprintk(1, "%s()\n", __func__);
 
-       if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) {
+       if (xc_load_fw_and_init_tuner(fe, 0) != XC_RESULT_SUCCESS) {
                printk(KERN_ERR "xc5000: Unable to initialise tuner\n");
                return -EREMOTEIO;
        }