diff options
| -rw-r--r-- | drivers/media/tuners/tuner-xc2028.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/drivers/media/tuners/tuner-xc2028.c b/drivers/media/tuners/tuner-xc2028.c index 1057da54c6e0..75afab718ba6 100644 --- a/drivers/media/tuners/tuner-xc2028.c +++ b/drivers/media/tuners/tuner-xc2028.c | |||
| @@ -709,6 +709,8 @@ static int load_scode(struct dvb_frontend *fe, unsigned int type, | |||
| 709 | return 0; | 709 | return 0; |
| 710 | } | 710 | } |
| 711 | 711 | ||
| 712 | static int xc2028_sleep(struct dvb_frontend *fe); | ||
| 713 | |||
| 712 | static int check_firmware(struct dvb_frontend *fe, unsigned int type, | 714 | static int check_firmware(struct dvb_frontend *fe, unsigned int type, |
| 713 | v4l2_std_id std, __u16 int_freq) | 715 | v4l2_std_id std, __u16 int_freq) |
| 714 | { | 716 | { |
| @@ -881,7 +883,7 @@ read_not_reliable: | |||
| 881 | return 0; | 883 | return 0; |
| 882 | 884 | ||
| 883 | fail: | 885 | fail: |
| 884 | priv->state = XC2028_SLEEP; | 886 | priv->state = XC2028_NO_FIRMWARE; |
| 885 | 887 | ||
| 886 | memset(&priv->cur_fw, 0, sizeof(priv->cur_fw)); | 888 | memset(&priv->cur_fw, 0, sizeof(priv->cur_fw)); |
| 887 | if (retry_count < 8) { | 889 | if (retry_count < 8) { |
| @@ -891,6 +893,9 @@ fail: | |||
| 891 | goto retry; | 893 | goto retry; |
| 892 | } | 894 | } |
| 893 | 895 | ||
| 896 | /* Firmware didn't load. Put the device to sleep */ | ||
| 897 | xc2028_sleep(fe); | ||
| 898 | |||
| 894 | if (rc == -ENOENT) | 899 | if (rc == -ENOENT) |
| 895 | rc = -EINVAL; | 900 | rc = -EINVAL; |
| 896 | return rc; | 901 | return rc; |
| @@ -1276,6 +1281,10 @@ static int xc2028_sleep(struct dvb_frontend *fe) | |||
| 1276 | if (no_poweroff || priv->ctrl.disable_power_mgmt) | 1281 | if (no_poweroff || priv->ctrl.disable_power_mgmt) |
| 1277 | return 0; | 1282 | return 0; |
| 1278 | 1283 | ||
| 1284 | /* Device is already in sleep mode */ | ||
| 1285 | if (priv->state == XC2028_SLEEP) | ||
| 1286 | return 0; | ||
| 1287 | |||
| 1279 | tuner_dbg("Putting xc2028/3028 into poweroff mode.\n"); | 1288 | tuner_dbg("Putting xc2028/3028 into poweroff mode.\n"); |
| 1280 | if (debug > 1) { | 1289 | if (debug > 1) { |
| 1281 | tuner_dbg("Printing sleep stack trace:\n"); | 1290 | tuner_dbg("Printing sleep stack trace:\n"); |
| @@ -1289,7 +1298,8 @@ static int xc2028_sleep(struct dvb_frontend *fe) | |||
| 1289 | else | 1298 | else |
| 1290 | rc = send_seq(priv, {0x80, XREG_POWER_DOWN, 0x00, 0x00}); | 1299 | rc = send_seq(priv, {0x80, XREG_POWER_DOWN, 0x00, 0x00}); |
| 1291 | 1300 | ||
| 1292 | priv->state = XC2028_SLEEP; | 1301 | if (rc >= 0) |
| 1302 | priv->state = XC2028_SLEEP; | ||
| 1293 | 1303 | ||
| 1294 | mutex_unlock(&priv->lock); | 1304 | mutex_unlock(&priv->lock); |
| 1295 | 1305 | ||
| @@ -1357,7 +1367,7 @@ static void load_firmware_cb(const struct firmware *fw, | |||
| 1357 | 1367 | ||
| 1358 | if (rc < 0) | 1368 | if (rc < 0) |
| 1359 | return; | 1369 | return; |
| 1360 | priv->state = XC2028_SLEEP; | 1370 | priv->state = XC2028_ACTIVE; |
| 1361 | } | 1371 | } |
| 1362 | 1372 | ||
| 1363 | static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg) | 1373 | static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg) |
