Esempio n. 1
0
static int dvb_frontend_thread(void *data)
{
	struct dvb_frontend *fe = data;
	struct dvb_frontend_private *fepriv = fe->frontend_priv;
	unsigned long timeout;
	char name [15];
	fe_status_t s;
	struct dvb_frontend_parameters *params;

	dprintk("%s\n", __FUNCTION__);

	snprintf (name, sizeof(name), "kdvb-fe-%i", fe->dvb->num);

	lock_kernel();
	daemonize(name);
	sigfillset(&current->blocked);
	unlock_kernel();

	fepriv->check_wrapped = 0;
	fepriv->quality = 0;
	fepriv->delay = 3*HZ;
	fepriv->status = 0;
	fepriv->wakeup = 0;
	fepriv->reinitialise = 0;

	dvb_frontend_init(fe);

	while (1) {
		up(&fepriv->sem);	    /* is locked when we enter the thread... */

		timeout = wait_event_interruptible_timeout(fepriv->wait_queue,
							   dvb_frontend_should_wakeup(fe),
							   fepriv->delay);
		if (0 != dvb_frontend_is_exiting(fe)) {
			/* got signal or quitting */
			break;
		}

		try_to_freeze();

		if (down_interruptible(&fepriv->sem))
			break;

		if (fepriv->reinitialise) {
			dvb_frontend_init(fe);
			if (fepriv->tone != -1) {
				fe->ops.set_tone(fe, fepriv->tone);
			}
			if (fepriv->voltage != -1) {
				fe->ops.set_voltage(fe, fepriv->voltage);
			}
			fepriv->reinitialise = 0;
		}

		/* do an iteration of the tuning loop */
		if (fe->ops.get_frontend_algo) {
			if (fe->ops.get_frontend_algo(fe) == FE_ALGO_HW) {
				/* have we been asked to retune? */
				params = NULL;
				if (fepriv->state & FESTATE_RETUNE) {
					params = &fepriv->parameters;
					fepriv->state = FESTATE_TUNED;
				}

				fe->ops.tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s);
				if (s != fepriv->status) {
					dvb_frontend_add_event(fe, s);
					fepriv->status = s;
				}
			} else
				dvb_frontend_swzigzag(fe);
		} else
			dvb_frontend_swzigzag(fe);
	}

	if (dvb_shutdown_timeout) {
		if (dvb_powerdown_on_sleep)
			if (fe->ops.set_voltage)
				fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF);
		if (fe->ops.tuner_ops.sleep) {
			fe->ops.tuner_ops.sleep(fe);
			if (fe->ops.i2c_gate_ctrl)
				fe->ops.i2c_gate_ctrl(fe, 0);
		}
		if (fe->ops.sleep)
			fe->ops.sleep(fe);
	}

	fepriv->thread_pid = 0;
	mb();

	dvb_frontend_wakeup(fe);
	return 0;
}
Esempio n. 2
0
static int dvb_frontend_thread(void *data)
{
    struct dvb_frontend *fe = data;
    struct dvb_frontend_private *fepriv = fe->frontend_priv;
    unsigned long timeout;
    fe_status_t s;
    struct dvb_frontend_parameters *params;

    dprintk("%s\n", __func__);

    fepriv->check_wrapped = 0;
    fepriv->quality = 0;
    fepriv->delay = 3*HZ;
    fepriv->status = 0;
    fepriv->wakeup = 0;
    fepriv->reinitialise = 0;

    dvb_frontend_init(fe);

    set_freezable();
    while (1) {
        up(&fepriv->sem);        /* is locked when we enter the thread... */
restart:
        timeout = wait_event_interruptible_timeout(fepriv->wait_queue,
            dvb_frontend_should_wakeup(fe) || kthread_should_stop()
                || freezing(current),
            fepriv->delay);

        if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) {
            /* got signal or quitting */
            break;
        }

        if (try_to_freeze())
            goto restart;

        if (down_interruptible(&fepriv->sem))
            break;

        if (fepriv->reinitialise) {
            dvb_frontend_init(fe);
            if (fepriv->tone != -1) {
                fe->ops.set_tone(fe, fepriv->tone);
            }
            if (fepriv->voltage != -1) {
                fe->ops.set_voltage(fe, fepriv->voltage);
            }
            fepriv->reinitialise = 0;
        }

        /* do an iteration of the tuning loop */
        if (fe->ops.get_frontend_algo) {
            if (fe->ops.get_frontend_algo(fe) == FE_ALGO_HW) {
                /* have we been asked to retune? */
                params = NULL;
                if (fepriv->state & FESTATE_RETUNE) {
                    params = &fepriv->parameters;
                    fepriv->state = FESTATE_TUNED;
                }

                fe->ops.tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s);
                if (s != fepriv->status) {
                    dvb_frontend_add_event(fe, s);
                    fepriv->status = s;
                }
            } else
                dvb_frontend_swzigzag(fe);
        } else
            dvb_frontend_swzigzag(fe);
    }

    if (dvb_powerdown_on_sleep) {
        if (fe->ops.set_voltage)
            fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF);
        if (fe->ops.tuner_ops.sleep) {
            fe->ops.tuner_ops.sleep(fe);
            if (fe->ops.i2c_gate_ctrl)
                fe->ops.i2c_gate_ctrl(fe, 0);
        }
        if (fe->ops.sleep)
            fe->ops.sleep(fe);
    }

    fepriv->thread = NULL;
    mb();

    dvb_frontend_wakeup(fe);
    return 0;
}