aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb-frontends/stv090x.c
diff options
context:
space:
mode:
authorAlexey Khoroshilov <khoroshilov@ispras.ru>2013-02-19 12:58:53 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-03-14 10:40:32 -0400
commitc67d2f074073b39e5eba84e852c894c22057d159 (patch)
tree8d8e857a7be4cd7382569495d84c324a2d93c2c4 /drivers/media/dvb-frontends/stv090x.c
parenta9fc36afc074db2d5995136b50b018c2ca77f48f (diff)
[media] stv090x: do not unlock unheld mutex in stv090x_sleep()
goto err and goto err_gateoff before mutex_lock(&state->internal->demod_lock) lead to unlock of unheld mutex in stv090x_sleep(). Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru> Cc: Manu Abraham <abraham.manu@gmail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb-frontends/stv090x.c')
-rw-r--r--drivers/media/dvb-frontends/stv090x.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c
index f36eeefb76a6..56d470ad5a82 100644
--- a/drivers/media/dvb-frontends/stv090x.c
+++ b/drivers/media/dvb-frontends/stv090x.c
@@ -3906,12 +3906,12 @@ static int stv090x_sleep(struct dvb_frontend *fe)
3906 reg = stv090x_read_reg(state, STV090x_TSTTNR1); 3906 reg = stv090x_read_reg(state, STV090x_TSTTNR1);
3907 STV090x_SETFIELD(reg, ADC1_PON_FIELD, 0); 3907 STV090x_SETFIELD(reg, ADC1_PON_FIELD, 0);
3908 if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0) 3908 if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)
3909 goto err; 3909 goto err_unlock;
3910 /* power off DiSEqC 1 */ 3910 /* power off DiSEqC 1 */
3911 reg = stv090x_read_reg(state, STV090x_TSTTNR2); 3911 reg = stv090x_read_reg(state, STV090x_TSTTNR2);
3912 STV090x_SETFIELD(reg, DISEQC1_PON_FIELD, 0); 3912 STV090x_SETFIELD(reg, DISEQC1_PON_FIELD, 0);
3913 if (stv090x_write_reg(state, STV090x_TSTTNR2, reg) < 0) 3913 if (stv090x_write_reg(state, STV090x_TSTTNR2, reg) < 0)
3914 goto err; 3914 goto err_unlock;
3915 3915
3916 /* check whether path 2 is already sleeping, that is when 3916 /* check whether path 2 is already sleeping, that is when
3917 ADC2 is off */ 3917 ADC2 is off */
@@ -3930,7 +3930,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
3930 if (full_standby) 3930 if (full_standby)
3931 STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1); 3931 STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1);
3932 if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0) 3932 if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
3933 goto err; 3933 goto err_unlock;
3934 reg = stv090x_read_reg(state, STV090x_STOPCLK2); 3934 reg = stv090x_read_reg(state, STV090x_STOPCLK2);
3935 /* sampling 1 clock */ 3935 /* sampling 1 clock */
3936 STV090x_SETFIELD(reg, STOP_CLKSAMP1_FIELD, 1); 3936 STV090x_SETFIELD(reg, STOP_CLKSAMP1_FIELD, 1);
@@ -3941,7 +3941,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
3941 if (full_standby) 3941 if (full_standby)
3942 STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1); 3942 STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1);
3943 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) 3943 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
3944 goto err; 3944 goto err_unlock;
3945 break; 3945 break;
3946 3946
3947 case STV090x_DEMODULATOR_1: 3947 case STV090x_DEMODULATOR_1:
@@ -3949,12 +3949,12 @@ static int stv090x_sleep(struct dvb_frontend *fe)
3949 reg = stv090x_read_reg(state, STV090x_TSTTNR3); 3949 reg = stv090x_read_reg(state, STV090x_TSTTNR3);
3950 STV090x_SETFIELD(reg, ADC2_PON_FIELD, 0); 3950 STV090x_SETFIELD(reg, ADC2_PON_FIELD, 0);
3951 if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0) 3951 if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0)
3952 goto err; 3952 goto err_unlock;
3953 /* power off DiSEqC 2 */ 3953 /* power off DiSEqC 2 */
3954 reg = stv090x_read_reg(state, STV090x_TSTTNR4); 3954 reg = stv090x_read_reg(state, STV090x_TSTTNR4);
3955 STV090x_SETFIELD(reg, DISEQC2_PON_FIELD, 0); 3955 STV090x_SETFIELD(reg, DISEQC2_PON_FIELD, 0);
3956 if (stv090x_write_reg(state, STV090x_TSTTNR4, reg) < 0) 3956 if (stv090x_write_reg(state, STV090x_TSTTNR4, reg) < 0)
3957 goto err; 3957 goto err_unlock;
3958 3958
3959 /* check whether path 1 is already sleeping, that is when 3959 /* check whether path 1 is already sleeping, that is when
3960 ADC1 is off */ 3960 ADC1 is off */
@@ -3973,7 +3973,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
3973 if (full_standby) 3973 if (full_standby)
3974 STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1); 3974 STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1);
3975 if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0) 3975 if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
3976 goto err; 3976 goto err_unlock;
3977 reg = stv090x_read_reg(state, STV090x_STOPCLK2); 3977 reg = stv090x_read_reg(state, STV090x_STOPCLK2);
3978 /* sampling 2 clock */ 3978 /* sampling 2 clock */
3979 STV090x_SETFIELD(reg, STOP_CLKSAMP2_FIELD, 1); 3979 STV090x_SETFIELD(reg, STOP_CLKSAMP2_FIELD, 1);
@@ -3984,7 +3984,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
3984 if (full_standby) 3984 if (full_standby)
3985 STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1); 3985 STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1);
3986 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) 3986 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
3987 goto err; 3987 goto err_unlock;
3988 break; 3988 break;
3989 3989
3990 default: 3990 default:
@@ -3997,7 +3997,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
3997 reg = stv090x_read_reg(state, STV090x_SYNTCTRL); 3997 reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
3998 STV090x_SETFIELD(reg, STANDBY_FIELD, 0x01); 3998 STV090x_SETFIELD(reg, STANDBY_FIELD, 0x01);
3999 if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0) 3999 if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0)
4000 goto err; 4000 goto err_unlock;
4001 } 4001 }
4002 4002
4003 mutex_unlock(&state->internal->demod_lock); 4003 mutex_unlock(&state->internal->demod_lock);
@@ -4005,8 +4005,10 @@ static int stv090x_sleep(struct dvb_frontend *fe)
4005 4005
4006err_gateoff: 4006err_gateoff:
4007 stv090x_i2c_gate_ctrl(state, 0); 4007 stv090x_i2c_gate_ctrl(state, 0);
4008err: 4008 goto err;
4009err_unlock:
4009 mutex_unlock(&state->internal->demod_lock); 4010 mutex_unlock(&state->internal->demod_lock);
4011err:
4010 dprintk(FE_ERROR, 1, "I/O error"); 4012 dprintk(FE_ERROR, 1, "I/O error");
4011 return -1; 4013 return -1;
4012} 4014}