Exemple #1
0
void pps_event(int source, struct pps_ktime *ts, int event, void *data)
{
	struct pps_device *pps;
	unsigned long flags;

	if ((event & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR)) == 0) {
		printk(KERN_ERR "pps: unknown event (%x) for source %d\n",
			event, source);
		return;
	}

	pps = pps_get_source(source);
	if (!pps)
		return;

	pr_debug("PPS event on source %d at %llu.%06u\n",
			pps->id, (unsigned long long) ts->sec, ts->nsec);

	spin_lock_irqsave(&pps->lock, flags);

	/* Must call the echo function? */
	if ((pps->params.mode & (PPS_ECHOASSERT | PPS_ECHOCLEAR)))
		pps->info.echo(source, event, data);

	/* Check the event */
	pps->current_mode = pps->params.mode;
	if (event & PPS_CAPTUREASSERT) {
		/* We have to add an offset? */
		if (pps->params.mode & PPS_OFFSETASSERT)
			pps_add_offset(ts, &pps->params.assert_off_tu);

		/* Save the time stamp */
		pps->assert_tu = *ts;
		pps->assert_sequence++;
		pr_debug("capture assert seq #%u for source %d\n",
			pps->assert_sequence, source);
	}
	if (event & PPS_CAPTURECLEAR) {
		/* We have to add an offset? */
		if (pps->params.mode & PPS_OFFSETCLEAR)
			pps_add_offset(ts, &pps->params.clear_off_tu);

		/* Save the time stamp */
		pps->clear_tu = *ts;
		pps->clear_sequence++;
		pr_debug("capture clear seq #%u for source %d\n",
			pps->clear_sequence, source);
	}

	pps->go = ~0;
	wake_up_interruptible(&pps->queue);

	kill_fasync(&pps->async_queue, SIGIO, POLL_IN);

	spin_unlock_irqrestore(&pps->lock, flags);

	/* Now we can release the PPS source for (possible) deregistration */
	pps_put_source(pps);
}
Exemple #2
0
/* pps_event - register a PPS event into the system
 * @pps: the PPS device
 * @ts: the event timestamp
 * @event: the event type
 * @data: userdef pointer
 *
 * This function is used by each PPS client in order to register a new
 * PPS event into the system (it's usually called inside an IRQ handler).
 *
 * If an echo function is associated with the PPS device it will be called
 * as:
 *	pps->info.echo(pps, event, data);
 */
void pps_event(struct pps_device *pps, struct pps_event_time *ts, int event,
		void *data)
{
	unsigned long flags;
	int captured = 0;
	struct pps_ktime ts_real;

	/* check event type */
	BUG_ON((event & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR)) == 0);

	dev_dbg(pps->dev, "PPS event at %ld.%09ld\n",
			ts->ts_real.tv_sec, ts->ts_real.tv_nsec);

	timespec_to_pps_ktime(&ts_real, ts->ts_real);

	spin_lock_irqsave(&pps->lock, flags);

	/* Must call the echo function? */
	if ((pps->params.mode & (PPS_ECHOASSERT | PPS_ECHOCLEAR)))
		pps->info.echo(pps, event, data);

	/* Check the event */
	pps->current_mode = pps->params.mode;
	if (event & pps->params.mode & PPS_CAPTUREASSERT) {
		/* We have to add an offset? */
		if (pps->params.mode & PPS_OFFSETASSERT)
			pps_add_offset(&ts_real,
					&pps->params.assert_off_tu);

		/* Save the time stamp */
		pps->assert_tu = ts_real;
		pps->assert_sequence++;
		dev_dbg(pps->dev, "capture assert seq #%u\n",
			pps->assert_sequence);

		captured = ~0;
	}
	if (event & pps->params.mode & PPS_CAPTURECLEAR) {
		/* We have to add an offset? */
		if (pps->params.mode & PPS_OFFSETCLEAR)
			pps_add_offset(&ts_real,
					&pps->params.clear_off_tu);

		/* Save the time stamp */
		pps->clear_tu = ts_real;
		pps->clear_sequence++;
		dev_dbg(pps->dev, "capture clear seq #%u\n",
			pps->clear_sequence);

		captured = ~0;
	}

	pps_kc_event(pps, ts, event);

	/* Wake up if captured something */
	if (captured) {
		pps->last_ev++;
		wake_up_interruptible_all(&pps->queue);

		kill_fasync(&pps->async_queue, SIGIO, POLL_IN);
	}

	spin_unlock_irqrestore(&pps->lock, flags);
}