diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c index 7fae5b1b8adf..8a3c41a80c03 100644 --- a/drivers/media/dvb-frontends/si2168.c +++ b/drivers/media/dvb-frontends/si2168.c @@ -514,6 +514,7 @@ static int si2168_init(struct dvb_frontend *fe) goto err; dev->warm = true; + dev->initialized = true; warm: /* Init stats here to indicate which stats are supported */ c->cnr.len = 1; @@ -535,6 +536,26 @@ err: return ret; } +static int si2168_resume(struct dvb_frontend *fe) +{ + struct i2c_client *client = fe->demodulator_priv; + struct si2168_dev *dev = i2c_get_clientdata(client); + + /* + * check whether si2168_init() has been called successfully + * outside of a resume cycle. Only call it (and load firmware) + * in this case. si2168_init() is only called during resume + * once the device has actually been used. Otherwise, leave the + * device untouched. + */ + if (dev->initialized) { + dev_dbg(&client->dev, "previsously initialized, call si2168_init()\n"); + return si2168_init(fe); + } + dev_dbg(&client->dev, "not initialized yet, skipping init on resume\n"); + return 0; +} + static int si2168_sleep(struct dvb_frontend *fe) { struct i2c_client *client = fe->demodulator_priv; @@ -644,6 +665,7 @@ static const struct dvb_frontend_ops si2168_ops = { .init = si2168_init, .sleep = si2168_sleep, + .resume = si2168_resume, .set_frontend = si2168_set_frontend, diff --git a/drivers/media/dvb-frontends/si2168_priv.h b/drivers/media/dvb-frontends/si2168_priv.h index 4f4d122e3963..3a8976229a4a 100644 --- a/drivers/media/dvb-frontends/si2168_priv.h +++ b/drivers/media/dvb-frontends/si2168_priv.h @@ -36,6 +36,7 @@ struct si2168_dev { u8 ts_mode; unsigned int active:1; unsigned int warm:1; + unsigned int initialized:1; unsigned int ts_clock_inv:1; unsigned int ts_clock_gapped:1; unsigned int spectral_inversion:1;