From: Daniel Scheller <d.schel...@gmx.net>

When a parent (demod) driver encounters and signals a problem with
gate_ctrl(), don't blindly continue poking the I2C bus.

Signed-off-by: Daniel Scheller <d.schel...@gmx.net>
Tested-by: Richard Scobie <rasco...@slingshot.co.nz>
---
 drivers/media/dvb-frontends/stv6111.c | 44 +++++++++++++++++++++--------------
 1 file changed, 27 insertions(+), 17 deletions(-)

diff --git a/drivers/media/dvb-frontends/stv6111.c 
b/drivers/media/dvb-frontends/stv6111.c
index e3e90070e293..789f7b61e628 100644
--- a/drivers/media/dvb-frontends/stv6111.c
+++ b/drivers/media/dvb-frontends/stv6111.c
@@ -424,6 +424,7 @@ static int set_bandwidth(struct dvb_frontend *fe, u32 
cutoff_frequency)
 {
        struct stv *state = fe->tuner_priv;
        u32 index = (cutoff_frequency + 999999) / 1000000;
+       int stat = 0;
 
        if (index < 6)
                index = 6;
@@ -435,12 +436,14 @@ static int set_bandwidth(struct dvb_frontend *fe, u32 
cutoff_frequency)
        state->reg[0x08] = (state->reg[0x08] & ~0xFC) | ((index - 6) << 2);
        state->reg[0x09] = (state->reg[0x09] & ~0x0C) | 0x08;
        if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       write_regs(state, 0x08, 2);
-       wait_for_call_done(state, 0x08);
-       if (fe->ops.i2c_gate_ctrl)
+               stat = fe->ops.i2c_gate_ctrl(fe, 1);
+       if (!stat) {
+               write_regs(state, 0x08, 2);
+               wait_for_call_done(state, 0x08);
+       }
+       if (fe->ops.i2c_gate_ctrl && !stat)
                fe->ops.i2c_gate_ctrl(fe, 0);
-       return 0;
+       return stat;
 }
 
 static int set_lof(struct stv *state, u32 local_frequency, u32 
cutoff_frequency)
@@ -518,6 +521,7 @@ static int set_params(struct dvb_frontend *fe)
        struct stv *state = fe->tuner_priv;
        struct dtv_frontend_properties *p = &fe->dtv_property_cache;
        u32 freq, cutoff;
+       int stat = 0;
 
        if (p->delivery_system != SYS_DVBS && p->delivery_system != SYS_DVBS2)
                return -EINVAL;
@@ -526,9 +530,10 @@ static int set_params(struct dvb_frontend *fe)
        cutoff = 5000000 + muldiv32(p->symbol_rate, 135, 200);
 
        if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       set_lof(state, freq, cutoff);
-       if (fe->ops.i2c_gate_ctrl)
+               stat = fe->ops.i2c_gate_ctrl(fe, 1);
+       if (!stat)
+               set_lof(state, freq, cutoff);
+       if (fe->ops.i2c_gate_ctrl && !stat)
                fe->ops.i2c_gate_ctrl(fe, 0);
        return 0;
 }
@@ -575,14 +580,17 @@ static int get_rf_strength(struct dvb_frontend *fe, u16 
*st)
        if ((state->reg[0x03] & 0x60) == 0) {
                /* RF Mode, Read AGC ADC */
                u8 reg = 0;
+               int stat = 0;
 
                if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 1);
-               write_reg(state, 0x02, state->reg[0x02] | 0x20);
-               read_reg(state, 2, &reg);
-               if (reg & 0x20)
+                       stat = fe->ops.i2c_gate_ctrl(fe, 1);
+               if (!stat) {
+                       write_reg(state, 0x02, state->reg[0x02] | 0x20);
                        read_reg(state, 2, &reg);
-               if (fe->ops.i2c_gate_ctrl)
+                       if (reg & 0x20)
+                               read_reg(state, 2, &reg);
+               }
+               if (fe->ops.i2c_gate_ctrl && !stat)
                        fe->ops.i2c_gate_ctrl(fe, 0);
 
                if ((state->reg[0x02] & 0x80) == 0)
@@ -652,7 +660,8 @@ struct dvb_frontend *stv6111_attach(struct dvb_frontend *fe,
                                    struct i2c_adapter *i2c, u8 adr)
 {
        struct stv *state;
-       int stat;
+       int stat = -ENODEV;
+       int gatestat = 0;
 
        state = kzalloc(sizeof(*state), GFP_KERNEL);
        if (!state)
@@ -663,9 +672,10 @@ struct dvb_frontend *stv6111_attach(struct dvb_frontend 
*fe,
        init_state(state);
 
        if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       stat = attach_init(state);
-       if (fe->ops.i2c_gate_ctrl)
+               gatestat = fe->ops.i2c_gate_ctrl(fe, 1);
+       if (!gatestat)
+               stat = attach_init(state);
+       if (fe->ops.i2c_gate_ctrl && !gatestat)
                fe->ops.i2c_gate_ctrl(fe, 0);
        if (stat < 0) {
                kfree(state);
-- 
2.13.6

Reply via email to