Esempio n. 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);
}
Esempio n. 2
0
static int pps_cdev_release(struct inode *inode, struct file *file)
{
	struct pps_device *pps = file->private_data;

	/* Free the PPS source and wake up (possible) deregistration */
	pps_put_source(pps);

	return 0;
}
Esempio n. 3
0
void pps_unregister_source(int source)
{
	struct pps_device *pps;

	spin_lock_irq(&pps_idr_lock);
	pps = idr_find(&pps_idr, source);

	if (!pps) {
		BUG();
		spin_unlock_irq(&pps_idr_lock);
		return;
	}
	spin_unlock_irq(&pps_idr_lock);

	pps_unregister_cdev(pps);
	pps_put_source(pps);
}