V4L/DVB: [STV090x, STV6110x] Use tuner sleep within the demodulator control

Oliver Endriss <o.endriss@gmx.de> pointed out:
Imho not a good idea, as the frontend thread calls
- fe->ops.tuner_ops.init
- fe->ops.tuner_ops.sleep

If you remove fe->ops.i2c_gate_ctrl, init and sleep will fail,
because gate_ctrl was never called...

--

Signed-off-by: Manu Abraham <manu@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c
index 0af1708..a80a34b 100644
--- a/drivers/media/dvb/frontends/stv090x.c
+++ b/drivers/media/dvb/frontends/stv090x.c
@@ -3838,6 +3838,11 @@
 	struct stv090x_state *state = fe->demodulator_priv;
 	u32 reg;
 
+	if (state->config->tuner_init) {
+		if (state->config->tuner_sleep(fe) < 0)
+			goto err_gateoff;
+	}
+
 	dprintk(FE_DEBUG, 1, "Set %s to sleep",
 		state->device == STV0900 ? "STV0900" : "STV0903");
 
@@ -3852,6 +3857,9 @@
 		goto err;
 
 	return 0;
+
+err_gateoff:
+	stv090x_i2c_gate_ctrl(state, 0);
 err:
 	dprintk(FE_ERROR, 1, "I/O error");
 	return -1;
diff --git a/drivers/media/dvb/frontends/stv090x.h b/drivers/media/dvb/frontends/stv090x.h
index 30f01a6..dd1b93a 100644
--- a/drivers/media/dvb/frontends/stv090x.h
+++ b/drivers/media/dvb/frontends/stv090x.h
@@ -87,6 +87,7 @@
 	bool diseqc_envelope_mode;
 
 	int (*tuner_init) (struct dvb_frontend *fe);
+	int (*tuner_sleep) (struct dvb_frontend *fe);
 	int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode);
 	int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency);
 	int (*tuner_get_frequency) (struct dvb_frontend *fe, u32 *frequency);
diff --git a/drivers/media/dvb/frontends/stv6110x.c b/drivers/media/dvb/frontends/stv6110x.c
index dea4245..c1ddb83 100644
--- a/drivers/media/dvb/frontends/stv6110x.c
+++ b/drivers/media/dvb/frontends/stv6110x.c
@@ -338,14 +338,12 @@
 		.frequency_max	= 2150000,
 		.frequency_step	= 0,
 	},
-
-	.init			= stv6110x_init,
-	.sleep          	= stv6110x_sleep,
 	.release		= stv6110x_release
 };
 
 static struct stv6110x_devctl stv6110x_ctl = {
 	.tuner_init		= stv6110x_init,
+	.tuner_sleep		= stv6110x_sleep,
 	.tuner_set_mode		= stv6110x_set_mode,
 	.tuner_set_frequency	= stv6110x_set_frequency,
 	.tuner_get_frequency	= stv6110x_get_frequency,
diff --git a/drivers/media/dvb/frontends/stv6110x.h b/drivers/media/dvb/frontends/stv6110x.h
index 2429ae6..47516753 100644
--- a/drivers/media/dvb/frontends/stv6110x.h
+++ b/drivers/media/dvb/frontends/stv6110x.h
@@ -40,6 +40,7 @@
 
 struct stv6110x_devctl {
 	int (*tuner_init) (struct dvb_frontend *fe);
+	int (*tuner_sleep) (struct dvb_frontend *fe);
 	int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode);
 	int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency);
 	int (*tuner_get_frequency) (struct dvb_frontend *fe, u32 *frequency);
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index 1500210..e5cb102 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -442,6 +442,7 @@
 	.repeater_level		= STV090x_RPTLEVEL_16,
 
 	.tuner_init		= NULL,
+	.tuner_sleep		= NULL,
 	.tuner_set_mode		= NULL,
 	.tuner_set_frequency	= NULL,
 	.tuner_get_frequency	= NULL,
@@ -628,6 +629,7 @@
 						 &budget->i2c_adap);
 
 				tt1600_stv090x_config.tuner_init	  = ctl->tuner_init;
+				tt1600_stv090x_config.tuner_sleep	  = ctl->tuner_sleep;
 				tt1600_stv090x_config.tuner_set_mode	  = ctl->tuner_set_mode;
 				tt1600_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency;
 				tt1600_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency;