Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 276b282e authored by Rodolfo Giometti's avatar Rodolfo Giometti Committed by Linus Torvalds
Browse files

pps: events reporting fix up



PPS events must be recorded according to PPS's mode settings.

If a process asks for (i.e.) capture-assert events only, when the PPS
client calls the pps_event() function to save the current PPS event, we
should verify the event type and then discard unwanted ones.

Also, without this patch userland processes waiting for a specific PPS
event (assert or clear but not both) may be awakened at wrong time.

Signed-off-by: default avatarRodolfo Giometti <giometti@linux.it>
Tested-by: default avatarWilliam S. Brasher <billb958@door.net>
Tested-by: default avatarReg Clemens <clemens@dwf.com>
Cc: <stable@kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent cbf83cc5
Loading
Loading
Loading
Loading
+15 −5
Original line number Diff line number Diff line
@@ -271,6 +271,7 @@ void pps_event(int source, struct pps_ktime *ts, int event, void *data)
{
	struct pps_device *pps;
	unsigned long flags;
	int captured = 0;

	if ((event & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR)) == 0) {
		printk(KERN_ERR "pps: unknown event (%x) for source %d\n",
@@ -293,7 +294,8 @@ void pps_event(int source, struct pps_ktime *ts, int event, void *data)

	/* Check the event */
	pps->current_mode = pps->params.mode;
	if (event & PPS_CAPTUREASSERT) {
	if ((event & PPS_CAPTUREASSERT) &
			(pps->params.mode & PPS_CAPTUREASSERT)) {
		/* We have to add an offset? */
		if (pps->params.mode & PPS_OFFSETASSERT)
			pps_add_offset(ts, &pps->params.assert_off_tu);
@@ -303,8 +305,11 @@ void pps_event(int source, struct pps_ktime *ts, int event, void *data)
		pps->assert_sequence++;
		pr_debug("capture assert seq #%u for source %d\n",
			pps->assert_sequence, source);

		captured = ~0;
	}
	if (event & PPS_CAPTURECLEAR) {
	if ((event & PPS_CAPTURECLEAR) &
			(pps->params.mode & PPS_CAPTURECLEAR)) {
		/* We have to add an offset? */
		if (pps->params.mode & PPS_OFFSETCLEAR)
			pps_add_offset(ts, &pps->params.clear_off_tu);
@@ -314,12 +319,17 @@ void pps_event(int source, struct pps_ktime *ts, int event, void *data)
		pps->clear_sequence++;
		pr_debug("capture clear seq #%u for source %d\n",
			pps->clear_sequence, source);

		captured = ~0;
	}

	/* Wake up iif captured somthing */
	if (captured) {
		pps->go = ~0;
		wake_up_interruptible(&pps->queue);

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

	spin_unlock_irqrestore(&pps->lock, flags);