From 33f53679484992a256e6264686db1c49c129d195 Mon Sep 17 00:00:00 2001 From: "nengwen.chen" Date: Thu, 8 Nov 2018 19:57:53 +0800 Subject: [PATCH] atv_demod: pc bad value in panic after change source [1/1] PD#SWPL-1636 Problem: 1.pc bad value in kernel panic after change source. 2.System crash down when change source. Solution: optimize atv demod code. Verify: verified by p321 Change-Id: I655d1253950475dfb49ae1b174597797000adb73 Signed-off-by: nengwen.chen --- drivers/amlogic/atv_demod/atv_demod_ops.c | 22 +++++++++++++++------- drivers/amlogic/atv_demod/atv_demod_v4l2.c | 18 ++++++++++++++++-- drivers/amlogic/atv_demod/atv_demod_v4l2.h | 2 ++ 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/drivers/amlogic/atv_demod/atv_demod_ops.c b/drivers/amlogic/atv_demod/atv_demod_ops.c index 50b556d..b620bf4 100644 --- a/drivers/amlogic/atv_demod/atv_demod_ops.c +++ b/drivers/amlogic/atv_demod/atv_demod_ops.c @@ -65,7 +65,9 @@ void aml_fe_get_atvaudio_state(int *state) } /* scan mode need mute */ - if (priv->state == ATVDEMOD_STATE_WORK && !priv->scanning) { + if (priv->state == ATVDEMOD_STATE_WORK + && !priv->scanning + && !priv->standby) { retrieve_vpll_carrier_lock(&vpll_lock); retrieve_vpll_carrier_line_lock(&line_lock); if ((vpll_lock == 0) && (line_lock == 0)) { @@ -78,8 +80,9 @@ void aml_fe_get_atvaudio_state(int *state) } } else { *state = 0; - pr_audio("%s, atv is not work, atv_state: %d.\n", - __func__, priv->state); + pr_audio("%s, ATV in state[%d], scanning[%d], standby[%d].\n", + __func__, priv->state, + priv->scanning, priv->standby); } /* If the atv signal is locked, it means there is audio data, @@ -146,6 +149,8 @@ int atv_demod_leave_mode(struct dvb_frontend *fe) { struct atv_demod_priv *priv = fe->analog_demod_priv; + priv->state = ATVDEMOD_STATE_IDEL; + if (priv->afc.disable) priv->afc.disable(&priv->afc); @@ -167,8 +172,6 @@ int atv_demod_leave_mode(struct dvb_frontend *fe) amlatvdemod_devp->audmode = 0; amlatvdemod_devp->soundsys = 0xFF; - priv->state = ATVDEMOD_STATE_IDEL; - pr_info("%s: OK.\n", __func__); return 0; @@ -183,7 +186,7 @@ static void atv_demod_set_params(struct dvb_frontend *fe, struct aml_atvdemod_parameters *p = &priv->atvdemod_param; bool reconfig = false; - priv->standby = false; + priv->standby = true; /* afc tune disable,must cancel wq before set tuner freq*/ if (priv->afc.disable) @@ -254,6 +257,8 @@ static void atv_demod_set_params(struct dvb_frontend *fe, if (priv->monitor.enable) priv->monitor.enable(&priv->monitor); } + + priv->standby = false; } static int atv_demod_has_signal(struct dvb_frontend *fe, u16 *signal) @@ -286,6 +291,7 @@ static void atv_demod_standby(struct dvb_frontend *fe) if (priv->state != ATVDEMOD_STATE_IDEL) { atv_demod_leave_mode(fe); priv->state = ATVDEMOD_STATE_SLEEP; + priv->standby = true; } pr_info("%s: OK.\n", __func__); @@ -355,8 +361,10 @@ static int atv_demod_set_config(struct dvb_frontend *fe, void *priv_cfg) case AML_ATVDEMOD_RESUME: if (priv->state == ATVDEMOD_STATE_SLEEP) { - if (!atv_demod_enter_mode(fe)) + if (!atv_demod_enter_mode(fe)) { priv->state = ATVDEMOD_STATE_WORK; + priv->standby = false; + } } break; diff --git a/drivers/amlogic/atv_demod/atv_demod_v4l2.c b/drivers/amlogic/atv_demod/atv_demod_v4l2.c index 76413a9..beaad44 100644 --- a/drivers/amlogic/atv_demod/atv_demod_v4l2.c +++ b/drivers/amlogic/atv_demod/atv_demod_v4l2.c @@ -331,6 +331,14 @@ static int v4l2_frontend_start(struct v4l2_frontend *v4l2_fe) } +static int v4l2_frontend_check_mode(struct v4l2_frontend *v4l2_fe) +{ + if (v4l2_fe->mode != V4L2_TUNER_ANALOG_TV) + return -EINVAL; + + return 0; +} + static int v4l2_set_frontend(struct v4l2_frontend *v4l2_fe, struct v4l2_analog_parameters *params) { @@ -343,6 +351,9 @@ static int v4l2_set_frontend(struct v4l2_frontend *v4l2_fe, pr_dbg("%s.\n", __func__); + if (v4l2_frontend_check_mode(v4l2_fe) < 0) + return -EINVAL; + freq_min = fe->ops.tuner_ops.info.frequency_min; freq_max = fe->ops.tuner_ops.info.frequency_max; @@ -419,10 +430,13 @@ static int v4l2_frontend_set_mode(struct v4l2_frontend *v4l2_fe, analog_ops = &v4l2_fe->fe.ops.analog_ops; - if (params) + if (params) { priv_cfg = AML_ATVDEMOD_INIT; - else + v4l2_fe->mode = V4L2_TUNER_ANALOG_TV; + } else { priv_cfg = AML_ATVDEMOD_UNINIT; + v4l2_fe->mode = V4L2_TUNER_RF; + } if (analog_ops && analog_ops->set_config) ret = analog_ops->set_config(&v4l2_fe->fe, &priv_cfg); diff --git a/drivers/amlogic/atv_demod/atv_demod_v4l2.h b/drivers/amlogic/atv_demod/atv_demod_v4l2.h index 0b2c9cd..0683c94 100644 --- a/drivers/amlogic/atv_demod/atv_demod_v4l2.h +++ b/drivers/amlogic/atv_demod/atv_demod_v4l2.h @@ -199,6 +199,8 @@ struct v4l2_frontend { unsigned int tuner_id; struct i2c_client i2c; + enum v4l2_tuner_type mode; + void *frontend_priv; void *tuner_priv; void *analog_demod_priv; -- 2.7.4