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 <nengwen.chen@amlogic.com>
This commit is contained in:
nengwen.chen
2018-11-08 19:57:53 +08:00
committed by Dongjin Kim
parent 5114c47b9c
commit b3fcc9138b
3 changed files with 33 additions and 9 deletions

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;